From 63a6ca9150da445fa957250ec0012819f420f3eb Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 24 Nov 2015 09:44:28 +0000 Subject: [PATCH] [ELF] Implements -z relro: create an ELF "PT_GNU_RELRO" segment header in the object. Partial (-z relro) and full (-z relro, -z now) relro cases are implemented. Partial relro: The ELF sections are reordered so that the ELF internal data sections (.got, .dtors, etc.) precede the program's data sections (.data and .bss). .got is readonly, .got.plt is still writeable. Full relro: Supports all the features of partial RELRO, .got.plt is also readonly. Differential revision: http://reviews.llvm.org/D14218 llvm-svn: 253967 --- lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 1 + lld/ELF/Writer.cpp | 54 ++++- lld/test/ELF/eh-frame-merge.s | 6 +- lld/test/ELF/gnu-hash-table.s | 4 +- lld/test/ELF/got-aarch64.s | 6 +- lld/test/ELF/merge-shared.s | 4 +- lld/test/ELF/merge-string.s | 18 +- lld/test/ELF/merge-sym.s | 4 +- lld/test/ELF/mips-dynamic.s | 18 +- lld/test/ELF/mips-got-relocs.s | 28 +-- lld/test/ELF/relative-dynamic-reloc-ppc64.s | 2 +- lld/test/ELF/relative-dynamic-reloc.s | 2 +- lld/test/ELF/relocation.s | 4 +- lld/test/ELF/relro.s | 243 ++++++++++++++++++++ lld/test/ELF/section-name.s | 6 +- lld/test/ELF/shared.s | 2 +- 17 files changed, 350 insertions(+), 53 deletions(-) create mode 100644 lld/test/ELF/relro.s diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 8baf28c4d2b0..1ec830ad74b6 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -67,6 +67,7 @@ struct Configuration { bool ZNodelete; bool ZNow; bool ZOrigin; + bool ZRelro; ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t EntryAddr = -1; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index c76aa864de7a..22297f5a7ae9 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -176,6 +176,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { Config->ZNodelete = hasZOption(Args, "nodelete"); Config->ZNow = hasZOption(Args, "now"); Config->ZOrigin = hasZOption(Args, "origin"); + Config->ZRelro = !hasZOption(Args, "norelro"); if (auto *Arg = Args.getLastArg(OPT_O)) { StringRef Val = Arg->getValue(); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index a993fc275e42..71827b48444b 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -47,6 +47,8 @@ private: iterator_range *> Rels); void scanRelocs(InputSection &C); void scanRelocs(InputSectionBase &S, const Elf_Shdr &RelSec); + void updateRelro(Elf_Phdr *Cur, Elf_Phdr *GnuRelroPhdr, + OutputSectionBase *Sec, uintX_t VA); void assignAddresses(); void buildSectionMap(); void openFile(StringRef OutputPath); @@ -81,6 +83,7 @@ private: uintX_t VA, uintX_t Size, uintX_t Align); void copyPhdr(Elf_Phdr *PH, OutputSectionBase *From); + bool HasRelro = false; SymbolTable &Symtab; std::vector Phdrs; @@ -353,6 +356,26 @@ static int getPPC64SectionRank(StringRef SectionName) { .Default(1); } +template static bool isRelroSection(OutputSectionBase *Sec) { + OutputSectionBase::uintX_t Flags = Sec->getFlags(); + if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE)) + return false; + uint32_t Type = Sec->getType(); + if ((Flags & SHF_TLS) || (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY || + Type == SHT_PREINIT_ARRAY)) + return true; + if (Sec == Out::GotPlt) + return Config->ZNow; + if (Sec == Out::Dynamic || Sec == Out::Got) + return true; + + StringRef Name = Sec->getName(); + StringRef WhiteList[] = {".data.rel.ro", ".ctors", ".dtors", ".jcr", + ".eh_frame"}; + return (std::find(std::begin(WhiteList), std::end(WhiteList), Name) != + std::end(WhiteList)); +} + // Output section ordering is determined by this function. template static bool compareOutputSections(OutputSectionBase *A, @@ -409,6 +432,12 @@ static bool compareOutputSections(OutputSectionBase *A, if (AIsNoBits != BIsNoBits) return BIsNoBits; + // We place RelRo section before plain r/w ones. + bool AIsRelRo = isRelroSection(A); + bool BIsRelRo = isRelroSection(B); + if (AIsRelRo != BIsRelRo) + return AIsRelRo; + // Some architectures have additional ordering restrictions for sections // within the same PT_LOAD. if (Config->EMachine == EM_PPC64) @@ -724,8 +753,10 @@ template void Writer::createSections() { std::stable_sort(OutputSections.begin(), OutputSections.end(), compareSections); - for (unsigned I = 0, N = OutputSections.size(); I < N; ++I) + for (unsigned I = 0, N = OutputSections.size(); I < N; ++I) { OutputSections[I]->SectionIndex = I + 1; + HasRelro |= (Config->ZRelro && isRelroSection(OutputSections[I])); + } for (OutputSectionBase *Sec : OutputSections) Out::ShStrTab->add(Sec->getName()); @@ -793,6 +824,18 @@ static uint32_t toPhdrFlags(uint64_t Flags) { return Ret; } +template +void Writer::updateRelro(Elf_Phdr *Cur, Elf_Phdr *GnuRelroPhdr, + OutputSectionBase *Sec, uintX_t VA) { + if (!Config->ZRelro || !(Cur->p_flags & PF_W) || !isRelroSection(Sec)) + return; + if (!GnuRelroPhdr->p_type) + setPhdr(GnuRelroPhdr, PT_GNU_RELRO, PF_R, Cur->p_offset, Cur->p_vaddr, + VA - Cur->p_vaddr, 1 /*p_align*/); + GnuRelroPhdr->p_filesz = VA - Cur->p_vaddr; + GnuRelroPhdr->p_memsz = VA - Cur->p_vaddr; +} + // Visits all sections to create PHDRs and to assign incremental, // non-overlapping addresses to output sections. template void Writer::assignAddresses() { @@ -819,6 +862,7 @@ template void Writer::assignAddresses() { setPhdr(&Phdrs[++PhdrIdx], PT_LOAD, PF_R, 0, Target->getVAStart(), FileOff, Target->getPageSize()); + Elf_Phdr GnuRelroPhdr = {}; Elf_Phdr TlsPhdr{}; uintX_t ThreadBSSOffset = 0; // Create phdrs as we assign VAs and file offsets to all output sections. @@ -852,6 +896,7 @@ template void Writer::assignAddresses() { VA = RoundUpToAlignment(VA, Sec->getAlign()); Sec->setVA(VA); VA += Sec->getSize(); + updateRelro(&Phdrs[PhdrIdx], &GnuRelroPhdr, Sec, VA); } } @@ -881,6 +926,11 @@ template void Writer::assignAddresses() { copyPhdr(PH, Out::Dynamic); } + if (HasRelro) { + Elf_Phdr *PH = &Phdrs[++PhdrIdx]; + *PH = GnuRelroPhdr; + } + // PT_GNU_STACK is a special section to tell the loader to make the // pages for the stack non-executable. if (!Config->ZExecStack) { @@ -932,6 +982,8 @@ template int Writer::getPhdrsNum() const { } if (Tls) ++I; + if (HasRelro) + ++I; return I; } diff --git a/lld/test/ELF/eh-frame-merge.s b/lld/test/ELF/eh-frame-merge.s index 8f44561f90c4..2855a3469dce 100644 --- a/lld/test/ELF/eh-frame-merge.s +++ b/lld/test/ELF/eh-frame-merge.s @@ -35,9 +35,9 @@ // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001 | // CHECK-NEXT: 0010: 1B0C0708 90010000 10000000 1C000000 | -// CHECK-NEXT: 0020: 880E0000 01000000 00000000 10000000 | -// CHECK-NEXT: 0030: 30000000 760E0000 02000000 00000000 | -// CHECK-NEXT: 0040: 10000000 44000000 610E0000 01000000 | +// CHECK-NEXT: 0020: 500E0000 01000000 00000000 10000000 | +// CHECK-NEXT: 0030: 30000000 3E0E0000 02000000 00000000 | +// CHECK-NEXT: 0040: 10000000 44000000 290E0000 01000000 | // CHECK-NEXT: 0050: 00000000 | // CHECK-NEXT: ) diff --git a/lld/test/ELF/gnu-hash-table.s b/lld/test/ELF/gnu-hash-table.s index b6f73d76d5f8..aae0ce3698b7 100644 --- a/lld/test/ELF/gnu-hash-table.s +++ b/lld/test/ELF/gnu-hash-table.s @@ -149,8 +149,8 @@ # PPC64-NEXT: Flags [ # PPC64-NEXT: SHF_ALLOC # PPC64-NEXT: ] -# PPC64-NEXT: Address: 0x1B8 -# PPC64-NEXT: Offset: 0x1B8 +# PPC64-NEXT: Address: 0x1F0 +# PPC64-NEXT: Offset: 0x1F0 # PPC64-NEXT: Size: 36 # PPC64-NEXT: Link: 1 # PPC64-NEXT: Info: 0 diff --git a/lld/test/ELF/got-aarch64.s b/lld/test/ELF/got-aarch64.s index 045a7bf1c0f4..b4aa456b4e81 100644 --- a/lld/test/ELF/got-aarch64.s +++ b/lld/test/ELF/got-aarch64.s @@ -10,7 +10,7 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x2098 +// CHECK-NEXT: Address: 0x2090 // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 0 @@ -19,7 +19,7 @@ // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { -// CHECK-NEXT: 0x2098 R_AARCH64_GLOB_DAT dat 0x0 +// CHECK-NEXT: 0x2090 R_AARCH64_GLOB_DAT dat 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] @@ -28,7 +28,7 @@ // DISASM: main: // DISASM-NEXT: 1000: {{.*}} adrp x0, #4096 -// DISASM-NEXT: 1004: {{.*}} ldr x0, [x0, #152] +// DISASM-NEXT: 1004: {{.*}} ldr x0, [x0, #144] .global main,foo,dat .text diff --git a/lld/test/ELF/merge-shared.s b/lld/test/ELF/merge-shared.s index 36bf5850763f..02ceb66493c0 100644 --- a/lld/test/ELF/merge-shared.s +++ b/lld/test/ELF/merge-shared.s @@ -17,10 +17,10 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x158 +// CHECK-NEXT: Address: 0x190 // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { -// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x15A +// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x192 // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/lld/test/ELF/merge-string.s b/lld/test/ELF/merge-string.s index c47269b2b745..731190c8d75c 100644 --- a/lld/test/ELF/merge-string.s +++ b/lld/test/ELF/merge-string.s @@ -26,8 +26,8 @@ zed: // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: SHF_STRINGS // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x158 -// CHECK-NEXT: Offset: 0x158 +// CHECK-NEXT: Address: 0x190 +// CHECK-NEXT: Offset: 0x190 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -44,8 +44,8 @@ zed: // NOTAIL-NEXT: SHF_MERGE // NOTAIL-NEXT: SHF_STRINGS // NOTAIL-NEXT: ] -// NOTAIL-NEXT: Address: 0x158 -// NOTAIL-NEXT: Offset: 0x158 +// NOTAIL-NEXT: Address: 0x190 +// NOTAIL-NEXT: Offset: 0x190 // NOTAIL-NEXT: Size: 7 // NOTAIL-NEXT: Link: 0 // NOTAIL-NEXT: Info: 0 @@ -62,8 +62,8 @@ zed: // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: SHF_STRINGS // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x15C -// CHECK-NEXT: Offset: 0x15C +// CHECK-NEXT: Address: 0x194 +// CHECK-NEXT: Offset: 0x194 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -75,11 +75,11 @@ zed: // CHECK: Name: bar -// CHECK-NEXT: Value: 0x159 +// CHECK-NEXT: Value: 0x191 // CHECK: Name: foo -// CHECK-NEXT: Value: 0x158 +// CHECK-NEXT: Value: 0x190 // CHECK: Name: zed -// CHECK-NEXT: Value: 0x15C +// CHECK-NEXT: Value: 0x194 // CHECK-NEXT: Size: 0 diff --git a/lld/test/ELF/merge-sym.s b/lld/test/ELF/merge-sym.s index 80277d0b8618..9a47aa325479 100644 --- a/lld/test/ELF/merge-sym.s +++ b/lld/test/ELF/merge-sym.s @@ -15,7 +15,7 @@ foo: // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x158 +// CHECK-NEXT: Address: 0x190 // CHECK: Name: foo -// CHECK-NEXT: Value: 0x15A +// CHECK-NEXT: Value: 0x192 diff --git a/lld/test/ELF/mips-dynamic.s b/lld/test/ELF/mips-dynamic.s index 54aa578f3920..626a3556d361 100644 --- a/lld/test/ELF/mips-dynamic.s +++ b/lld/test/ELF/mips-dynamic.s @@ -20,15 +20,6 @@ # EXE-NEXT: Flags [ # EXE-NEXT: SHF_ALLOC # EXE-NEXT: ] -# EXE: Name: .rld_map -# EXE-NEXT: Type: SHT_PROGBITS -# EXE-NEXT: Flags [ -# EXE-NEXT: SHF_ALLOC -# EXE-NEXT: SHF_WRITE -# EXE-NEXT: ] -# EXE-NEXT: Address: [[RLDMAPADDR:0x[0-9a-f]+]] -# EXE-NEXT: Offset: -# EXE-NEXT: Size: 4 # EXE: Name: .got # EXE-NEXT: Type: SHT_PROGBITS # EXE-NEXT: Flags [ (0x10000003) @@ -38,6 +29,15 @@ # EXE-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]] # EXE-NEXT: Offset: # EXE-NEXT: Size: 8 +# EXE: Name: .rld_map +# EXE-NEXT: Type: SHT_PROGBITS +# EXE-NEXT: Flags [ +# EXE-NEXT: SHF_ALLOC +# EXE-NEXT: SHF_WRITE +# EXE-NEXT: ] +# EXE-NEXT: Address: [[RLDMAPADDR:0x[0-9a-f]+]] +# EXE-NEXT: Offset: +# EXE-NEXT: Size: 4 # EXE: ] # EXE: DynamicSection [ # EXE-NEXT: Tag Type Name/Value diff --git a/lld/test/ELF/mips-got-relocs.s b/lld/test/ELF/mips-got-relocs.s index 76b7d023e14e..f8b7be4098b7 100644 --- a/lld/test/ELF/mips-got-relocs.s +++ b/lld/test/ELF/mips-got-relocs.s @@ -45,21 +45,21 @@ v1: .word 0 # EXE_SYM: Sections: -# EXE_SYM: .got 0000000c 0000000000030004 DATA +# EXE_SYM: .got 0000000c 0000000000030000 DATA # EXE_SYM: SYMBOL TABLE: -# EXE_SYM: 00037ff4 *ABS* 00000000 _gp +# EXE_SYM: 00037ff0 *ABS* 00000000 _gp # ^-- .got + GP offset (0x7ff0) -# EXE_SYM: 00030000 g .data 00000004 v1 +# EXE_SYM: 00030010 g .data 00000004 v1 # EXE_GOT_BE: Contents of section .got: -# EXE_GOT_BE: 30004 00000000 80000000 00030000 -# ^ ^ ^-- v1 (0x30000) +# EXE_GOT_BE: 30000 00000000 80000000 00030010 +# ^ ^ ^-- v1 (0x30010) # | +-- Module pointer (0x80000000) # +-- Lazy resolver (0x0) # EXE_GOT_EL: Contents of section .got: -# EXE_GOT_EL: 30004 00000000 00000080 00000300 -# ^ ^ ^-- v1 (0x30000) +# EXE_GOT_EL: 30000 00000000 00000080 10000300 +# ^ ^ ^-- v1 (0x30010) # | +-- Module pointer (0x80000000) # +-- Lazy resolver (0x0) @@ -68,21 +68,21 @@ v1: # EXE_DIS_EL: 20000: 18 80 02 3c lui $2, 32792 # DSO_SYM: Sections: -# DSO_SYM: .got 0000000c 0000000000020004 DATA +# DSO_SYM: .got 0000000c 0000000000020000 DATA # DSO_SYM: SYMBOL TABLE: -# DSO_SYM: 00027ff4 *ABS* 00000000 _gp +# DSO_SYM: 00027ff0 *ABS* 00000000 _gp # ^-- .got + GP offset (0x7ff0) -# DSO_SYM: 00020000 g .data 00000004 v1 +# DSO_SYM: 00020010 g .data 00000004 v1 # DSO_GOT_BE: Contents of section .got: -# DSO_GOT_BE: 20004 00000000 80000000 00020000 -# ^ ^ ^-- v1 (0x20000) +# DSO_GOT_BE: 20000 00000000 80000000 00020010 +# ^ ^ ^-- v1 (0x20010) # | +-- Module pointer (0x80000000) # +-- Lazy resolver (0x0) # DSO_GOT_EL: Contents of section .got: -# DSO_GOT_EL: 20004 00000000 00000080 00000200 -# ^ ^ ^-- v1 (0x20000) +# DSO_GOT_EL: 20000 00000000 00000080 10000200 +# ^ ^ ^-- v1 (0x20010) # | +-- Module pointer (0x80000000) # +-- Lazy resolver (0x0) diff --git a/lld/test/ELF/relative-dynamic-reloc-ppc64.s b/lld/test/ELF/relative-dynamic-reloc-ppc64.s index fc7d4c699071..97f74ccab53d 100644 --- a/lld/test/ELF/relative-dynamic-reloc-ppc64.s +++ b/lld/test/ELF/relative-dynamic-reloc-ppc64.s @@ -13,7 +13,7 @@ // CHECK-NEXT: 0x10010 R_PPC64_RELATIVE - 0x10009 // CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[ZED_ADDR:.*]] // CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[FOO_ADDR]] -// CHECK-NEXT: 0x160 R_PPC64_ADDR64 external 0x0 +// CHECK-NEXT: 0x198 R_PPC64_ADDR64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/lld/test/ELF/relative-dynamic-reloc.s b/lld/test/ELF/relative-dynamic-reloc.s index b790afd51941..6760a4f796d6 100644 --- a/lld/test/ELF/relative-dynamic-reloc.s +++ b/lld/test/ELF/relative-dynamic-reloc.s @@ -12,7 +12,7 @@ // CHECK-NEXT: 0x1010 R_X86_64_RELATIVE - 0x1009 // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[ZED_ADDR:.*]] // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[FOO_ADDR]] -// CHECK-NEXT: 0x160 R_X86_64_64 external 0x0 +// CHECK-NEXT: 0x198 R_X86_64_64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/lld/test/ELF/relocation.s b/lld/test/ELF/relocation.s index 6a5d072cb03a..e201ee0577ec 100644 --- a/lld/test/ELF/relocation.s +++ b/lld/test/ELF/relocation.s @@ -104,7 +104,7 @@ R_X86_64_64: .quad R_X86_64_64 // CHECK: Contents of section .R_X86_64_64: -// CHECK-NEXT: 10158 58010100 00000000 +// CHECK-NEXT: 10190 90010100 00000000 .section .R_X86_64_GOTPCREL,"a",@progbits .global R_X86_64_GOTPCREL @@ -114,4 +114,4 @@ R_X86_64_GOTPCREL: // 0x120A8 - 0x10160 = 8008 // 8008 = 0x481f0000 in little endian // CHECK: Contents of section .R_X86_64_GOTPCREL -// CHECK-NEXT: 10160 801f0000 +// CHECK-NEXT: 10198 481f0000 diff --git a/lld/test/ELF/relro.s b/lld/test/ELF/relro.s new file mode 100644 index 000000000000..43b0d34adcef --- /dev/null +++ b/lld/test/ELF/relro.s @@ -0,0 +1,243 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: ld.lld %t.o %t2.so -z now -z relro -o %t +// RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data %t | FileCheck --check-prefix=FULLRELRO %s +// RUN: ld.lld %t.o %t2.so -z relro -o %t +// RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data %t | FileCheck --check-prefix=PARTRELRO %s +// RUN: ld.lld %t.o %t2.so -z norelro -o %t +// RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data %t | FileCheck --check-prefix=NORELRO %s +// REQUIRES: x86 + +// FULLRELRO: Section { +// FULLRELRO: Index: 9 +// FULLRELRO-NEXT: Name: .got +// FULLRELRO-NEXT: Type: SHT_PROGBITS +// FULLRELRO-NEXT: Flags [ +// FULLRELRO-NEXT: SHF_ALLOC +// FULLRELRO-NEXT: SHF_WRITE +// FULLRELRO-NEXT: ] +// FULLRELRO-NEXT: Address: 0x12100 +// FULLRELRO-NEXT: Offset: 0x2100 +// FULLRELRO-NEXT: Size: 8 +// FULLRELRO-NEXT: Link: 0 +// FULLRELRO-NEXT: Info: 0 +// FULLRELRO-NEXT: AddressAlignment: 8 +// FULLRELRO-NEXT: EntrySize: 0 +// FULLRELRO-NEXT: SectionData ( +// FULLRELRO-NEXT: 0000: 00000000 00000000 +// FULLRELRO-NEXT: ) +// FULLRELRO-NEXT: } +// FULLRELRO-NEXT: Section { +// FULLRELRO-NEXT: Index: 10 +// FULLRELRO-NEXT: Name: .got.plt +// FULLRELRO-NEXT: Type: SHT_PROGBITS +// FULLRELRO-NEXT: Flags [ +// FULLRELRO-NEXT: SHF_ALLOC +// FULLRELRO-NEXT: SHF_WRITE +// FULLRELRO-NEXT: ] +// FULLRELRO-NEXT: Address: 0x12108 +// FULLRELRO-NEXT: Offset: 0x2108 +// FULLRELRO-NEXT: Size: 32 +// FULLRELRO-NEXT: Link: 0 +// FULLRELRO-NEXT: Info: 0 +// FULLRELRO-NEXT: AddressAlignment: 8 +// FULLRELRO-NEXT: EntrySize: 0 +// FULLRELRO-NEXT: SectionData ( +// FULLRELRO-NEXT: 0000: +// FULLRELRO-NEXT: 0010: +// FULLRELRO-NEXT: ) +// FULLRELRO-NEXT: } +// FULLRELRO-NEXT: Section { +// FULLRELRO-NEXT: Index: 11 +// FULLRELRO-NEXT: Name: .data +// FULLRELRO-NEXT: Type: SHT_PROGBITS +// FULLRELRO-NEXT: Flags [ +// FULLRELRO-NEXT: SHF_ALLOC +// FULLRELRO-NEXT: SHF_WRITE +// FULLRELRO-NEXT: ] +// FULLRELRO-NEXT: Address: 0x12128 +// FULLRELRO-NEXT: Offset: 0x2128 +// FULLRELRO-NEXT: Size: 12 +// FULLRELRO-NEXT: Link: 0 +// FULLRELRO-NEXT: Info: 0 +// FULLRELRO-NEXT: AddressAlignment: +// FULLRELRO-NEXT: EntrySize: 0 +// FULLRELRO-NEXT: SectionData ( +// FULLRELRO-NEXT: 0000: +// FULLRELRO-NEXT: ) +// FULLRELRO-NEXT: } +// FULLRELRO-NEXT: Section { +// FULLRELRO-NEXT: Index: 12 +// FULLRELRO-NEXT: Name: .foo +// FULLRELRO-NEXT: Type: SHT_PROGBITS +// FULLRELRO-NEXT: Flags [ +// FULLRELRO-NEXT: SHF_ALLOC +// FULLRELRO-NEXT: SHF_WRITE +// FULLRELRO-NEXT: ] +// FULLRELRO-NEXT: Address: 0x12134 +// FULLRELRO-NEXT: Offset: 0x2134 +// FULLRELRO-NEXT: Size: 0 +// FULLRELRO-NEXT: Link: 0 +// FULLRELRO-NEXT: Info: 0 +// FULLRELRO-NEXT: AddressAlignment: +// FULLRELRO-NEXT: EntrySize: 0 +// FULLRELRO-NEXT: SectionData ( +// FULLRELRO-NEXT: ) +// FULLRELRO-NEXT: } +// 308 - sizeof(.data)(12) = 296 +// FULLRELRO: ProgramHeaders [ +// FULLRELRO: Type: PT_LOAD +// FULLRELRO: Offset: 0x2000 +// FULLRELRO-NEXT: VirtualAddress: [[RWADDR:.*]] +// FULLRELRO-NEXT: PhysicalAddress: +// FULLRELRO-NEXT: FileSize: 308 +// FULLRELRO-NEXT: MemSize: 308 +// FULLRELRO-NEXT: Flags [ +// FULLRELRO-NEXT: PF_R +// FULLRELRO-NEXT: PF_W +// FULLRELRO-NEXT: ] +// FULLRELRO-NEXT: Alignment: 4096 +// FULLRELRO-NEXT:} +// FULLRELRO: Type: PT_GNU_RELRO +// FULLRELRO-NEXT: Offset: 0x +// FULLRELRO-NEXT: VirtualAddress: [[RWADDR]] +// FULLRELRO-NEXT: PhysicalAddress: +// FULLRELRO-NEXT: FileSize: 296 +// FULLRELRO-NEXT: MemSize: 296 +// FULLRELRO-NEXT: Flags [ +// FULLRELRO-NEXT: PF_R +// FULLRELRO-NEXT: ] +// FULLRELRO-NEXT: Alignment: 1 +// FULLRELRO-NEXT:} + +// PARTRELRO: Section { +// PARTRELRO: Index: 9 +// PARTRELRO-NEXT: Name: .got +// PARTRELRO-NEXT: Type: SHT_PROGBITS +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: SHF_ALLOC +// PARTRELRO-NEXT: SHF_WRITE +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Address: 0x120E0 +// PARTRELRO-NEXT: Offset: 0x20E0 +// PARTRELRO-NEXT: Size: 8 +// PARTRELRO-NEXT: Link: 0 +// PARTRELRO-NEXT: Info: 0 +// PARTRELRO-NEXT: AddressAlignment: 8 +// PARTRELRO-NEXT: EntrySize: 0 +// PARTRELRO-NEXT: SectionData ( +// PARTRELRO-NEXT: 0000: +// PARTRELRO-NEXT: ) +// PARTRELRO-NEXT: } +// PARTRELRO-NEXT: Section { +// PARTRELRO-NEXT: Index: 10 +// PARTRELRO-NEXT: Name: .data +// PARTRELRO-NEXT: Type: SHT_PROGBITS +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: SHF_ALLOC +// PARTRELRO-NEXT: SHF_WRITE +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Address: 0x120E8 +// PARTRELRO-NEXT: Offset: 0x20E8 +// PARTRELRO-NEXT: Size: 12 +// PARTRELRO-NEXT: Link: 0 +// PARTRELRO-NEXT: Info: 0 +// PARTRELRO-NEXT: AddressAlignment: 1 +// PARTRELRO-NEXT: EntrySize: 0 +// PARTRELRO-NEXT: SectionData ( +// PARTRELRO-NEXT: 0000: +// PARTRELRO-NEXT: ) +// PARTRELRO-NEXT: } +// PARTRELRO-NEXT: Section { +// PARTRELRO-NEXT: Index: 11 +// PARTRELRO-NEXT: Name: .foo +// PARTRELRO-NEXT: Type: SHT_PROGBITS +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: SHF_ALLOC +// PARTRELRO-NEXT: SHF_WRITE +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Address: 0x120F4 +// PARTRELRO-NEXT: Offset: 0x20F4 +// PARTRELRO-NEXT: Size: 0 +// PARTRELRO-NEXT: Link: 0 +// PARTRELRO-NEXT: Info: 0 +// PARTRELRO-NEXT: AddressAlignment: 1 +// PARTRELRO-NEXT: EntrySize: 0 +// PARTRELRO-NEXT: SectionData ( +// PARTRELRO-NEXT: ) +// PARTRELRO-NEXT: } +// PARTRELRO-NEXT: Section { +// PARTRELRO-NEXT: Index: 12 +// PARTRELRO-NEXT: Name: .got.plt +// PARTRELRO-NEXT: Type: SHT_PROGBITS +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: SHF_ALLOC +// PARTRELRO-NEXT: SHF_WRITE +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Address: 0x120F8 +// PARTRELRO-NEXT: Offset: 0x20F8 +// PARTRELRO-NEXT: Size: 32 +// PARTRELRO-NEXT: Link: 0 +// PARTRELRO-NEXT: Info: 0 +// PARTRELRO-NEXT: AddressAlignment: 8 +// PARTRELRO-NEXT: EntrySize: 0 +// PARTRELRO-NEXT: SectionData ( +// PARTRELRO-NEXT: 0000: +// PARTRELRO-NEXT: 0010: +// PARTRELRO-NEXT: ) +// PARTRELRO-NEXT: } +// PARTRELRO-NEXT: Section { +// PARTRELRO-NEXT: Index: 13 +// PARTRELRO-NEXT: Name: .bss +// PARTRELRO-NEXT: Type: SHT_NOBITS +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: SHF_ALLOC +// PARTRELRO-NEXT: SHF_WRITE +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Address: 0x12118 +// PARTRELRO-NEXT: Offset: 0x2118 +// PARTRELRO-NEXT: Size: 0 +// PARTRELRO-NEXT: Link: 0 +// PARTRELRO-NEXT: Info: 0 +// PARTRELRO-NEXT: AddressAlignment: 1 +// PARTRELRO-NEXT: EntrySize: 0 +// PARTRELRO-NEXT: } +// 232 + sizeof(.data)(12) + align(4) + sizeof(.got.plt)(32) = 280 +// PARTRELRO: ProgramHeader { +// PARTRELRO: Type: PT_LOAD +// PARTRELRO: Offset: 0x2000 +// PARTRELRO-NEXT: VirtualAddress: [[RWADDR:.*]] +// PARTRELRO-NEXT: PhysicalAddress: +// PARTRELRO-NEXT: FileSize: 280 +// PARTRELRO-NEXT: MemSize: 280 +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: PF_R (0x4) +// PARTRELRO-NEXT: PF_W (0x2) +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Alignment: 4096 +// PARTRELRO: Type: PT_GNU_RELRO +// PARTRELRO-NEXT: Offset: 0x2000 +// PARTRELRO-NEXT: VirtualAddress: [[RWADDR]] +// PARTRELRO-NEXT: PhysicalAddress: +// PARTRELRO-NEXT: FileSize: 232 +// PARTRELRO-NEXT: MemSize: 232 +// PARTRELRO-NEXT: Flags [ +// PARTRELRO-NEXT: PF_R +// PARTRELRO-NEXT: ] +// PARTRELRO-NEXT: Alignment: 1 + +// NORELRO: ProgramHeaders [ +// NORELRO-NOT: PT_GNU_RELRO + +.global _start +_start: + .long bar + jmp *bar@GOTPCREL(%rip) + +.section .data,"aw" +.quad 0 + +.zero 4 +.section .foo,"aw" +.section .bss,"",@nobits diff --git a/lld/test/ELF/section-name.s b/lld/test/ELF/section-name.s index 7a528795c68c..2d7ed4e63717 100644 --- a/lld/test/ELF/section-name.s +++ b/lld/test/ELF/section-name.s @@ -26,12 +26,12 @@ _start: // CHECK: Name: .rodata // CHECK-NOT: Name: .text.a // CHECK: Name: .text +// CHECK-NOT: Name: .data.rel.ro.a +// CHECK-NOT: Name: .data.rel.ro.local.a +// CHECK: Name: .data.rel.ro // CHECK-NOT: Name: .data.a // CHECK: Name: .data // CHECK: Name: .foo.a // CHECK: Name: .foo -// CHECK-NOT: Name: .data.rel.ro.a -// CHECK-NOT: Name: .data.rel.ro.local.a -// CHECK: Name: .data.rel.ro // CHECK-NOT: Name: .bss.a // CHECK: Name: .bss diff --git a/lld/test/ELF/shared.s b/lld/test/ELF/shared.s index 03b1d0a17b27..5485559bb411 100644 --- a/lld/test/ELF/shared.s +++ b/lld/test/ELF/shared.s @@ -46,7 +46,7 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[DYNSYMADDR:.*]] -// CHECK-NEXT: Offset: 0x110 +// CHECK-NEXT: Offset: 0x130 // CHECK-NEXT: Size: // CHECK-NEXT: Link: [[DYNSTR:.*]] // CHECK-NEXT: Info: 1