diff options
-rw-r--r-- | ld/ChangeLog | 22 | ||||
-rw-r--r-- | ld/emulparams/elf32ppc.sh | 9 | ||||
-rw-r--r-- | ld/emultempl/ppc32elf.em | 77 | ||||
-rw-r--r-- | ld/ldgram.y | 3 | ||||
-rw-r--r-- | ld/ldlang.c | 7 | ||||
-rw-r--r-- | ld/ldlex.l | 1 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 29 |
7 files changed, 135 insertions, 13 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 5da5097..e9d188c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,23 @@ +2005-05-11 Alan Modra <amodra@bigpond.net.au> + + * ldgram.y: Add SPECIAL token. + (sect_constraint): Handle SPECIAL. + * ldlang.c (lang_output_section_find_1): Don't match SPECIAL. + (map_input_to_output_sections): Likewise. + * ldlex.l (SPECIAL): Define. + * emulparams/elf32ppc.sh (DATA_GOT, SDATA_GOT, SEPARATE_GOTPLT, + GOT, PLT, GOTPLT): Define. + * emultempl/ppc32elf.em (old_plt, old_got): New static vars. + (ppc_after_open): New function. + (PARSE_AND_LIST_PROLOGUE): Define OPTION_OLD_LPT and OPTION_OLD_GOT. + (PARSE_AND_LIST_LONGOPTS): Add "bss-plt" and "sdata-got". + (PARSE_AND_LIST_OPTIONS): Document them. + (PARSE_AND_LIST_ARGS_CASES): Handle them. + (LDEMUL_AFTER_OPEN): Define. + * scripttempl/elf.sc (PLT): Don't override existing define. + (DATA_GOT, SDATA_GOT): Define and use to enable alternate got + placement rather than using NO_SMALL_DATA. Emit GOTPLT for RELRO_NOW. + 2005-05-10 Alan Modra <amodra@bigpond.net.au> * scripttempl/elf.sc (DATA_SEGMENT_RELRO_GOTPLT_END): Delete. @@ -164,7 +184,7 @@ 2005-04-07 Nick Clifton <nickc@redhat.com> * emultempl/m68kcoff.em: Include ldexp.h and ldlang.h so that - ldfile.h can use the lang_input_statement type. + ldfile.h can use the lang_input_statement type. 2005-04-06 Jakub Jelinek <jakub@redhat.com> diff --git a/ld/emulparams/elf32ppc.sh b/ld/emulparams/elf32ppc.sh index 3e5224f..5a38aed 100644 --- a/ld/emulparams/elf32ppc.sh +++ b/ld/emulparams/elf32ppc.sh @@ -12,7 +12,16 @@ MAXPAGESIZE=0x10000 COMMONPAGESIZE=0x1000 ARCH=powerpc:common MACHINE= +# Yes, we want duplicate .got and .plt sections. The linker chooses the +# appropriate one magically in ppc_after_open +DATA_GOT= +SDATA_GOT= +SEPARATE_GOTPLT=0 BSS_PLT= +GOT=".got ${RELOCATING-0} : SPECIAL { *(.got) }" +PLT=".plt ${RELOCATING-0} : SPECIAL { *(.plt) }" +GOTPLT="${PLT}" +OTHER_TEXT_SECTIONS="*(.glink)" EXECUTABLE_SYMBOLS='PROVIDE (__stack = 0); PROVIDE (___stack = 0);' OTHER_BSS_END_SYMBOLS='__end = .;' OTHER_RELRO_SECTIONS=" diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em index 710160d..cbd77ac 100644 --- a/ld/emultempl/ppc32elf.em +++ b/ld/emultempl/ppc32elf.em @@ -32,6 +32,66 @@ extern const bfd_target bfd_elf32_powerpcle_vec; /* Whether to run tls optimization. */ static int notlsopt = 0; +/* Chooses the correct place for .plt and .got. */ +static int old_plt = 0; +static int old_got = 0; + +static void +ppc_after_open (void) +{ + if (link_info.hash->creator == &bfd_elf32_powerpc_vec + || link_info.hash->creator == &bfd_elf32_powerpcle_vec) + { + int new_plt; + int keep_new; + unsigned int num_plt; + unsigned int num_got; + lang_output_section_statement_type *os; + lang_output_section_statement_type *plt_os[2]; + lang_output_section_statement_type *got_os[2]; + + new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt); + if (new_plt < 0) + einfo ("%X%P: select_plt_layout problem %E\n"); + + num_got = 0; + num_plt = 0; + for (os = &lang_output_section_statement.head->output_section_statement; + os != NULL; + os = os->next) + { + if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0) + { + if (num_plt < 2) + plt_os[num_plt] = os; + ++num_plt; + } + if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0) + { + if (num_got < 2) + got_os[num_got] = os; + ++num_got; + } + } + + keep_new = new_plt == 1 ? 0 : -1; + if (num_plt == 2) + { + plt_os[0]->constraint = keep_new; + plt_os[1]->constraint = ~keep_new; + } + if (num_got == 2) + { + if (old_got) + keep_new = -1; + got_os[0]->constraint = keep_new; + got_os[1]->constraint = ~keep_new; + } + } + + gld${EMULATION_NAME}_after_open (); +} + static void ppc_before_allocation (void) { @@ -68,15 +128,21 @@ EOF # PARSE_AND_LIST_PROLOGUE=' #define OPTION_NO_TLS_OPT 301 +#define OPTION_OLD_PLT 302 +#define OPTION_OLD_GOT 303 ' PARSE_AND_LIST_LONGOPTS=' { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT }, + { "bss-plt", no_argument, NULL, OPTION_OLD_PLT }, + { "sdata-got", no_argument, NULL, OPTION_OLD_GOT }, ' PARSE_AND_LIST_OPTIONS=' fprintf (file, _("\ - --no-tls-optimize Don'\''t try to optimize TLS accesses.\n" + --no-tls-optimize Don'\''t try to optimize TLS accesses.\n\ + --bss-plt Force old-style BSS PLT.\n\ + --sdata-got Force GOT location just before .sdata.\n" )); ' @@ -84,9 +150,18 @@ PARSE_AND_LIST_ARGS_CASES=' case OPTION_NO_TLS_OPT: notlsopt = 1; break; + + case OPTION_OLD_PLT: + old_plt = 1; + break; + + case OPTION_OLD_GOT: + old_got = 1; + break; ' # Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation # +LDEMUL_AFTER_OPEN=ppc_after_open LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation diff --git a/ld/ldgram.y b/ld/ldgram.y index fefd7bc..d24ad07 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -151,7 +151,7 @@ static int error_index; %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START %token <name> VERS_TAG VERS_IDENTIFIER %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT -%token KEEP ONLY_IF_RO ONLY_IF_RW +%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL %token EXCLUDE_FILE %type <versyms> vers_defns %type <versnode> vers_tag @@ -899,6 +899,7 @@ opt_subalign: sect_constraint: ONLY_IF_RO { $$ = ONLY_IF_RO; } | ONLY_IF_RW { $$ = ONLY_IF_RW; } + | SPECIAL { $$ = SPECIAL; } | { $$ = 0; } ; diff --git a/ld/ldlang.c b/ld/ldlang.c index 453b7ac..c7310d7 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -991,7 +991,9 @@ lang_output_section_find_1 (const char *const name, int constraint) { if (strcmp (name, lookup->name) == 0 && lookup->constraint != -1 - && (constraint == 0 || constraint == lookup->constraint)) + && (constraint == 0 + || (constraint == lookup->constraint + && constraint != SPECIAL))) return lookup; } return NULL; @@ -2951,7 +2953,8 @@ map_input_to_output_sections case lang_output_section_statement_enum: if (s->output_section_statement.constraint) { - if (s->output_section_statement.constraint == -1) + if (s->output_section_statement.constraint != ONLY_IF_RW + && s->output_section_statement.constraint != ONLY_IF_RO) break; s->output_section_statement.all_input_readonly = TRUE; check_input_sections (s->output_section_statement.children.head, @@ -303,6 +303,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* <EXPRESSION,BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);} <EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RO" { RTOKEN(ONLY_IF_RO); } <EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RW" { RTOKEN(ONLY_IF_RW); } +<EXPRESSION,BOTH,SCRIPT>"SPECIAL" { RTOKEN(SPECIAL); } <BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);} <BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);} <BOTH,SCRIPT>"l" { RTOKEN( LENGTH);} diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index c2a2dcf..3e0f0b0 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -101,7 +101,9 @@ if test -n "${COMMONPAGESIZE}"; then DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);" fi INTERP=".interp ${RELOCATING-0} : { *(.interp) }" -PLT=".plt ${RELOCATING-0} : { *(.plt) }" +if test -z "$PLT"; then + PLT=".plt ${RELOCATING-0} : { *(.plt) }" +fi if test -z "$GOT"; then if test -z "$SEPARATE_GOTPLT"; then GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) }" @@ -144,6 +146,16 @@ if test -z "${NO_SMALL_DATA}"; then else NO_SMALL_DATA=" " fi +if test -z "${DATA_GOT}"; then + if test -n "${NO_SMALL_DATA}"; then + DATA_GOT=" " + fi +fi +if test -z "${SDATA_GOT}"; then + if test -z "${NO_SMALL_DATA}"; then + SDATA_GOT=" " + fi +fi test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" " CTOR=".ctors ${CONSTRUCTING-0} : { @@ -343,11 +355,12 @@ cat <<EOF ${RELOCATING+${DATARELRO}} ${OTHER_RELRO_SECTIONS} ${TEXT_DYNAMIC-${DYNAMIC}} - ${NO_SMALL_DATA+${RELRO_NOW+${GOT}}} - ${NO_SMALL_DATA+${RELRO_NOW-${SEPARATE_GOTPLT+${GOT}}}} + ${DATA_GOT+${RELRO_NOW+${GOT}}} + ${DATA_GOT+${RELRO_NOW+${GOTPLT}}} + ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${GOT}}}} ${RELOCATING+${DATA_SEGMENT_RELRO_END}} - ${NO_SMALL_DATA+${RELRO_NOW-${SEPARATE_GOTPLT+${GOTPLT}}}} - ${NO_SMALL_DATA+${RELRO_NOW-${SEPARATE_GOTPLT-${GOT}}}} + ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${GOT}}}} + ${DATA_GOT+${RELRO_NOW-${GOTPLT}}} ${DATA_PLT+${PLT_BEFORE_GOT-${PLT}}} @@ -364,9 +377,9 @@ cat <<EOF ${SMALL_DATA_CTOR+${RELOCATING+${CTOR}}} ${SMALL_DATA_DTOR+${RELOCATING+${DTOR}}} ${DATA_PLT+${PLT_BEFORE_GOT+${PLT}}} - ${RELOCATING+${OTHER_GOT_SYMBOLS}} - ${NO_SMALL_DATA-${GOT}} - ${OTHER_GOT_SECTIONS} + ${SDATA_GOT+${RELOCATING+${OTHER_GOT_SYMBOLS}}} + ${SDATA_GOT+${GOT}} + ${SDATA_GOT+${OTHER_GOT_SECTIONS}} ${SDATA} ${OTHER_SDATA_SECTIONS} ${RELOCATING+${DATA_END_SYMBOLS-_edata = .; PROVIDE (edata = .);}} |