Rafael Auler
2015-Jul-06 05:50 UTC
[LLVMdev] [lld] Current ways to position memory sections (e.g. .text, .data, .bss) with lld?
Hi Ed, I wrote http://reviews.llvm.org/D10952 to address your last problem. There is also the related http://reviews.llvm.org/D10918 by Denis to address how you can directly assign sections to segments in the script. Both are in code review. Rafael auelr On Fri, Jul 3, 2015 at 12:29 AM, Rafael Auler <rafaelauler at gmail.com> wrote:> Hi Ed, > > It looks like lld is failing at mapping two sections far apart from each > other into two different segments. Since it puts these two sections (.text > and .data) in the same ELF segment, the segment is forced to be huge > because the start addresses of these sections are far apart from each > other. I would begin by investigating how > TargetLayout<ELFT>::assignSectionsToSegments() works and go from there. > This function lives at lld/lib/ReaderWriter/ELF/TargetLayout.cpp. I don't > believe you can try any other flags to try to get this done without fixing > this logic. > > Rafael Auler > > On Wed, Jul 1, 2015 at 12:00 PM, ed at modk.it <ed at modk.it> wrote: > >> Hi All, >> >> Congratulations on the major progress on the llvm linker lld over the >> past year including the new linker script support. This really makes it >> possible to ditch binutils altogether. It looks like lld's MEMORY sections >> are currently parsed but not evaluated, but so far that hasn't been a >> problem. >> >> The only snag is I can't figure out how to define the start of the .data >> section in a sane way. Let's say we want our flash (.text) section to >> start at address 0x20000 with a max size of 0x8000 bytes and a data section >> start at 0x20005000 with a max length of 0x3000 bytes. We'd usually >> accomplish this with a combination of MEMORY and SECTION entries in the >> linker script tied together by region aliases, the "AT" directive and the >> ">" operator: >> >> MEMORY >> >> { >> >> flash (rx) : ORIGIN = 0x20000, LENGTH = 0x8000 >> >> ram (rwx) : ORIGIN = 0x20005000, LENGTH = 0x00003000 >> >> } >> >> >> REGION_ALIAS("REGION_TEXT", flash); >> >> REGION_ALIAS("REGION_RAM", ram); >> >> >> SECTIONS >> >> { >> >> .text : >> >> { >> >> ... >> >> } > REGION_TEXT >> >> >> >> _etext = .; >> >> .data : >> >> { >> >> ... >> >> } > REGION_RAM AT > REGION_TEXT >> >> >> } >> >> >> But the MEMORY entries don't seem to be evaluated and ">", "AT", and >> "REGION_ALIAS" don't seem to be hooked up either. Command line options >> like "-Tdata=org=0x20005000" or "--section-start=.data= 0x20005000" are >> also not working. >> >> >> However, the following linker script gets us close: >> >> >> SECTIONS >> >> { >> >> . = 0x20000; >> >> .text : >> >> { >> >> ... >> >> } >> >> >> >> _etext = .; >> >> . = 0x20005000; >> >> _data = .; >> >> .data : >> >> { >> >> ... >> >> } >> >> } >> >> >> The only problem is the resulting elf and binary files are HUGE (e.g. elf >> is 500mb vs 50k) as the linker seems to be filling the space between the >> end of text and the beginning of data. A "llvm-readobj -s" on the >> resulting elf is nearly identical to one created with binutils except >> binults-ld puts .data at Address: 0x20005000 Offset: 0xD000 and llvm-lld >> has data at Address: 0x20005000 Offset: 0x1FFED000 (based on start address >> of 0x18000.) >> >> Any thoughts on a supported linker flag or linker script option that can >> help here? Or a source file to dive into to get something working? I'd be >> willing to take a pass at completing the MEMORY section implementation if >> that's the most sane way to move forward but would love a pointer in the >> right direction. >> >> >> Thanks, >> >> Ed >> >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150706/d7dc0539/attachment.html>
ed at modk.it
2015-Jul-06 12:25 UTC
[LLVMdev] [lld] Current ways to position memory sections (e.g. .text, .data, .bss) with lld?
Hi Raphael, Thanks for the quick responses. I was able to get things working as is. It turns out we don't actually want to put the .data segment way up there where it would be in actual memory, we just wanted a reference to where it would end up for our c startup routine to move the c initialization data (this is for baremetal ARM stuff) from it's actual location in flash to where it would be accessed in ram. But it looks like we can just leave it in flash. And since .bss takes no space (SHT_NOBITS) we can just set .bss to the beginning of ram. So we end up with something like: SECTIONS { . = 0x20000; .text : { ... } _etext = .; _data = .; .data : { ... } . = 0x20005000; .bss : { ... } } We're going to add support for some additional microcontrollers so I'll look into what it will take to add the MEMORY support. But it looks like we'll never actually have those large gaps after all. Thanks again, Ed On Mon, Jul 6, 2015 at 1:50 AM, Rafael Auler <rafaelauler at gmail.com> wrote:> Hi Ed, > > I wrote http://reviews.llvm.org/D10952 to address your last problem. > There is also the related http://reviews.llvm.org/D10918 by Denis to > address how you can directly assign sections to segments in the script. > Both are in code review. > > Rafael auelr > > On Fri, Jul 3, 2015 at 12:29 AM, Rafael Auler <rafaelauler at gmail.com> > wrote: > >> Hi Ed, >> >> It looks like lld is failing at mapping two sections far apart from each >> other into two different segments. Since it puts these two sections (.text >> and .data) in the same ELF segment, the segment is forced to be huge >> because the start addresses of these sections are far apart from each >> other. I would begin by investigating how >> TargetLayout<ELFT>::assignSectionsToSegments() works and go from there. >> This function lives at lld/lib/ReaderWriter/ELF/TargetLayout.cpp. I don't >> believe you can try any other flags to try to get this done without fixing >> this logic. >> >> Rafael Auler >> >> On Wed, Jul 1, 2015 at 12:00 PM, ed at modk.it <ed at modk.it> wrote: >> >>> Hi All, >>> >>> Congratulations on the major progress on the llvm linker lld over the >>> past year including the new linker script support. This really makes it >>> possible to ditch binutils altogether. It looks like lld's MEMORY sections >>> are currently parsed but not evaluated, but so far that hasn't been a >>> problem. >>> >>> The only snag is I can't figure out how to define the start of the .data >>> section in a sane way. Let's say we want our flash (.text) section to >>> start at address 0x20000 with a max size of 0x8000 bytes and a data section >>> start at 0x20005000 with a max length of 0x3000 bytes. We'd usually >>> accomplish this with a combination of MEMORY and SECTION entries in the >>> linker script tied together by region aliases, the "AT" directive and the >>> ">" operator: >>> >>> MEMORY >>> >>> { >>> >>> flash (rx) : ORIGIN = 0x20000, LENGTH = 0x8000 >>> >>> ram (rwx) : ORIGIN = 0x20005000, LENGTH = 0x00003000 >>> >>> } >>> >>> >>> REGION_ALIAS("REGION_TEXT", flash); >>> >>> REGION_ALIAS("REGION_RAM", ram); >>> >>> >>> SECTIONS >>> >>> { >>> >>> .text : >>> >>> { >>> >>> ... >>> >>> } > REGION_TEXT >>> >>> >>> >>> _etext = .; >>> >>> .data : >>> >>> { >>> >>> ... >>> >>> } > REGION_RAM AT > REGION_TEXT >>> >>> >>> } >>> >>> >>> But the MEMORY entries don't seem to be evaluated and ">", "AT", and >>> "REGION_ALIAS" don't seem to be hooked up either. Command line options >>> like "-Tdata=org=0x20005000" or "--section-start=.data= 0x20005000" are >>> also not working. >>> >>> >>> However, the following linker script gets us close: >>> >>> >>> SECTIONS >>> >>> { >>> >>> . = 0x20000; >>> >>> .text : >>> >>> { >>> >>> ... >>> >>> } >>> >>> >>> >>> _etext = .; >>> >>> . = 0x20005000; >>> >>> _data = .; >>> >>> .data : >>> >>> { >>> >>> ... >>> >>> } >>> >>> } >>> >>> >>> The only problem is the resulting elf and binary files are HUGE (e.g. >>> elf is 500mb vs 50k) as the linker seems to be filling the space between >>> the end of text and the beginning of data. A "llvm-readobj -s" on the >>> resulting elf is nearly identical to one created with binutils except >>> binults-ld puts .data at Address: 0x20005000 Offset: 0xD000 and llvm-lld >>> has data at Address: 0x20005000 Offset: 0x1FFED000 (based on start address >>> of 0x18000.) >>> >>> Any thoughts on a supported linker flag or linker script option that can >>> help here? Or a source file to dive into to get something working? I'd be >>> willing to take a pass at completing the MEMORY section implementation if >>> that's the most sane way to move forward but would love a pointer in the >>> right direction. >>> >>> >>> Thanks, >>> >>> Ed >>> >>> >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150706/18665214/attachment.html>
ed at modk.it
2015-Jul-06 14:18 UTC
[LLVMdev] [lld] Current ways to position memory sections (e.g. .text, .data, .bss) with lld?
Raphael, I spoke too soon. While I can produce the correct binary after passing the lld built elf (using binutils objcopy), the elf itself is still way too large. Your patch doesn't seem to work for my case for shrinking the elf. I have a hack that works for our specific case so I'll see if I can figure out what's missing in your general patch. Thanks, Ed On Mon, Jul 6, 2015 at 8:25 AM, ed at modk.it <ed at modk.it> wrote:> Hi Raphael, > > Thanks for the quick responses. I was able to get things working as is. > > It turns out we don't actually want to put the .data segment way up there > where it would be in actual memory, we just wanted a reference to where it > would end up for our c startup routine to move the c initialization data > (this is for baremetal ARM stuff) from it's actual location in flash to > where it would be accessed in ram. But it looks like we can just leave it > in flash. And since .bss takes no space (SHT_NOBITS) we can just set .bss > to the beginning of ram. > > So we end up with something like: > > SECTIONS > > { > > . = 0x20000; > > .text : > > { > > ... > > } > > > > _etext = .; > > _data = .; > > .data : > > { > > ... > > } > > . = 0x20005000; > > .bss : > > { > > ... > > } > > } > > > We're going to add support for some additional microcontrollers so I'll > look into what it will take to add the MEMORY support. But it looks like > we'll never actually have those large gaps after all. > > > Thanks again, > > Ed > > > On Mon, Jul 6, 2015 at 1:50 AM, Rafael Auler <rafaelauler at gmail.com> > wrote: > >> Hi Ed, >> >> I wrote http://reviews.llvm.org/D10952 to address your last problem. >> There is also the related http://reviews.llvm.org/D10918 by Denis to >> address how you can directly assign sections to segments in the script. >> Both are in code review. >> >> Rafael auelr >> >> On Fri, Jul 3, 2015 at 12:29 AM, Rafael Auler <rafaelauler at gmail.com> >> wrote: >> >>> Hi Ed, >>> >>> It looks like lld is failing at mapping two sections far apart from each >>> other into two different segments. Since it puts these two sections (.text >>> and .data) in the same ELF segment, the segment is forced to be huge >>> because the start addresses of these sections are far apart from each >>> other. I would begin by investigating how >>> TargetLayout<ELFT>::assignSectionsToSegments() works and go from there. >>> This function lives at lld/lib/ReaderWriter/ELF/TargetLayout.cpp. I don't >>> believe you can try any other flags to try to get this done without fixing >>> this logic. >>> >>> Rafael Auler >>> >>> On Wed, Jul 1, 2015 at 12:00 PM, ed at modk.it <ed at modk.it> wrote: >>> >>>> Hi All, >>>> >>>> Congratulations on the major progress on the llvm linker lld over the >>>> past year including the new linker script support. This really makes it >>>> possible to ditch binutils altogether. It looks like lld's MEMORY sections >>>> are currently parsed but not evaluated, but so far that hasn't been a >>>> problem. >>>> >>>> The only snag is I can't figure out how to define the start of the >>>> .data section in a sane way. Let's say we want our flash (.text) section >>>> to start at address 0x20000 with a max size of 0x8000 bytes and a data >>>> section start at 0x20005000 with a max length of 0x3000 bytes. We'd >>>> usually accomplish this with a combination of MEMORY and SECTION entries in >>>> the linker script tied together by region aliases, the "AT" directive and >>>> the ">" operator: >>>> >>>> MEMORY >>>> >>>> { >>>> >>>> flash (rx) : ORIGIN = 0x20000, LENGTH = 0x8000 >>>> >>>> ram (rwx) : ORIGIN = 0x20005000, LENGTH = 0x00003000 >>>> >>>> } >>>> >>>> >>>> REGION_ALIAS("REGION_TEXT", flash); >>>> >>>> REGION_ALIAS("REGION_RAM", ram); >>>> >>>> >>>> SECTIONS >>>> >>>> { >>>> >>>> .text : >>>> >>>> { >>>> >>>> ... >>>> >>>> } > REGION_TEXT >>>> >>>> >>>> >>>> _etext = .; >>>> >>>> .data : >>>> >>>> { >>>> >>>> ... >>>> >>>> } > REGION_RAM AT > REGION_TEXT >>>> >>>> >>>> } >>>> >>>> >>>> But the MEMORY entries don't seem to be evaluated and ">", "AT", and >>>> "REGION_ALIAS" don't seem to be hooked up either. Command line options >>>> like "-Tdata=org=0x20005000" or "--section-start=.data= 0x20005000" >>>> are also not working. >>>> >>>> >>>> However, the following linker script gets us close: >>>> >>>> >>>> SECTIONS >>>> >>>> { >>>> >>>> . = 0x20000; >>>> >>>> .text : >>>> >>>> { >>>> >>>> ... >>>> >>>> } >>>> >>>> >>>> >>>> _etext = .; >>>> >>>> . = 0x20005000; >>>> >>>> _data = .; >>>> >>>> .data : >>>> >>>> { >>>> >>>> ... >>>> >>>> } >>>> >>>> } >>>> >>>> >>>> The only problem is the resulting elf and binary files are HUGE (e.g. >>>> elf is 500mb vs 50k) as the linker seems to be filling the space between >>>> the end of text and the beginning of data. A "llvm-readobj -s" on the >>>> resulting elf is nearly identical to one created with binutils except >>>> binults-ld puts .data at Address: 0x20005000 Offset: 0xD000 and llvm-lld >>>> has data at Address: 0x20005000 Offset: 0x1FFED000 (based on start address >>>> of 0x18000.) >>>> >>>> Any thoughts on a supported linker flag or linker script option that >>>> can help here? Or a source file to dive into to get something working? >>>> I'd be willing to take a pass at completing the MEMORY section >>>> implementation if that's the most sane way to move forward but would love a >>>> pointer in the right direction. >>>> >>>> >>>> Thanks, >>>> >>>> Ed >>>> >>>> >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> >>> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150706/0e2caab6/attachment.html>