about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2022-05-18 18:18:11 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2022-05-18 18:18:11 +0200
commit7a10059268e456ec89aa05e4df23a2b19b4d8395 (patch)
tree9cd44a98363ce5f58b8c8df6299bab3c83f87406
parent01ab51bb16f3b356f081b792a2dc9574d43b5449 (diff)
downloadrust-7a10059268e456ec89aa05e4df23a2b19b4d8395.tar.gz
rust-7a10059268e456ec89aa05e4df23a2b19b4d8395.zip
Fix symbol tables in case of multiple object files with the same name
Fixes #1228
-rw-r--r--src/archive.rs19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/archive.rs b/src/archive.rs
index a099e8b3a6a..b54898cc02a 100644
--- a/src/archive.rs
+++ b/src/archive.rs
@@ -117,7 +117,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
 
         let mut entries = Vec::new();
 
-        for (entry_name, entry) in self.entries {
+        for (mut entry_name, entry) in self.entries {
             // FIXME only read the symbol table of the object files to avoid having to keep all
             // object files in memory at once, or read them twice.
             let data = match entry {
@@ -140,6 +140,23 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             };
 
             if !self.no_builtin_ranlib {
+                if symbol_table.contains_key(&entry_name) {
+                    // The ar crate can't handle creating a symbol table in case of multiple archive
+                    // members with the same name. Work around this by prepending a number until we
+                    // get a unique name.
+                    for i in 1.. {
+                        let new_name = format!("{}_", i)
+                            .into_bytes()
+                            .into_iter()
+                            .chain(entry_name.iter().copied())
+                            .collect::<Vec<_>>();
+                        if !symbol_table.contains_key(&new_name) {
+                            entry_name = new_name;
+                            break;
+                        }
+                    }
+                }
+
                 match object::File::parse(&*data) {
                     Ok(object) => {
                         symbol_table.insert(