* Help needed - defining the output section order
@ 2005-08-22 11:03 Simon Kissel
2005-08-22 12:03 ` Nick Clifton
2005-08-22 12:11 ` Andreas Schwab
0 siblings, 2 replies; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 11:03 UTC (permalink / raw)
To: binutils
Hi List,
I'm working on a replaceable resource compiler for the FreePascal
(www.freepascal.org) team. I'm mentioning this to clarify that any
"upgrade your gcc", "pascal sucks anyway, use c" kind of answers
won't really help me ;)
After fiddling with this for a few nights, I really need some help
from you binutils gurus out there.
The situation is the following:
I need to link an object file into an ELF executable. This is how the
object file looks like:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 4
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 4
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 4
[ 4] fpc.ressym PROGBITS 00000000 000034 00000f 00 A 0 0 4
[ 5] fpc.resstr PROGBITS 00000000 000044 000000 00 A 0 0 4
[ 6] fpc.reshash PROGBITS 00000000 000044 000040 00 A 0 0 4
[ 7] fpc.resdata PROGBITS 00000000 000084 0005b8 00 A 0 0 4
[ 8] fpc.resspare NOBITS 00000000 00063c 0005b8 00 A 0 0 4
[ 9] .shstrtab STRTAB 00000000 00063c 000067 00 0 0 1
[10] .symtab SYMTAB 00000000 000884 000090 10 11 9 4
[11] .strtab STRTAB 00000000 000914 000001 00 0 0 1
What I need is to have the fpc.* sections in exactly the same order
(or at least have fpc.resspare directly after fpc.resdata) in the
output. Instead I get this:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 080480d4 0000d4 000013 00 A 0 0 1
[ 2] .hash HASH 080480e8 0000e8 000038 04 A 3 0 4
[ 3] .dynsym DYNSYM 08048120 000120 000090 10 A 4 1 4
[ 4] .dynstr STRTAB 080481b0 0001b0 00007f 00 A 0 0 1
[ 5] .gnu.version VERSYM 08048230 000230 000012 02 A 3 0 2
[ 6] .gnu.version_r VERNEED 08048244 000244 000020 00 A 4 1 4
[ 7] .rel.dyn REL 08048264 000264 000008 08 A 3 0 4
[ 8] .rel.plt REL 0804826c 00026c 000040 08 A 3 a 4
[ 9] .init PROGBITS 080482ac 0002ac 000034 00 AX 0 0 4
[10] .plt PROGBITS 080482e0 0002e0 000090 04 AX 0 0 4
[11] .text PROGBITS 08048370 000370 028ec4 00 AX 0 0 4
[12] .fini PROGBITS 08071234 029234 00001f 00 AX 0 0 4
[13] fpc.ressym PROGBITS 08071254 029254 00000f 00 A 0 0 4
[14] fpc.resstr PROGBITS 08071264 029264 000000 00 A 0 0 4
[15] fpc.reshash PROGBITS 08071264 029264 000040 00 A 0 0 4
[16] fpc.resdata PROGBITS 080712a4 0292a4 0005b8 00 A 0 0 4
[17] .eh_frame PROGBITS 08072000 02a000 000004 00 WA 0 0 4
[18] .ctors PROGBITS 08072004 02a004 000008 00 WA 0 0 4
[19] .dtors PROGBITS 0807200c 02a00c 000008 00 WA 0 0 4
[20] .dynamic DYNAMIC 08072014 02a014 0000c8 08 WA 4 0 4
[21] .got PROGBITS 080720dc 02a0dc 000004 04 WA 0 0 4
[22] .got.plt PROGBITS 080720e0 02a0e0 00002c 04 WA 0 0 4
[23] .data PROGBITS 0807210c 02a10c 00b450 00 WA 0 0 4
[24] .bss NOBITS 0807d560 03555c 001dd8 00 WA 0 0 16
[25] fpc.resspare NOBITS 0807f338 03555c 0005b8 00 A 0 0 4
[26] .comment PROGBITS 00000000 03555c 000098 00 0 0 1
[27] .note NOTE 00000000 0355f4 000050 00 0 0 1
[28] .shstrtab STRTAB 00000000 035644 0000ed 00 0 0 1
As you can see, fpc.resspare got moved away, probably because it's of
NOBITS type.
Now the big questions is: Is there any way to force ld to put the fpc.resspare
section after fpc.resdata?
From reading the docs it appeared to me that possibly using a SECTIONS
command in the linker script might do the trick - so added the
following to the end of the linker script:
SECTIONS{
fpc.ressym : { *(fpc.ressym) }
fpc.resstr : { *(fpc.resstr) }
fpc.reshash : { *(fpc.reshash) }
fpc.resdata : { *(fpc.resdata) }
fpc.resspare : { *(fpc.resspare) }
}
Sadly this only results in
"Not enough room for program headers (allocated 5, need 6)" and "final
link failed: Bad value".
Here's the really simple linker script. I know it's ugly, that's
because it's auto-generated by the compiler. Don't be shocked of the
c:\crossfpc\... stuff, this is GNU ld version 2.15.94 20050118 used
for cross-compiling/linking ELF under Windows) ;)
SEARCH_DIR(C:\crossfpc\lib\)
SEARCH_DIR(.\)
SEARCH_DIR(C:\crossfpc\fpcunits\i386-linux\rtl\)
SEARCH_DIR(C:\crossfpc\kylixcompat\)
INPUT(
C:\crossfpc\fpcunits\i386-linux\rtl\cprt21.o
C:\crossfpc\lib\crtbegin.o
C:\crossfpc\lib\crti.o
res.o
C:\crossfpc\fpcunits\i386-linux\rtl\system.o
C:\crossfpc\fpcunits\i386-linux\rtl\objpas.o
C:\crossfpc\fpcunits\i386-linux\rtl\cmem.o
C:\crossfpc\fpcunits\i386-linux\rtl\sysutils.o
C:\crossfpc\fpcunits\i386-linux\rtl\unix.o
C:\crossfpc\fpcunits\i386-linux\rtl\errors.o
C:\crossfpc\fpcunits\i386-linux\rtl\sysconst.o
C:\crossfpc\fpcunits\i386-linux\rtl\unixtype.o
C:\crossfpc\fpcunits\i386-linux\rtl\baseunix.o
C:\crossfpc\fpcunits\i386-linux\rtl\strings.o
C:\crossfpc\fpcunits\i386-linux\rtl\syscall.o
)
GROUP(
C:\crossfpc\examples\resources\libptestres.a
)
INPUT(
-lc
)
INPUT(
C:\crossfpc\lib\crtend.o
C:\crossfpc\lib\crtn.o
)
Using this script works, but will change the section order of res.o as
explained above. Adding the SECTIONS stuff listed above to the end of
the script gives the error message above.
Any pointers on how to achieve my goal would be very welcome. If you
instead wish me to explain "the bigger picture" (WHY I need this),
I'll be happy to do that, too.
Thank you,
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 11:03 Help needed - defining the output section order Simon Kissel
@ 2005-08-22 12:03 ` Nick Clifton
2005-08-22 13:11 ` Re[2]: " Simon Kissel
` (2 more replies)
2005-08-22 12:11 ` Andreas Schwab
1 sibling, 3 replies; 16+ messages in thread
From: Nick Clifton @ 2005-08-22 12:03 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils
Hi Simon,
> Now the big questions is: Is there any way to force ld to put the fpc.resspare
> section after fpc.resdata?
Yes - use the SECTIONS command in the linker script...
> From reading the docs it appeared to me that possibly using a SECTIONS
> command in the linker script might do the trick - so added the
> following to the end of the linker script:
>
> SECTIONS{
> fpc.ressym : { *(fpc.ressym) }
> fpc.resstr : { *(fpc.resstr) }
> fpc.reshash : { *(fpc.reshash) }
> fpc.resdata : { *(fpc.resdata) }
> fpc.resspare : { *(fpc.resspare) }
> }
>
> Sadly this only results in
> "Not enough room for program headers (allocated 5, need 6)" and "final
> link failed: Bad value".
Ah well, that is because your new linker script is too simple. There is
a section in the linker documentation that talks about this problem:
When producing an ELF output file, if the linker script uses
the SIZEOF_HEADERS builtin function, the linker must compute
the number of program headers before it has determined all
the section addresses and sizes. If the linker later
discovers that it needs additional program headers, it will
report an error "not enough room for program headers". To
avoid this error, you must avoid using the SIZEOF_HEADERS
function, or you must rework your linker script to avoid
forcing the linker to use additional program headers, or
you must define the program headers yourself using the
PHDRS command.
So what you probably need to do is to add a PHDRS command to your linker
script.
Plus what you probably really want to do is to find out the default
script used by the linker (by running ld --verbose) and then take the
SECTIONS command from there and merge in your fpc.* sections. The
SECTIONS command in the default script will probably be a lot more
comprehensive than the one that you are currently using.
Cheers
Nick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 11:03 Help needed - defining the output section order Simon Kissel
2005-08-22 12:03 ` Nick Clifton
@ 2005-08-22 12:11 ` Andreas Schwab
2005-08-22 13:18 ` Re[2]: " Simon Kissel
1 sibling, 1 reply; 16+ messages in thread
From: Andreas Schwab @ 2005-08-22 12:11 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils
Simon Kissel <scamp@untergrund.net> writes:
> From reading the docs it appeared to me that possibly using a SECTIONS
> command in the linker script might do the trick - so added the
> following to the end of the linker script:
>
> SECTIONS{
> fpc.ressym : { *(fpc.ressym) }
> fpc.resstr : { *(fpc.resstr) }
> fpc.reshash : { *(fpc.reshash) }
> fpc.resdata : { *(fpc.resdata) }
> fpc.resspare : { *(fpc.resspare) }
> }
You could try to put all fpc.* sections in a single output section.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, MaxfeldstraÃe 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-22 12:03 ` Nick Clifton
@ 2005-08-22 13:11 ` Simon Kissel
2005-08-22 13:35 ` Simon Kissel
2005-08-24 8:12 ` Segher Boessenkool
2 siblings, 0 replies; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 13:11 UTC (permalink / raw)
To: Nick Clifton; +Cc: binutils
Hi Nick,
NC> Yes - use the SECTIONS command in the linker script...
In this case it would keep it in the order as the sections are listed
in the SECTIONS command? That would be cool.
NC> Ah well, that is because your new linker script is too simple. There is
NC> a section in the linker documentation that talks about this problem:
NC> When producing an ELF output file, if the linker script uses
NC> the SIZEOF_HEADERS builtin function, the linker must compute
NC> the number of program headers before it has determined all
NC> the section addresses and sizes. If the linker later
NC> discovers that it needs additional program headers, it will
NC> report an error "not enough room for program headers". To
NC> avoid this error, you must avoid using the SIZEOF_HEADERS
NC> function, or you must rework your linker script to avoid
NC> forcing the linker to use additional program headers, or
NC> you must define the program headers yourself using the
NC> PHDRS command.
...well, that part of the docs doesn't say "If you use the SECTIONS
command, generation of program headers will fail" ;)
(But this is a completely different topic)
NC> So what you probably need to do is to add a PHDRS command to your linker
NC> script.
Ok, that looks really complex. But if there is no other way, I'll try
to go and survive that route.
NC> Plus what you probably really want to do is to find out the default
NC> script used by the linker (by running ld --verbose) and then take the
NC> SECTIONS command from there and merge in your fpc.* sections. The
NC> SECTIONS command in the default script will probably be a lot more
NC> comprehensive than the one that you are currently using.
I'll try that first and report back.
Thank you,
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-22 12:11 ` Andreas Schwab
@ 2005-08-22 13:18 ` Simon Kissel
0 siblings, 0 replies; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 13:18 UTC (permalink / raw)
To: Andreas Schwab; +Cc: binutils
Hello Andreas,
>> From reading the docs it appeared to me that possibly using a SECTIONS
>> command in the linker script might do the trick - so added the
>> following to the end of the linker script:
>>
>> SECTIONS{
>> fpc.ressym : { *(fpc.ressym) }
>> fpc.resstr : { *(fpc.resstr) }
>> fpc.reshash : { *(fpc.reshash) }
>> fpc.resdata : { *(fpc.resdata) }
>> fpc.resspare : { *(fpc.resspare) }
>> }
AS> You could try to put all fpc.* sections in a single output section.
No, this doesn't help. They need to be in separated sections.
Here's why:
First of all: The goal was to implement a replaceable resource system
for FPC's ELF flavors that is similar to Kylix ones.
The goals in particular were:
- Resources can be embedded into the executable by the compiler
- Resources can be accessed from inside the executable at runtime
- It's possible to add, extract and change resources in a compiled
executable.
The ELF binary format doesn't really provide support for all this.
Most importantly it does not support resizing of sections in the
binary.
This is solved in Kylix (and now for FPC) the following way: Inside
the ELF binary there are a bunch of new sections, holding the
resources, their names, pointers to the sections - and, here is the
clever trick: A spare section that has 0 bytes saved in the exe, but
is marked as the same size as the currently embedded resources are
(this is possible in ELF). It directly follows the section that has
the resource data. Now, if after compiling the resources are changed,
both the resource data section and the spare section get resized. This
means that at maxmimum, you can double the size of the resources in an
exisiting exe. This always should be enough headroom. It's important
to point out, that the spare section does not take up any space. It's
just that empty address room of the same size as the current resource
data get's reserved, which later can be re-used.
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-22 12:03 ` Nick Clifton
2005-08-22 13:11 ` Re[2]: " Simon Kissel
@ 2005-08-22 13:35 ` Simon Kissel
2005-08-22 14:00 ` Nick Clifton
2005-08-22 14:03 ` Nick Clifton
2005-08-24 8:12 ` Segher Boessenkool
2 siblings, 2 replies; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 13:35 UTC (permalink / raw)
To: Nick Clifton; +Cc: binutils
Hi Nick,
NC> Plus what you probably really want to do is to find out the default
NC> script used by the linker (by running ld --verbose) and then take the
NC> SECTIONS command from there and merge in your fpc.* sections. The
NC> SECTIONS command in the default script will probably be a lot more
NC> comprehensive than the one that you are currently using.
What I now tried was to simply take the internal linker script
displayed using --verbose and put it at the end (also tried at the
beginning) of my linker script.
The interesting part is now that ld chokes on the exact same script
it uses internally (at least it says so), when it gets fed with it
from the outside:
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.dyn :
{
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data.rel.ro*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
}
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
}
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init :
{
KEEP (*(.init))
} =0x90909090
.plt : { *(.plt) }
.text :
{
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
} =0x90909090
.fini :
{
KEEP (*(.fini))
} =0x90909090
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { KEEP (*(.preinit_array)) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { KEEP (*(.init_array)) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { KEEP (*(.fini_array)) }
PROVIDE (__fini_array_end = .);
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin*.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin*.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) }
. = DATA_SEGMENT_RELRO_END (12, .);
.got.plt : { *(.got.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/DISCARD/ : { *(.note.GNU-stack) }
}
And LD reports "invalid assignment to location counter" on the line
that follows the last }.
I think I'm in need for a little more help here :)
(Also, I still would love to hear an alternative solution that does
not require the compiler to generate all LD default scripts for each
platform itself - this sounds like the direct way to version hell).
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 13:35 ` Simon Kissel
@ 2005-08-22 14:00 ` Nick Clifton
2005-08-22 14:35 ` Re[2]: " Simon Kissel
2005-08-22 14:03 ` Nick Clifton
1 sibling, 1 reply; 16+ messages in thread
From: Nick Clifton @ 2005-08-22 14:00 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils
Hi Simon,
> (Also, I still would love to hear an alternative solution that does
> not require the compiler to generate all LD default scripts for each
> platform itself - this sounds like the direct way to version hell).
Ok - how about using objcopy and the --add-section and --remove-section
switches ? When you need to resize the fpc.* sections you could use
--remove-section to strip the old ones of the executable and then
--add-section to add in the new ones. Of course this assumes that you
have some way of recreating the contents of these sections since the
--add-section switch just reads in a file and dumps its contents into
the newly created section.
Cheers
Nick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 13:35 ` Simon Kissel
2005-08-22 14:00 ` Nick Clifton
@ 2005-08-22 14:03 ` Nick Clifton
2005-08-22 14:17 ` Re[2]: " Simon Kissel
1 sibling, 1 reply; 16+ messages in thread
From: Nick Clifton @ 2005-08-22 14:03 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils
Hi Simon,
> What I now tried was to simply take the internal linker script
> displayed using --verbose and put it at the end (also tried at the
> beginning) of my linker script.
Are you using the -T linker command line switch so that your new script
*overrides* the old linker script or are you just putting the name of
the file containing the script on the linker command line ? In the
latter case the linker will treat it as an *additional* linker script to
be used in addition to the builtin script which will cause all kinds of
problems.
Cheers
Nick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-22 14:03 ` Nick Clifton
@ 2005-08-22 14:17 ` Simon Kissel
2005-08-22 14:58 ` Nick Clifton
0 siblings, 1 reply; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 14:17 UTC (permalink / raw)
To: Nick Clifton; +Cc: binutils
Hi Nick,
>> What I now tried was to simply take the internal linker script
>> displayed using --verbose and put it at the end (also tried at the
>> beginning) of my linker script.
NC> Are you using the -T linker command line switch so that your new script
NC> *overrides* the old linker script or are you just putting the name of
NC> the file containing the script on the linker command line ? In the
NC> latter case the linker will treat it as an *additional* linker script to
NC> be used in addition to the builtin script which will cause all kinds of
NC> problems.
Oops. That was indeed the problem. With -T it now eats it's script
just fine.
Sadly if I add my
fpc.ressym : { *(fpc.ressym) }
fpc.resstr : { *(fpc.resstr) }
fpc.reshash : { *(fpc.reshash) }
fpc.resdata : { *(fpc.resdata) }
fpc.resspare : { *(fpc.resspare) }
block to it, I'm back at "Not enough room for program headers
(allocated 5, need 6)". Darn ;)
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-22 14:00 ` Nick Clifton
@ 2005-08-22 14:35 ` Simon Kissel
0 siblings, 0 replies; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 14:35 UTC (permalink / raw)
To: binutils
[Forgot the copy for the list, sorry]
Hi Nick,
>> (Also, I still would love to hear an alternative solution that does
>> not require the compiler to generate all LD default scripts for each
>> platform itself - this sounds like the direct way to version hell).
NC> Ok - how about using objcopy and the --add-section and --remove-section
NC> switches ? When you need to resize the fpc.* sections you could use
NC> --remove-section to strip the old ones of the executable and then
NC> --add-section to add in the new ones. Of course this assumes that you
NC> have some way of recreating the contents of these sections since the
NC> --add-section switch just reads in a file and dumps its contents into
NC> the newly created section.
I have to admit I've got next to no knowledge about objcopy. But
looking at it from the ELF perspective, my logic says to me this can't
work: If one would change the size of a section when replacing it,
sections after it in the ELF would need be relocated. And this again
could only theoretically work if the symbols would still be present
and not stripped.
That's the whole concept behind what I'm trying to achieve - as we
know that it's impossible to resize sections in an ELF executable, we
use a NOBITS section directly following the section containing the
resource data. This way we can make sure there is address space
available in case we later wish to increase the size of the section
containing the resources. Changing the size now simply is a matter of
increasing the size of the resource data section, decreasing the size of the
NOBITS section, and changing the file offsets of the sections after
it - the load addresses of all sections remain unchanged, and
therefore relocation isn't needed.
That's what Borland has implemented on Linux for Kylix. However, they
wrote their own ELF linker to do that. And I'm now trying to achieve
the same thing WITHOUT having to write an own linker ;)
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 14:17 ` Re[2]: " Simon Kissel
@ 2005-08-22 14:58 ` Nick Clifton
2005-08-22 22:27 ` Re[2]: " Simon Kissel
0 siblings, 1 reply; 16+ messages in thread
From: Nick Clifton @ 2005-08-22 14:58 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils
Hi Simon,
> Sadly if I add my
> fpc.ressym : { *(fpc.ressym) }
> fpc.resstr : { *(fpc.resstr) }
> fpc.reshash : { *(fpc.reshash) }
> fpc.resdata : { *(fpc.resdata) }
> fpc.resspare : { *(fpc.resspare) }
> block to it, I'm back at "Not enough room for program headers
> (allocated 5, need 6)". Darn ;)
Right, but now you have a single script which contains a big SECTIONS
command which handles everything and to which you can add a PHDR command.
Creating the PHDRS command should not be too bad. Just take the linked
executable with the fpc.* sections in the wrong place and run "readelf
-l" on it. This should display the program headers for the executable.
Now all you have to do is to translate this information into a PHDRS
command and add an extra header.
Here's an example from running this command on my local system:
$ readelf -l `which readelf`
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x2fbdc 0x2fbdc R E 0x1000
LOAD 0x02fbdc 0x08078bdc 0x08078bdc 0x005b8 0x01218 RW 0x1000
DYNAMIC 0x02fbf0 0x08078bf0 0x08078bf0 0x000c8 0x000c8 RW 0x4
NOTE 0x000148 0x08048148 0x08048148 0x00020 0x00020 R 0x4
GNU_EH_FRAME 0x02fb64 0x08077b64 0x08077b64 0x0001c 0x0001c R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
Which turns into:
PHDRS
{
headers PT_PHDR PHDRS ;
interp PT_INTERP ;
text PT_LOAD FILEHDR ;
data PT_LOAD ;
dynamic PT_DYNAMIC ;
note PT_NOTE ;
gnu_eh_frame 0xa74e550 ;
gnu_stack 0xa74e551 ;
extra PT_LOAD ;
}
Note - I had to use numbers for the header types not supported by the
linker script syntax. You will probably not need to do this.
You may then find that you need to add ":<phdr-name>" to various parts
of the SECTIONS command, especially the fpc.* assignments. eg:
fpc.ressym : { *(fpc.ressym) } :extra
fpc.resstr : { *(fpc.resstr) } :extra
fpc.reshash : { *(fpc.reshash) } :extra
fpc.resdata : { *(fpc.resdata) } :extra
fpc.resspare : { *(fpc.resspare) } :extra
Cheers
Nick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-22 14:58 ` Nick Clifton
@ 2005-08-22 22:27 ` Simon Kissel
2005-08-23 8:19 ` Nick Clifton
0 siblings, 1 reply; 16+ messages in thread
From: Simon Kissel @ 2005-08-22 22:27 UTC (permalink / raw)
To: Nick Clifton; +Cc: binutils
Hi Nick,
NC> Which turns into:
NC> PHDRS
NC> {
NC> headers PT_PHDR PHDRS ;
NC> interp PT_INTERP ;
NC> text PT_LOAD FILEHDR ;
NC> data PT_LOAD ;
NC> dynamic PT_DYNAMIC ;
NC> note PT_NOTE ;
NC> gnu_eh_frame 0xa74e550 ;
NC> gnu_stack 0xa74e551 ;
NC> extra PT_LOAD ;
NC> }
Ok, so I tried this.
Here is the script:
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS;
[...etc, the copied default ld script for elf_i386]
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/DISCARD/ : { *(.note.GNU-stack) }
fpc.ressym : { *(fpc.ressym) } :extra
fpc.resstr : { *(fpc.resstr) } :extra
fpc.reshash : { *(fpc.reshash) } :extra
fpc.resdata : { *(fpc.resdata) } :extra
fpc.resspare : { *(fpc.resspare) } :extra
}
PHDRS
{
headers PT_PHDR PHDRS ;
interp PT_INTERP ;
text PT_LOAD FILEHDR ;
data PT_LOAD ;
dynamic PT_DYNAMIC ;
extra PT_LOAD ;
}
SEARCH_DIR(.\)
[...and so on]
INPUT(
[...and so on]
)
Well, it works. Sort of. The resulting executable now is >130 MB in
size, and completely broken:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00001034 0x00000000 0x000c0 0x000c0 R 0x4
INTERP 0x000000 0x00000000 0x00000000 0x00000 0x00000 0x4
[Requesting program interpreter: ¦ELF???]
LOAD 0x000000 0x00000000 0x00000000 0x000f4 0x000f4 R 0x1000
LOAD 0x0000f4 0x00000000 0x00000000 0x00000 0x00000 0x1000
DYNAMIC 0x000000 0x00000000 0x00000000 0x00000 0x00000 0x4readelf:
Warning: the .dynamic section is not contained within the dynamic segment
LOAD 0x001098 0x00000098 0x00000098 0x807d738 0x8080510 RWE 0x1000
Hrmm?! ;)
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 22:27 ` Re[2]: " Simon Kissel
@ 2005-08-23 8:19 ` Nick Clifton
0 siblings, 0 replies; 16+ messages in thread
From: Nick Clifton @ 2005-08-23 8:19 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils
Hi Simon,
> Here is the script:
> PHDRS
> {
> headers PT_PHDR PHDRS ;
> interp PT_INTERP ;
> text PT_LOAD FILEHDR ;
> data PT_LOAD ;
> dynamic PT_DYNAMIC ;
> extra PT_LOAD ;
> }
> Well, it works. Sort of. The resulting executable now is >130 MB in
> size, and completely broken:
Oh well. It looks like you will need to sprinkle :text and :data
liberally through the SECTIONS command then to make sure that sections
are placed into the right segments.
Cheers
Nick
PS. Yes this is difficult but then you are trying to make the linker do
something that it was not designed to do. :-(
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Help needed - defining the output section order
2005-08-22 12:03 ` Nick Clifton
2005-08-22 13:11 ` Re[2]: " Simon Kissel
2005-08-22 13:35 ` Simon Kissel
@ 2005-08-24 8:12 ` Segher Boessenkool
2005-08-24 15:43 ` Re[2]: " Simon Kissel
2 siblings, 1 reply; 16+ messages in thread
From: Segher Boessenkool @ 2005-08-24 8:12 UTC (permalink / raw)
To: Nick Clifton; +Cc: binutils, Simon Kissel
>> Sadly this only results in
>> "Not enough room for program headers (allocated 5, need 6)" and "final
>> link failed: Bad value".
>
> Ah well, that is because your new linker script is too simple. There
> is a section in the linker documentation that talks about this
> problem:
[snip]
> So what you probably need to do is to add a PHDRS command to your
> linker script.
It might be enough if you prevent ld from creating the magic stack
segment behind its own back, e.g., I have this in my Makefiles:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ && $(OBJCOPY) -R .note.GNU-stack $@
(using /DISCARD/ in your linker script is _not_ enough).
Segher
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Help needed - defining the output section order
2005-08-24 8:12 ` Segher Boessenkool
@ 2005-08-24 15:43 ` Simon Kissel
2005-08-24 15:55 ` Segher Boessenkool
0 siblings, 1 reply; 16+ messages in thread
From: Simon Kissel @ 2005-08-24 15:43 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Nick Clifton, binutils
Hello Segher,
Wednesday, August 24, 2005, 9:30:08 AM, you wrote:
SB> [snip]
>> So what you probably need to do is to add a PHDRS command to your
>> linker script.
SB> It might be enough if you prevent ld from creating the magic stack
SB> segment behind its own back, e.g., I have this in my Makefiles:
SB> %.o: %.c
SB> $(CC) $(CFLAGS) -c $< -o $@ && $(OBJCOPY) -R .note.GNU-stack $@
SB> (using /DISCARD/ in your linker script is _not_ enough).
This sounds very interesting - however, I have to admit I don't know
much about makefile syntax and/or gcc options - I'm a pascal guy,
after all ;). To which ld options would this translate to?
Thanks,
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[2]: Help needed - defining the output section order
2005-08-24 15:43 ` Re[2]: " Simon Kissel
@ 2005-08-24 15:55 ` Segher Boessenkool
0 siblings, 0 replies; 16+ messages in thread
From: Segher Boessenkool @ 2005-08-24 15:55 UTC (permalink / raw)
To: Simon Kissel; +Cc: binutils, Nick Clifton
> SB> It might be enough if you prevent ld from creating the magic stack
> SB> segment behind its own back, e.g., I have this in my Makefiles:
>
> SB> %.o: %.c
> SB> $(CC) $(CFLAGS) -c $< -o $@ && $(OBJCOPY) -R
> .note.GNU-stack $@
>
> SB> (using /DISCARD/ in your linker script is _not_ enough).
>
> This sounds very interesting - however, I have to admit I don't know
> much about makefile syntax and/or gcc options - I'm a pascal guy,
> after all ;). To which ld options would this translate to?
Not an ld option; instead, you run an objcopy command on every
object file, before you link them together. An example is
objcopy -R .note.GNU-stack example.o
Do this on _every_ object file that is used in the link.
Some background: if ld sees a .note.GNU-stack note section in
all of the input files, it puts a GNU_STACK segment into the
output file automagically. Linux uses this information to make
the stack non-executable. But this automatic generation of a
PHDR seems to screw up the precomputed count of PHDRS. Maybe
we can call this a bug, even?
Segher
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2005-08-24 15:55 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-22 11:03 Help needed - defining the output section order Simon Kissel
2005-08-22 12:03 ` Nick Clifton
2005-08-22 13:11 ` Re[2]: " Simon Kissel
2005-08-22 13:35 ` Simon Kissel
2005-08-22 14:00 ` Nick Clifton
2005-08-22 14:35 ` Re[2]: " Simon Kissel
2005-08-22 14:03 ` Nick Clifton
2005-08-22 14:17 ` Re[2]: " Simon Kissel
2005-08-22 14:58 ` Nick Clifton
2005-08-22 22:27 ` Re[2]: " Simon Kissel
2005-08-23 8:19 ` Nick Clifton
2005-08-24 8:12 ` Segher Boessenkool
2005-08-24 15:43 ` Re[2]: " Simon Kissel
2005-08-24 15:55 ` Segher Boessenkool
2005-08-22 12:11 ` Andreas Schwab
2005-08-22 13:18 ` Re[2]: " Simon Kissel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).