[PATCH] -Trodata-segment option
Roland McGrath
mcgrathr@google.com
Wed Dec 12 00:30:00 GMT 2012
For *-*-nacl* targets (and other potential SEPARATE_CODE=yes targets), it's
sometimes necessary to override the placement of the read-only data segment
on the command line. Traditionally, this would be done with
--section-start .rodata=ADDR. But for this layout, that really doesn't do
the right thing. When ADDR is a maxpagesize-aligned address as it usually
would be, this results in any orphans-placed sections that precede .rodata
(such as SHT_NOTE sections) being at the default rodata address while
.rodata is elsewhere, yielding two different segments. Similarly, with the
*-*-nacl* special layout (which probably one day ought to be the canonical
layout for any SEPARATE_CODE=yes target, not specific to *-*-nacl*
targets), there is no room for the headers and so the headers-in-rodata
logic breaks down.
What we really want is just an option to specify the address of the
segment, rather than of particular sections--just like -Ttext-segment=...
works better than --section-start .text=... for the common targets.
So this change adds -Trodata-segment in the straightforward way.
Ok for trunk? I'd really like to put this on the 2.23 branch too, even
though it's a new feature. It seems a pretty a simple and harmless
addition, and I need it for production use much sooner than 2.24 will be.
Thanks,
Roland
ld/
* ld.texinfo (Options): Describe -Trodata-segment.
* ldlex.h (enum option_values): Add OPTION_TRODATA_SEGMENT.
* lexsup.c (ld_options, parse_args): Handle -Trodata-segment.
* scripttempl/elf.sc (RODATA_ADDR, SHLIB_RODATA_ADDR): Wrap
SEGMENT_START("rodata-segment", ...) + SIZEOF_HEADERS around the value.
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1837,6 +1837,13 @@ Same as @option{--section-start}, with
@code{.bss}, @code{.data} or
When creating an ELF executable or shared object, it will set the address
of the first byte of the text segment.
+@kindex -Trodata-segment=@var{org}
+@item -Trodata-segment=@var{org}
+@cindex rodata segment origin, cmd line
+When creating an ELF executable or shared object for a target where
+the read-only data is in its own segment separate from the executable
+text, it will set the address of the first byte of the read-only data segment.
+
@kindex --unresolved-symbols
@item --unresolved-symbols=@var{method}
Determine how to handle unresolved symbols. There are four possible
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -68,6 +68,7 @@ enum option_values
OPTION_TDATA,
OPTION_TTEXT,
OPTION_TTEXT_SEGMENT,
+ OPTION_TRODATA_SEGMENT,
OPTION_TRADITIONAL_FORMAT,
OPTION_UR,
OPTION_VERBOSE,
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -441,6 +441,8 @@ static const struct ld_option ld_options[] =
'\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
{ {"Ttext-segment", required_argument, NULL, OPTION_TTEXT_SEGMENT},
'\0', N_("ADDRESS"), N_("Set address of text segment"), ONE_DASH },
+ { {"Trodata-segment", required_argument, NULL, OPTION_TRODATA_SEGMENT},
+ '\0', N_("ADDRESS"), N_("Set address of rodata segment"), ONE_DASH },
{ {"unresolved-symbols=<method>", required_argument, NULL,
OPTION_UNRESOLVED_SYMBOLS},
'\0', NULL, N_("How to handle unresolved symbols. <method> is:\n"
@@ -1191,6 +1193,9 @@ parse_args (unsigned argc, char **argv)
case OPTION_TTEXT_SEGMENT:
set_segment_start (".text-segment", optarg);
break;
+ case OPTION_TRODATA_SEGMENT:
+ set_segment_start (".rodata-segment", optarg);
+ break;
case OPTION_TRADITIONAL_FORMAT:
link_info.traditional_format = TRUE;
break;
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -492,12 +492,26 @@ cat <<EOF
EOF
if test -n "${SEPARATE_CODE}"; then
+ if test -n "${RODATA_ADDR}"; then
+ RODATA_ADDR="\
+SEGMENT_START(\"rodata-segment\", ${RODATA_ADDR}) + SIZEOF_HEADERS"
+ else
+ RODATA_ADDR="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))}"
+ RODATA_ADDR="SEGMENT_START(\"rodata-segment\", ${RODATA_ADDR})"
+ fi
+ if test -n "${SHLIB_RODATA_ADDR}"; then
+ SHLIB_RODATA_ADDR="\
+SEGMENT_START(\"rodata-segment\", ${SHLIB_RODATA_ADDR}) + SIZEOF_HEADERS"
+ else
+ SHLIB_RODATA_ADDR="SEGMENT_START(\"rodata-segment\", ${SHLIB_RODATA_ADDR})"
+ SHLIB_RODATA_ADDR="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
+ fi
cat <<EOF
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
- ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. =
${RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}}
- ${CREATE_SHLIB+${RELOCATING+. =
${SHLIB_RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} -
1))};}}
- ${CREATE_PIE+${RELOCATING+. =
${SHLIB_RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} -
1))};}}
+ ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${RODATA_ADDR};}}}
+ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_RODATA_ADDR};}}
+ ${CREATE_PIE+${RELOCATING+. = ${SHLIB_RODATA_ADDR};}}
EOF
emit_early_ro
emit_dyn
More information about the Binutils
mailing list