summaryrefslogtreecommitdiffstats
path: root/lld/ELF
Commit message (Collapse)AuthorAgeFilesLines
* [ELF] Don't cause assertion failure if --dynamic-list or --version-script ↵Fangrui Song2020-06-161-1/+5
| | | | | | | | | takes an empty file Fixes PR46184 Report line 1 of the last memory buffer. (cherry picked from commit ac6abc99e2794e4674a8498f817fda19b176bbfe)
* [lld][ELF] Mark empty NOLOAD output sections SHT_NOBITS instead of SHT_PROGBITSMatt Schulte2020-06-161-0/+1
| | | | | | | | | | | This fixes PR# 45336. Output sections described in a linker script as NOLOAD with no input sections would be marked as SHT_PROGBITS. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D76981 (cherry picked from commit fdc41aa22c60958e6b6df461174b814a4aae3384)
* [ELF] Allow SHF_LINK_ORDER and non-SHF_LINK_ORDER to be mixedFangrui Song2020-04-142-11/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently, `error: incompatible section flags for .rodata` is reported when we mix SHF_LINK_ORDER and non-SHF_LINK_ORDER sections in an output section. This is overconstrained. This patch allows mixed flags with the requirement that SHF_LINK_ORDER sections must be contiguous. Mixing flags is used by Linux aarch64 (https://github.com/ClangBuiltLinux/linux/issues/953) .init.data : { ... KEEP(*(__patchable_function_entries)) ... } When the integrated assembler is enabled, clang's -fpatchable-function-entry=N[,M] implementation sets the SHF_LINK_ORDER flag (D72215) to fix a number of garbage collection issues. Strictly speaking, the ELF specification does not require contiguous SHF_LINK_ORDER sections but for many current uses of SHF_LINK_ORDER like .ARM.exidx/__patchable_function_entries there has been a requirement for the sections to be contiguous on top of the requirements of the ELF specification. This patch also imposes one restriction: SHF_LINK_ORDER sections cannot be separated by a symbol assignment or a BYTE command. Not allowing BYTE is a natural extension that a non-SHF_LINK_ORDER cannot be a separator. Symbol assignments can delimiter the contents of SHF_LINK_ORDER sections. Allowing SHF_LINK_ORDER sections across symbol assignments (especially __start_/__stop_) can make things hard to explain. The restriction should not be a problem for practical use cases. Reviewed By: psmith Differential Revision: https://reviews.llvm.org/D77007 (cherry picked from commit 673e81eee4fa3ffa38736f1063e6c4fa2d9278b0)
* [ELF] Fix a null pointer dereference when --emit-relocs and --strip-debug ↵Fangrui Song2020-04-103-4/+16
| | | | | | | | | | | | | | | | | | | | | | | | are used together Fixes https://bugs.llvm.org//show_bug.cgi?id=44878 When --strip-debug is specified, .debug* are removed from inputSections while .rel[a].debug* (incorrectly) remain. LinkerScript::addOrphanSections() requires the output section of a relocated InputSectionBase to be created first. .debug* are not in inputSections -> output sections .debug* are not created -> getOutputSectionName(.rel[a].debug*) dereferences a null pointer. Fix the null pointer dereference by deleting .rel[a].debug* from inputSections as well. Reviewed By: grimar, nickdesaulniers Differential Revision: https://reviews.llvm.org/D74510 (cherry picked from commit 6c73246179376442705b3a545f4e1f1478777a04)
* [LLD][ELF][ARM][AArch64] Only round up ThunkSection Size when large OS.Peter Smith2020-02-043-6/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In D71281 a fix was put in to round up the size of a ThunkSection to the nearest 4KiB when performing errata patching. This fixed a problem with a very large instrumented program that had thunks and patches mutually trigger each other. Unfortunately it triggers an assertion failure in an AArch64 allyesconfig build of the kernel. There is a specific assertion preventing an InputSectionDescription being larger than 4KiB. This will always trigger if there is at least one Thunk needed in that InputSectionDescription, which is possible for an allyesconfig build. Abstractly the problem case is: .text : { *(.text) ; ... . = ALIGN(SZ_4K); __idmap_text_start = .; *(.idmap.text) __idmap_text_end = .; ... } The assertion checks that __idmap_text_end - __idmap_start is < 4 KiB. Note that there is more than one InputSectionDescription in the OutputSection so we can't just restrict the fix to OutputSections smaller than 4 KiB. The fix presented here limits the D71281 to InputSectionDescriptions that meet the following conditions: 1.) The OutputSection is bigger than the thunkSectionSpacing so adding thunks will affect the addresses of following code. 2.) The InputSectionDescription is larger than 4 KiB. This will prevent any assertion failures that an InputSectionDescription is < 4 KiB in size. We do this at ThunkSection creation time as at this point we know that the addresses are stable and up to date prior to adding the thunks as assignAddresses() will have been called immediately prior to thunk generation. The fix reverts the two tests affected by D71281 to their original state as they no longer need the 4KiB size roundup. I've added simpler tests to check for D71281 when the OutputSection size is larger than the ThunkSection spacing. Fixes https://github.com/ClangBuiltLinux/linux/issues/812 Differential Revision: https://reviews.llvm.org/D72344 (cherry picked from commit 01ad4c838466bd5db180608050ed8ccb3b62d136)
* [ELF] Decrease alignment of ThunkSection on 64-bit targets from 8 to 4Fangrui Song2020-02-041-2/+2
| | | | | | | | | | | | | ThunkSection contains 4-byte instructions on all targets that use thunks. Thunks should not be used in any performance sensitive places, and locality/cache line/instruction fetching arguments should not apply. We use 16 bytes as preferred function alignments for modern PowerPC cores. In any case, 8 is not optimal. Differential Revision: https://reviews.llvm.org/D72819 (cherry picked from commit 870094decfc9fe80c8e0a6405421b7d09b97b02b)
* [LLD][ELF][ARM] Do not insert interworking thunks for non STT_FUNC symbolsPeter Smith2020-01-291-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | ELF for the ARM architecture requires linkers to provide interworking for symbols that are of type STT_FUNC. Interworking for other symbols must be encoded directly in the object file. LLD was always providing interworking, regardless of the symbol type, this breaks some programs that have branches from Thumb state targeting STT_NOTYPE symbols that have bit 0 clear, but they are in fact internal labels in a Thumb function. LLD treats these symbols as ARM and inserts a transition to Arm. This fixes the problem for in range branches, R_ARM_JUMP24, R_ARM_THM_JUMP24 and R_ARM_THM_JUMP19. This is expected to be the vast majority of problem cases as branching to an internal label close to the function. There is at least one follow up patch required. - R_ARM_CALL and R_ARM_THM_CALL may do interworking via BL/BLX substitution. In theory range-extension thunks can be altered to not change state when the symbol type is not STT_FUNC. I will need to check with ld.bfd to see if this is the case in practice. Fixes (part of) https://github.com/ClangBuiltLinux/linux/issues/773 Differential Revision: https://reviews.llvm.org/D73474 (cherry picked from commit 4f38ab250ff4680375c4c01db0a88c157093c665)
* [ELF][PPC32] Support --emit-relocs link of R_PPC_PLTREL24Fangrui Song2020-01-281-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Similar to R_MIPS_GPREL16 and R_MIPS_GPREL32 (D45972). If the addend of an R_PPC_PLTREL24 is >= 0x8000, it indicates that r30 is relative to the input section .got2. ``` addis 30, 30, .got2+0x8000-.L1$pb@ha addi 30, 30, .got2+0x8000-.L1$pb@l ... bl foo+0x8000@PLT ``` After linking, the relocation will be relative to the output section .got2. To compensate for the shift `address(input section .got2) - address(output section .got2) = ppc32Got2OutSecOff`, adjust by `ppc32Got2OutSecOff`: ``` addis 30, 30, .got2+0x8000-.L1+ppc32Got2OutSecOff$pb@ha addi 30, 30, .got2+0x8000-.L1+ppc32Got2OutSecOff$pb@ha$pb@l ... bl foo+0x8000+ppc32Got2OutSecOff@PLT ``` This rule applys to a relocatable link or a non-relocatable link with --emit-relocs. Reviewed By: Bdragon28 Differential Revision: https://reviews.llvm.org/D73532 (cherry picked from commit e11b709b1922ca46b443fcfa5d76b87edca48721)
* [ELF][PPC32] Support range extension thunks with addendsFangrui Song2020-01-253-23/+53
| | | | | | | | | | | * Generalize the code added in D70637 and D70937. We should eventually remove the EM_MIPS special case. * Handle R_PPC_LOCAL24PC the same way as R_PPC_REL24. Reviewed By: Bdragon28 Differential Revision: https://reviews.llvm.org/D73424 (cherry picked from commit 70389be7a029bec3c45991a60b627445ef996120)
* [ELF][PPC32] Support canonical PLTFangrui Song2020-01-254-12/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -fno-pie produces a pair of non-GOT-non-PLT relocations R_PPC_ADDR16_{HA,LO} (R_ABS) referencing external functions. ``` lis 3, func@ha la 3, func@l(3) ``` In a -no-pie/-pie link, if func is not defined in the executable, a canonical PLT entry (st_value>0, st_shndx=0) will be needed. References to func in shared objects will be resolved to this address. -fno-pie -pie should fail with "can't create dynamic relocation ... against ...", so we just need to think about -no-pie. On x86, the PLT entry passes the JMP_SLOT offset to the rtld PLT resolver. On x86-64: the PLT entry passes the JUMP_SLOT index to the rtld PLT resolver. On ARM/AArch64: the PLT entry passes &.got.plt[n]. The PLT header passes &.got.plt[fixed-index]. The rtld PLT resolver can compute the JUMP_SLOT index from the two addresses. For these targets, the canonical PLT entry can just reuse the regular PLT entry (in PltSection). On PPC32: PltSection (.glink) consists of `b PLTresolve` instructions and `PLTresolve`. The rtld PLT resolver depends on r11 having been set up to the .plt (GotPltSection) entry. On PPC64 ELFv2: PltSection (.glink) consists of `__glink_PLTresolve` and `bl __glink_PLTresolve`. The rtld PLT resolver depends on r12 having been set up to the .plt (GotPltSection) entry. We cannot reuse a `b PLTresolve`/`bl __glink_PLTresolve` in PltSection as a canonical PLT entry. PPC64 ELFv2 avoids the problem by using TOC for any external reference, even in non-pic code, so the canonical PLT entry scenario should not happen in the first place. For PPC32, we have to create a PLT call stub as the canonical PLT entry. The code sequence sets up r11. Reviewed By: Bdragon28 Differential Revision: https://reviews.llvm.org/D73399 (cherry picked from commit 837e8a9c0cd097034e023dfba146d17ce132998c)
* [lld][RISCV] Print error when encountering R_RISCV_ALIGNJames Clarke2020-01-241-2/+7
| | | | | | | | | | | | | | | | | | | | | | | | | Summary: Unlike R_RISCV_RELAX, which is a linker hint, R_RISCV_ALIGN requires the support of the linker even when ignoring all R_RISCV_RELAX relocations. This is because the compiler emits as many NOPs as may be required for the requested alignment, more than may be required pre-relaxation, to allow for the target becoming more unaligned after relaxing earlier sequences. This means that the target is often not initially aligned in the object files, and so the R_RISCV_ALIGN relocations cannot just be ignored. Since we do not support linker relaxation, we must turn these into errors. Reviewers: ruiu, MaskRay, espindola Reviewed By: MaskRay Subscribers: grimar, Jim, emaste, arichardson, asb, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, lenary, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71820 (cherry picked from commit d1da63664f4e42191daf2e6a9fa682ca9f75ef5e)
* [ELF][PowerPC] Support R_PPC_COPY and R_PPC64_COPYFangrui Song2020-01-242-0/+2
| | | | | | | | Reviewed By: Bdragon28, jhenderson, grimar, sfertile Differential Revision: https://reviews.llvm.org/D73255 (cherry picked from commit f1dab29908d25a4044abff6ffc120c48b20f034d)
* [ELF] --no-dynamic-linker: don't emit undefined weak symbols to .dynsymFangrui Song2020-01-233-2/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | I felt really sad to push this commit for my selfish purpose to make glibc -static-pie build with lld. Some code constructs in glibc require R_X86_64_GOTPCREL/R_X86_64_REX_GOTPCRELX referencing undefined weak to be resolved to a GOT entry not relocated by R_X86_64_GLOB_DAT (GNU ld behavior), e.g. csu/libc-start.c if (__pthread_initialize_minimal != NULL) __pthread_initialize_minimal (); elf/dl-object.c void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) { /* We modify the list of loaded objects. */ __rtld_lock_lock_recursive (GL(dl_load_write_lock)); Emitting a GLOB_DAT will make the address equal &__ehdr_start (true value) and cause elf/ldconfig to segfault. glibc really should move away from weak references, which do not have defined semantics. Temporarily special case --no-dynamic-linker. (cherry picked from commit 0fbf28f7aae0ceb70071cac56de345e3ff04439c)
* [ELF] Allow R_PLT_PC (R_PC) to a hidden undefined weak symbolFangrui Song2020-01-171-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | This essentially reverts b841e119d77ed0502e3a2e710f26a899bef28b3c. Such code construct can be used in the following way: // glibc/stdlib/exit.c // clang -fuse-ld=lld => succeeded // clang -fuse-ld=lld -fpie -pie => relocation R_PLT_PC cannot refer to absolute symbol __attribute__((weak, visibility("hidden"))) extern void __call_tls_dtors(); void __run_exit_handlers() { if (__call_tls_dtors) __call_tls_dtors(); } Since we allow R_PLT_PC in -no-pie mode, it makes sense to allow it in -pie mode as well. Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D72943 (cherry picked from commit 6ab89c3c5df8b679e6ee240a13356309c048fc71)
* [ELF] Avoid false-positive assert in getErrPlace()Alex Richardson2020-01-171-1/+1
| | | | | | | | | | | | | This assertion was added as part of D70659 but did not account for .bss input sections. I noticed that this assert was incorrectly triggering while building FreeBSD for MIPS64. Fixed by relaxing the assert to also account for SHT_NOBITS input sections and adjust the test mips-jalr-non-function.s to link a file with a .bss section first. Reviewed By: MaskRay, grimar Differential Revision: https://reviews.llvm.org/D72567 (cherry picked from commit 441410be471d5d0a5d1d47cf363de155e397a0c2)
* [ELF] -r: don't create .interpFangrui Song2020-01-161-2/+2
| | | | | | | | | | | | | `{clang,gcc} -nostdlib -r a.c` passes --dynamic-linker to the linker, and the expected behavior is to ignore it. If .interp is kept in the relocatable object file, a final link will get PT_INTERP even if --dynamic-linker is not specified. glibc ld.so expects to see PT_DYNAMIC and the executable will likely fail to run. Ignore --dynamic-linker in -r mode as well as -shared. (cherry picked from commit 2d7a8cf90478cd845ffb39763b0e95b7715322d2)
* [ELF] Delete the RelExpr member R_HINT. NFCFangrui Song2020-01-143-4/+3
| | | | | | | R_HINT is ignored like R_NONE. There are no strong reasons to keep R_HINT. The largest RelExpr member R_RISCV_PC_INDIRECT is 60 now. Differential Revision: https://reviews.llvm.org/D71822
* [ELF] --exclude-libs: don't assign VER_NDX_LOCAL to undefined symbolsFangrui Song2020-01-141-1/+1
| | | | | | | | | | | | | | | Suggested by Peter Collingbourne. Non-VER_NDX_GLOBAL versions should not be assigned to defined symbols. --exclude-libs violates this and can cause a spurious error "cannot refer to absolute symbol" after D71795. excludeLibs incorrectly assigns VER_NDX_LOCAL to an undefined weak symbol => isPreemptible is false => R_PLT_PC is optimized to R_PC => in isStaticLinkTimeConstant, an error is emitted. Reviewed By: pcc, grimar Differential Revision: https://reviews.llvm.org/D72681
* [ELF] Delete unintended --force-btiFangrui Song2020-01-131-3/+0
|
* [ELF] Add -z force-ibt and -z shstk for Intel Control-flow Enforcement ↵Fangrui Song2020-01-139-29/+262
| | | | | | | | | | | | | | | | | | | | | | | | | | | Technology This patch is a joint work by Rui Ueyama and me based on D58102 by Xiang Zhang. It adds Intel CET (Control-flow Enforcement Technology) support to lld. The implementation follows the draft version of psABI which you can download from https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI. CET introduces a new restriction on indirect jump instructions so that you can limit the places to which you can jump to using indirect jumps. In order to use the feature, you need to compile source files with -fcf-protection=full. * IBT is enabled if all input files are compiled with the flag. To force enabling ibt, pass -z force-ibt. * SHSTK is enabled if all input files are compiled with the flag, or if -z shstk is specified. IBT-enabled executables/shared objects have two PLT sections, ".plt" and ".plt.sec". For the details as to why we have two sections, please read the comments. Reviewed By: xiangzhangllvm Differential Revision: https://reviews.llvm.org/D59780
* [ELF] Make TargetInfo::writeIgotPlt a no-opFangrui Song2020-01-102-5/+1
| | | | | | | | | | | | | | RELA targets don't read initial .got.plt entries. REL targets (ARM, x86-32) write the address of the IFUNC resolver to the entry (`write32le(buf, s.getVA())`). The default writeIgotPlt() is not meaningful. Make it a no-op. AArch64 and x86-64 will have 0 as initial .got.plt entries associated with IFUNC. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D72474
* [ThinLTO] Pass CodeGenOpts like UnrollLoops/VectorizeLoop/VectorizeSLPWei Mi2020-01-092-0/+4
| | | | | | | | | | | | | down to pass builder in ltobackend. Currently CodeGenOpts like UnrollLoops/VectorizeLoop/VectorizeSLP in clang are not passed down to pass builder in ltobackend when new pass manager is used. This is inconsistent with the behavior when new pass manager is used and thinlto is not used. Such inconsistency causes slp vectorization pass not being enabled in ltobackend for O3 + thinlto right now. This patch fixes that. Differential Revision: https://reviews.llvm.org/D72386
* [ELF] Fix includeInDynsym() when an undefined weak is merged with a lazy ↵Fangrui Song2020-01-091-1/+3
| | | | | | | | | | | | definition An undefined weak does not fetch the lazy definition. A lazy weak symbol should be considered undefined, and thus preemptible if .dynsym exists. D71795 is not quite an NFC. It errors on an R_X86_64_PLT32 referencing an undefined weak symbol. isPreemptible is false (incorrect) => R_PLT_PC is optimized to R_PC => in isStaticLinkTimeConstant, an error is emitted when an R_PC is applied on an undefined weak (considered absolute).
* Re-apply "[ELF] Allow getErrPlace() to work before Out::bufferStart is set"Alex Richardson2020-01-091-4/+10
| | | | | | This time with a fix for the UBSAN failure. Differential Revision: https://reviews.llvm.org/D70659
* [ELF][Hexagon] Add support for IE relocationsSid Manning2020-01-092-1/+25
| | | | Differential Revision: https://reviews.llvm.org/D71143
* [ELF] Delete an unused special rule from isStaticLinkTimeConstant. NFCFangrui Song2020-01-081-10/+0
| | | | | | | | | | | | | | | | | | Weak undefined symbols are preemptible after D71794. if (sym.isPreemptible) return false; if (!config->isPic) return true; // isPic means includeInDynsym is true after D71794. ... // We can delete this if because it can never be true. if (sym.isUndefWeak) return true; Differential Revision: https://reviews.llvm.org/D71795
* [ELF] Don't special case weak symbols for pie with no shared objectsFangrui Song2020-01-081-5/+0
| | | | | | | | | | | | | | | | | | | | | | D59275 added the following clause to Symbol::includeInDynsym() if (isUndefWeak() && Config->Pie && SharedFiles.empty()) return false; D59549 explored the possibility to generalize it for -no-pie. GNU ld's rules are architecture dependent and partly controlled by -z {,no-}dynamic-undefined-weak. Our attempts to mimic its rules are actually half-baked and don't provide perceivable benefits (it can save a few more weak undefined symbols in .dynsym in a -static-pie executable). Let's just delete the rule for simplicity. We will expect cosmetic inconsistencies with ld.bfd in certain -static-pie scenarios. This permits a simplification in D71795. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D71794
* [LLD][ELF][AArch64] Do not use thunk for undefined weak symbol.Peter Smith2020-01-071-0/+4
| | | | | | | | | | | | | | | In AArch64 a branch to an undefined weak symbol that does not have a PLT entry should resolve to the next instruction. The thunk generation code can prevent this from happening as a range extension thunk can be generated if the branch is sufficiently far away from 0, the value of an undefined weak symbol. The fix is taken from the Arm implementation of needsThunk(), we prevent a thunk from being generated to an undefined weak symbol. fixes pr44451 Differential Revision: https://reviews.llvm.org/D72267
* [lld] Fix trivial typos in commentsKazuaki Ishizaki2020-01-065-5/+5
| | | | | | Reviewed By: ruiu, MaskRay Differential Revision: https://reviews.llvm.org/D72196
* [ELF] Drop const qualifier to fix -Wrange-loop-analysis. NFCFangrui Song2020-01-041-1/+1
| | | | | | | | | | | | | | | | ``` lld/ELF/Relocations.cpp:1622:56: warning: loop variable 'ts' of type 'const std::pair<ThunkSection *, uint32_t>' (aka 'const pair<lld::elf::ThunkSection *, unsigned int>') creates a copy from type 'const std::pair<ThunkSection *, uint32_t>' [-Wrange-loop-analysis] for (const std::pair<ThunkSection *, uint32_t> ts : isd->thunkSections) ``` Drop const qualifier to fix -Wrange-loop-analysis. We can make -Wrange-loop-analysis warnings (DiagnoseForRangeConstVariableCopies) on `const A` more permissive on more types (e.g. POD -> trivially copyable), unfortunately it will not make std::pair good, because `constexpr pair& operator=(const pair& p);` is unfortunately user-defined. Reviewed By: Mordante Differential Revision: https://reviews.llvm.org/D72211
* Add TPREL relocation support to HexagonSid Manning2020-01-022-0/+16
| | | | Differential Revision: https://reviews.llvm.org/D71069
* [lld] Fix -Wrange-loop-analysis warningsFangrui Song2020-01-012-5/+2
| | | | | | | | | | One instance looks like a false positive: lld/ELF/Relocations.cpp:1622:14: note: use reference type 'const std::pair<ThunkSection *, uint32_t> &' (aka 'cons t pair<lld::elf::ThunkSection *, unsigned int> &') to prevent copying for (const std::pair<ThunkSection *, uint32_t> ts : isd->thunkSections) It is not changed in this commit.
* [ELF][RISCV] Improve error message for unknown relocationsFangrui Song2019-12-311-16/+15
| | | | Like rLLD354040.
* [ELF][PPC64] Improve "call lacks nop" diagnostic and make it compatible with ↵Fangrui Song2019-12-292-2/+11
| | | | | | | | | | | | | | | | GCC<5.5 and GCC<6.4 GCC before r245813 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79439) did not emit nop after b/bl. This can happen with recursive calls. r245813 was back ported to GCC 5.5 and GCC 6.4. This is common, for example, libstdc++.a(locale.o) shipped with GCC 4.9 and many objects in netlib lapack can cause lld to error. gold allows such calls to the same section. Our __plt_foo symbol's `section` field is used for ThunkSection, so we can't implement a similar loosen rule easily. But we can make use of its `file` field which is currently NULL. Differential Revision: https://reviews.llvm.org/D71639
* [ELF][PPC32] Implement IPLT code sequence for non-preemptible IFUNCFangrui Song2019-12-293-10/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Similar to D71509 (EM_PPC64), on EM_PPC, the IPLT code sequence should be similar to a PLT call stub. Unlike EM_PPC64, EM_PPC -msecure-plt has small/large PIC model differences. * -fpic/-fpie: R_PPC_PLTREL24 r_addend=0. The call stub loads an address relative to `_GLOBAL_OFFSET_TABLE_`. * -fPIC/-fPIE: R_PPC_PLTREL24 r_addend=0x8000. (A partial linked object file may have an addend larger than 0x8000.) The call stub loads an address relative to .got2+0x8000. Just assume large PIC model for now. This patch makes: // clang -fuse-ld=lld -msecure-plt -fno-pie -no-pie a.c // clang -fuse-ld=lld -msecure-plt -fPIE -pie a.c #include <stdio.h> static void impl(void) { puts("meow"); } void thefunc(void) __attribute__((ifunc("resolver"))); void *resolver(void) { return &impl; } int main(void) { thefunc(); void (*theptr)(void) = &thefunc; theptr(); } work on Linux glibc. -fpie will crash because the compiler and the linker do not agree on the value which r30 stores (_GLOBAL_OFFSET_TABLE_ vs .got2+0x8000). Differential Revision: https://reviews.llvm.org/D71621
* [ELF][PPC64] Implement IPLT code sequence for non-preemptible IFUNCFangrui Song2019-12-293-4/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Non-preemptible IFUNC are placed in in.iplt (.glink on EM_PPC64). If there is a non-GOT non-PLT relocation, for pointer equality, we change the type of the symbol from STT_IFUNC and STT_FUNC and bind it to the .glink entry. On EM_386, EM_X86_64, EM_ARM, and EM_AARCH64, the PLT code sequence loads the address from its associated .got.plt slot. An IPLT also has an associated .got.plt slot and can use the same code sequence. On EM_PPC64, the PLT code sequence is actually a bl instruction in .glink . It jumps to `__glink_PLTresolve` (the PLT header). and `__glink_PLTresolve` computes the .plt slot (relocated by R_PPC64_JUMP_SLOT). An IPLT does not have an associated R_PPC64_JUMP_SLOT, so we cannot use `bl` in .iplt . Instead, create a call stub which has a similar code sequence as PPC64PltCallStub. We don't save the TOC pointer, so such scenarios will not work: a function pointer to a non-preemptible ifunc, which resolves to a function defined in another DSO. This is the restriction described by https://sourceware.org/glibc/wiki/GNU_IFUNC (though on many architectures it works in practice): Requirement (a): Resolver must be defined in the same translation unit as the implementations. If an ifunc is taken address but not called, technically we don't need an entry for it, but we currently do that. This patch makes // clang -fuse-ld=lld -fno-pie -no-pie a.c // clang -fuse-ld=lld -fPIE -pie a.c #include <stdio.h> static void impl(void) { puts("meow"); } void thefunc(void) __attribute__((ifunc("resolver"))); void *resolver(void) { return &impl; } int main(void) { thefunc(); void (*theptr)(void) = &thefunc; theptr(); } work on Linux glibc and FreeBSD. Calling a function pointer pointing to a Non-preemptible IFUNC never worked before. Differential Revision: https://reviews.llvm.org/D71509
* [ELF] Improve the condition to create .interpFangrui Song2019-12-271-1/+1
| | | | | | | | | | | | | | | This restores commit 1417558e4a61794347c6bfbafaff7cd96985b2c3 and its follow-up, reverted by commit c3dbd782f1e0578c7ebc342f2e92f54d9644cff7. After this commit: clang -fuse-ld=bfd -no-pie -nostdlib a.c => .interp not created clang -fuse-ld=bfd -pie -fPIE -nostdlib a.c => .interp created clang -fuse-ld=gold -no-pie -nostdlib a.c => .interp not created clang -fuse-ld=gold -pie -fPIE -nostdlib a.c => .interp created clang -fuse-ld=lld -no-pie -nostdlib a.c => .interp created clang -fuse-ld=lld -pie -fPIE -nostdlib a.c => .interp created
* Revert "[ELF] Improve the condition to create .interp"Reid Kleckner2019-12-271-1/+1
| | | | | | | | This reverts commit 1417558e4a61794347c6bfbafaff7cd96985b2c3. Also reverts commit 019a92bb2832447092bb5c1faf9d03bb03b8c9c8. This causes check-sanitizer to fail. The "-Nolib" variant of the test crashes on startup in the loader.
* [ELF] Improve the condition to create .interpFangrui Song2019-12-261-1/+1
| | | | | | | | | | | | | | | | | Similar to rL362355, but with the `!config->shared` guard. (1) {gcc,clang} -fuse-ld=bfd -pie -fPIE -nostdlib a.c => .interp created (2) {gcc,clang} -fuse-ld=lld -pie -fPIE -nostdlib a.c => .interp not created (3) {gcc,clang} -fuse-ld=lld -pie -fPIE -nostdlib a.c a.so => .interp created The inconsistency of (2) is due to the condition `!Config->SharedFiles.empty()`. To make lld behave more like ld.bfd, we could change the condition to: config->hasDynSymTab && !config->dynamicLinker.empty() && script->needsInterpSection(); However, that would bring another inconsistency as can be observed with: (4) {gcc,clang} -fuse-ld=bfd -no-pie -nostdlib a.c => .interp not created
* [ELF] Support input section description .gnu.version* in /DISCARD/Fangrui Song2019-12-261-6/+6
| | | | | | | | | | | | | | Linux powerpc discards `*(.gnu.version*)` (arch/powerpc/kernel/vmlinux.lds.S) to suppress --orphan-handling=warn warnings in the -pie output `.tmp_vmlinux1` The support is simple. Just add isLive() to: 1) Fix an assertion in SectionBase::getPartition() called by VersionTableSection::isNeeded(). 2) Suppress DT_VERSYM, DT_VERDEF, DT_VERNEED and DT_VERNEEDNUM, if the relevant section is discarded. Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D71819
* [ELF] Don't suggest an alternative spelling for a symbol in a discarded sectionFangrui Song2019-12-231-4/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | For undef-not-suggest.test, we currently make redundant alternative spelling suggestions: ``` ld.lld: error: relocation refers to a discarded section: .text.foo >>> defined in a.o >>> section group signature: foo >>> prevailing definition is in a.o >>> referenced by a.o:(.rodata+0x0) >>> did you mean: >>> defined in: a.o ld.lld: error: relocation refers to a symbol in a discarded section: foo >>> defined in a.o >>> section group signature: foo >>> prevailing definition is in a.o >>> referenced by a.o:(.rodata+0x8) >>> did you mean: for >>> defined in: a.o ``` Reviewed By: grimar, ruiu Differential Revision: https://reviews.llvm.org/D71735
* [ELF] Delete a redundant R_HINT check from isStaticLinkTimeConstant(). NFCFangrui Song2019-12-221-2/+2
| | | | scanReloc() returns when it sees an R_HINT.
* [lld][RISCV] Use an e_flags of 0 if there are only binary input files.John Baldwin2019-12-211-1/+4
| | | | | | | | | | | | | | | | | | Summary: If none of the input files are ELF object files (for example, when generating an object file from a single binary input file via "-b binary"), use a fallback value for the ELF header flags instead of crashing with an assertion failure. Reviewers: MaskRay, ruiu, espindola Reviewed By: MaskRay, ruiu Subscribers: kevans, grimar, emaste, arichardson, asb, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, lenary, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits, jrtc27 Tags: #llvm Differential Revision: https://reviews.llvm.org/D71101
* [ELF] writePlt, writeIplt: replace parameters gotPltEntryAddr and index with ↵Fangrui Song2019-12-1812-88/+89
| | | | | | | | | | `const Symbol &`. NFC PPC::writeIplt (IPLT code sequence, D71621) needs to access `Symbol`. Reviewed By: grimar, ruiu Differential Revision: https://reviews.llvm.org/D71631
* [ELF] Fix a comment. NFCFangrui Song2019-12-171-1/+1
|
* [ELF] Rename .plt to .iplt and decrease EM_PPC{,64} alignment of .glink to 4Fangrui Song2019-12-171-1/+3
| | | | | | | | | | | | | | | | | | | | | | GNU ld creates the synthetic section .iplt, and has a built-in linker script that assigns .iplt to the output section .plt . There is no output section named .iplt . Making .iplt an output section actually has a benefit that makes the tricky toolchain feature stand out. Symbolizers don't have to deal with mixed PLT entries (e.g. llvm-objdump -d incorrectly annotates such jump targets). On EM_PPC{,64}, .glink contains a PLT resolver and a series of jump instructions. The 4-byte entry size makes it unnecessary to have an alignment of 16. Mark ppc32-gnu-ifunc.s and ppc32-gnu-ifunc-nonpreemptable.s as `XFAIL: *`. They test IPLT on EM_PPC, which never works. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D71520
* [ELF] Add IpltSectionFangrui Song2019-12-1713-48/+114
| | | | | | | | | | | | | | | | | | | PltSection is used by both PLT and IPLT. The PLT section may have a header while the IPLT section does not. Split off IpltSection from PltSection to be clearer. Unlike other targets, PPC64 cannot use the same code sequence for PLT and IPLT. This helps make a future PPC64 patch (D71509) more isolated. On EM_386 and EM_X86_64, when PLT is empty while IPLT is not, currently we are inconsistent whether the PLT header is conceptually attached to in.plt or in.iplt . Consistently attach the header to in.plt can make the -z retpolineplt logic simpler. It also makes `jmp` point to an aesthetically better place for non-retpolineplt cases. Reviewed By: grimar, ruiu Differential Revision: https://reviews.llvm.org/D71519
* [ELF] Delete unused declaration addIRelativeRelocs after D65995. NFCFangrui Song2019-12-161-2/+0
|
* [ELF] Delete relOff from TargetInfo::writePLTFangrui Song2019-12-1612-55/+36
| | | | | | | | | | | | | | This change only affects EM_386. relOff can be computed from `index` easily, so it is unnecessarily passed as a parameter. Both in.plt and in.iplt entries are written by writePLT. For in.iplt, the instruction `push reloc_offset` will change because `index` is now different. Fortunately, this does not matter because `push; jmp` is only used by PLT. IPLT does not need the code sequence. Reviewed By: grimar, ruiu Differential Revision: https://reviews.llvm.org/D71518
* [ELF] De-template PltSection::addEntry. NFCFangrui Song2019-12-163-13/+8
|
OpenPOWER on IntegriCloud