Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -67,6 +67,7 @@ bool ZNodelete = false; bool ZNow = false; bool ZOrigin = false; + bool ZRelro; ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t EntryAddr = -1; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -177,6 +177,7 @@ 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(); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -47,6 +47,8 @@ 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 @@ 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 @@ .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,11 @@ if (AIsNoBits != BIsNoBits) return BIsNoBits; + 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 +752,11 @@ 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 = + HasRelro || (Config->ZRelro && isRelroSection(OutputSections[I])); + } for (OutputSectionBase *Sec : OutputSections) Out::ShStrTab->add(Sec->getName()); @@ -793,6 +824,18 @@ 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 @@ 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 @@ VA = RoundUpToAlignment(VA, Sec->getAlign()); Sec->setVA(VA); VA += Sec->getSize(); + updateRelro(&Phdrs[PhdrIdx], &GnuRelroPhdr, Sec, VA); } } @@ -881,6 +926,11 @@ copyPhdr(PH, Out::Dynamic); } + if (HasRelro) { + Elf_Phdr *PH = &Phdrs[++PhdrIdx]; + *PH = GnuRelroPhdr; + } + Elf_Phdr *PH = &Phdrs[++PhdrIdx]; PH->p_type = PT_GNU_STACK; PH->p_flags = Config->ZExecStack ? toPhdrFlags(SHF_WRITE | SHF_EXECINSTR) @@ -927,6 +977,8 @@ } if (Tls) ++I; + if (HasRelro) + ++I; return I; } Index: test/ELF/eh-frame-merge.s =================================================================== --- test/ELF/eh-frame-merge.s +++ 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: 500E0000 01000000 00000000 10000000 | -// CHECK-NEXT: 0030: 30000000 3E0E0000 02000000 00000000 | -// CHECK-NEXT: 0040: 10000000 44000000 290E0000 01000000 | +// CHECK-NEXT: 0020: 180E0000 01000000 00000000 10000000 | +// CHECK-NEXT: 0030: 30000000 060E0000 02000000 00000000 | +// CHECK-NEXT: 0040: 10000000 44000000 F10D0000 01000000 | // CHECK-NEXT: 0050: 00000000 | // CHECK-NEXT: ) Index: test/ELF/gnu-hash-table.s =================================================================== --- test/ELF/gnu-hash-table.s +++ test/ELF/gnu-hash-table.s @@ -149,8 +149,8 @@ # PPC64-NEXT: Flags [ # PPC64-NEXT: SHF_ALLOC # PPC64-NEXT: ] -# PPC64-NEXT: Address: 0x1F0 -# PPC64-NEXT: Offset: 0x1F0 +# PPC64-NEXT: Address: 0x228 +# PPC64-NEXT: Offset: 0x228 # PPC64-NEXT: Size: 36 # PPC64-NEXT: Link: 1 # PPC64-NEXT: Info: 0 Index: test/ELF/merge-shared.s =================================================================== --- test/ELF/merge-shared.s +++ test/ELF/merge-shared.s @@ -17,10 +17,10 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x190 +// CHECK-NEXT: Address: 0x1C8 // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { -// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x192 +// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1CA // CHECK-NEXT: } // CHECK-NEXT: ] Index: test/ELF/merge-string.s =================================================================== --- test/ELF/merge-string.s +++ test/ELF/merge-string.s @@ -26,8 +26,8 @@ // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: SHF_STRINGS // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x190 -// CHECK-NEXT: Offset: 0x190 +// CHECK-NEXT: Address: 0x1C8 +// CHECK-NEXT: Offset: 0x1C8 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -44,8 +44,8 @@ // NOTAIL-NEXT: SHF_MERGE // NOTAIL-NEXT: SHF_STRINGS // NOTAIL-NEXT: ] -// NOTAIL-NEXT: Address: 0x190 -// NOTAIL-NEXT: Offset: 0x190 +// NOTAIL-NEXT: Address: 0x1C8 +// NOTAIL-NEXT: Offset: 0x1C8 // NOTAIL-NEXT: Size: 7 // NOTAIL-NEXT: Link: 0 // NOTAIL-NEXT: Info: 0 @@ -62,8 +62,8 @@ // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: SHF_STRINGS // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x194 -// CHECK-NEXT: Offset: 0x194 +// CHECK-NEXT: Address: 0x1CC +// CHECK-NEXT: Offset: 0x1CC // CHECK-NEXT: Size: 4 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -75,11 +75,11 @@ // CHECK: Name: bar -// CHECK-NEXT: Value: 0x191 +// CHECK-NEXT: Value: 0x1C9 // CHECK: Name: foo -// CHECK-NEXT: Value: 0x190 +// CHECK-NEXT: Value: 0x1C8 // CHECK: Name: zed -// CHECK-NEXT: Value: 0x194 +// CHECK-NEXT: Value: 0x1CC // CHECK-NEXT: Size: 0 Index: test/ELF/merge-sym.s =================================================================== --- test/ELF/merge-sym.s +++ test/ELF/merge-sym.s @@ -15,7 +15,7 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_MERGE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x190 +// CHECK-NEXT: Address: 0x1C8 // CHECK: Name: foo -// CHECK-NEXT: Value: 0x192 +// CHECK-NEXT: Value: 0x1CA Index: test/ELF/mips-dynamic.s =================================================================== --- test/ELF/mips-dynamic.s +++ test/ELF/mips-dynamic.s @@ -20,24 +20,24 @@ # EXE-NEXT: Flags [ # EXE-NEXT: SHF_ALLOC # EXE-NEXT: ] -# EXE: Name: .rld_map +# EXE: Name: .got # EXE-NEXT: Type: SHT_PROGBITS -# EXE-NEXT: Flags [ +# EXE-NEXT: Flags [ (0x10000003) # EXE-NEXT: SHF_ALLOC # EXE-NEXT: SHF_WRITE # EXE-NEXT: ] -# EXE-NEXT: Address: [[RLDMAPADDR:0x[0-9a-f]+]] +# EXE-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]] # EXE-NEXT: Offset: -# EXE-NEXT: Size: 4 -# EXE: Name: .got +# EXE-NEXT: Size: 8 +# EXE: Name: .rld_map # EXE-NEXT: Type: SHT_PROGBITS -# EXE-NEXT: Flags [ (0x10000003) +# EXE-NEXT: Flags [ # EXE-NEXT: SHF_ALLOC # EXE-NEXT: SHF_WRITE # EXE-NEXT: ] -# EXE-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]] +# EXE-NEXT: Address: [[RLDMAPADDR:0x[0-9a-f]+]] # EXE-NEXT: Offset: -# EXE-NEXT: Size: 8 +# EXE-NEXT: Size: 4 # EXE: ] # EXE: DynamicSection [ # EXE-NEXT: Tag Type Name/Value Index: test/ELF/mips-got-relocs.s =================================================================== --- test/ELF/mips-got-relocs.s +++ test/ELF/mips-got-relocs.s @@ -45,21 +45,21 @@ .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 @@ # 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) Index: test/ELF/relative-dynamic-reloc-ppc64.s =================================================================== --- test/ELF/relative-dynamic-reloc-ppc64.s +++ 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: 0x198 R_PPC64_ADDR64 external 0x0 +// CHECK-NEXT: 0x1D0 R_PPC64_ADDR64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] Index: test/ELF/relative-dynamic-reloc.s =================================================================== --- test/ELF/relative-dynamic-reloc.s +++ 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: 0x198 R_X86_64_64 external 0x0 +// CHECK-NEXT: 0x1D0 R_X86_64_64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] Index: test/ELF/relocation.s =================================================================== --- test/ELF/relocation.s +++ test/ELF/relocation.s @@ -104,14 +104,14 @@ .quad R_X86_64_64 // CHECK: Contents of section .R_X86_64_64: -// CHECK-NEXT: 10190 90010100 00000000 +// CHECK-NEXT: 101c8 c8010100 00000000 .section .R_X86_64_GOTPCREL,"a",@progbits .global R_X86_64_GOTPCREL R_X86_64_GOTPCREL: .long zed@gotpcrel -// 0x120A8 - 0x10160 = 8008 -// 8008 = 0x481f0000 in little endian +// 0x120E0 - 0x101d0 = 7952 +// 7952 = 0x101f0000 in little endian // CHECK: Contents of section .R_X86_64_GOTPCREL -// CHECK-NEXT: 10198 481f0000 +// CHECK-NEXT: 101d0 101f0000 Index: test/ELF/relro.s =================================================================== --- test/ELF/relro.s +++ 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 Index: test/ELF/section-name.s =================================================================== --- test/ELF/section-name.s +++ test/ELF/section-name.s @@ -26,12 +26,12 @@ // 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 Index: test/ELF/shared.s =================================================================== --- test/ELF/shared.s +++ test/ELF/shared.s @@ -46,7 +46,7 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[DYNSYMADDR:.*]] -// CHECK-NEXT: Offset: 0x130 +// CHECK-NEXT: Offset: 0x150 // CHECK-NEXT: Size: // CHECK-NEXT: Link: [[DYNSTR:.*]] // CHECK-NEXT: Info: 1