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