George Rimar via llvm-dev
2016-Aug-12 17:24 UTC
[llvm-dev] How LLD should create segments when linkerscript is used ?
I wonder what is correct way to create PT_LOADs when linkerscript is used ? Currently we create new one for each section that changes access flags. But ld seems to do different thing. Imagine we have next sections: .section .AX.1,"ax" .quad 1 .section .A.1,"a" .quad 2 .section .AW.1,"aw" .quad 3 And script: SECTIONS { . = ALIGN(CONSTANT (MAXPAGESIZE)); .AX : { *(.AX.*) } . = ALIGN(CONSTANT (MAXPAGESIZE)); .A : { *(.A.*) } . = ALIGN(CONSTANT (MAXPAGESIZE)); .AW : { *(.AW.*) } } ld creates 2 segments here: LOAD 0x0000000000200000 0x0000000000000000 0x0000000000000000 0x0000000000200008 0x0000000000200008 R E 200000 LOAD 0x0000000000600000 0x0000000000400000 0x0000000000400000 0x0000000000000008 0x0000000000000008 RW 200000 Section to Segment mapping: Segment Sections... 00 .AX .text .A 01 .AW And if I change script in the next way: SECTIONS { . = ALIGN(CONSTANT (MAXPAGESIZE)); .AX : { *(.AX.*) } . = ALIGN(CONSTANT (MAXPAGESIZE)); .A : { *(.A.*) } .AW : { *(.AW.*) } } It will create single segment, combining access attributes: LOAD 0x0000000000200000 0x0000000000000000 0x0000000000000000 0x0000000000200010 0x0000000000200010 RWE 200000 So looks like its behavior is to combine all sections before writable ones to single segment and create writable segment for others if possible, but if not it will create single segment for everything. I think FreeBSD script relies on this behavior. When linking with ld It has 2 PT_LOADS (RE + RW) when LLD creates 4 (R RE R RW), and since we do not align sections to the page boundary manually or in script, it will not work I think. Below is lld output of FreeBSD kernel (notice that RE and R loads are not aligned): Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0xffffffff80001040 0xffffffff80001040 0x00000000000001f8 0x00000000000001f8 R 8 INTERP 0x0000000000000238 0xffffffff80001238 0xffffffff80001238 0x000000000000000d 0x000000000000000d R 1 [Requesting program interpreter: /red/herring] LOAD 0x0000000000000000 0xffffffff80001000 0xffffffff80001000 0x00000000000e410e 0x00000000000e410e R 1000 LOAD 0x00000000000e4110 0xffffffff800e5110 0xffffffff800e5110 0x0000000000ba2b0c 0x0000000000ba2b0c R E 1000 LOAD 0x0000000000c86c20 0xffffffff80c87c20 0xffffffff80c87c20 0x000000000038ab28 0x000000000038ab28 R 1000 LOAD 0x0000000001012000 0xffffffff81013000 0xffffffff81013000 0x000000000012ae30 0x0000000000331e30 RW 1000 DYNAMIC 0x0000000001012000 0xffffffff81013000 0xffffffff81013000 0x0000000000000080 0x0000000000000080 RW 8 GNU_RELRO 0x0000000001012000 0xffffffff81013000 0xffffffff81013000 0x0000000000000080 0x0000000000000080 R 1 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0 ld output of the same: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0xffffffff80200040 0xffffffff80200040 0x0000000000000150 0x0000000000000150 R E 8 INTERP 0x0000000000000190 0xffffffff80200190 0xffffffff80200190 0x000000000000000d 0x000000000000000d R 1 [Requesting program interpreter: /red/herring] LOAD 0x0000000000000000 0xffffffff80200000 0xffffffff80200000 0x0000000000fe2de8 0x0000000000fe2de8 R E 200000 LOAD 0x0000000000fe3000 0xffffffff813e3000 0xffffffff813e3000 0x0000000000129430 0x00000000003313c0 RW 200000 DYNAMIC 0x0000000000fe3000 0xffffffff813e3000 0xffffffff813e3000 0x00000000000000d0 0x00000000000000d0 RW 8 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RWE 8 So see next possible solutions: 1) Align first sections of each segment to the page boundary like we do for non-script case. 2) Implement the described ld behavior. Thoughts ?
Davide Italiano via llvm-dev
2016-Aug-12 17:27 UTC
[llvm-dev] How LLD should create segments when linkerscript is used ?
+ Michael On Fri, Aug 12, 2016 at 7:24 PM, George Rimar via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I wonder what is correct way to create PT_LOADs when linkerscript is used ? > Currently we create new one for each section that changes access flags. But ld seems to do different thing. > > Imagine we have next sections: > .section .AX.1,"ax" > .quad 1 > .section .A.1,"a" > .quad 2 > .section .AW.1,"aw" > .quad 3 > > And script: > SECTIONS { > . = ALIGN(CONSTANT (MAXPAGESIZE)); > .AX : { *(.AX.*) } > . = ALIGN(CONSTANT (MAXPAGESIZE)); > .A : { *(.A.*) } > . = ALIGN(CONSTANT (MAXPAGESIZE)); > .AW : { *(.AW.*) } > } > > ld creates 2 segments here: > LOAD 0x0000000000200000 0x0000000000000000 0x0000000000000000 > 0x0000000000200008 0x0000000000200008 R E 200000 > LOAD 0x0000000000600000 0x0000000000400000 0x0000000000400000 > 0x0000000000000008 0x0000000000000008 RW 200000 > Section to Segment mapping: > Segment Sections... > 00 .AX .text .A > 01 .AW > > And if I change script in the next way: > SECTIONS { > . = ALIGN(CONSTANT (MAXPAGESIZE)); > .AX : { *(.AX.*) } > . = ALIGN(CONSTANT (MAXPAGESIZE)); > .A : { *(.A.*) } > .AW : { *(.AW.*) } > } > > It will create single segment, combining access attributes: > LOAD 0x0000000000200000 0x0000000000000000 0x0000000000000000 > 0x0000000000200010 0x0000000000200010 RWE 200000 > > So looks like its behavior is to combine all sections before writable ones to single segment > and create writable segment for others if possible, but if not it will create single segment for everything. > I think FreeBSD script relies on this behavior. When linking with ld It has 2 PT_LOADS (RE + RW) when LLD creates 4 (R RE R RW), > and since we do not align sections to the page boundary manually or in script, it will not work I think. > > Below is lld output of FreeBSD kernel (notice that RE and R loads are not aligned): > Program Headers: > Type Offset VirtAddr PhysAddr > FileSiz MemSiz Flags Align > PHDR 0x0000000000000040 0xffffffff80001040 0xffffffff80001040 > 0x00000000000001f8 0x00000000000001f8 R 8 > INTERP 0x0000000000000238 0xffffffff80001238 0xffffffff80001238 > 0x000000000000000d 0x000000000000000d R 1 > [Requesting program interpreter: /red/herring] > LOAD 0x0000000000000000 0xffffffff80001000 0xffffffff80001000 > 0x00000000000e410e 0x00000000000e410e R 1000 > LOAD 0x00000000000e4110 0xffffffff800e5110 0xffffffff800e5110 > 0x0000000000ba2b0c 0x0000000000ba2b0c R E 1000 > LOAD 0x0000000000c86c20 0xffffffff80c87c20 0xffffffff80c87c20 > 0x000000000038ab28 0x000000000038ab28 R 1000 > LOAD 0x0000000001012000 0xffffffff81013000 0xffffffff81013000 > 0x000000000012ae30 0x0000000000331e30 RW 1000 > DYNAMIC 0x0000000001012000 0xffffffff81013000 0xffffffff81013000 > 0x0000000000000080 0x0000000000000080 RW 8 > GNU_RELRO 0x0000000001012000 0xffffffff81013000 0xffffffff81013000 > 0x0000000000000080 0x0000000000000080 R 1 > GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 > 0x0000000000000000 0x0000000000000000 RW 0 > > ld output of the same: > Program Headers: > Type Offset VirtAddr PhysAddr > FileSiz MemSiz Flags Align > PHDR 0x0000000000000040 0xffffffff80200040 0xffffffff80200040 > 0x0000000000000150 0x0000000000000150 R E 8 > INTERP 0x0000000000000190 0xffffffff80200190 0xffffffff80200190 > 0x000000000000000d 0x000000000000000d R 1 > [Requesting program interpreter: /red/herring] > LOAD 0x0000000000000000 0xffffffff80200000 0xffffffff80200000 > 0x0000000000fe2de8 0x0000000000fe2de8 R E 200000 > LOAD 0x0000000000fe3000 0xffffffff813e3000 0xffffffff813e3000 > 0x0000000000129430 0x00000000003313c0 RW 200000 > DYNAMIC 0x0000000000fe3000 0xffffffff813e3000 0xffffffff813e3000 > 0x00000000000000d0 0x00000000000000d0 RW 8 > GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 > 0x0000000000000000 0x0000000000000000 RWE 8 > > > So see next possible solutions: > 1) Align first sections of each segment to the page boundary like we do for non-script case. > 2) Implement the described ld behavior. > > Thoughts ? > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Davide "There are no solved problems; there are only problems that are more or less solved" -- Henri Poincare
Rafael EspĂndola via llvm-dev
2016-Aug-25 18:00 UTC
[llvm-dev] How LLD should create segments when linkerscript is used ?
>> So see next possible solutions: >> 1) Align first sections of each segment to the page boundary like we do for non-script case. >> 2) Implement the described ld behavior. >> >> Thoughts ?Probably 1. I think the difference is because we default to creating a RO PT_LOAD, but bfd default to merging RO and RO+E into one PT_LOAD. Cheers, Rafael