Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -822,6 +822,16 @@ expect(")"); return [](uint64_t Dot) { return Dot; }; } + if (Tok == "DATA_SEGMENT_RELRO_END") { + expect("("); + next(); + expect(","); + next(); + expect(")"); + if (!Config->ZRelro) + return [](uint64_t Dot) { return Dot; }; + return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; + } // Parse a number literal uint64_t V = 0; Index: test/ELF/linkerscript/Inputs/shared.s =================================================================== --- test/ELF/linkerscript/Inputs/shared.s +++ test/ELF/linkerscript/Inputs/shared.s @@ -0,0 +1,10 @@ +.global bar +.type bar, @function +bar: + +.global bar2 +.type bar2, @function +bar2: + +.global zed +zed: Index: test/ELF/linkerscript/linkerscript-data-segment-relro.s =================================================================== --- test/ELF/linkerscript/linkerscript-data-segment-relro.s +++ test/ELF/linkerscript/linkerscript-data-segment-relro.s @@ -0,0 +1,104 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.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: echo "SECTIONS { \ +# RUN: .plt : { *(.plt) } \ +# RUN: .text : { *(.text) } \ +# RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \ +# RUN: .dynamic : { *(.dynamic) } \ +# RUN: .got : { *(.got) } \ +# RUN: . = DATA_SEGMENT_RELRO_END (24, .); \ +# RUN: .got.plt : { *(.got.plt) } \ +# RUN: .data : { *(.data) } \ +# RUN: .bss : { *(.bss) } \ +# RUN: . = DATA_SEGMENT_END (.); \ +# RUN: }" > %t.script +# RUN: ld.lld -z norelro %t1.o %t2.so --script %t.script -o %t +# RUN: llvm-readobj -s %t | FileCheck -check-prefix=NORELRO %s + +## .got.plt is the first section after DATA_SEGMENT_RELRO_END, +## verify that if relro is disabled then it is not aligned, +## so DATA_SEGMENT_RELRO_END is ignored. +# NORELRO: Section { +# NORELRO: Index: 4 +# NORELRO-NEXT: Name: .got +# NORELRO-NEXT: Type: SHT_PROGBITS +# NORELRO-NEXT: Flags [ +# NORELRO-NEXT: SHF_ALLOC +# NORELRO-NEXT: SHF_WRITE +# NORELRO-NEXT: ] +# NORELRO-NEXT: Address: 0x10F0 +# NORELRO-NEXT: Offset: 0x10F0 +# NORELRO-NEXT: Size: +# NORELRO-NEXT: Link: +# NORELRO-NEXT: Info: +# NORELRO-NEXT: AddressAlignment: +# NORELRO-NEXT: EntrySize: +# NORELRO-NEXT: } +# NORELRO-NEXT: Section { +# NORELRO-NEXT: Index: 5 +# NORELRO-NEXT: Name: .got.plt +# NORELRO-NEXT: Type: SHT_PROGBITS +# NORELRO-NEXT: Flags [ +# NORELRO-NEXT: SHF_ALLOC +# NORELRO-NEXT: SHF_WRITE +# NORELRO-NEXT: ] +# NORELRO-NEXT: Address: 0x10F8 +# NORELRO-NEXT: Offset: 0x10F8 +# NORELRO-NEXT: Size: +# NORELRO-NEXT: Link: +# NORELRO-NEXT: Info: +# NORELRO-NEXT: AddressAlignment: +# NORELRO-NEXT: EntrySize: +# NORELRO-NEXT: } + +## When relro is enabled, DATA_SEGMENT_RELRO_END works as +## align command. +# RUN: ld.lld -z relro %t1.o %t2.so --script %t.script -o %t2 +# RUN: llvm-readobj -s %t2 | FileCheck -check-prefix=RELRO %s +# RELRO: Section { +# RELRO: Index: 4 +# RELRO-NEXT: Name: .got +# RELRO-NEXT: Type: SHT_PROGBITS +# RELRO-NEXT: Flags [ +# RELRO-NEXT: SHF_ALLOC +# RELRO-NEXT: SHF_WRITE +# RELRO-NEXT: ] +# RELRO-NEXT: Address: 0x10F0 +# RELRO-NEXT: Offset: 0x10F0 +# RELRO-NEXT: Size: +# RELRO-NEXT: Link: +# RELRO-NEXT: Info: +# RELRO-NEXT: AddressAlignment: +# RELRO-NEXT: EntrySize: +# RELRO-NEXT: } +# RELRO-NEXT: Section { +# RELRO-NEXT: Index: 5 +# RELRO-NEXT: Name: .got.plt +# RELRO-NEXT: Type: SHT_PROGBITS +# RELRO-NEXT: Flags [ +# RELRO-NEXT: SHF_ALLOC +# RELRO-NEXT: SHF_WRITE +# RELRO-NEXT: ] +# RELRO-NEXT: Address: 0x2000 +# RELRO-NEXT: Offset: 0x2000 +# RELRO-NEXT: Size: +# RELRO-NEXT: Link: +# RELRO-NEXT: Info: +# RELRO-NEXT: AddressAlignment: +# RELRO-NEXT: EntrySize: +# RELRO-NEXT: } + +.global _start +_start: + .long bar + jmp *bar2@GOTPCREL(%rip) + +.section .data,"aw" +.quad 0 + +.zero 4 +.section .foo,"aw" +.section .bss,"",@nobits