summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp5
-rw-r--r--lld/test/ELF/dso_handle.s19
2 files changed, 24 insertions, 0 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 4b36d884071..dd95c9ac917 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -907,6 +907,11 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
if (!InX::DynSymTab)
Symtab<ELFT>::X->addIgnored("__tls_get_addr");
+ // __dso_handle symbol is passed to cxa_finalize as a marker to identify
+ // each DSO. The address of the symbol doesn't matter as long as they are
+ // different in different DSOs, so we chose the start address of the DSO.
+ addOptionalRegular<ELFT>("__dso_handle", Out::ElfHeader, 0, STV_HIDDEN);
+
// __ehdr_start is the location of ELF file headers. Note that we define
// this symbol unconditionally even when using a linker script, which
// differs from the behavior implemented by GNU linker which only define
diff --git a/lld/test/ELF/dso_handle.s b/lld/test/ELF/dso_handle.s
new file mode 100644
index 00000000000..99e2594ef81
--- /dev/null
+++ b/lld/test/ELF/dso_handle.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-readobj -symbols %t | FileCheck %s
+# CHECK: Name: __dso_handle
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other [
+# CHECK-NEXT: STV_HIDDEN
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .dynsym
+
+.text
+.global foo, __dso_handle
+foo:
+ lea __dso_handle(%rip),%rax
OpenPOWER on IntegriCloud