RFC: PR 30907: BFD linker option to allow read-only data in code segments
Palmer Dabbelt
palmer@dabbelt.com
Tue Jun 4 17:13:59 GMT 2024
On Tue, 04 Jun 2024 10:02:29 PDT (-0700), Nick Clifton wrote:
> Hi Guys,
>
> Attached is an experimental patch to add new option the bfd linker:
> -z rodata-in-code.
>
> If used the option allows read only data to be placed into a code
> segment. This is only effective if the -z separate-code option is in
> effect. When used it has the ability to reduce the number of loadable
> segments from 4 to 3, which can have a big effect on the overall size
> of an executable. (See PR 30907 for more discussion on this).
>
> Here is an example:
>
> $ cat test.c
> extern int printf (const char *, ...);
> int i = 42;
> const int * j = & i;
> int main (void) { return printf ("hello world %d\n", * j); }
>
> $ gcc test.c -Wl,-z,separate-code
> $ readelf -Wl a.out
> [...]
> LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000510 0x000510 R 0x1000
> LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x000155 0x000155 R E 0x1000
> LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x0000dc 0x0000dc R 0x1000
> LOAD 0x002df8 0x0000000000403df8 0x0000000000403df8 0x000228 0x000230 RW 0x1000
> [...]
> Section to Segment mapping:
> [...]
> 02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
> 03 .init .plt .text .fini
> 04 .rodata .eh_frame_hdr .eh_frame
> 05 .init_array .fini_array .dynamic .got .got.plt .data .bss
>
> $ gcc test.c -Wl,-z,separate-code -Wl,-z,rodata-in-code
> $ readelf -Wl a.out
> [...]
> LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0004d8 0x0004d8 R 0x1000
> LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x0010dc 0x0010dc R E 0x1000
> LOAD 0x002df8 0x0000000000403df8 0x0000000000403df8 0x000228 0x000230 RW 0x1000
> [...]
> Section to Segment mapping:
> [...]
> 02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
> 03 .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
> 04 .init_array .fini_array .dynamic .got .got.plt .data .bss
>
> The patch is incomplete. It does not have any documentation or test
> cases yet. But I wanted to see if the general idea was going to cause
> concern for people, and to see if I had missed anything obvious.
>
> Thoughts, suggestions ?
I'd be slightly worried we mangle things with the mapping symbols in
RISC-V land (and I suppose Arm has something similar). I don't think
there's any fundamental reason that can't be made to work, we'd just
need to give it some testing.
Aside from that it seems like generally a useful concept. In
microcontroller land we spent a lot of time trying to make sure rodata
doesn't eat writable memory. Trying to juggle .rodata and .text mapping
to the same flash can be clunky as it requires linker scripts and users
generally don't understand those, so having an option seems reasonable
to me.
>
> Cheers
> Nick
More information about the Binutils
mailing list