This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] -Trodata-segment option
ping?
On Tue, Dec 11, 2012 at 4:29 PM, Roland McGrath <mcgrathr@google.com> wrote:
> 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