diff options
author | Tom Stellard <tstellar@redhat.com> | 2019-05-29 03:26:49 +0000 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2019-05-29 03:26:49 +0000 |
commit | c743d72d7f5c21df632ea47b87a6a91179d388ec (patch) | |
tree | 9dfaeea44711092e98ea129a41b0f6e398299d56 | |
parent | Merging r360825: (diff) | |
download | llvm-project-c743d72d7f5c21df632ea47b87a6a91179d388ec.tar.gz llvm-project-c743d72d7f5c21df632ea47b87a6a91179d388ec.tar.bz2 llvm-project-c743d72d7f5c21df632ea47b87a6a91179d388ec.zip |
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.cpp | 5 | ||||
-rw-r--r-- | lld/test/ELF/ppc64-local-entry.s | 47 |
2 files changed, 52 insertions, 0 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b1a3f8bc70ae..10675588ebe2 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 000000000000..2a2295169b95 --- /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 |