Index: lld/ELF/OutputSections.h =================================================================== --- lld/ELF/OutputSections.h +++ lld/ELF/OutputSections.h @@ -206,6 +206,7 @@ static uint8_t First; static EhOutputSection *EhFrame; static OutputSection *Bss; + static OutputSection *BssRelRo; static OutputSectionBase *Opd; static uint8_t *OpdBuf; static PhdrEntry *TlsPhdr; @@ -252,6 +253,7 @@ template uint8_t Out::First; template EhOutputSection *Out::EhFrame; template OutputSection *Out::Bss; +template OutputSection *Out::BssRelRo; template OutputSectionBase *Out::Opd; template uint8_t *Out::OpdBuf; template PhdrEntry *Out::TlsPhdr; Index: lld/ELF/Relocations.cpp =================================================================== --- lld/ELF/Relocations.cpp +++ lld/ELF/Relocations.cpp @@ -399,7 +399,21 @@ return 1 << TrailingZeros; } -// Reserve space in .bss for copy relocation. +template static bool isReadOnly(SharedSymbol *SS) { + typedef typename ELFT::uint uintX_t; + typedef typename ELFT::Phdr Elf_Phdr; + + // Determine if the symbol is read-only by scanning the DSO's program headers. + uintX_t Value = SS->Sym.st_value; + for (const Elf_Phdr &Phdr : check(SS->file()->getObj().program_headers())) + if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) && + !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr && + Value < Phdr.p_vaddr + Phdr.p_memsz) + return true; + return false; +} + +// Reserve space in .bss or .bss.rel.ro for copy relocation. template static void addCopyRelSymbol(SharedSymbol *SS) { typedef typename ELFT::uint uintX_t; typedef typename ELFT::Sym Elf_Sym; @@ -409,10 +423,16 @@ if (SymSize == 0) fatal("cannot create a copy relocation for symbol " + toString(*SS)); + // See if this symbol is in a read-only segment. If so, preserve the symbol's + // memory protection by reserving space in the .bss.rel.ro section. + bool IsReadOnly = isReadOnly(SS); + OutputSection *CopySec = + IsReadOnly ? Out::BssRelRo : Out::Bss; + uintX_t Alignment = getAlignment(SS); - uintX_t Off = alignTo(Out::Bss->Size, Alignment); - Out::Bss->Size = Off + SymSize; - Out::Bss->updateAlignment(Alignment); + uintX_t Off = alignTo(CopySec->Size, Alignment); + CopySec->Size = Off + SymSize; + CopySec->updateAlignment(Alignment); uintX_t Shndx = SS->Sym.st_shndx; uintX_t Value = SS->Sym.st_value; // Look through the DSO's dynamic symbol table for aliases and create a @@ -425,12 +445,12 @@ Symtab::X->find(check(S.getName(SS->file()->getStringTable())))); if (!Alias) continue; - Alias->OffsetInBss = Off; + Alias->CopyIsInBssRelRo = IsReadOnly; + Alias->CopyOffset = Off; Alias->NeedsCopyOrPltAddr = true; Alias->symbol()->IsUsedInRegularObj = true; } - In::RelaDyn->addReloc( - {Target->CopyRel, Out::Bss, SS->OffsetInBss, false, SS, 0}); + In::RelaDyn->addReloc({Target->CopyRel, CopySec, Off, false, SS, 0}); } template Index: lld/ELF/Symbols.h =================================================================== --- lld/ELF/Symbols.h +++ lld/ELF/Symbols.h @@ -16,6 +16,7 @@ #define LLD_ELF_SYMBOLS_H #include "InputSection.h" +#include "OutputSections.h" #include "Strings.h" #include "lld/Core/LLVM.h" @@ -30,8 +31,6 @@ class InputFile; class LazyObjectFile; template class ObjectFile; -template class OutputSection; -class OutputSectionBase; template class SharedFile; struct Symbol; @@ -123,6 +122,11 @@ // True if this symbol is in the Igot sub-section of the .got.plt or .got. unsigned IsInIgot : 1; + // True if this is a shared symbol in a read-only segment which requires a + // copy relocation. This causes space for the symbol to be allocated in the + // .bss.rel.ro section. + unsigned CopyIsInBssRelRo : 1; + // The following fields have the same meaning as the ELF symbol attributes. uint8_t Type; // symbol type uint8_t StOther; // st_other field value @@ -282,13 +286,18 @@ // This field is a pointer to the symbol's version definition. const Elf_Verdef *Verdef; - // OffsetInBss is significant only when needsCopy() is true. - uintX_t OffsetInBss = 0; + // CopyOffset is significant only when needsCopy() is true. + uintX_t CopyOffset = 0; // If non-null the symbol has a Thunk that may be used as an alternative // destination for callers of this Symbol. Thunk *ThunkData = nullptr; bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->isFunc(); } + + OutputSection *getBssSectionForCopy() const { + assert(needsCopy()); + return CopyIsInBssRelRo ? Out::BssRelRo : Out::Bss; + } }; // This class represents a symbol defined in an archive file. It is Index: lld/ELF/Symbols.cpp =================================================================== --- lld/ELF/Symbols.cpp +++ lld/ELF/Symbols.cpp @@ -81,7 +81,7 @@ return 0; if (SS.isFunc()) return Body.getPltVA(); - return Out::Bss->Addr + SS.OffsetInBss; + return SS.getBssSectionForCopy()->Addr + SS.CopyOffset; } case SymbolBody::UndefinedKind: return 0; @@ -97,7 +97,8 @@ uint8_t Type) : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(IsLocal), IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), - IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {} + IsInIgot(false), CopyIsInBssRelRo(false), Type(Type), StOther(StOther), + Name(Name) {} // Returns true if a symbol can be replaced at load-time by a symbol // with the same name defined in other ELF executable or DSO. Index: lld/ELF/SyntheticSections.cpp =================================================================== --- lld/ELF/SyntheticSections.cpp +++ lld/ELF/SyntheticSections.cpp @@ -1201,10 +1201,12 @@ } case SymbolBody::DefinedCommonKind: return In::Common->OutSec; - case SymbolBody::SharedKind: - if (cast>(Sym)->needsCopy()) - return Out::Bss; + case SymbolBody::SharedKind: { + auto &SS = cast>(*Sym); + if (SS.needsCopy()) + return SS.getBssSectionForCopy(); break; + } case SymbolBody::UndefinedKind: case SymbolBody::LazyArchiveKind: case SymbolBody::LazyObjectKind: Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -250,6 +250,8 @@ // Create singleton output sections. Out::Bss = make>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + Out::BssRelRo = make>(".bss.rel.ro", SHT_NOBITS, + SHF_ALLOC | SHF_WRITE); In::DynStrTab = make>(".dynstr", true); In::Dynamic = make>(); Out::EhFrame = make>(); @@ -498,6 +500,8 @@ return true; if (In::MipsGot && Sec == In::MipsGot->OutSec) return true; + if (Sec == Out::BssRelRo) + return true; StringRef S = Sec->getName(); return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" || S == ".eh_frame" || S == ".openbsd.randomdata"; @@ -557,30 +561,38 @@ // If we got here we know that both A and B are in the same PT_LOAD. - // The TLS initialization block needs to be a single contiguous block in a R/W - // PT_LOAD, so stick TLS sections directly before R/W sections. The TLS NOBITS - // sections are placed here as they don't take up virtual address space in the - // PT_LOAD. bool AIsTls = A->Flags & SHF_TLS; bool BIsTls = B->Flags & SHF_TLS; - if (AIsTls != BIsTls) - return AIsTls; - - // The next requirement we have is to put nobits sections last. The - // reason is that the only thing the dynamic linker will see about - // them is a p_memsz that is larger than p_filesz. Seeing that it - // zeros the end of the PT_LOAD, so that has to correspond to the - // nobits sections. bool AIsNoBits = A->Type == SHT_NOBITS; bool BIsNoBits = B->Type == SHT_NOBITS; - if (AIsNoBits != BIsNoBits) - return BIsNoBits; - // We place RelRo section before plain r/w ones. + // The first requirement we have is to put (non-TLS) nobits sections last. The + // reason is that the only thing the dynamic linker will see about them is a + // p_memsz that is larger than p_filesz. Seeing that it zeros the end of the + // PT_LOAD, so that has to correspond to the nobits sections. + bool AIsNonTlsNoBits = AIsNoBits && !AIsTls; + bool BIsNonTlsNoBits = BIsNoBits && !BIsTls; + if (AIsNonTlsNoBits != BIsNonTlsNoBits) + return BIsNonTlsNoBits; + + // We place nobits RelRo sections before plain r/w ones, and non-nobits RelRo + // sections after r/w ones, so that the RelRo sections are contiguous. bool AIsRelRo = isRelroSection(A); bool BIsRelRo = isRelroSection(B); if (AIsRelRo != BIsRelRo) - return AIsRelRo; + return AIsNonTlsNoBits ? AIsRelRo : BIsRelRo; + + // The TLS initialization block needs to be a single contiguous block in a R/W + // PT_LOAD, so stick TLS sections directly before the other RelRo R/W + // sections. The TLS NOBITS sections are placed here as they don't take up + // virtual address space in the PT_LOAD. + if (AIsTls != BIsTls) + return AIsTls; + + // Within the TLS initialization block, the non-nobits sections need to appear + // first. + if (AIsNoBits != BIsNoBits) + return BIsNoBits; // Some architectures have additional ordering restrictions for sections // within the same PT_LOAD. @@ -1071,6 +1083,8 @@ template void Writer::addPredefinedSections() { if (Out::Bss->Size > 0) OutputSections.push_back(Out::Bss); + if (Out::BssRelRo->Size > 0) + OutputSections.push_back(Out::BssRelRo); auto OS = dyn_cast_or_null>(findSection(".ARM.exidx")); if (OS && !OS->Sections.empty() && !Config->Relocatable) @@ -1272,8 +1286,9 @@ Phdrs.push_back(ARMExidx); } -// The first section of each PT_LOAD and the first section after PT_GNU_RELRO -// have to be page aligned so that the dynamic linker can set the permissions. +// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the +// first section after PT_GNU_RELRO have to be page aligned so that the dynamic +// linker can set the permissions. template void Writer::fixSectionAlignments() { for (const PhdrEntry &P : Phdrs) if (P.p_type == PT_LOAD && P.First) @@ -1282,6 +1297,8 @@ for (const PhdrEntry &P : Phdrs) { if (P.p_type != PT_GNU_RELRO) continue; + if (P.First) + P.First->PageAlign = true; // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we // have to align it to a page. auto End = OutputSections.end(); Index: lld/test/ELF/Inputs/copy-rel-pie.s =================================================================== --- lld/test/ELF/Inputs/copy-rel-pie.s +++ lld/test/ELF/Inputs/copy-rel-pie.s @@ -1,9 +1,11 @@ +.data .global foo .type foo, @object .size foo, 4 foo: .long 0 +.text .global bar .type bar, @function bar: Index: lld/test/ELF/Inputs/relocation-copy-relro.s =================================================================== --- /dev/null +++ lld/test/ELF/Inputs/relocation-copy-relro.s @@ -0,0 +1,13 @@ +.rodata +.globl a +.size a, 4 +.type a, @object +a: +.word 1 + +.section .data.rel.ro,"aw",%progbits +.globl b +.size b, 4 +.type b, @object +b: +.word 2 Index: lld/test/ELF/aarch64-condb-reloc.s =================================================================== --- lld/test/ELF/aarch64-condb-reloc.s +++ lld/test/ELF/aarch64-condb-reloc.s @@ -36,8 +36,8 @@ #DSOREL-NEXT: SHF_ALLOC #DSOREL-NEXT: SHF_WRITE #DSOREL-NEXT: ] -#DSOREL-NEXT: Address: 0x30000 -#DSOREL-NEXT: Offset: 0x30000 +#DSOREL-NEXT: Address: 0x20000 +#DSOREL-NEXT: Offset: 0x20000 #DSOREL-NEXT: Size: 48 #DSOREL-NEXT: Link: 0 #DSOREL-NEXT: Info: 0 @@ -46,9 +46,9 @@ #DSOREL-NEXT: } #DSOREL: Relocations [ #DSOREL-NEXT: Section ({{.*}}) .rela.plt { -#DSOREL-NEXT: 0x30018 R_AARCH64_JUMP_SLOT _foo -#DSOREL-NEXT: 0x30020 R_AARCH64_JUMP_SLOT _bar -#DSOREL-NEXT: 0x30028 R_AARCH64_JUMP_SLOT _dah +#DSOREL-NEXT: 0x20018 R_AARCH64_JUMP_SLOT _foo +#DSOREL-NEXT: 0x20020 R_AARCH64_JUMP_SLOT _bar +#DSOREL-NEXT: 0x20028 R_AARCH64_JUMP_SLOT _dah #DSOREL-NEXT: } #DSOREL-NEXT:] @@ -72,22 +72,22 @@ #DSO-NEXT: Disassembly of section .plt: #DSO-NEXT: .plt: #DSO-NEXT: 10030: {{.*}} stp x16, x30, [sp, #-16]! -#DSO-NEXT: 10034: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10034: {{.*}} adrp x16, #65536 #DSO-NEXT: 10038: {{.*}} ldr x17, [x16, #16] #DSO-NEXT: 1003c: {{.*}} add x16, x16, #16 #DSO-NEXT: 10040: {{.*}} br x17 #DSO-NEXT: 10044: {{.*}} nop #DSO-NEXT: 10048: {{.*}} nop #DSO-NEXT: 1004c: {{.*}} nop -#DSO-NEXT: 10050: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10050: {{.*}} adrp x16, #65536 #DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24] #DSO-NEXT: 10058: {{.*}} add x16, x16, #24 #DSO-NEXT: 1005c: {{.*}} br x17 -#DSO-NEXT: 10060: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10060: {{.*}} adrp x16, #65536 #DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32] #DSO-NEXT: 10068: {{.*}} add x16, x16, #32 #DSO-NEXT: 1006c: {{.*}} br x17 -#DSO-NEXT: 10070: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10070: {{.*}} adrp x16, #65536 #DSO-NEXT: 10074: {{.*}} ldr x17, [x16, #40] #DSO-NEXT: 10078: {{.*}} add x16, x16, #40 #DSO-NEXT: 1007c: {{.*}} br x17 Index: lld/test/ELF/aarch64-gnu-ifunc-plt.s =================================================================== --- lld/test/ELF/aarch64-gnu-ifunc-plt.s +++ lld/test/ELF/aarch64-gnu-ifunc-plt.s @@ -10,19 +10,19 @@ // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt // CHECK: Relocations [ // CHECK-NEXT: Section (4) .rela.plt { -// CHECK: 0x40018 R_AARCH64_JUMP_SLOT bar2 0x0 -// CHECK-NEXT: 0x40020 R_AARCH64_JUMP_SLOT zed2 0x0 -// CHECK-NEXT: 0x40028 R_AARCH64_IRELATIVE - 0x20000 -// CHECK-NEXT: 0x40030 R_AARCH64_IRELATIVE - 0x20004 +// CHECK: 0x30018 R_AARCH64_JUMP_SLOT bar2 0x0 +// CHECK-NEXT: 0x30020 R_AARCH64_JUMP_SLOT zed2 0x0 +// CHECK-NEXT: 0x30028 R_AARCH64_IRELATIVE - 0x20000 +// CHECK-NEXT: 0x30030 R_AARCH64_IRELATIVE - 0x20004 // CHECK-NEXT: } // CHECK-NEXT: ] // Check that .got.plt entries point back to PLT header // GOTPLT: Contents of section .got.plt: -// GOTPLT-NEXT: 40000 00000000 00000000 00000000 00000000 -// GOTPLT-NEXT: 40010 00000000 00000000 20000200 00000000 -// GOTPLT-NEXT: 40020 20000200 00000000 20000200 00000000 -// GOTPLT-NEXT: 40030 20000200 00000000 +// GOTPLT-NEXT: 30000 00000000 00000000 00000000 00000000 +// GOTPLT-NEXT: 30010 00000000 00000000 20000200 00000000 +// GOTPLT-NEXT: 30020 20000200 00000000 20000200 00000000 +// GOTPLT-NEXT: 30030 20000200 00000000 // Check that the PLTRELSZ tag includes the IRELATIVE relocations // CHECK: DynamicSection [ @@ -31,40 +31,40 @@ // Check that a PLT header is written and the ifunc entries appear last // DISASM: Disassembly of section .text: // DISASM-NEXT: foo: -// DISASM-NEXT: 20000: c0 03 5f d6 ret +// DISASM-NEXT: 20000: {{.*}} ret // DISASM: bar: -// DISASM-NEXT: 20004: c0 03 5f d6 ret +// DISASM-NEXT: 20004: {{.*}} ret // DISASM: _start: -// DISASM-NEXT: 20008: 16 00 00 94 bl #88 -// DISASM-NEXT: 2000c: 19 00 00 94 bl #100 -// DISASM-NEXT: 20010: 0c 00 00 94 bl #48 -// DISASM-NEXT: 20014: 0f 00 00 94 bl #60 +// DISASM-NEXT: 20008: {{.*}} bl #88 +// DISASM-NEXT: 2000c: {{.*}} bl #100 +// DISASM-NEXT: 20010: {{.*}} bl #48 +// DISASM-NEXT: 20014: {{.*}} bl #60 // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 20020: f0 7b bf a9 stp x16, x30, [sp, #-16]! -// DISASM-NEXT: 20024: 10 01 00 90 adrp x16, #131072 -// DISASM-NEXT: 20028: 11 0a 40 f9 ldr x17, [x16, #16] -// DISASM-NEXT: 2002c: 10 42 00 91 add x16, x16, #16 -// DISASM-NEXT: 20030: 20 02 1f d6 br x17 -// DISASM-NEXT: 20034: 1f 20 03 d5 nop -// DISASM-NEXT: 20038: 1f 20 03 d5 nop -// DISASM-NEXT: 2003c: 1f 20 03 d5 nop -// DISASM-NEXT: 20040: 10 01 00 90 adrp x16, #131072 -// DISASM-NEXT: 20044: 11 0e 40 f9 ldr x17, [x16, #24] -// DISASM-NEXT: 20048: 10 62 00 91 add x16, x16, #24 -// DISASM-NEXT: 2004c: 20 02 1f d6 br x17 -// DISASM-NEXT: 20050: 10 01 00 90 adrp x16, #131072 -// DISASM-NEXT: 20054: 11 12 40 f9 ldr x17, [x16, #32] -// DISASM-NEXT: 20058: 10 82 00 91 add x16, x16, #32 -// DISASM-NEXT: 2005c: 20 02 1f d6 br x17 -// DISASM-NEXT: 20060: 10 01 00 90 adrp x16, #131072 -// DISASM-NEXT: 20064: 11 16 40 f9 ldr x17, [x16, #40] -// DISASM-NEXT: 20068: 10 a2 00 91 add x16, x16, #40 -// DISASM-NEXT: 2006c: 20 02 1f d6 br x17 -// DISASM-NEXT: 20070: 10 01 00 90 adrp x16, #131072 -// DISASM-NEXT: 20074: 11 1a 40 f9 ldr x17, [x16, #48] -// DISASM-NEXT: 20078: 10 c2 00 91 add x16, x16, #48 -// DISASM-NEXT: 2007c: 20 02 1f d6 br x17 +// DISASM-NEXT: 20020: {{.*}} stp x16, x30, [sp, #-16]! +// DISASM-NEXT: 20024: {{.*}} adrp x16, #65536 +// DISASM-NEXT: 20028: {{.*}} ldr x17, [x16, #16] +// DISASM-NEXT: 2002c: {{.*}} add x16, x16, #16 +// DISASM-NEXT: 20030: {{.*}} br x17 +// DISASM-NEXT: 20034: {{.*}} nop +// DISASM-NEXT: 20038: {{.*}} nop +// DISASM-NEXT: 2003c: {{.*}} nop +// DISASM-NEXT: 20040: {{.*}} adrp x16, #65536 +// DISASM-NEXT: 20044: {{.*}} ldr x17, [x16, #24] +// DISASM-NEXT: 20048: {{.*}} add x16, x16, #24 +// DISASM-NEXT: 2004c: {{.*}} br x17 +// DISASM-NEXT: 20050: {{.*}} adrp x16, #65536 +// DISASM-NEXT: 20054: {{.*}} ldr x17, [x16, #32] +// DISASM-NEXT: 20058: {{.*}} add x16, x16, #32 +// DISASM-NEXT: 2005c: {{.*}} br x17 +// DISASM-NEXT: 20060: {{.*}} adrp x16, #65536 +// DISASM-NEXT: 20064: {{.*}} ldr x17, [x16, #40] +// DISASM-NEXT: 20068: {{.*}} add x16, x16, #40 +// DISASM-NEXT: 2006c: {{.*}} br x17 +// DISASM-NEXT: 20070: {{.*}} adrp x16, #65536 +// DISASM-NEXT: 20074: {{.*}} ldr x17, [x16, #48] +// DISASM-NEXT: 20078: {{.*}} add x16, x16, #48 +// DISASM-NEXT: 2007c: {{.*}} br x17 .text .type foo STT_GNU_IFUNC Index: lld/test/ELF/aarch64-tstbr14-reloc.s =================================================================== --- lld/test/ELF/aarch64-tstbr14-reloc.s +++ lld/test/ELF/aarch64-tstbr14-reloc.s @@ -35,8 +35,8 @@ #DSOREL-NEXT: SHF_ALLOC #DSOREL-NEXT: SHF_WRITE #DSOREL-NEXT: ] -#DSOREL-NEXT: Address: 0x30000 -#DSOREL-NEXT: Offset: 0x30000 +#DSOREL-NEXT: Address: 0x20000 +#DSOREL-NEXT: Offset: 0x20000 #DSOREL-NEXT: Size: 40 #DSOREL-NEXT: Link: 0 #DSOREL-NEXT: Info: 0 @@ -45,8 +45,8 @@ #DSOREL-NEXT: } #DSOREL: Relocations [ #DSOREL-NEXT: Section ({{.*}}) .rela.plt { -#DSOREL-NEXT: 0x30018 R_AARCH64_JUMP_SLOT _foo -#DSOREL-NEXT: 0x30020 R_AARCH64_JUMP_SLOT _bar +#DSOREL-NEXT: 0x20018 R_AARCH64_JUMP_SLOT _foo +#DSOREL-NEXT: 0x20020 R_AARCH64_JUMP_SLOT _bar #DSOREL-NEXT: } #DSOREL-NEXT:] @@ -72,18 +72,18 @@ #DSO-NEXT: Disassembly of section .plt: #DSO-NEXT: .plt: #DSO-NEXT: 10030: {{.*}} stp x16, x30, [sp, #-16]! -#DSO-NEXT: 10034: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10034: {{.*}} adrp x16, #65536 #DSO-NEXT: 10038: {{.*}} ldr x17, [x16, #16] #DSO-NEXT: 1003c: {{.*}} add x16, x16, #16 #DSO-NEXT: 10040: {{.*}} br x17 #DSO-NEXT: 10044: {{.*}} nop #DSO-NEXT: 10048: {{.*}} nop #DSO-NEXT: 1004c: {{.*}} nop -#DSO-NEXT: 10050: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10050: {{.*}} adrp x16, #65536 #DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24] #DSO-NEXT: 10058: {{.*}} add x16, x16, #24 #DSO-NEXT: 1005c: {{.*}} br x17 -#DSO-NEXT: 10060: {{.*}} adrp x16, #131072 +#DSO-NEXT: 10060: {{.*}} adrp x16, #65536 #DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32] #DSO-NEXT: 10068: {{.*}} add x16, x16, #32 #DSO-NEXT: 1006c: {{.*}} br x17 Index: lld/test/ELF/amdgpu-relocs.s =================================================================== --- lld/test/ELF/amdgpu-relocs.s +++ lld/test/ELF/amdgpu-relocs.s @@ -89,5 +89,5 @@ # CHECK-NEXT: ] # OBJDUMP: Contents of section nonalloc: -# OBJDUMP-NEXT: 0000 00000000 14380000 00000000 18340000 -# OBJDUMP-NEXT: 00000000 1c300000 +# OBJDUMP-NEXT: 0000 00000000 04480000 00000000 08440000 +# OBJDUMP-NEXT: 00000000 0c400000 Index: lld/test/ELF/arm-abs32-dyn.s =================================================================== --- lld/test/ELF/arm-abs32-dyn.s +++ lld/test/ELF/arm-abs32-dyn.s @@ -18,8 +18,8 @@ // RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s // CHECK: Dynamic Relocations { -// CHECK-NEXT: 0x2004 R_ARM_RELATIVE -// CHECK-NEXT: 0x2000 R_ARM_ABS32 foo 0x0 +// CHECK-NEXT: 0x1004 R_ARM_RELATIVE +// CHECK-NEXT: 0x1000 R_ARM_ABS32 foo 0x0 // CHECK-NEXT: } // CHECK: Symbols [ Index: lld/test/ELF/arm-exidx-shared.s =================================================================== --- lld/test/ELF/arm-exidx-shared.s +++ lld/test/ELF/arm-exidx-shared.s @@ -38,7 +38,7 @@ // CHECK: Relocations [ // CHECK-NEXT: Section (6) .rel.plt { -// CHECK-NEXT: 0x300C R_ARM_JUMP_SLOT __gxx_personality_v0 +// CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0 // CHECK-EXTAB: Contents of section .ARM.extab.text.func2: // 014c + 0ed8 = 0x1024 = __gxx_personality_v0(PLT) Index: lld/test/ELF/arm-fpic-got.s =================================================================== --- lld/test/ELF/arm-fpic-got.s +++ lld/test/ELF/arm-fpic-got.s @@ -36,7 +36,7 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x12000 +// CHECK-NEXT: Address: 0x13000 // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 4 // CHECK-NEXT: Link: @@ -45,7 +45,7 @@ // CHECK-NEXT: EntrySize: // SYMBOLS: Name: val -// SYMBOLS-NEXT: Value: 0x13000 +// SYMBOLS-NEXT: Value: 0x12000 // SYMBOLS-NEXT: Size: 4 // SYMBOLS-NEXT: Binding: Global // SYMBOLS-NEXT: Type: Object @@ -59,5 +59,5 @@ // CODE-NEXT: 11008: 00 00 90 e5 ldr r0, [r0] // CODE-NEXT: 1100c: 1e ff 2f e1 bx lr // CODE: $d.1: -// 0x11004 + 0x0ff4 + 8 = 0x12000 = .got -// CODE-NEXT: 11010: f4 0f 00 00 +// 0x11004 + 0x1ff4 + 8 = 0x13000 = .got +// CODE-NEXT: 11010: f4 1f 00 00 Index: lld/test/ELF/arm-gnu-ifunc-plt.s =================================================================== --- lld/test/ELF/arm-gnu-ifunc-plt.s +++ lld/test/ELF/arm-gnu-ifunc-plt.s @@ -10,23 +10,23 @@ // Check that the IRELATIVE relocations are last in the .got // CHECK: Relocations [ // CHECK-NEXT: Section (4) .rel.dyn { -// CHECK-NEXT: 0x12078 R_ARM_GLOB_DAT bar2 0x0 -// CHECK-NEXT: 0x1207C R_ARM_GLOB_DAT zed2 0x0 -// CHECK-NEXT: 0x12080 R_ARM_IRELATIVE - 0x0 -// CHECK-NEXT: 0x12084 R_ARM_IRELATIVE - 0x0 +// CHECK-NEXT: 0x13078 R_ARM_GLOB_DAT bar2 0x0 +// CHECK-NEXT: 0x1307C R_ARM_GLOB_DAT zed2 0x0 +// CHECK-NEXT: 0x13080 R_ARM_IRELATIVE - 0x0 +// CHECK-NEXT: 0x13084 R_ARM_IRELATIVE - 0x0 // CHECK-NEXT: } // CHECK-NEXT: Section (5) .rel.plt { -// CHECK-NEXT: 0x1300C R_ARM_JUMP_SLOT bar2 0x0 -// CHECK-NEXT: 0x13010 R_ARM_JUMP_SLOT zed2 0x0 +// CHECK-NEXT: 0x1200C R_ARM_JUMP_SLOT bar2 0x0 +// CHECK-NEXT: 0x12010 R_ARM_JUMP_SLOT zed2 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] // Check that the GOT entries refer back to the ifunc resolver +// GOTPLT: Contents of section .got.plt: +// GOTPLT-NEXT: 12000 00000000 00000000 00000000 20100100 +// GOTPLT-NEXT: 12010 20100100 // GOTPLT: Contents of section .got: -// GOTPLT-NEXT: 12078 00000000 00000000 00100100 04100100 -// GOTPLT-NEXT: Contents of section .got.plt: -// GOTPLT-NEXT: 13000 00000000 00000000 00000000 20100100 -// GOTPLT-NEXT: 13010 20100100 +// GOTPLT-NEXT: 13078 00000000 00000000 00100100 04100100 // DISASM: Disassembly of section .text: // DISASM-NEXT: foo: @@ -46,15 +46,15 @@ // DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4] // DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr // DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]! -// DISASM-NEXT: 11030: d0 1f 00 00 +// DISASM-NEXT: 11030: d0 0f 00 00 // DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4] // DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc // DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12] -// DISASM-NEXT: 11040: cc 1f 00 00 +// DISASM-NEXT: 11040: cc 0f 00 00 // DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4] // DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc // DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12] -// DISASM-NEXT: 11050: c0 1f 00 00 +// DISASM-NEXT: 11050: c0 0f 00 00 // Alignment to 16 byte boundary not strictly necessary on ARM, but harmless // DISASM-NEXT: 11054: 00 00 00 00 andeq r0, r0, r0 // DISASM-NEXT: 11058: 00 00 00 00 andeq r0, r0, r0 @@ -62,11 +62,11 @@ // DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4] // DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc // DISASM-NEXT: 11068: 00 f0 9c e5 ldr pc, [r12] -// DISASM-NEXT: 1106c: 14 10 00 00 +// DISASM-NEXT: 1106c: 14 20 00 00 // DISASM-NEXT: 11070: 04 c0 9f e5 ldr r12, [pc, #4] // DISASM-NEXT: 11074: 0f c0 8c e0 add r12, r12, pc // DISASM-NEXT: 11078: 00 f0 9c e5 ldr pc, [r12] -// DISASM-NEXT: 1107c: 08 10 00 00 +// DISASM-NEXT: 1107c: 08 20 00 00 .syntax unified Index: lld/test/ELF/arm-pie-relative.s =================================================================== --- lld/test/ELF/arm-pie-relative.s +++ lld/test/ELF/arm-pie-relative.s @@ -19,7 +19,7 @@ // CHECK: Relocations [ // CHECK-NEXT: Section (4) .rel.dyn { -// CHECK-NEXT: 0x2058 R_ARM_RELATIVE +// CHECK-NEXT: 0x3058 R_ARM_RELATIVE // GOT: Contents of section .got: -// GOT-NEXT: 2058 00300000 +// GOT-NEXT: 3058 00200000 Index: lld/test/ELF/arm-plt-reloc.s =================================================================== --- lld/test/ELF/arm-plt-reloc.s +++ lld/test/ELF/arm-plt-reloc.s @@ -52,23 +52,23 @@ // DSO-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] // DSO-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr // DSO-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! -// 0x1028 + 8 + 1fd0 = 0x3000 -// DSO-NEXT: 1030: d0 1f 00 00 +// 0x1028 + 8 + 0fd0 = 0x2000 +// DSO-NEXT: 1030: d0 0f 00 00 // DSO-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] // DSO-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc // DSO-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] -// 0x1038 + 8 + 1fcc = 0x300c -// DSO-NEXT: 1040: cc 1f 00 00 +// 0x1038 + 8 + 0fcc = 0x200c +// DSO-NEXT: 1040: cc 0f 00 00 // DSO-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] // DSO-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc // DSO-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] -// 0x1048 + 8 + 1fc0 = 0x3010 -// DSO-NEXT: 1050: c0 1f 00 00 +// 0x1048 + 8 + 0fc0 = 0x2010 +// DSO-NEXT: 1050: c0 0f 00 00 // DSO-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4] // DSO-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc // DSO-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12] -// 0x1058 + 8 + 1fb4 = 0x3014 -// DSO-NEXT: 1060: b4 1f 00 00 +// 0x1058 + 8 + 0fb4 = 0x2014 +// DSO-NEXT: 1060: b4 0f 00 00 // DSOREL: Name: .got.plt // DSOREL-NEXT: Type: SHT_PROGBITS @@ -76,7 +76,7 @@ // DSOREL-NEXT: SHF_ALLOC // DSOREL-NEXT: SHF_WRITE // DSOREL-NEXT: ] -// DSOREL-NEXT: Address: 0x3000 +// DSOREL-NEXT: Address: 0x2000 // DSOREL-NEXT: Offset: // DSOREL-NEXT: Size: 24 // DSOREL-NEXT: Link: @@ -85,6 +85,6 @@ // DSOREL-NEXT: EntrySize: // DSOREL: Relocations [ // DSOREL-NEXT: Section (4) .rel.plt { -// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0 -// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0 -// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0 +// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0 +// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0 +// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0 Index: lld/test/ELF/arm-thumb-interwork-shared.s =================================================================== --- lld/test/ELF/arm-thumb-interwork-shared.s +++ lld/test/ELF/arm-thumb-interwork-shared.s @@ -33,12 +33,12 @@ // PLT-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] // PLT-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr // PLT-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! -// PLT-NEXT: 1030: d0 1f 00 00 +// PLT-NEXT: 1030: d0 0f 00 00 // PLT-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] // PLT-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc // PLT-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] -// PLT-NEXT: 1040: cc 1f 00 00 +// PLT-NEXT: 1040: cc 0f 00 00 // PLT-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] // PLT-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc // PLT-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] -// PLT-NEXT: 1050: c0 1f 00 00 +// PLT-NEXT: 1050: c0 0f 00 00 Index: lld/test/ELF/arm-thumb-plt-reloc.s =================================================================== --- lld/test/ELF/arm-thumb-plt-reloc.s +++ lld/test/ELF/arm-thumb-plt-reloc.s @@ -63,23 +63,23 @@ // DSOARM-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] // DSOARM-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr // DSOARM-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! -// DSOARM-NEXT: 1030: d0 1f 00 00 -// 0x1028 + 8 + 1fd0 = 0x3000 +// DSOARM-NEXT: 1030: d0 0f 00 00 +// 0x1028 + 8 + 0fd0 = 0x2000 // DSOARM-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] // DSOARM-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc // DSOARM-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] -// DSOARM-NEXT: 1040: cc 1f 00 00 -// 0x1038 + 8 + 1fcc = 0x300c +// DSOARM-NEXT: 1040: cc 0f 00 00 +// 0x1038 + 8 + 0fcc = 0x200c // DSOARM-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] // DSOARM-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc // DSOARM-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] -// DSOARM-NEXT: 1050: c0 1f 00 00 -// 0x1048 + 8 + 1fc0 = 0x3010 +// DSOARM-NEXT: 1050: c0 0f 00 00 +// 0x1048 + 8 + 0fc0 = 0x2010 // DSOARM-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4] // DSOARM-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc // DSOARM-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12] -// DSOARM-NEXT: 1060: b4 1f 00 00 -// 0x1058 + 8 + 1fb4 = 0x3014 +// DSOARM-NEXT: 1060: b4 0f 00 00 +// 0x1058 + 8 + 0fb4 = 0x2014 // DSOREL: Name: .got.plt // DSOREL-NEXT: Type: SHT_PROGBITS @@ -87,7 +87,7 @@ // DSOREL-NEXT: SHF_ALLOC // DSOREL-NEXT: SHF_WRITE // DSOREL-NEXT: ] -// DSOREL-NEXT: Address: 0x3000 +// DSOREL-NEXT: Address: 0x2000 // DSOREL-NEXT: Offset: // DSOREL-NEXT: Size: 24 // DSOREL-NEXT: Link: @@ -96,6 +96,6 @@ // DSOREL-NEXT: EntrySize: // DSOREL: Relocations [ // DSOREL-NEXT: Section (4) .rel.plt { -// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0 -// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0 -// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0 +// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0 +// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0 +// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0 Index: lld/test/ELF/arm-tls-norelax-gd-ie.s =================================================================== --- lld/test/ELF/arm-tls-norelax-gd-ie.s +++ lld/test/ELF/arm-tls-norelax-gd-ie.s @@ -25,6 +25,6 @@ .Lt0: .word y(TLSGD) + (. - .L0 - 8) // CHECK: Dynamic Relocations { -// CHECK-NEXT: 0x12078 R_ARM_TLS_DTPMOD32 y -// CHECK-NEXT: 0x1207C R_ARM_TLS_DTPOFF32 y -// CHECK-NEXT: 0x1300C R_ARM_JUMP_SLOT __tls_get_addr +// CHECK-NEXT: 0x13078 R_ARM_TLS_DTPMOD32 y +// CHECK-NEXT: 0x1307C R_ARM_TLS_DTPOFF32 y +// CHECK-NEXT: 0x1200C R_ARM_JUMP_SLOT __tls_get_addr Index: lld/test/ELF/arm-tls-norelax-gd-le.s =================================================================== --- lld/test/ELF/arm-tls-norelax-gd-le.s +++ lld/test/ELF/arm-tls-norelax-gd-le.s @@ -33,5 +33,5 @@ // CHECK: Contents of section .got: // Module index is always 1 for executable -// CHECK-NEXT: 12060 01000000 00000000 +// CHECK-NEXT: 13060 01000000 00000000 Index: lld/test/ELF/arm-tls-norelax-ie-le.s =================================================================== --- lld/test/ELF/arm-tls-norelax-ie-le.s +++ lld/test/ELF/arm-tls-norelax-ie-le.s @@ -36,6 +36,6 @@ .space 4 .type x2, %object -// CHECK: Contents of section .got +// CHECK: Contents of section .got: // x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 8 -// CHECK-NEXT: 12064 08000000 0c000000 +// CHECK-NEXT: 13064 08000000 0c000000 Index: lld/test/ELF/arm-tls-norelax-ld-le.s =================================================================== --- lld/test/ELF/arm-tls-norelax-ld-le.s +++ lld/test/ELF/arm-tls-norelax-ld-le.s @@ -32,4 +32,4 @@ .word 10 // CHECK: Contents of section .got: -// CHECK-NEXT: 12064 01000000 00000000 +// CHECK-NEXT: 13064 01000000 00000000 Index: lld/test/ELF/relocation-copy-relro.s =================================================================== --- /dev/null +++ lld/test/ELF/relocation-copy-relro.s @@ -0,0 +1,33 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-relro.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t.so +// RUN: ld.lld %t.o %t.so -o %t3 +// RUN: llvm-readobj -program-headers -s -r %t3 | FileCheck %s + +// CHECK: Index: 7 +// CHECK-NEXT: Name: .data.rel.ro (48) +// CHECK-NEXT: Type: SHT_PROGBITS (0x1) +// CHECK-NEXT: Flags [ (0x3) +// CHECK-NEXT: SHF_ALLOC (0x2) +// CHECK-NEXT: SHF_WRITE (0x1) +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2020B0 +// CHECK-NEXT: Offset: 0x20B0 +// CHECK-NEXT: Size: 8 + +// CHECK: 0x2020B0 R_X86_64_COPY a 0x0 +// CHECK: 0x2020B4 R_X86_64_COPY b 0x0 + +// CHECK: Type: PT_GNU_RELRO (0x6474E552) +// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: VirtualAddress: 0x202000 +// CHECK-NEXT: PhysicalAddress: 0x202000 +// CHECK-NEXT: FileSize: 184 +// CHECK-NEXT: MemSize: 4096 + +.text +.global _start +_start: +movl $1, a +movl $2, b