[llvm] [orc] Add the name of static archives to the name of their member objects (PR #99407)

Ben Langmuir via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 17 16:49:49 PDT 2024


https://github.com/benlangmuir created https://github.com/llvm/llvm-project/pull/99407

Changes "MyObj.o" to "/path/to/libMyLib.a(MyObj.o)".

This allows us to differentiate between objects that have the same basename but came from different archives. It also fixes a bug where if two such objects were both linked and both have initializer sections their initializer symbol would cause a duplicate symbol error.

rdar://131782514

>From b1f18feb7bb20c34db752dfbd20f2d02914bdbb7 Mon Sep 17 00:00:00 2001
From: Ben Langmuir <blangmuir at apple.com>
Date: Wed, 17 Jul 2024 16:42:32 -0700
Subject: [PATCH] [orc] Add the name of static archives to the name of their
 member objects

Changes "MyObj.o" to "/path/to/libMyLib.a(MyObj.o)".

This allows us to differentiate between objects that have the same
basename but came from different archives. It also fixes a bug where if
two such objects were both linked and both have initializer sections
their initializer symbol would cause a duplicate symbol error.

rdar://131782514
---
 .../llvm/ExecutionEngine/Orc/ExecutionUtils.h |  1 +
 .../ExecutionEngine/Orc/ExecutionUtils.cpp    | 14 +++-
 .../MachO_archive_two_objects_same_name.s     | 64 +++++++++++++++++++
 3 files changed, 78 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/ExecutionEngine/JITLink/x86-64/MachO_archive_two_objects_same_name.s

diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index ed30a792e9e9c..f997faf1ebcb0 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -328,6 +328,7 @@ class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
   std::unique_ptr<MemoryBuffer> ArchiveBuffer;
   std::unique_ptr<object::Archive> Archive;
   DenseMap<SymbolStringPtr, MemoryBufferRef> ObjectFilesMap;
+  BumpPtrAllocator ObjFileNameStorage;
 };
 
 /// A utility class to create COFF dllimport GOT symbols (__imp_*) and PLT
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index 8a5986c1b88b1..c1a193f6a2802 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -17,6 +17,7 @@
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Target/TargetMachine.h"
 #include <string>
 
@@ -422,6 +423,7 @@ Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() {
   DenseMap<uint64_t, MemoryBufferRef> MemoryBuffers;
   DenseSet<uint64_t> Visited;
   DenseSet<uint64_t> Excluded;
+  StringSaver FileNames(ObjFileNameStorage);
   for (auto &S : Archive->symbols()) {
     StringRef SymName = S.getName();
     auto Member = S.getMember();
@@ -438,7 +440,17 @@ Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() {
         Excluded.insert(DataOffset);
         continue;
       }
-      MemoryBuffers[DataOffset] = (*Child)->getMemoryBufferRef();
+
+      // Give members of the archive a name that contains the archive path so
+      // that they can be differentiated from a member with the same name in a
+      // different archive. This also ensure initializer symbols names will be
+      // unique within a JITDylib.
+      StringRef FullName = FileNames.save(Archive->getFileName() + "(" +
+                                          (*Child)->getFileName() + ")");
+      MemoryBufferRef MemBuffer((*Child)->getMemoryBufferRef().getBuffer(),
+                                FullName);
+
+      MemoryBuffers[DataOffset] = MemBuffer;
     }
     if (!Excluded.count(DataOffset))
       ObjectFilesMap[L.getExecutionSession().intern(SymName)] =
diff --git a/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_archive_two_objects_same_name.s b/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_archive_two_objects_same_name.s
new file mode 100644
index 0000000000000..f2bd64f02ca80
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_archive_two_objects_same_name.s
@@ -0,0 +1,64 @@
+# Check that the generated __inits symbol name does not clash between objects
+# with the same base name in two different static archives. Otherwise we get a
+# duplicate symbol error.
+
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: split-file %s %t
+
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN:   -o %t/dir1/myobj.o %t/dir1/myobj.s
+# RUN: llvm-ar crs %t/libmyobj1.a %t/dir1/myobj.o
+
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN:   -o %t/dir2/myobj.o %t/dir2/myobj.s
+# RUN: llvm-ar crs %t/libmyobj2.a %t/dir2/myobj.o
+
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN:   -o %t/main.o %t/main.s
+
+# RUN: llvm-jitlink -noexec %t/main.o -lmyobj1 -lmyobj2 -L%t
+
+#--- dir1/myobj.s
+        .section        __TEXT,__text,regular,pure_instructions
+        .build_version macos, 15, 0     sdk_version 15, 0
+        .globl  _myobj1
+        .p2align        4, 0x90
+_myobj1:                                     ## @f
+        retq
+
+        .section        __DATA,__mod_init_func,mod_init_funcs
+        .p2align        3, 0x0
+        .quad   _myobj1
+
+        .subsections_via_symbols
+
+#--- dir2/myobj.s
+        .section        __TEXT,__text,regular,pure_instructions
+        .build_version macos, 15, 0     sdk_version 15, 0
+        .globl  _myobj2
+        .p2align        4, 0x90
+_myobj2:                                     ## @f
+        retq
+
+        .section        __DATA,__mod_init_func,mod_init_funcs
+        .p2align        3, 0x0
+        .quad   _myobj2
+
+        .subsections_via_symbols
+
+#--- main.s
+
+        .section  __TEXT,__text,regular,pure_instructions
+
+        .globl  _main
+        .p2align  4, 0x90
+_main:
+        pushq   %rbp
+        movq    %rsp, %rbp
+        callq   _myobj1
+        callq   _myobj2
+        xorl    %eax, %eax
+        popq    %rbp
+        retq
+
+        .subsections_via_symbols



More information about the llvm-commits mailing list