* ldgram.y: Add SPECIAL token.
authorAlan Modra <amodra@gmail.com>
Wed, 11 May 2005 14:10:10 +0000 (14:10 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 11 May 2005 14:10:10 +0000 (14:10 +0000)
(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.

ld/ChangeLog
ld/emulparams/elf32ppc.sh
ld/emultempl/ppc32elf.em
ld/ldgram.y
ld/ldlang.c
ld/ldlex.l
ld/scripttempl/elf.sc

index 5da5097..e9d188c 100644 (file)
@@ -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.
 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>
 
index 3e5224f..5a38aed 100644 (file)
@@ -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="
index 710160d..cbd77ac 100644 (file)
@@ -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
index fefd7bc..d24ad07 100644 (file)
@@ -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; }
        ;
 
index 453b7ac..c7310d7 100644 (file)
@@ -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,
index ea6fa99..f3a0ba1 100644 (file)
@@ -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);}
index c2a2dcf..3e0f0b0 100644 (file)
@@ -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 = .);}}