PORTAGE_QUIET=${tmp_quiet}
fi
+ if [[ ${CHOST} == *-aix* ]] && ! hasq binchecks ${RESTRICT}; then
+ local tmp_quiet=${PORTAGE_QUIET}
+ local queryline deplib
+ local insecure_rpath_list= undefined_symbols_list=
+
+ # display warnings when using stricter because we die afterwards
+ if has stricter ${FEATURES} ; then
+ unset PORTAGE_QUIET
+ fi
+
+ rm -f "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
+ find "${ED}" -not -type d -exec \
+ "${EPREFIX}/usr/bin/aixdll-query" '{}' FILE MEMBER FLAGS FORMAT RUNPATH DEPLIBS ';' \
+ > "${T}"/needed 2>/dev/null
+
+ # Symlinking archive libraries is not a good idea on aix,
+ # as there is nothing like "soname" on pure filesystem level.
+ # So we create a copy instead of the symlink.
+ local prev_FILE=
+ while read queryline
+ do
+ local FILE= MEMBER= FLAGS= FORMAT= RUNPATH= DEPLIBS=
+ eval ${queryline}
+
+ if [[ ${prev_FILE} != ${FILE} ]]; then
+ prev_FILE=${FILE}
+ if [[ -n ${MEMBER} || " ${FLAGS} " == *" SHROBJ "* ]] && [[ -h ${FILE} ]]; then
+ local target=$(readlink "${FILE}")
+ if [[ ${target} == /* ]]; then
+ target=${D}${target}
+ else
+ target=${FILE%/*}/${target}
+ fi
+ rm -f "${FILE}" || die "cannot prune ${FILE#${ED}}"
+ cp -f "${target}" "${FILE}" || die "cannot copy ${target#${ED}} to ${FILE#${ED}}"
+ fi
+ fi
+ done <"${T}"/needed
+
+ prev_FILE=
+ while read queryline
+ do
+ local FILE= MEMBER= FLAGS= FORMAT= RUNPATH= DEPLIBS=
+ eval ${queryline}
+
+ if [[ ${prev_FILE} != ${FILE} ]]; then
+ # Save NEEDED information for the archive library stub
+ echo "${FORMAT##* }${FORMAT%%-*};${FILE#${D%/}};${FILE##*/};;" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
+ fi
+
+ # Make sure we disallow insecure RUNPATH'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.
+ # And we really want absolute paths only.
+ if [[ -n $(echo ":${RUNPATH}:" | grep -E "(${PORTAGE_BUILDDIR}|::|:[^/])") ]]; then
+ insecure_rpath_list="${insecure_rpath_list}\n${FILE}"
+ fi
+
+ # Although we do have runtime linking, we don't want undefined symbols.
+ # AIX does indicate this by needing either '.' or '..'
+ local needed=${FILE##*/}
+ for deplib in ${DEPLIBS}; do
+ eval deplib=${deplib}
+ if [[ ${deplib} == '.' || ${deplib} == '..' ]]; then
+ undefined_symbols_list="${undefined_symbols_list}\n${FILE}"
+ else
+ needed="${needed},${deplib}"
+ fi
+ done
+
+ FILE=${FILE#${D%/}}
+
+ [[ -n ${MEMBER} ]] && MEMBER="[${MEMBER}]"
+ # Save NEEDED information
+ echo "${FORMAT##* }${FORMAT%%-*};${FILE}${MEMBER};${FILE##*/}${MEMBER};${RUNPATH};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
+ done <"${T}"/needed
+
+ if [[ -n ${undefined_symbols_list} ]]; then
+ vecho -ne '\a\n'
+ eqawarn "QA Notice: The following files contain undefined symbols."
+ eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
+ eqawarn " with 'prefix' as the maintaining herd of the package."
+ eqawarn "${undefined_symbols_list}"
+ vecho -ne '\a\n'
+ fi
+
+ if [[ -n ${insecure_rpath_list} ]] ; 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 'prefix' as the maintaining herd of the package."
+ eqawarn "${insecure_rpath_list}"
+ vecho -ne '\a\n'
+ if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
+ insecure_rpath=1
+ fi
+ fi
+
+ 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
+
+ PORTAGE_QUIET=${tmp_quiet}
+ fi
+
local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')')
if [[ -n ${unsafe_files} ]] ; then
eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
mtree -e -p "${EROOT}" -U -k flags < "${T}/bsdflags.mtree" &> /dev/null
}
+preinst_aix() {
+ if [[ ${CHOST} != *-aix* ]] || hasq binchecks ${RESTRICT}; then
+ return 0
+ fi
+ local ar strip
+ if type ${CHOST}-ar >/dev/null 2>&1 && type ${CHOST}-strip >/dev/null 2>&1; then
+ ar=${CHOST}-ar
+ strip=${CHOST}-strip
+ elif [[ ${CBUILD} == "${CHOST}" ]] && type ar >/dev/null 2>&1 && type strip >/dev/null 2>&1; then
+ ar=ar
+ strip=strip
+ elif [[ -x /usr/ccs/bin/ar && -x /usr/ccs/bin/strip ]]; then
+ ar=/usr/ccs/bin/ar
+ strip=/usr/ccs/bin/strip
+ else
+ die "cannot find where to use 'ar' and 'strip' from"
+ fi
+
+ local archive prev_archive= archives=()
+ while read archive; do
+ archive=${archive#*;}
+ archive=${archive%%;*}
+ if [[ ${archive} == *'['*']' ]]; then
+ archive=${archive%[*}
+ [[ ${prev_archive} == ${archive} ]] && continue
+ prev_archive=${archive}
+ archives[${#archives[@]}]=${archive#${EPREFIX}/}
+ fi
+ done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
+ unset prev_archive
+
+ local libmetadir members preservemembers member contentmember chmod400files=() prunedirs=()
+ for archive in "${archives[@]}"; do
+ libmetadir=${ED}${archive%/*}/.${archive##*/}
+ [[ ! -e ${libmetadir} ]] || rm -rf "${libmetadir}" || die "cannot prune ${libmetadir}"
+ mkdir "${libmetadir}" || die "cannot create ${libmetadir}"
+ pushd "${libmetadir}" >/dev/null || die "cannot cd to ${libmetadir}"
+ ${ar} -X32_64 -x "${ED}${archive}" || die "cannot unpack ${archive}"
+ members=" $(echo *) "
+ preservemembers=
+ if [[ -e ${EROOT}${archive} ]]; then
+ for member in $(${ar} -X32_64 -t "${EROOT}${archive}"); do
+ [[ ${members} == *" ${member} "* ]] && continue
+ preservemembers="${preservemembers} ${member}"
+ done
+ if [[ -n ${preservemembers} ]]; then
+ einfo "preserving (on spec)${preservemembers}"
+ ${ar} -X32_64 -x "${EROOT}${archive}" ${preservemembers} || die "cannot extract ${preservemembers} from ${EROOT}${archive}"
+ chmod u+w ${preservemembers} || die "cannot chmod${preservedmembers}"
+ ${strip} -X32_64 -e ${preservemembers} || die "cannot strip${preservemembers}"
+ ${ar} -X32_64 -q "${ED}${archive}" ${preservemembers} || die "cannot update ${archive}"
+ eend $?
+ fi
+ fi
+ for member in ${members}; do
+ contentmember="${archive%/*}/.${archive##*/}[${member}]"
+ # portage does os.lstat() on merged files every now
+ # and then, so keep stamp-files for archive members
+ # around to get the preserve-libs feature working.
+ { echo "Please leave this file alone, it is an important helper"
+ echo "for portage to implement the 'preserve-libs' feature on AIX."
+ } > "${ED}${contentmember}" || die "cannot create ${contentmember}"
+ chmod400files[${#chmod400files[@]}]=${ED}${contentmember}
+ done
+ popd >/dev/null || die "cannot leave ${libmetadir}"
+ prunedirs[${#prunedirs[@]}]=${libmetadir}
+ done
+ [[ ${#chmod400files[@]} == 0 ]] ||
+ chmod 0400 "${chmod400files[@]}" || die "cannot chmod ${chmod400files[@]}"
+ [[ ${#prunedirs[@]} == 0 ]] ||
+ rm -rf "${prunedirs[@]}" || die "cannot prune ${prunedirs[@]}"
+ return 0
+}
+
+postinst_aix() {
+ if [[ ${CHOST} != *-aix* ]] || hasq binchecks ${RESTRICT}; then
+ return 0
+ fi
+ local MY_PR=${PR%r0}
+ local ar strip
+ if type ${CHOST}-ar >/dev/null 2>&1 && type ${CHOST}-strip >/dev/null 2>&1; then
+ ar=${CHOST}-ar
+ strip=${CHOST}-strip
+ elif [[ ${CBUILD} == "${CHOST}" ]] && type ar >/dev/null 2>&1 && type strip >/dev/null 2>&1; then
+ ar=ar
+ strip=strip
+ elif [[ -x /usr/ccs/bin/ar && -x /usr/ccs/bin/strip ]]; then
+ ar=/usr/ccs/bin/ar
+ strip=/usr/ccs/bin/strip
+ else
+ die "cannot find where to use 'ar' and 'strip' from"
+ fi
+
+ local member contentmember activecontentmembers= prev_archive= archive activearchives=
+ while read member; do
+ member=${member#*;} # drop "^type;"
+ member=${member%%;*} # drop ";soname;runpath;needed$"
+ [[ ${member##*/} == *'['*']' ]] || continue
+ contentmember=${member%/*}/.${member##*/}
+ activecontentmembers="${activecontentmembers}:(${contentmember}):"
+ archive=${member%[*}
+ [[ ${prev_archive} != ${archive} ]] || continue
+ prev_archive=${archive}
+ activearchives="${activearchives}:(${archive}):"
+ done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
+
+ local type allcontentmembers= all_archives=()
+ prev_archive=
+ while read type contentmember; do
+ contentmember=${contentmember% *} # drop " timestamp$"
+ contentmember=${contentmember% *} # drop " hash$"
+ [[ ${contentmember##*/} == *'['*']' ]] || continue
+ allcontentmembers="${allcontentmembers}:(${contentmember}):"
+ member=${contentmember%/.*}/${contentmember##*/.}
+ archive=${member%[*}
+ [[ ${prev_archive} != ${archive} ]] || continue
+ prev_archive=${archive}
+ all_archives[${#all_archives[@]}]=${archive}
+ done < "${EPREFIX}/var/db/pkg/${CATEGORY}/${P}${MY_PR:+-}${MY_PR}/CONTENTS"
+
+ local delmembers oldmembers libmetadir prunemembers=() prunedirs=()
+ for archive in "${all_archives[@]}"; do
+ [[ -r ${ROOT}${archive} && -w ${ROOT}${archive} ]] ||
+ chmod a+r,u+w "${ROOT}${archive}" || die "cannot chmod ${archive}"
+ delmembers= oldmembers=
+ for member in $(${ar} -X32_64 -t "${ROOT}${archive}"); do
+ contentmember="${archive%/*}/.${archive##*/}[${member}]"
+ if [[ ${allcontentmembers} != *":(${contentmember}):"* ]]; then
+ # not existent any more, just drop it
+ delmembers="${delmembers} ${member}"
+ prunemembers[${#prunemembers[@]}]=${ROOT}${contentmember}
+ elif [[ ${activecontentmembers} != *":(${contentmember}):"* ]]; then
+ oldmembers="${oldmembers} ${member}"
+ fi
+ done
+ if [[ -n ${delmembers} ]]; then
+ einfo "dropping${delmembers}"
+ ${ar} -X32_64 -z -o -d "${ROOT}${archive}" ${delmembers} || die "cannot remove${delmembers} from ${archive}"
+ eend $?
+ fi
+ if [[ -n ${oldmembers} && ${activearchives} != *":(${archive}):"* ]]; then
+ einfo "preserving (extra)${oldmembers}"
+ libmetadir=${ROOT}${archive%/*}/.${archive##*/}
+ [[ ! -e ${libmetadir} ]] || rm -rf "${libmetadir}" || die "cannot prune ${libmetadir}"
+ mkdir "${libmetadir}" || die "cannot create ${libmetadir}"
+ pushd "${libmetadir}" >/dev/null || die "cannot cd to ${libmetadir}"
+ ${ar} -X32_64 -x "${ROOT}${archive}" ${oldmembers} || die "cannot unpack ${archive}"
+ ${strip} -e ${oldmembers} || die "cannot strip ${oldmembers}"
+ ${ar} -X32_64 -z -o -r "${ROOT}${archive}" ${oldmembers} || die "cannot update${oldmembers} in ${archive}"
+ popd > /dev/null || die "cannot leave ${libmetadir}"
+ prunedirs[${#prunedirs[@]}]=${libmetadir}
+ eend $?
+ fi
+ done
+ [[ ${#prunedirs[@]} == 0 ]] ||
+ rm -rf "${prunedirs[@]}" || die "cannot prune ${prunedirs[@]}"
+ [[ ${#prunemembers[@]} == 0 ]] ||
+ rm -f "${prunemembers[@]}" || die "cannot prune ${contentmenbers[@]}"
+ return 0
+}
+
preinst_mask() {
if [ -z "${D}" ]; then
eerror "${FUNCNAME}: D is unset"
from __future__ import print_function
__all__ = ["PreservedLibsRegistry", "LinkageMap",
- "LinkageMapMachO", "LinkageMapPeCoff",
+ "LinkageMapMachO", "LinkageMapPeCoff", "LinkageMapXCoff"
"vardbapi", "vartree", "dblink"] + \
["write_contents", "tar_contents"]
)
from portage.const import CACHE_PATH, CONFIG_MEMORY_FILE, \
- PORTAGE_PACKAGE_ATOM, PRIVATE_PATH, VDB_PATH, EPREFIX, EPREFIX_LSTRIP
+ PORTAGE_PACKAGE_ATOM, PRIVATE_PATH, VDB_PATH, EPREFIX, EPREFIX_LSTRIP, BASH_BINARY
from portage.data import portage_gid, portage_uid, secpass
from portage.dbapi import dbapi
from portage.exception import CommandNotFound, \
arch_map[needed_soname] = soname_map
soname_map.consumers.add(obj_key)
+class LinkageMapXCoff(LinkageMap):
+
+ """Models dynamic linker dependencies."""
+
+ _needed_aux_key = "NEEDED.XCOFF.1"
+
+ class _ObjectKey(LinkageMap._ObjectKey):
+
+ def __init__(self, obj, root):
+ LinkageMap._ObjectKey.__init__(self, obj, root)
+
+ def _generate_object_key(self, obj, root):
+ """
+ Generate object key for a given object.
+
+ @param object: path to a file
+ @type object: string (example: '/usr/bin/bar')
+ @rtype: 2-tuple of types (long, int) if object exists. string if
+ object does not exist.
+ @return:
+ 1. 2-tuple of object's inode and device from a stat call, if object
+ exists.
+ 2. realpath of object if object does not exist.
+
+ """
+
+ 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:
+ # Use the realpath as the key if the file does not exists on the
+ # filesystem.
+ return os.path.realpath(abs_path)
+ # Return a tuple of the device and inode, as well as the basename,
+ # because of hardlinks the device and inode might be identical.
+ return (object_stat.st_dev, object_stat.st_ino, os.path.basename(abs_path.rstrip(os.sep)))
+
+ 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 isinstance(self._key, tuple)
+
+ class _LibGraphNode(_ObjectKey):
+ __slots__ = ("alt_paths",)
+
+ def __init__(self, obj, root):
+ LinkageMapXCoff._ObjectKey.__init__(self, obj, root)
+ self.alt_paths = set()
+
+ def __str__(self):
+ return str(sorted(self.alt_paths))
+
+ def rebuild(self, exclude_pkgs=None, include_file=None):
+ """
+ Raises CommandNotFound if there are preserved libs
+ and the scanelf binary is not available.
+ """
+
+ os = _os_merge
+ root = self._root
+ root_len = len(root) - 1
+ self._clear_cache()
+ self._defpath.update(getlibpaths(self._root))
+ libs = self._libs
+ obj_key_cache = self._obj_key_cache
+ 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:
+ lines += grabfile(include_file)
+
+ aux_keys = [self._needed_aux_key]
+ for cpv in self._dbapi.cpv_all():
+ if exclude_pkgs is not None and cpv in exclude_pkgs:
+ continue
+ lines += self._dbapi.aux_get(cpv, aux_keys)[0].split('\n')
+ # Cache NEEDED.* files avoid doing excessive IO for every rebuild.
+ self._dbapi.flush_cache()
+
+ # have to call scanelf for preserved libs here as they aren't
+ # registered in NEEDED.XCOFF.1 files
+ if self._dbapi.plib_registry and self._dbapi.plib_registry.getPreservedLibs():
+ for items in self._dbapi.plib_registry.getPreservedLibs().values():
+ for x in items:
+ args = [BASH_BINARY, "-c", ':'
+ + '; member="' + x + '"'
+ + '; archive=${member}'
+ + '; if [[ ${member##*/} == .*"["*"]" ]]'
+ + '; then member=${member%/.*}/${member##*/.}'
+ + '; archive=${member%[*}'
+ + '; fi'
+ + '; member=${member#${archive}}'
+ + '; [[ -r ${archive} ]] || chmod a+r "${archive}"'
+ + '; eval $(aixdll-query "${archive}${member}" FILE MEMBER FLAGS FORMAT RUNPATH DEPLIBS)'
+ + '; [[ -n ${member} ]] && needed=${FILE##*/} || needed='
+ + '; for deplib in ${DEPLIBS}'
+ + '; do eval deplib=${deplib}'
+ + '; if [[ ${deplib} != "." && ${deplib} != ".." ]]'
+ + '; then needed="${needed}${needed:+,}${deplib}"'
+ + '; fi'
+ + '; done'
+ + '; [[ -n ${MEMBER} ]] && MEMBER="[${MEMBER}]"'
+ + '; [[ " ${FLAGS} " == *" SHROBJ "* ]] && soname=${FILE##*/}${MEMBER} || soname='
+ + '; echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}}${MEMBER};${soname};${RUNPATH};${needed}"'
+ + '; [[ -n ${member} ]] || echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}};${FILE##*/};;"'
+ ]
+ try:
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+ except EnvironmentError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ raise CommandNotFound("aixdll-query via " + argv[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 aixdll-query: %s\n\n") % (l,),
+ level=logging.ERROR, noiselevel=-1)
+ l = l.rstrip("\n")
+ if not l:
+ continue
+ fields = l.split(";")
+ if len(fields) < 5:
+ writemsg_level(_("\nWrong number of fields " \
+ "returned from aixdll-query: %s\n\n") % (l,),
+ level=logging.ERROR, noiselevel=-1)
+ continue
+ fields[1] = fields[1][root_len:]
+ lines.append(";".join(fields))
+ proc.wait()
+
+ for 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") % (self._needed_aux_key, l),
+ level=logging.ERROR, noiselevel=-1)
+ continue
+ arch = fields[0]
+
+ def as_contentmember(obj):
+ if obj.endswith("]"):
+ if obj.find("/") >= 0:
+ return obj[:obj.rfind("/")] + "/." + obj[obj.rfind("/")+1:]
+ return "." + obj
+ return obj
+
+ obj = as_contentmember(fields[1])
+ soname = as_contentmember(fields[2])
+ path = set([normalize_path(x) \
+ for x in filter(None, fields[3].replace(
+ "${ORIGIN}", os.path.dirname(obj)).replace(
+ "$ORIGIN", os.path.dirname(obj)).split(":"))])
+ needed = [as_contentmember(x) for x in fields[4].split(",") if x]
+
+ obj_key = self._obj_key(obj)
+ indexed = True
+ myprops = obj_properties.get(obj_key)
+ if myprops is None:
+ indexed = False
+ myprops = (arch, needed, path, soname, set())
+ obj_properties[obj_key] = myprops
+ # All object paths are added into the obj_properties tuple.
+ myprops[4].add(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=set(), consumers=set())
+ arch_map[soname] = soname_map
+ soname_map.providers.add(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=set(), consumers=set())
+ arch_map[needed_soname] = soname_map
+ soname_map.consumers.add(obj_key)
+
+ def getSoname(self, obj):
+ """
+ Return the soname associated with an object.
+
+ @param obj: absolute path to an object
+ @type obj: string (example: '/usr/bin/bar')
+ @rtype: string
+ @return: soname as a string
+
+ """
+ if not self._libs:
+ self.rebuild()
+ if isinstance(obj, self._ObjectKey):
+ obj_key = obj
+ if obj_key not in self._obj_properties:
+ raise KeyError("%s not in object list" % obj_key)
+ return self._obj_properties[obj_key][3]
+ if obj not in self._obj_key_cache:
+ raise KeyError("%s not in object list" % obj)
+ return self._obj_properties[self._obj_key_cache[obj]][3]
class vardbapi(dbapi):
self.linkmap = LinkageMapMachO(self)
elif chost.find('interix') >= 0 or chost.find('winnt') >= 0:
self.linkmap = LinkageMapPeCoff(self)
+ elif chost.find('aix'):
+ self.linkmap = LinkageMapXCoff(self)
else:
self.linkmap = LinkageMap(self)
self._owners = self._owners_db(self)
node = LinkageMapMachO._LibGraphNode(path, root)
elif chost.find('interix') >= 0 or chost.find('winnt') >= 0:
node = LinkageMapPeCoff._LibGraphNode(path, root)
+ elif chost.find('aix') >= 0:
+ node = LinkageMapXCoff._LibGraphNode(path, root)
else:
node = LinkageMap._LibGraphNode(path, root)
alt_path_node = lib_graph.get(node)