Frans Pop wrote:
To reproduce (assuming you have debian sid or lenny installed) you'll need to do something like this (besides building and installing your version of mklibs and mklibs-copy of course): $ apt-get install build-essential subversion $ svn co svn://svn.debian.org/svn/d-i/trunk/installer $ cd installer/build $ apt-get build-dep debian-installer $ make all_build
I don't have debian, but I have managed to reproduce the problem on a different 32-bit Ubuntu system just generating the libs for /bin/bash.
I think this patch should work for you. It works for /bin/bash and I also tried a few bits and pieces from /usr/bin/X11.
Andrew
--- src/mklibs-readelf/elf.cpp | 20 +++++++++++++++++--- src/mklibs-readelf/elf.hpp | 8 ++++++++ src/mklibs-readelf/elf_data.hpp | 2 +- src/mklibs-readelf/main.cpp | 3 ++- src/mklibs.py | 40 ++++++++++++++++++++++++---------------- 5 files changed, 52 insertions(+), 21 deletions(-) Index: src/mklibs-readelf/elf.cpp =================================================================== --- src/mklibs-readelf/elf.cpp.orig +++ src/mklibs-readelf/elf.cpp @@ -445,6 +445,14 @@ std::string symbol::get_version () const return "Base"; } +std::string symbol::get_version_file () const throw (std::bad_alloc) +{ + if (verneed) + return verneed->get_file(); + + return "unknown"; +} + std::string symbol::get_name_version () const throw (std::bad_alloc) { std::string ver; @@ -539,10 +547,12 @@ version_requirement_data<_class, _data>: char *act = reinterpret_cast<char *> (verneed) + aux; + file = convert<_data, typeof (verneed->vn_file)> () (verneed->vn_file); + for (int i = 0; i < cnt; i++) { Vernaux *vernaux = reinterpret_cast<Vernaux *> (act); - entries.push_back(new version_requirement_entry_data<_class, _data> (vernaux)); + entries.push_back(new version_requirement_entry_data<_class, _data> (this, vernaux)); uint32_t next = convert<_data, typeof (vernaux->vna_next)> () (vernaux->vna_next); act += next; } @@ -551,17 +561,21 @@ version_requirement_data<_class, _data>: template <typename _class, typename _data> void version_requirement_data<_class, _data>::update_string(const section_type<section_type_STRTAB> §ion) throw (std::bad_alloc) { + file_string = section.get_string(file); + for (std::vector<version_requirement_entry *>::iterator it = entries.begin(); it != entries.end(); ++it) { version_requirement_entry_data<_class, _data> &vernaux = - dynamic_cast<version_requirement_entry_data<_class, _data> &> (**it); + dynamic_cast<version_requirement_entry_data<_class, _data> &> (this, **it); vernaux.update_string(section); } } template <typename _class, typename _data> -version_requirement_entry_data<_class, _data>::version_requirement_entry_data (Vernaux *vna) throw () +version_requirement_entry_data<_class, _data>::version_requirement_entry_data (const version_requirement_data<_class, _data> *parent, Vernaux *vna) throw () { + this->parent = parent; + flags = convert<_data, typeof (vna->vna_flags)> () (vna->vna_flags); other = convert<_data, typeof (vna->vna_other)> () (vna->vna_other); name = convert<_data, typeof (vna->vna_name)> () (vna->vna_name); Index: src/mklibs-readelf/elf.hpp =================================================================== --- src/mklibs-readelf/elf.hpp.orig +++ src/mklibs-readelf/elf.hpp @@ -264,6 +264,7 @@ namespace Elf uint8_t get_type () const throw () { return type; } const std::string &get_name_string () const throw () { return name_string; } std::string get_version() const throw (std::bad_alloc); + std::string get_version_file() const throw (std::bad_alloc); uint16_t get_version_data() const throw () { return versym; } std::string get_name_version() const throw (std::bad_alloc); @@ -306,9 +307,13 @@ namespace Elf public: virtual ~version_requirement () throw () { } + const std::string &get_file() const throw () { return file_string; } const std::vector<version_requirement_entry *> &get_entries () const throw () { return entries; } protected: + uint32_t file; + + std::string file_string; std::vector<version_requirement_entry *> entries; }; @@ -319,8 +324,11 @@ namespace Elf uint16_t get_other () const throw () { return other; } const std::string &get_name() const throw () { return name_string; } + const std::string &get_file() const throw () { return parent->get_file(); } protected: + const version_requirement *parent; + uint16_t flags; uint16_t other; uint32_t name; Index: src/mklibs-readelf/elf_data.hpp =================================================================== --- src/mklibs-readelf/elf_data.hpp.orig +++ src/mklibs-readelf/elf_data.hpp @@ -214,7 +214,7 @@ namespace Elf public: typedef typename _elfdef<_class>::Vernaux Vernaux; - version_requirement_entry_data (Vernaux *) throw (); + version_requirement_entry_data (const version_requirement_data<_class,_data> *, Vernaux *) throw (); void update_string(const section_type<section_type_STRTAB> &) throw (std::bad_alloc); }; Index: src/mklibs-readelf/main.cpp =================================================================== --- src/mklibs-readelf/main.cpp.orig +++ src/mklibs-readelf/main.cpp @@ -95,7 +95,8 @@ static void process_symbols_undefined (c std::cout << symbol->get_name_string () << ' ' << (bind == STB_WEAK ? "True" : "False") << ' ' << - symbol->get_version() << '\n'; + symbol->get_version() << ' ' << + symbol->get_version_file() << '\n'; } } Index: src/mklibs.py =================================================================== --- src/mklibs.py.orig +++ src/mklibs.py @@ -139,8 +139,8 @@ def undefined_symbols(obj): result = [] output = command("mklibs-readelf", "--print-symbols-undefined", obj) for line in output: - name, weak_string, version = line.split()[:3] - result.append(UndefinedSymbol(name, bool(eval(weak_string)), version)) + name, weak_string, version, library = line.split()[:4] + result.append(UndefinedSymbol(name, bool(eval(weak_string)), "%...@%s" % (version, library))) return result class ProvidedSymbol(Symbol): @@ -149,14 +149,20 @@ class ProvidedSymbol(Symbol): self.default_version = default_version def base_names(self): - if self.default_version and self.version != "Base": - return ["%...@%s" % (self.name, self.version), "%...@base" % self.name] - return ["%...@%s" % (self.name, self.version)] + ver, lib = self.version.split('@', 1)[:2] + if self.default_version and ver != "Base": + return ["%...@%s" % (self.name, self.version), + "%...@%s@unknown" % (self.name, ver), + "%...@base@%s" % (self.name, lib), + "%...@base@unknown" % self.name] + return ["%...@%s" % (self.name, self.version), + "%...@%s@unknown" % (self.name, ver)] def linker_name(self): - if self.default_version or self.version == "Base": + ver, lib = self.version.split('@', 1)[:2] + if self.default_version or ver == "Base": return self.name - return "%...@%s" % (self.name, self.version) + return "%...@%s" % (self.name, ver) # Return a set of symbols provided by a library def provided_symbols(obj): @@ -167,7 +173,7 @@ def provided_symbols(obj): output = command("mklibs-readelf", "--print-symbols-provided", obj) for line in output: name, weak, version, default_version_string = line.split()[:4] - result.append(ProvidedSymbol(name, version, bool(eval(default_version_string)))) + result.append(ProvidedSymbol(name, "%...@%s" % (version, extract_soname(obj)), bool(eval(default_version_string)))) return result # Return real target of a symlink @@ -208,10 +214,17 @@ def find_pic_map(lib): return resolve_link(file) return "" +soname_cache = {} def extract_soname(so_file): + name = soname_cache.get(so_file) + if name is not None: + return name soname_data = command("mklibs-readelf", "--print-soname", so_file) if soname_data: - return soname_data.pop() + name = soname_data.pop() + soname_cache[so_file] = name + return name + soname_cache[so_file] = "" return "" def usage(was_err): @@ -479,12 +492,7 @@ while 1: for symbol in symbols: for name in symbol.base_names(): if name in symbol_provider: - # in doubt, prefer symbols from libc - if re.match("^libc[\.-]", library): - library_symbols[library][name] = symbol - symbol_provider[name] = library - else: - debug(DEBUG_SPAM, "duplicate symbol %s in %s and %s" % (symbol, symbol_provider[name], library)) + debug(DEBUG_SPAM, "duplicate symbol %s in %s and %s" % (name, symbol_provider[name], library)) else: library_symbols[library][name] = symbol symbol_provider[name] = library @@ -540,7 +548,7 @@ while 1: # may segfault in ptmalloc_init due to undefined weak reference extra_pre_obj.append(sysroot + libc_extras_dir + "/soinit.o") extra_post_obj.append(sysroot + libc_extras_dir + "/sofini.o") - symbols.add(ProvidedSymbol('__dso_handle', 'Base', True)) + symbols.add(ProvidedSymbol('__dso_handle', 'b...@%s' % soname, True)) map_file = find_pic_map(library) if map_file: