summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Writer.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* [ELF] Add -z separate-code and pad the last page of last PF_X PT_LOAD with ↵Fangrui Song2019-08-011-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | traps only if -z separate-code is specified This patch 1) adds -z separate-code and -z noseparate-code (default). 2) changes the condition that the last page of last PF_X PT_LOAD is padded with trap instructions. Current condition (after D33630): if there is no `SECTIONS` commands. After this change: if -z separate-code is specified. -z separate-code was introduced to ld.bfd in 2018, to place the text segment in its own pages. There is no overlap in pages between an executable segment and a non-executable segment: 1) RX cannot load initial contents from R or RW(or non-SHF_ALLOC). 2) R and RW(or non-SHF_ALLOC) cannot load initial contents from RX. lld's current status: - Between R and RX: in `Writer<ELFT>::fixSectionAlignments()`, the start of a segment is always aligned to maxPageSize, so the initial contents loaded by R and RX do not overlap. I plan to allow overlaps in D64906 if -z noseparate-code is in effect. - Between RX and RW(or non-SHF_ALLOC if RW doesn't exist): we currently unconditionally pad the last page to commonPageSize (defaults to 4096 on all targets we support). This patch will make it effective only if -z separate-code is specified. -z separate-code is a dubious feature that intends to reduce the number of ROP gadgets (which is actually ineffective because attackers can find plenty of gadgets in the text segment, no need to find gadgets in non-code regions). With the overlapping PT_LOAD technique D64906, -z noseparate-code removes two more alignments at segment boundaries than -z separate-code. This saves at most defaultCommonPageSize*2 bytes, which are significant on targets with large defaultCommonPageSize (AArch64/MIPS/PPC: 65536). Issues/feedback on alignment at segment boundaries to help understand the implication: * binutils PR24490 (the situation on ld.bfd is worse because they have two R-- on both sides of R-E so more alignments.) * In binutils, the 2018-02-27 commit "ld: Add --enable-separate-code" made -z separate-code the default on Linux. https://github.com/richfelker/musl-cross-make/commit/d969dea983a2cc54a1e0308a0cdeb6c3307e4bfa In musl-cross-make, binutils is configured with --disable-separate-code to address size regressions caused by -z separate-code. (lld actually has the same issue, which I plan to fix in a future patch. The ld.bfd x86 status is worse because they default to max-page-size=0x200000). * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=237676 people want smaller code size. This patch will remove one alignment boundary. * Stef O'Rear: I'm opposed to any kind of page alignment at the text/rodata line (having a partial page of text aliased as rodata and vice versa has no demonstrable harm, and I actually care about small systems). So, make -z noseparate-code the default. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D64903 llvm-svn: 367537
* [ELF] Detemplate maybeReportUndefined and copySectionsIntoPartitionsFangrui Song2019-07-261-2/+2
| | | | llvm-svn: 367117
* [ELF] Delete redundant pageAlign at PT_GNU_RELRO boundaries after D58892Fangrui Song2019-07-171-19/+0
| | | | | | | | | | | | | | | | | | | | | | | Summary: After D58892 split the RW PT_LOAD on the PT_GNU_RELRO boundary, the new layout is: PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro)) PT_LOAD(.data. .bss) The two pageAlign() calls at PT_GNU_RELRO boundaries are redundant due to the existence of PT_LOAD. Reviewers: grimar, peter.smith, ruiu, espindola Reviewed By: ruiu Subscribers: sfertile, atanasyan, emaste, arichardson, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64854 llvm-svn: 366307
* [ELF] Fix variable names in comments after VariableName -> variableName changeFangrui Song2019-07-161-4/+4
| | | | | | Also fix some typos. llvm-svn: 366181
* Update comments for r365730. NFC.Rui Ueyama2019-07-111-13/+13
| | | | llvm-svn: 365733
* [Coding style change][lld] Rename variables for non-ELF portsRui Ueyama2019-07-111-5/+5
| | | | | | | | | | | This patch does the same thing as r365595 to other subdirectories, which completes the naming style change for the entire lld directory. With this, the naming style conversion is complete for lld. Differential Revision: https://reviews.llvm.org/D64473 llvm-svn: 365730
* [Coding style change] Rename variables so that they start with a lowercase ↵Rui Ueyama2019-07-101-1137/+1137
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | letter This patch is mechanically generated by clang-llvm-rename tool that I wrote using Clang Refactoring Engine just for creating this patch. You can see the source code of the tool at https://reviews.llvm.org/D64123. There's no manual post-processing; you can generate the same patch by re-running the tool against lld's code base. Here is the main discussion thread to change the LLVM coding style: https://lists.llvm.org/pipermail/llvm-dev/2019-February/130083.html In the discussion thread, I proposed we use lld as a testbed for variable naming scheme change, and this patch does that. I chose to rename variables so that they are in camelCase, just because that is a minimal change to make variables to start with a lowercase letter. Note to downstream patch maintainers: if you are maintaining a downstream lld repo, just rebasing ahead of this commit would cause massive merge conflicts because this patch essentially changes every line in the lld subdirectory. But there's a remedy. clang-llvm-rename tool is a batch tool, so you can rename variables in your downstream repo with the tool. Given that, here is how to rebase your repo to a commit after the mass renaming: 1. rebase to the commit just before the mass variable renaming, 2. apply the tool to your downstream repo to mass-rename variables locally, and 3. rebase again to the head. Most changes made by the tool should be identical for a downstream repo and for the head, so at the step 3, almost all changes should be merged and disappear. I'd expect that there would be some lines that you need to merge by hand, but that shouldn't be too many. Differential Revision: https://reviews.llvm.org/D64121 llvm-svn: 365595
* lld/elf: Deduplicate undefined symbol diagnosticsNico Weber2019-06-201-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before: ``` ld.lld: error: undefined symbol: f() >>> referenced by test.cc:3 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-9c0808.o:(g()) ld.lld: error: undefined symbol: f() >>> referenced by test.cc:4 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-9c0808.o:(h()) ld.lld: error: undefined symbol: f() >>> referenced by test.cc:5 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-9c0808.o:(j()) ld.lld: error: undefined symbol: k() >>> referenced by test.cc:5 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-9c0808.o:(j()) ld.lld: error: undefined symbol: f() >>> referenced by test2.cc:2 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test2-07b391.o:(asdf()) clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` Now: ``` ld.lld: error: undefined symbol: f() >>> referenced by test.cc:3 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-0e07ba.o:(g()) >>> referenced by test.cc:4 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-0e07ba.o:(h()) >>> referenced by test.cc:5 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-0e07ba.o:(j()) >>> referenced by test2.cc:2 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test2-6bdb24.o:(asdf()) ld.lld: error: undefined symbol: k() >>> referenced by test.cc:5 >>> /var/folders/c5/8d7sdn1x2mg92mj0rndghhdr0000gn/T/test-0e07ba.o:(j()) clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` If there are more than 10 references to an undefined symbol, only the first 10 are printed. Fixes PR42260. Differential Revision: https://reviews.llvm.org/D63344 llvm-svn: 363962
* [ELF][RISCV] Create dummy .sdata for __global_pointer$ if .sdata does not existFangrui Song2019-06-141-3/+11
| | | | | | | | | | | | | | | | | | | | | | | | | If .sdata is absent, linker synthesized __global_pointer$ gets a section index of SHN_ABS. (ld.bfd has a similar issue: binutils PR24678) Scrt1.o may use `lla gp, __global_pointer$` to reference the symbol PC relatively. In -pie/-shared mode, lld complains if a PC relative relocation references an absolute symbol (SHN_ABS) but ld.bfd doesn't: ld.lld: error: relocation R_RISCV_PCREL_HI20 cannot refer to lute symbol: __global_pointer$ Let the reference of __global_pointer$ to force creation of .sdata to fix the problem. This is similar to _GLOBAL_OFFSET_TABLE_, which forces creation of .got or .got.plt . Also, change the visibility from STV_HIDDEN to STV_DEFAULT and don't define the symbol for -shared. This matches ld.bfd, though I don't understand why it uses STV_DEFAULT. Reviewed By: ruiu, jrtc27 Differential Revision: https://reviews.llvm.org/D63132 llvm-svn: 363351
* ELF: Don't process the partition end marker during combineEhSections().Peter Collingbourne2019-06-111-2/+4
| | | | | | | | | | Otherwise the getPartition() accessor may return an OOB pointer. Found using _GLIBCXX_DEBUG. The error is benign (we never dereference the pointer for the end marker) so this wasn't caught by e.g. the sanitizer bots. llvm-svn: 363026
* ELF: Create synthetic sections for loadable partitions.Peter Collingbourne2019-06-071-245/+330
| | | | | | | | | | | | | | | We create several types of synthetic sections for loadable partitions, including: - The dynamic symbol table. This allows code outside of the loadable partitions to find entry points with dlsym. - Creating a dynamic symbol table also requires the creation of several other synthetic sections for the partition, such as the dynamic table and hash table sections. - The partition's ELF header is represented as a synthetic section in the combined output file, and will be used by llvm-objcopy to extract partitions. Differential Revision: https://reviews.llvm.org/D62350 llvm-svn: 362819
* Revert [ELF] Simplify the condition to create .interpJordan Rupprecht2019-06-061-1/+2
| | | | | | | | This reverts r362355 (git commit c78c999a9cd7a77b9d13c610c9faebac5d560a55) This causes some internal tests to fail; details provided offthread. llvm-svn: 362755
* [PPC32] Improve the 32-bit PowerPC portFangrui Song2019-06-061-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Many -static/-no-pie/-shared/-pie applications linked against glibc or musl should work with this patch. This also helps FreeBSD PowerPC64 to migrate their lib32 (PR40888). * Fix default image base and max page size. * Support new-style Secure PLT (see below). Old-style BSS PLT is not implemented, so it is not suitable for FreeBSD rtld now because it doesn't support Secure PLT yet. * Support more initial relocation types: R_PPC_ADDR32, R_PPC_REL16*, R_PPC_LOCAL24PC, R_PPC_PLTREL24, and R_PPC_GOT16. The addend of R_PPC_PLTREL24 is special: it decides the call stub PLT type but it should be ignored for the computation of target symbol VA. * Support GNU ifunc * Support .glink used for lazy PLT resolution in glibc * Add a new thunk type: PPC32PltCallStub that is similar to PPC64PltCallStub. It is used by R_PPC_REL24 and R_PPC_PLTREL24. A PLT stub used in -fPIE/-fPIC usually loads an address relative to .got2+0x8000 (-fpie/-fpic code uses _GLOBAL_OFFSET_TABLE_ relative addresses). Two .got2 sections in two object files have different addresses, thus a PLT stub can't be shared by two object files. To handle this incompatibility, change the parameters of Thunk::isCompatibleWith to `const InputSection &, const Relocation &`. PowerPC psABI specified an old-style .plt (BSS PLT) that is both writable and executable. Linkers don't make separate RW- and RWE segments, which causes all initially writable memory (think .data) executable. This is a big security concern so a new PLT scheme (secure PLT) was developed to address the security issue. TLS will be implemented in D62940. glibc older than ~2012 requires .rela.dyn to include .rela.plt, it can not handle the DT_RELA+DT_RELASZ == DT_JMPREL case correctly. A hack (not included in this patch) in LinkerScript.cpp addOrphanSections() to work around the issue: if (Config->EMachine == EM_PPC) { // Older glibc assumes .rela.dyn includes .rela.plt Add(In.RelaDyn); if (In.RelaPlt->isLive() && !In.RelaPlt->Parent) In.RelaDyn->getParent()->addSection(In.RelaPlt); } Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D62464 llvm-svn: 362721
* Read .note.gnu.property sections and emit a merged .note.gnu.property section.Rui Ueyama2019-06-051-0/+3
| | | | | | | | | | | | | This patch also adds `--require-cet` option for the sake of testing. The actual feature for IBT-aware PLT is not included in this patch. This is a part of https://reviews.llvm.org/D59780. Submitting this first should make it easy to work with a related change (https://reviews.llvm.org/D62609). Differential Revision: https://reviews.llvm.org/D62853 llvm-svn: 362579
* ELF: Introduce a separate bit for tracking whether an output section has ↵Peter Collingbourne2019-06-031-6/+7
| | | | | | | | | | | | | | | | | | ever had an input section added to it. NFCI. We currently (ab)use the Live bit on output sections to track whether the section has ever had an input section added to it, and then later use it during orphan placement. This will conflict with one of my upcoming partition-related changes that will assign all output sections to a partition (thus marking them as live) so that they can be added to the correct segment by the code that creates program headers. Instead of using the Live bit for this purpose, create a new flag and start using it to track the property explicitly. Differential Revision: https://reviews.llvm.org/D62348 llvm-svn: 362444
* [ELF] Simplify the condition to create .interpFangrui Song2019-06-031-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (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 So instead, use `!Config->DynamicLinker.empty() && Script->needsInterpSection()`, which is both simple and consistent in these cases. The inconsistency of (4) likely originated from ld.bfd and gold's choice to have a default --dynamic-linker. Their condition to create .interp is ANDed with (not -shared). Since lld doesn't have a default --dynamic-linker, compiler drivers (gcc/clang) don't pass --dynamic-linker for -shared, and direct ld users are not supposed to specify --dynamic-linker for -shared, we do not need the condition !Config->Shared. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D62765 llvm-svn: 362355
* [ELF][MIPS] Delete dead !Sym->isDefined() check in addAbsolute()Fangrui Song2019-06-021-2/+0
| | | | llvm-svn: 362314
* [ELF] Implement Local Dynamic style TLSDESC for x86-64Fangrui Song2019-05-301-0/+21
| | | | | | | | | | | | | | | | | | | | | | | For the Local Dynamic case of TLSDESC, _TLS_MODULE_BASE_ is defined as a special TLS symbol that makes: 1) Without relaxation: it produces a dynamic TLSDESC relocation that computes 0. Adding @dtpoff to access a TLS symbol. 2) With LD->LE relaxation: _TLS_MODULE_BASE_@tpoff = 0 (lowest address in the TLS block). Adding @tpoff to access a TLS symbol. For 1), this saves dynamic relocations and GOT slots as otherwise (General Dynamic) we would create an R_X86_64_TLSDESC and reserve two GOT slots for each symbol. Add ElfSym::TlsModuleBase and change the signature of getTlsTpOffset() to special case _TLS_MODULE_BASE_. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D62577 llvm-svn: 362078
* ELF: Add basic partition data structures and behaviours.Peter Collingbourne2019-05-291-10/+11
| | | | | | | | | | | | | | This change causes us to read partition specifications from partition specification sections and split output sections into partitions according to their reachability from partition entry points. This is only the first step towards a full implementation of partitions. Later changes will add additional synthetic sections to each partition so that they can be loaded independently. Differential Revision: https://reviews.llvm.org/D60353 llvm-svn: 361925
* [ELF] Replace two addSymbol() call sites with Symbol::resolve(). NFCFangrui Song2019-05-281-6/+5
| | | | | | | If we have a handle of the symbol, insert() called by addSymbol() is redundant. Just call resolve(). llvm-svn: 361802
* Use SymbolTable::insert() to implement --trace.Rui Ueyama2019-05-281-6/+11
| | | | | | Differential Revision: https://reviews.llvm.org/D62381 llvm-svn: 361791
* [ARM][AArch64] Revert Android Bionic PT_TLS overaligning hackFangrui Song2019-05-181-13/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts D53906. D53906 increased p_align of PT_TLS on ARM/AArch64 to 32/64 to make the static TLS layout compatible with Android Bionic's ELF TLS. However, this may cause glibc ARM/AArch64 programs to crash (see PR41527). The faulty PT_TLS in the executable satisfies p_vaddr%p_align != 0. The remainder is normally 0 but may be non-zero with the hack in place. The problem is that we increase PT_TLS's p_align after OutputSections' addresses are fixed (assignAddress()). It is possible that p_vaddr%old_p_align = 0 while p_vaddr%new_p_align != 0. For a thread local variable defined in the executable, lld computed TLS offset (local exec) is different from glibc computed TLS offset from another module (initial exec/generic dynamic). Note: PR41527 said the bug affects initial exec but actually generic dynamic is affected as well. (glibc is correct in that it compute offsets that satisfy `offset%p_align == p_vaddr%p_align`, which is a basic ELF requirement. This hack appears to work on FreeBSD rtld, musl<=1.1.22, and Bionic, but that is just because they (and lld) incorrectly compute offsets that satisfy `offset%p_align = 0` instead.) Android developers are fine to revert this patch, carry this patch in their tree before figuring out a long-term solution (e.g. a dummy .tdata with sh_addralign=64 sh_size={0,1} in crtbegin*.o files. The overhead is now insignificant after D62059). Reviewed By: rprichard, srhines Differential Revision: https://reviews.llvm.org/D62055 llvm-svn: 361090
* [ELF] Don't align PT_TLS's p_memszFangrui Song2019-05-171-5/+0
| | | | | | | | | | | | | | | The code was added in r252352, probably to address some layout issues. Actually PT_TLS's p_memsz doesn't need to be aligned on either variant. ld.bfd doesn't do that. In case of larger alignment (e.g. 64 for Android Bionic on AArch64, see D62055), this may make the overhead smaller. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D62059 llvm-svn: 361029
* Move symbol resolution code out of SymbolTable class.Rui Ueyama2019-05-171-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the last patch of the series of patches to make it possible to resolve symbols without asking SymbolTable to do so. The main point of this patch is the introduction of `elf::resolveSymbol(Symbol *Old, Symbol *New)`. That function resolves or merges given symbols by examining symbol types and call replaceSymbol (which memcpy's New to Old) if necessary. With the new function, we have now separated symbol resolution from symbol lookup. If you already have a Symbol pointer, you can directly resolve the symbol without asking SymbolTable to do that. Now that the nice abstraction become available, I can start working on performance improvement of the linker. As a starter, I'm thinking of making --{start,end}-lib faster. --{start,end}-lib is currently unnecessarily slow because it looks up the symbol table twice for each symbol. - The first hash table lookup/insertion occurs when we instantiate a LazyObject file to insert LazyObject symbols. - The second hash table lookup/insertion occurs when we create an ObjFile from LazyObject file. That overwrites LazyObject symbols with Defined symbols. I think it is not too hard to see how we can now eliminate the second hash table lookup. We can keep LazyObject symbols in Step 1, and then call elf::resolveSymbol() to do Step 2. Differential Revision: https://reviews.llvm.org/D61898 llvm-svn: 360975
* Introduce CommonSymbol.Rui Ueyama2019-05-161-9/+12
| | | | | | | | | | | | | | | | | Previously, we handled common symbols as a kind of Defined symbol, but what we were doing for common symbols is pretty different from regular defined symbols. Common symbol and defined symbol are probably as different as shared symbol and defined symbols are different. This patch introduces CommonSymbol to represent common symbols. After symbols are resolved, they are converted to Defined symbols residing in a .bss section. Differential Revision: https://reviews.llvm.org/D61895 llvm-svn: 360841
* Simplify SymbolTable::add{Defined,Undefined,...} functions.Rui Ueyama2019-05-161-11/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | SymbolTable's add-family functions have lots of parameters because when they have to create a new symbol, they forward given arguments to Symbol's constructors. Therefore, the functions take at least as many arguments as their corresponding constructors. This patch simplifies the add-family functions. Now, the functions take a symbol instead of arguments to construct a symbol. If there's no existing symbol, a given symbol is memcpy'ed to the symbol table. Otherwise, the functions attempt to merge the existing and a given new symbol. I also eliminated `CanOmitFromDynSym` parameter, so that the functions take really one argument. Symbol classes are trivially constructible, so looks like constructing them to pass to add-family functions is as cheap as passing a lot of arguments to the functions. A quick benchmark showed that this patch seems performance-neutral. This is a preparation for http://lists.llvm.org/pipermail/llvm-dev/2019-April/131902.html Differential Revision: https://reviews.llvm.org/D61855 llvm-svn: 360838
* [ELF] Full support for -n (--nmagic) and -N (--omagic) via common pagePeter Smith2019-05-131-6/+7
| | | | | | | | | | | | | | | | | | | | | | The -n (--nmagic) disables page alignment, and acts as a -Bstatic The -N (--omagic) does what -n does but also marks the executable segment as writeable. As page alignment is disabled headers are not allocated unless explicit in the linker script. To disable page alignment in LLD we choose to set the page sizes to 1 so that any alignment based on the page size does nothing. To set the Target->PageSize to 1 we implement -z common-page-size, which has the side effect of allowing the user to set the value as well. Setting the page alignments to 1 does mean that any use of CONSTANT(MAXPAGESIZE) or CONSTANT(COMMONPAGESIZE) in a linker script will return 1, unlike in ld.bfd. However given that -n and -N disable paging these probably shouldn't be used in a linker script where -n or -N is in use. Differential Revision: https://reviews.llvm.org/D61688 llvm-svn: 360593
* [LLD][NFC] Refactor: BuildID hash size now computed in one place.Ben Dunbobbin2019-05-091-24/+18
| | | | | | Differential Revision: https://reviews.llvm.org/D61078 llvm-svn: 360316
* [ELF] Place SHT_NOTE sections with the same alignment into one PT_NOTEFangrui Song2019-05-031-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: While the generic ABI requires notes to be 8-byte aligned in ELF64, many vendor-specific notes (from Linux, NetBSD, Solaris, etc) use 4-byte alignment. In a PT_NOTE segment, if 4-byte aligned notes are followed by an 8-byte aligned note, the possible 4-byte padding may make consumers fail to parse the 8-byte aligned note. See PR41000 for a recent report about .note.gnu.property (NT_GNU_PROPERTY_TYPE_0). (Note, for NT_GNU_PROPERTY_TYPE_0, the consumers should probably migrate to PT_GNU_PROPERTY, but the alignment issue affects other notes as well.) To fix the issue, don't mix notes with different alignments in one PT_NOTE. If compilers emit 4-byte aligned notes before 8-byte aligned notes, we'll create at most 2 segments. sh_size%sh_addralign=0 is actually implied by the rule for linking unrecognized sections (in generic ABI), so we don't have to check that. Notes that match in name, type and attribute flags are concatenated into a single output section. The compilers have to ensure sh_size%sh_addralign=0 to make concatenated notes parsable. An alternative approach is to create a PT_NOTE for each SHT_NOTE, but we'll have to incur the sizeof(Elf64_Phdr)=56 overhead every time a new note section is introduced. Reviewers: ruiu, jakehehrlich, phosek, jhenderson, pcc, espindola Subscribers: emaste, arichardson, krytarowski, fedor.sergeev, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61296 llvm-svn: 359853
* [LLD][ELF] Fix getRankProximity to "ignore" not live sectionsAndrew Ng2019-04-301-3/+2
| | | | | | | | | | This is a follow up to r358979 which made findOrphanPos only consider live sections. Unfortunately, this required change to getRankProximity, used by findOrphanPos, was missed. Differential Revision: https://reviews.llvm.org/D61197 llvm-svn: 359554
* [ELF] Change findOrphanPos to only consider live sectionsAndrew Ng2019-04-231-4/+7
| | | | | | | | | | This patch changes the behaviour of findOrphanPos to only consider live sections when placing orphan sections. This used to be how it behaved in the past. Differential Revision: https://reviews.llvm.org/D60273 llvm-svn: 358979
* Use llvm::stable_sortFangrui Song2019-04-231-6/+6
| | | | | | | | | Make some small adjustment while touching the code: make parameters const, use less_first(), etc. Differential Revision: https://reviews.llvm.org/D60989 llvm-svn: 358943
* [LLD][ELF] - Fix the different behavior of the linker script symbols on ↵George Rimar2019-04-181-22/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | different platforms. This generalizes code and also fixes the broken behavior shown in one of our test cases for some targets, like x86-64. The issue occurs when the forward declarations are used in the script. One of the samples is: SECTIONS { foo = ADDR(.text) - ABSOLUTE(ADDR(.text)); }; In that case, we have a broken output when output target does not use thunks. That happens because thunks creating code (called from maybeAddThunks) calls Script->assignAddresses() at least one more time, what fixups the values. As a result final symbols values can be different on AArch64 and x86, for example. In this patch, I generalize and rename maybeAddThunks to finalizeAddressDependentContent and now it is used and called by all targets. Differential revision: https://reviews.llvm.org/D55550 llvm-svn: 358646
* ELF: Move build id computation to Writer. NFCI.Peter Collingbourne2019-04-161-1/+74
| | | | | | | | | | | | With partitions, each partition should have the same build id. This means that the build id needs to be only computed once, otherwise we will end up with different build ids in each partition as a result of the file contents changing. This change moves the computation of the build id into Writer so that it only happens once. Differential Revision: https://reviews.llvm.org/D60342 llvm-svn: 358536
* ELF: Move verneed tracking data structures out of VersionNeedSection.Peter Collingbourne2019-04-081-1/+1
| | | | | | | | | | | | | | | | For partitions I intend to use the same set of version indexes in each partition for simplicity. Since each partition will need its own VersionNeedSection this will require moving the verneed tracking out of VersionNeedSection. The way I've done this is to move most of the tracking into SharedFile. What will eventually become the per-partition tracking still lives in VersionNeedSection. As a bonus the code gets a little simpler and more consistent with how we handle verdef. Differential Revision: https://reviews.llvm.org/D60307 llvm-svn: 357926
* ELF: De-template SharedFile. NFCI.Peter Collingbourne2019-04-081-8/+7
| | | | | | Differential Revision: https://reviews.llvm.org/D60305 llvm-svn: 357925
* Fix -emit-reloc against local symbols.Rui Ueyama2019-04-081-0/+5
| | | | | | | | | | | | | | | | Previously, we drop symbols starting with .L from the symbol table, so if there is a relocation that refers a .L symbol, it ended up referencing a null -- which happened to be interpreted as an absolute symbol. This patch copies all symbols including local ones if -emit-reloc is given. Fixes https://bugs.llvm.org/show_bug.cgi?id=41385 Differential Revision: https://reviews.llvm.org/D60306 llvm-svn: 357885
* Remove redundant parameters. NFC.Rui Ueyama2019-04-051-7/+7
| | | | llvm-svn: 357738
* ELF: Perform per-section .ARM.exidx processing during ↵Peter Collingbourne2019-04-011-6/+13
| | | | | | | | | | | | combineEhFrameSections(). NFCI. And rename the function to combineEhSections(). This makes the processing of .ARM.exidx even more similar to .eh_frame and means that we can avoid an additional loop over InputSections. Differential Revision: https://reviews.llvm.org/D60026 llvm-svn: 357417
* [ELF] Rename SyntheticSection::empty to more appropriate isNeeded() with ↵Fangrui Song2019-04-011-6/+6
| | | | | | | | | | | | | | | | | | | | | | | opposite meaning Summary: Some synthetic sections can be empty while still being needed, thus they can't be removed by removeUnusedSyntheticSections(). Rename this member function to more appropriate isNeeded() with the opposite meaning. No functional change intended. Reviewers: ruiu, espindola Reviewed By: ruiu Subscribers: jhenderson, grimar, emaste, arichardson, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59982 llvm-svn: 357377
* Replace `typedef A B` with `using B = A`. NFC.Rui Ueyama2019-04-011-3/+3
| | | | | | | | I did this using Perl. Differential Revision: https://reviews.llvm.org/D60003 llvm-svn: 357372
* [ELF][MachO][wasm] Simplify range-style std::find{,_if} with STLExtras.h ↵Fangrui Song2019-03-291-1/+1
| | | | | | utilities. NFC llvm-svn: 357269
* Create an instance of Target after reading all input files. NFC.Rui Ueyama2019-03-281-9/+16
| | | | | | | | This change itself doesn't mean anything, but it helps D59780 because in patch, we don't know whether we need to create a CET-aware PLT or not until we read all input files. llvm-svn: 357194
* [ELF][ARM] Recommit Redesign of .ARM.exidx handling to use a SyntheticSectionPeter Smith2019-03-281-92/+17
| | | | | | | | | | | | | | | | | | | | | | Recommit r356666 with fixes for buildbot failure, as well as handling for --emit-relocs, which we decide not to emit any relocation sections as the table is already position independent and an offline tool can deduce the relocations. Instead of creating extra Synthetic .ARM.exidx sections to account for gaps in the table, create a single .ARM.exidx SyntheticSection that can derive the contents of the gaps from a sorted list of the executable InputSections. This has the benefit of moving the ARM specific code for SyntheticSections in SHF_LINK_ORDER processing and the table merging code into the ARM specific SyntheticSection. This also makes it easier to create EXIDX_CANTUNWIND table entries for executable InputSections that don't have an associated .ARM.exidx section. Fixes pr40277 Differential Revision: https://reviews.llvm.org/D59216 llvm-svn: 357160
* [ELF] Change GOT*_FROM_END (relative to end(.got)) to GOTPLT* (start(.got.plt))Fangrui Song2019-03-251-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This should address remaining issues discussed in PR36555. Currently R_GOT*_FROM_END are exclusively used by x86 and x86_64 to express relocations types relative to the GOT base. We have _GLOBAL_OFFSET_TABLE_ (GOT base) = start(.got.plt) but end(.got) != start(.got.plt) This can have problems when _GLOBAL_OFFSET_TABLE_ is used as a symbol, e.g. glibc dl_machine_dynamic assumes _GLOBAL_OFFSET_TABLE_ is start(.got.plt), which is not true. extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; return _GLOBAL_OFFSET_TABLE_[0]; // R_X86_64_GOTPC32 In this patch, we * Change all GOT*_FROM_END to GOTPLT* to fix the problem. * Add HasGotPltOffRel to denote whether .got.plt should be kept even if the section is empty. * Simplify GotSection::empty and GotPltSection::empty by setting HasGotOffRel and HasGotPltOffRel according to GlobalOffsetTable early. The change of R_386_GOTPC makes X86::writePltHeader simpler as we don't have to compute the offset start(.got.plt) - Ebx (it is constant 0). We still diverge from ld.bfd (at least in most cases) and gold in that .got.plt and .got are not adjacent, but the advantage doing that is unclear. Reviewers: ruiu, sivachandra, espindola Subscribers: emaste, mehdi_amini, arichardson, dexonsmith, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59594 llvm-svn: 356968
* [ELF][ARM] Revert Redesign of .ARM.exidx handling to use a SyntheticSectionPeter Smith2019-03-211-17/+92
| | | | | | | | | There is a reproducible buildbot failure (segfault) on the 2 stage clang-cmake-armv8-lld bot. Reverting while I investigate. Differential Revision: https://reviews.llvm.org/D59216 llvm-svn: 356684
* [ELF][ARM] Redesign of .ARM.exidx handling to use a SyntheticSectionPeter Smith2019-03-211-92/+17
| | | | | | | | | | | | | | | | | Instead of creating extra Synthetic .ARM.exidx sections to account for gaps in the table, create a single .ARM.exidx SyntheticSection that can derive the contents of the gaps from a sorted list of the executable InputSections. This has the benefit of moving the ARM specific code for SyntheticSections in SHF_LINK_ORDER processing and the table merging code into the ARM specific SyntheticSection. This also makes it easier to create EXIDX_CANTUNWIND table entries for executable InputSections that don't have an associated .ARM.exidx section. Fixes pr40277 Differential Revision: https://reviews.llvm.org/D59216 llvm-svn: 356666
* [ELF] De-virtualize findOrphanPos, excludeLibs and handleARMTlsRelocationFangrui Song2019-03-171-2/+1
| | | | llvm-svn: 356331
* [ELF] Split RW PT_LOAD on the PT_GNU_RELRO boundaryFangrui Song2019-03-151-24/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Based on Peter Collingbourne's suggestion in D56828. Before D56828: PT_LOAD(.data PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) .bss) Old: PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) .data .bss) New: PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro)) PT_LOAD(.data. .bss) The new layout reflects the runtime memory mappings. By having two PT_LOAD segments, we can utilize the NOBITS part of the first PT_LOAD and save bytes for .bss.rel.ro. .bss.rel.ro is currently small and only used by copy relocations of symbols in read-only segments, but it can be used for other purposes in the future, e.g. if a relro section's statically relocated data is all zeros, we can move it to .bss.rel.ro. Reviewers: espindola, ruiu, pcc Reviewed By: ruiu Subscribers: nemanjai, jvesely, nhaehnle, javed.absar, kbarton, emaste, arichardson, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58892 llvm-svn: 356226
* [ELF] Simplify RelRo, TLS, NOBITS section ranks and make RW PT_LOAD start ↵Fangrui Song2019-03-141-35/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | with RelRo Old: PT_LOAD(.data | PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) | .bss) New: PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) | .data .bss) The placement of | indicates page alignment caused by PT_GNU_RELRO. The new layout has simpler rules and saves space for many cases. Old size: roundup(.data) + roundup(.data.rel.ro) New size: roundup(.data.rel.ro + .bss.rel.ro) + .data Other advantages: * At runtime the 3 memory mappings decrease to 2. * start(PT_TLS) = start(PT_GNU_RELRO) = start(RW PT_LOAD). This simplifies binary manipulation tools. GNU strip before 2.31 discards PT_GNU_RELRO if its address is not equal to the start of its associated PT_LOAD. This has been fixed by https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f2731e0c374e5323ce4cdae2bcc7b7fe22da1a6f But with this change, we will be compatible with GNU strip before 2.31 * Before, .got.plt (non-relro by default) was placed before .got (relro by default), which made it impossible to have _GLOBAL_OFFSET_TABLE_ (start of .got.plt on x86-64) equal to the end of .got (R_GOT*_FROM_END) (https://bugs.llvm.org/show_bug.cgi?id=36555). With the new ordering, we can improve on this regard if we'd like to. Reviewers: ruiu, espindola, pcc Subscribers: emaste, arichardson, llvm-commits, joerg, jdoerfert Differential Revision: https://reviews.llvm.org/D56828 llvm-svn: 356117
OpenPOWER on IntegriCloud