commit: e5c884abfc5a00fad25c7086bc987f003f0b5473
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 25 17:32:40 2022 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon Jul 25 17:32:40 2022 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=e5c884ab
*: drop Interix/WinNT support
Support for this was dropped from the tree long ago.
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
bin/misc-functions.sh | 128 -----------
bin/readpecoff | 108 ----------
lib/portage/dbapi/vartree.py | 5 -
lib/portage/util/_dyn_libs/LinkageMapPeCoff.py | 286 -------------------------
4 files changed, 527 deletions(-)
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index 786c06c04..313fe0570 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -172,10 +172,6 @@ install_qa_check() {
# Mach-O platforms (NeXT, Darwin, OSX/macOS)
install_qa_check_macho
;;
- *-interix*|*-winnt*)
- # PECOFF platforms (Windows/Interix)
- install_qa_check_pecoff
- ;;
*)
# because this is the majority: ELF platforms
(Linux,
# Solaris, *BSD, IRIX, etc.)
@@ -437,130 +433,6 @@ install_qa_check_macho() {
fi
}
-install_qa_check_pecoff() {
- local _pfx_scan="readpecoff ${CHOST}"
-
- # this one uses readpecoff, which supports multiple prefix platforms!
- # this is absolutely _not_ optimized for speed, and there may be plenty
- # of possibilities by introducing one or the other cache!
- if ! has binchecks ${RESTRICT}; then
- # copied and adapted from the above scanelf code.
- local qa_var insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET}
- local f x
-
- # display warnings when using stricter because we die afterwards
- if has stricter ${FEATURES} ; then
- unset PORTAGE_QUIET
- fi
-
- local _exec_find_opt="-executable"
- [[ ${CHOST} == *-winnt* ]] && _exec_find_opt='-name *.dll -o
-name *.exe'
-
- # Make sure we disallow insecure RUNPATH/RPATH's
- # Don't want paths that point to the tree where the package was
built
- # (older, broken libtools would do this). Also check for null
paths
- # because the loader will search $PWD when it finds null paths.
-
- f=$(
- find "${ED}" -type f '(' ${_exec_find_opt} ')' -print0
| xargs -0 ${_pfx_scan} | \
- while IFS=";" read arch obj soname rpath needed ; do \
- echo "${rpath}" | grep -E "(${PORTAGE_BUILDDIR}|:
|::|^:|^ )" > /dev/null 2>&1 \
- && echo "${obj}"; done;
- )
- # Reject set*id binaries with $ORIGIN in RPATH #260331
- x=$(
- find "${ED}" -type f '(' -perm -u+s -o -perm -g+s ')'
-print0 | \
- xargs -0 ${_pfx_scan} | while IFS=";" read arch obj
soname rpath needed; do \
- echo "${rpath}" | grep '$ORIGIN' > /dev/null 2>&1 &&
echo "${obj}"; done;
- )
- if [[ -n ${f}${x} ]] ; then
- __vecho -ne '\a\n'
- eqawarn "QA Notice: The following files contain
insecure RUNPATH's"
- eqawarn " Please file a bug about this at
http://bugs.gentoo.org/"
- eqawarn " with the maintaining herd of the package."
- eqawarn "${f}${f:+${x:+\n}}${x}"
- __vecho -ne '\a\n'
- if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
- insecure_rpath=1
- else
- eqawarn "cannot automatically fix runpaths on
interix platforms!"
- fi
- fi
-
- rm -f "${PORTAGE_BUILDDIR}"/build-info/NEEDED
- rm -f "${PORTAGE_BUILDDIR}"/build-info/NEEDED.PECOFF.1
-
- # Save NEEDED information after removing self-contained
providers
- find "${ED}" -type f '(' ${_exec_find_opt} ')' -print0 | xargs
-0 ${_pfx_scan} | { while IFS=';' read arch obj soname rpath needed; do
- # need to strip image dir from object name.
- obj="/${obj#${D}}"
- if [ -z "${rpath}" -o -n "${rpath//*ORIGIN*}" ]; then
- # object doesn't contain $ORIGIN in its runpath
attribute
- echo "${obj} ${needed}" >>
"${PORTAGE_BUILDDIR}"/build-info/NEEDED
- echo
"${arch};${obj};${soname};${rpath};${needed}" >>
"${PORTAGE_BUILDDIR}"/build-info/NEEDED.PECOFF.1
- else
- dir=${obj%/*}
- # replace $ORIGIN with the dirname of the
current object for the lookup
- opath=$(echo :${rpath}: | sed -e
"s#.*:\(.*\)\$ORIGIN\(.*\):.*#\1${dir}\2#")
- sneeded=$(echo ${needed} | tr , ' ')
- rneeded=""
- for lib in ${sneeded}; do
- found=0
- for path in ${opath//:/ }; do
- [ -e "${ED}/${path}/${lib}" ]
&& found=1 && break
- done
- [ "${found}" -eq 0 ] &&
rneeded="${rneeded},${lib}"
- done
- rneeded=${rneeded:1}
- if [ -n "${rneeded}" ]; then
- echo "${obj} ${rneeded}" >>
"${PORTAGE_BUILDDIR}"/build-info/NEEDED
- echo
"${arch};${obj};${soname};${rpath};${rneeded}" >>
"${PORTAGE_BUILDDIR}"/build-info/NEEDED.PECOFF.1
- fi
- fi
- done }
-
- if [[ ${insecure_rpath} -eq 1 ]] ; then
- die "Aborting due to serious QA concerns with
RUNPATH/RPATH"
- elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
- die "Aborting due to QA concerns: ${die_msg}"
- fi
-
- local _so_ext='.so*'
-
- case "${CHOST}" in
- *-winnt*) _so_ext=".dll" ;; # no "*" intentionally!
- esac
-
- # Run some sanity checks on shared libraries
- for d in "${ED}"lib* "${ED}"usr/lib* ; do
- [[ -d "${d}" ]] || continue
- f=$(find "${d}" -name "lib*${_so_ext}" -print0 | \
- xargs -0 ${_pfx_scan} | while IFS=";" read arch
obj soname rpath needed; \
- do [[ -z "${soname}" ]] && echo "${obj}"; done)
- if [[ -n ${f} ]] ; then
- __vecho -ne '\a\n'
- eqawarn "QA Notice: The following shared
libraries lack a SONAME"
- eqawarn "${f}"
- __vecho -ne '\a\n'
- sleep 1
- fi
-
- f=$(find "${d}" -name "lib*${_so_ext}" -print0 | \
- xargs -0 ${_pfx_scan} | while IFS=";" read arch
obj soname rpath needed; \
- do [[ -z "${needed}" ]] && echo "${obj}"; done)
- if [[ -n ${f} ]] ; then
- __vecho -ne '\a\n'
- eqawarn "QA Notice: The following shared
libraries lack NEEDED entries"
- eqawarn "${f}"
- __vecho -ne '\a\n'
- sleep 1
- fi
- done
-
- PORTAGE_QUIET=${tmp_quiet}
- fi
-}
-
__dyn_instprep() {
if [[ -e ${PORTAGE_BUILDDIR}/.instprepped ]] ; then
__vecho ">>> It appears that '$PF' is already instprepped;
skipping."
diff --git a/bin/readpecoff b/bin/readpecoff
deleted file mode 100755
index acd163a24..000000000
--- a/bin/readpecoff
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env bash
-
-###################################################################
-# This script does the following: for implemented platforms, #
-# it echos for each given path a line with the following format: #
-# #
-# <arch>;<obj>;<soname>;<rpath1:rpathN>;<needed1,neededN> #
-# #
-# arch may be any string, e.g. "PE32". obj is the full (!) path #
-# to the file itself. soname, rpath and needed should be self #
-# explaining - rpath is ":" separated, needed is "," separated. #
-# #
-# WARNING: Depends on CHOST argument to decide what to do! #
-# #
-# WARNING: The Script does _never_ fail! If required binaries #
-# are missing, or information gathering fails, the #
-# script will SILENTLY (!) exit, to not disturb the #
-# normal merging process. #
-# #
-# WARNING: The _first_ argument needs to be a valid CHOST!!! #
-# #
-###################################################################
-
-
-# Interix: Uses native objdump, since thats the only facility that
-# knows about the native shared library information data.
-# objdump is there in all interix installations where the GNU SDK
-# is installed, which is a prerequisite for prefix anyway.
-
-scanbin_interix() {
- local _itx_objdump="/opt/gcc.3.3/bin/objdump"
- [[ -x ${_itx_objdump} ]] || _itx_objdump="/opt/gcc.4.2/bin/objdump"
- [[ -x ${_itx_objdump} ]] || exit 0
-
- # objdump is there, so now gather the information
- _itx_full_info() {
- local obj="$(cd "$(dirname "$1")"; pwd)/${1##*/}"
- local so=
- local rp=
- local ne=
-
- { file -L "${obj}" | grep "PE" > /dev/null 2>&1; } || return
-
- _itx_gather() {
- ${_itx_objdump} -p "$1" | while IFS= read line; do
- [[ ${line} == *RPATH* || ${line} == *NEEDED* ||
${line} == *SONAME* ]] || continue
-
- eval "$(echo "${line}" | sed -e
's,[[:space:]]*\([A-Z]*\)[[:space:]]*\(.*\)$,key=\1;value="\2",g')"
-
- case "${key}" in
- RPATH) echo "rp=\"${value}\"" ;;
- NEEDED) echo "test -n \"\${ne}\" &&
ne=\"\${ne},${value}\"; test -z \"\${ne}\" && ne=\"${value}\"" ;;
- SONAME) echo "so=\"${value}\"" ;;
- esac
- done
- }
-
- eval "$(_itx_gather ${obj})"
- echo "386;${obj};${so};${rp};${ne}"
- }
-
- for x in "$@"; do
- _itx_full_info "${x}"
- done
-
- exit 0
-}
-
-
-# Native Windows: Uses the winnt compiler ("parity") to gather
-# information. parity is the only one knowing about the location
-# and format of the relevant data, and it is there always when
-# wanting to build native win32 executables.
-
-scanbin_winnt() {
- local _winnt_inspector="$(type -P "parity.inspector")"
- [[ -x ${_winnt_inspector} ]] || exit 0
-
- _winnt_full_info () {
- local obj="$(cd "$(dirname "$1")"; pwd)/${1##*/}"
-
- { file -L "${obj}" | grep "PE" > /dev/null 2>&1; } || exit 0
-
- # parity.inspector in --raw mode has exactly the format we
- # want - wonder, wonder, i implemented that switch :)
-
- local info="$(${_winnt_inspector} --raw "${obj}")"
- echo "386;${obj};${info}"
- }
-
- for x in "$@"; do
- _winnt_full_info "${x}"
- done
-}
-
-# CHOST is the first argument!
-_chost=$1
-
-# verify CHOST...
-[[ -z ${_chost} ]] && { echo "CHOST not set!!"; exit 1; }
-[[ ${_chost} == *-*-* ]] || { echo "invalid CHOST!!"; exit 1; }
-shift
-
-case "${_chost}" in
-*-interix*) scanbin_interix "$@" ;;
-*-winnt*) scanbin_winnt "$@" ;;
-esac
-
diff --git a/lib/portage/dbapi/vartree.py b/lib/portage/dbapi/vartree.py
index 7a41fae01..db05aaa01 100644
--- a/lib/portage/dbapi/vartree.py
+++ b/lib/portage/dbapi/vartree.py
@@ -40,7 +40,6 @@ portage.proxy.lazyimport.lazyimport(
"portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap",
# BEGIN PREFIX LOCAL
'portage.util._dyn_libs.LinkageMapMachO:LinkageMapMachO',
- 'portage.util._dyn_libs.LinkageMapPeCoff:LinkageMapPeCoff',
# END PREFIX LOCAL
"portage.util._dyn_libs.NeededEntry:NeededEntry",
"portage.util._async.SchedulerInterface:SchedulerInterface",
@@ -246,8 +245,6 @@ class vardbapi(dbapi):
chost = 'lunix?' # this happens when profiles are not available
if chost.find('darwin') >= 0:
self._linkmap = LinkageMapMachO(self)
- elif chost.find('interix') >= 0 or chost.find('winnt') >= 0:
- self._linkmap = LinkageMapPeCoff(self)
else:
self._linkmap = LinkageMap(self)
# END PREFIX LOCAL
@@ -3772,8 +3769,6 @@ class dblink:
chost = self.settings.get('CHOST')
if chost.find('darwin') >= 0:
node =
LinkageMapMachO._LibGraphNode(linkmap._obj_key(path))
- elif chost.find('interix') >= 0 or chost.find('winnt') >= 0:
- node =
LinkageMapPeCoff._LibGraphNode(linkmap._obj_key(path))
else:
node = LinkageMap._LibGraphNode(linkmap._obj_key(path))
# END PREFIX LOCAL
diff --git a/lib/portage/util/_dyn_libs/LinkageMapPeCoff.py
b/lib/portage/util/_dyn_libs/LinkageMapPeCoff.py
deleted file mode 100644
index fd0ab6ee8..000000000
--- a/lib/portage/util/_dyn_libs/LinkageMapPeCoff.py
+++ /dev/null
@@ -1,286 +0,0 @@
-# Copyright 1998-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-import errno
-import logging
-import subprocess
-
-import portage
-from portage import _encodings
-from portage import _os_merge
-from portage import _unicode_decode
-from portage import _unicode_encode
-from portage.cache.mappings import slot_dict_class
-from portage.exception import CommandNotFound
-from portage.localization import _
-from portage.util import getlibpaths
-from portage.util import grabfile
-from portage.util import normalize_path
-from portage.util import writemsg_level
-from portage.const import EPREFIX
-from portage.util._dyn_libs.LinkageMapELF import LinkageMapELF
-
-class LinkageMapPeCoff(LinkageMapELF):
-
- """Models dynamic linker dependencies."""
-
- # NEEDED.PECOFF.1 has effectively the _same_ format as NEEDED.ELF.2,
- # but we keep up the relation "scanelf" -> "NEEDED.ELF", "readpecoff" ->
- # "NEEDED.PECOFF", "scanmacho" -> "NEEDED.MACHO", etc. others will
follow.
- _needed_aux_key = "NEEDED.PECOFF.1"
-
- class _ObjectKey(LinkageMapELF._ObjectKey):
-
- """Helper class used as _obj_properties keys for objects."""
-
- def _generate_object_key(self, obj, root):
- """
- Generate object key for a given object. This is
different from the
- Linux implementation, since some systems (e.g. interix)
don't have
- "inodes", thus the inode field is always zero, or a
random value,
- making it inappropriate for identifying a file... :)
-
- @param object: path to a file
- @type object: string (example: '/usr/bin/bar')
- @rtype: 2-tuple of types (bool, string)
- @return:
- 2-tuple of boolean indicating existance, and
absolut path
- """
-
- os = _os_merge
-
- try:
- _unicode_encode(obj,
- encoding=_encodings['merge'],
errors='strict')
- except UnicodeEncodeError:
- # The package appears to have been merged with
a
- # different value of
sys.getfilesystemencoding(),
- # so fall back to utf_8 if appropriate.
- try:
- _unicode_encode(obj,
- encoding=_encodings['fs'],
errors='strict')
- except UnicodeEncodeError:
- pass
- else:
- os = portage.os
-
- abs_path = os.path.join(root, obj.lstrip(os.sep))
- try:
- object_stat = os.stat(abs_path)
- except OSError:
- return (False, os.path.realpath(abs_path))
- # On Interix, the inode field may always be zero, since
the
- # filesystem (NTFS) has no inodes ...
- return (True, os.path.realpath(abs_path))
-
- def file_exists(self):
- """
- Determine if the file for this key exists on the
filesystem.
-
- @rtype: Boolean
- @return:
- 1. True if the file exists.
- 2. False if the file does not exist or is a
broken symlink.
-
- """
- return self._key[0]
-
- class _LibGraphNode(_ObjectKey):
- __slots__ = ("alt_paths",)
-
- def __init__(self, key):
- """
- Create a _LibGraphNode from an existing _ObjectKey.
- This re-uses the _key attribute in order to avoid
repeating
- any previous stat calls, which helps to avoid potential
race
- conditions due to inconsistent stat results when the
- file system is being modified concurrently.
- """
- self._key = key._key
- self.alt_paths = set()
-
- def __str__(self):
- return str(sorted(self.alt_paths))
-
- def rebuild(self, exclude_pkgs=None, include_file=None,
- preserve_paths=None):
- """
- Raises CommandNotFound if there are preserved libs
- and the readpecoff binary is not available.
-
- @param exclude_pkgs: A set of packages that should be excluded
from
- the LinkageMap, since they are being unmerged and their
NEEDED
- entries are therefore irrelevant and would only serve
to corrupt
- the LinkageMap.
- @type exclude_pkgs: set
- @param include_file: The path of a file containing NEEDED
entries for
- a package which does not exist in the vardbapi yet
because it is
- currently being merged.
- @type include_file: String
- @param preserve_paths: Libraries preserved by a package
instance that
- is currently being merged. They need to be explicitly
passed to the
- LinkageMap, since they are not registered in the
- PreservedLibsRegistry yet.
- @type preserve_paths: set
- """
-
- os = _os_merge
- root = self._root
- root_len = len(root) - 1
- self._clear_cache()
- self._defpath.update(getlibpaths(self._root,
env=self._dbapi.settings))
- libs = self._libs
- obj_properties = self._obj_properties
-
- lines = []
-
- # Data from include_file is processed first so that it
- # overrides any data from previously installed files.
- if include_file is not None:
- for line in grabfile(include_file):
- lines.append((None, include_file, line))
-
- aux_keys = [self._needed_aux_key]
- can_lock = os.access(os.path.dirname(self._dbapi._dbroot),
os.W_OK)
- if can_lock:
- self._dbapi.lock()
- try:
- for cpv in self._dbapi.cpv_all():
- if exclude_pkgs is not None and cpv in
exclude_pkgs:
- continue
- needed_file = self._dbapi.getpath(cpv,
- filename=self._needed_aux_key)
- for line in self._dbapi.aux_get(cpv,
aux_keys)[0].splitlines():
- lines.append((cpv, needed_file, line))
- finally:
- if can_lock:
- self._dbapi.unlock()
-
- # have to call readpecoff for preserved libs here as they
aren't
- # registered in NEEDED.PECOFF.1 files
- plibs = {}
- if preserve_paths is not None:
- plibs.update((x, None) for x in preserve_paths)
- if self._dbapi._plib_registry and \
- self._dbapi._plib_registry.hasEntries():
- for cpv, items in \
-
self._dbapi._plib_registry.getPreservedLibs().items():
- if exclude_pkgs is not None and cpv in
exclude_pkgs:
- # These preserved libs will either be
unmerged,
- # rendering them irrelevant, or they
will be
- # preserved in the replacement package
and are
- # already represented via the
preserve_paths
- # parameter.
- continue
- plibs.update((x, cpv) for x in items)
- if plibs:
- args = ["readpecoff", self._dbapi.settings.get('CHOST')]
- args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
- for x in plibs)
- try:
- proc = subprocess.Popen(args,
stdout=subprocess.PIPE)
- except EnvironmentError as e:
- if e.errno != errno.ENOENT:
- raise
- raise CommandNotFound(args[0])
- else:
- for l in proc.stdout:
- try:
- l = _unicode_decode(l,
-
encoding=_encodings['content'], errors='strict')
- except UnicodeDecodeError:
- l = _unicode_decode(l,
-
encoding=_encodings['content'], errors='replace')
- writemsg_level(_("\nError
decoding characters " \
- "returned from
readpecoff: %s\n\n") % (l,),
- level=logging.ERROR,
noiselevel=-1)
- l = l[3:].rstrip("\n")
- if not l:
- continue
- fields = l.split(";")
- if len(fields) < 5:
- writemsg_level(_("\nWrong
number of fields " \
- "returned from
readpecoff: %s\n\n") % (l,),
- level=logging.ERROR,
noiselevel=-1)
- continue
- fields[1] = fields[1][root_len:]
- owner = plibs.pop(fields[1], None)
- lines.append((owner, "readpecoff",
";".join(fields)))
- proc.wait()
-
- if plibs:
- # Preserved libraries that did not appear in the
scanelf output.
- # This is known to happen with statically linked
libraries.
- # Generate dummy lines for these, so we can assume that
every
- # preserved library has an entry in
self._obj_properties. This
- # is important in order to prevent findConsumers from
raising
- # an unwanted KeyError.
- for x, cpv in plibs.items():
- lines.append((cpv, "plibs", ";".join(['', x,
'', '', ''])))
-
- # Share identical frozenset instances when available,
- # in order to conserve memory.
- frozensets = {}
-
- for owner, location, l in lines:
- l = l.rstrip("\n")
- if not l:
- continue
- fields = l.split(";")
- if len(fields) < 5:
- writemsg_level(_("\nWrong number of fields " \
- "in %s: %s\n\n") % (location, l),
- level=logging.ERROR, noiselevel=-1)
- continue
- arch = fields[0]
- obj = fields[1]
- soname = fields[2]
- path = frozenset(normalize_path(x) \
- for x in filter(None, fields[3].replace(
- "${ORIGIN}", os.path.dirname(obj)).replace(
- "$ORIGIN", os.path.dirname(obj)).split(":")))
- path = frozensets.setdefault(path, path)
- needed = frozenset(x for x in fields[4].split(",") if x)
- needed = frozensets.setdefault(needed, needed)
-
- obj_key = self._obj_key(obj)
- indexed = True
- myprops = obj_properties.get(obj_key)
- if myprops is None:
- indexed = False
- myprops = self._obj_properties_class(
- arch, needed, path, soname, [], owner)
- obj_properties[obj_key] = myprops
- # All object paths are added into the obj_properties
tuple.
- myprops.alt_paths.append(obj)
-
- # Don't index the same file more that once since only
one
- # set of data can be correct and therefore mixing data
- # may corrupt the index (include_file overrides
previously
- # installed).
- if indexed:
- continue
-
- arch_map = libs.get(arch)
- if arch_map is None:
- arch_map = {}
- libs[arch] = arch_map
- if soname:
- soname_map = arch_map.get(soname)
- if soname_map is None:
- soname_map = self._soname_map_class(
- providers=[], consumers=[])
- arch_map[soname] = soname_map
- soname_map.providers.append(obj_key)
- for needed_soname in needed:
- soname_map = arch_map.get(needed_soname)
- if soname_map is None:
- soname_map = self._soname_map_class(
- providers=[], consumers=[])
- arch_map[needed_soname] = soname_map
- soname_map.consumers.append(obj_key)
-
- for arch, sonames in libs.items():
- for soname_node in sonames.values():
- soname_node.providers =
tuple(set(soname_node.providers))
- soname_node.consumers =
tuple(set(soname_node.consumers))