aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2019-05-29 03:26:49 +0000
committerTom Stellard <tstellar@redhat.com>2019-05-29 03:26:49 +0000
commitc743d72d7f5c21df632ea47b87a6a91179d388ec (patch)
tree9dfaeea44711092e98ea129a41b0f6e398299d56
parent11c3a5c0f988cc3f412daf13ef8e47d813cc77f1 (diff)
downloadllvm-c743d72d7f5c21df632ea47b87a6a91179d388ec.zip
llvm-c743d72d7f5c21df632ea47b87a6a91179d388ec.tar.gz
llvm-c743d72d7f5c21df632ea47b87a6a91179d388ec.tar.bz2
Merging r354184:
------------------------------------------------------------------------ r354184 | ruiu | 2019-02-15 15:11:18 -0800 (Fri, 15 Feb 2019) | 10 lines [PPC64] Preserve LocalEntry when linking On PowerPC64, it is necessary to keep the LocalEntry bits in st_other, especially when -r is used. Otherwise, when the resulting object is used in a posterior linking, LocalEntry info will be unavailable and functions may be called through the wrong entrypoint. Patch by Leandro Lupori. Differential Revision: https://reviews.llvm.org/D56782 ------------------------------------------------------------------------ llvm-svn: 361921
-rw-r--r--lld/ELF/SyntheticSections.cpp5
-rw-r--r--lld/test/ELF/ppc64-local-entry.s47
2 files changed, 52 insertions, 0 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index b1a3f8b..1067558 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2001,6 +2001,11 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
ESym->setVisibility(Sym->Visibility);
}
+ // The 3 most significant bits of st_other are used by OpenPOWER ABI.
+ // See getPPC64GlobalEntryToLocalEntryOffset() for more details.
+ if (Config->EMachine == EM_PPC64)
+ ESym->st_other |= Sym->StOther & 0xe0;
+
ESym->st_name = Ent.StrTabOffset;
ESym->st_shndx = getSymSectionIndex(Ent.Sym);
diff --git a/lld/test/ELF/ppc64-local-entry.s b/lld/test/ELF/ppc64-local-entry.s
new file mode 100644
index 0000000..2a22951
--- /dev/null
+++ b/lld/test/ELF/ppc64-local-entry.s
@@ -0,0 +1,47 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t
+# RUN: ld.lld -r %t -o %t2
+# RUN: llvm-objdump -s -section=.symtab %t2 | FileCheck %s
+
+.text
+.abiversion 2
+.globl _start
+.p2align 2
+.type _start,@function
+
+_start:
+.Lfunc_begin0:
+.Lfunc_gep0:
+ addis 2, 12, .TOC.-.Lfunc_gep0@ha
+ addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+ .localentry _start, .Lfunc_lep0-.Lfunc_gep0
+ # The code below is not important, it just needs to access some
+ # global data or function, in order to use the TOC.
+ # In this case, it performs the following:
+ # g += 10;
+ # Also note that this code is not intended to be run, but only
+ # to check if the linker will preserve the localentry info.
+ addis 3, 2, g@toc@ha
+ addi 3, 3, g@toc@l
+ lwz 4, 0(3)
+ addi 4, 4, 10
+ stw 4, 0(3)
+ blr
+ .long 0
+ .quad 0
+.Lfunc_end0:
+ .size _start, .Lfunc_end0-.Lfunc_begin0
+
+ .type g,@object # @g
+ .lcomm g,4,4
+
+// We expect the st_other byte to be 0x60:
+// localentry = 011 (gep + 2 instructions), reserved = 000,
+// visibility = 00 (STV_DEFAULT)
+// Currently, llvm-objdump does not support displaying
+// st_other's PPC64 specific flags, thus we check the
+// result of the hexdump of .symtab section.
+
+// CHECK: 0070 00000000 00000000 00000009 12600001