* config/tc-i386.c (lex_got): Provide implementation for PE
authorNick Clifton <nickc@redhat.com>
Tue, 7 Aug 2012 13:47:19 +0000 (13:47 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 7 Aug 2012 13:47:19 +0000 (13:47 +0000)
format.

* gas/i386/secrel.s: Add test of <symbol>@SECREL32.
* gas/i386/secrel.d: Add expected disassembly.

* scripttempl/pe.sc (R_TLS): Add .tls$AAA and .tls$ZZZ.
* scripttempl/pep.sc (R_TLS): Add .tls$AAA and .tls$ZZZ.

* archive.c (_bfd_delete_archive_data): New function.
* libbfd-in.h (_bfd_delete_archive_data): Declare.
* libbfd.h: Rebuild.
* opncls.c (_bfd_delete_bfd): Call _bfd_delete_archive_data.

13 files changed:
bfd/ChangeLog
bfd/archive.c
bfd/libbfd-in.h
bfd/libbfd.h
bfd/opncls.c
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/secrel.d
gas/testsuite/gas/i386/secrel.s
ld/ChangeLog
ld/scripttempl/pe.sc
ld/scripttempl/pep.sc

index 91a09e6..da2a229 100644 (file)
@@ -1,3 +1,10 @@
+2012-08-07  Tom Tromey  <tromey@redhat.com>
+
+       * archive.c (_bfd_delete_archive_data): New function.
+       * libbfd-in.h (_bfd_delete_archive_data): Declare.
+       * libbfd.h: Rebuild.
+       * opncls.c (_bfd_delete_bfd): Call _bfd_delete_archive_data.
+
 2012-08-07  Nick Clifton  <nickc@redhat.com>
 
        * po/uk.po: Updated Ukranian translation.
index fe57755..1148c11 100644 (file)
@@ -293,6 +293,19 @@ bfd_set_archive_head (bfd *output_archive, bfd *new_head)
   return TRUE;
 }
 
+/* Free the archive hash table, if it exists.  */
+
+void
+_bfd_delete_archive_data (bfd *abfd)
+{
+  struct artdata *ardata = bfd_ardata (abfd);
+
+  BFD_ASSERT (abfd->format == bfd_archive);
+
+  if (ardata && ardata->cache)
+    htab_delete (ardata->cache);
+}
+
 bfd *
 _bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos)
 {
index 1495825..8cdb1c6 100644 (file)
@@ -130,6 +130,8 @@ extern void bfd_release
 
 bfd * _bfd_create_empty_archive_element_shell
   (bfd *obfd);
+void _bfd_delete_archive_data
+  (bfd *abfd);
 bfd * _bfd_look_for_bfd_in_cache
   (bfd *, file_ptr);
 bfd_boolean _bfd_add_bfd_to_archive_cache
index c31780d..a1e544f 100644 (file)
@@ -135,6 +135,8 @@ extern void bfd_release
 
 bfd * _bfd_create_empty_archive_element_shell
   (bfd *obfd);
+void _bfd_delete_archive_data
+  (bfd *abfd);
 bfd * _bfd_look_for_bfd_in_cache
   (bfd *, file_ptr);
 bfd_boolean _bfd_add_bfd_to_archive_cache
index 0c02ee4..e538981 100644 (file)
@@ -130,11 +130,15 @@ _bfd_new_bfd_contained_in (bfd *obfd)
 static void
 _bfd_delete_bfd (bfd *abfd)
 {
+  if (abfd->format == bfd_archive)
+    _bfd_delete_archive_data (abfd);
+
   if (abfd->memory)
     {
       bfd_hash_table_free (&abfd->section_htab);
       objalloc_free ((struct objalloc *) abfd->memory);
     }
+
   free (abfd);
 }
 
index 9597f5e..f3af931 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-07  Daniel Green  <venix1@gmail.com>
+
+       * config/tc-i386.c (lex_got): Provide implementation for PE
+       format.
+
 2012-08-06  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * config/tc-mips.c (append_insn): Also handle moving delay-slot
index 5303f63..49eb8c1 100644 (file)
@@ -6788,6 +6788,109 @@ lex_got (enum bfd_reloc_code_real *rel,
 }
 #endif
 
+#ifdef TE_PE
+#ifdef lex_got
+#undef lex_got
+#endif
+/* Parse operands of the form
+   <symbol>@SECREL32+<nnn>
+
+   If we find one, set up the correct relocation in RELOC and copy the
+   input string, minus the `@SECREL32' into a malloc'd buffer for
+   parsing by the calling routine.  Return this buffer, and if ADJUST
+   is non-null set it to the length of the string we removed from the
+   input line.  Otherwise return NULL.  
+   
+   This function is copied from the ELF version above adjusted for PE targets.  */
+
+static char *
+lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
+        int *adjust ATTRIBUTE_UNUSED,
+        i386_operand_type *types ATTRIBUTE_UNUSED)
+{
+  static const struct
+  {
+    const char *str;
+    int len;
+    const enum bfd_reloc_code_real rel[2];
+    const i386_operand_type types64;
+  }
+  gotrel[] =
+  {
+    { STRING_COMMA_LEN ("SECREL32"),    { BFD_RELOC_32_SECREL,
+                                         BFD_RELOC_32_SECREL },
+      OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
+  };
+
+  char *cp;
+  unsigned j;
+
+  for (cp = input_line_pointer; *cp != '@'; cp++)
+    if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
+      return NULL;
+
+  for (j = 0; j < ARRAY_SIZE (gotrel); j++)
+    {
+      int len = gotrel[j].len;
+
+      if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
+       {
+         if (gotrel[j].rel[object_64bit] != 0)
+           {
+             int first, second;
+             char *tmpbuf, *past_reloc;
+
+             *rel = gotrel[j].rel[object_64bit];
+             if (adjust)
+               *adjust = len;
+
+             if (types)
+               {
+                 if (flag_code != CODE_64BIT)
+                   {
+                     types->bitfield.imm32 = 1;
+                     types->bitfield.disp32 = 1;
+                   }
+                 else
+                   *types = gotrel[j].types64;
+               }
+
+             /* The length of the first part of our input line.  */
+             first = cp - input_line_pointer;
+
+             /* The second part goes from after the reloc token until
+                (and including) an end_of_line char or comma.  */
+             past_reloc = cp + 1 + len;
+             cp = past_reloc;
+             while (!is_end_of_line[(unsigned char) *cp] && *cp != ',')
+               ++cp;
+             second = cp + 1 - past_reloc;
+
+             /* Allocate and copy string.  The trailing NUL shouldn't
+                be necessary, but be safe.  */
+             tmpbuf = (char *) xmalloc (first + second + 2);
+             memcpy (tmpbuf, input_line_pointer, first);
+             if (second != 0 && *past_reloc != ' ')
+               /* Replace the relocation token with ' ', so that
+                  errors like foo@SECLREL321 will be detected.  */
+               tmpbuf[first++] = ' ';
+             memcpy (tmpbuf + first, past_reloc, second);
+             tmpbuf[first + second] = '\0';
+             return tmpbuf;
+           }
+
+         as_bad (_("@%s reloc is not supported with %d-bit output format"),
+                 gotrel[j].str, 1 << (5 + object_64bit));
+         return NULL;
+       }
+    }
+
+  /* Might be a symbol version string.  Don't as_bad here.  */
+  return NULL;
+}
+
+#endif /* TE_PE */
+
 void
 x86_cons (expressionS *exp, int size)
 {
index 026750e..b5d11cc 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-07  Nick Clifton  <nickc@redhat.com>
+
+       * gas/i386/secrel.s: Add test of <symbol>@SECREL32.
+       * gas/i386/secrel.d: Add expected disassembly.
+
 2012-08-06  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * gas/mips/mips.exp: Set has_newabi for all Linux targets.
index 58967cb..ac23301 100644 (file)
@@ -21,7 +21,7 @@ OFFSET[       ]+TYPE[         ]+VALUE
 0+89 secrel32          ext2d\r
 0+8e secrel32          ext36\r
 0+93 secrel32          ext3f\r
-\r
+0+a2 secrel32          bar\r
 \r
 Contents of section \.text:\r
  0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c  >>>><<<<>>>>><<<\r
@@ -37,6 +37,7 @@ Contents of section \.data:
  0070 0000111f 00000011 3c3c3c3c 3c3c3c3c  ........<<<<<<<<\r
  0080 3e3e3e3e 00000000 11000000 00110000  >>>>............\r
  0090 00001100 00000011 3c3c3c3c 3c3c3c3c  ........<<<<<<<<\r
+ 00a0 8d902c00 00000000                    ..,.....        \r
 Contents of section \.rdata:\r
  0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c  >>>><<<<>>>>><<<\r
  0010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c  >>>>>><<>>>>>>><\r
index c162990..2fc5a25 100644 (file)
@@ -64,6 +64,8 @@ sam1f:        .ascii "<"
        .byte 0x11\r
        .ascii "<<<<<<<<"\r
 \r
+       leal    bar@SECREL32+44(%eax), %edx\r
+       \r
 .section .rdata\r
 \r
        .ascii ">>>>"\r
index cd2402b..c4bc473 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-07  Daniel Green  <venix1@gmail.com>
+
+       * scripttempl/pe.sc (R_TLS): Add .tls$AAA and .tls$ZZZ.
+       * scripttempl/pep.sc (R_TLS): Add .tls$AAA and .tls$ZZZ.
+
 2012-08-07  Nick Clifton  <nickc@redhat.com>
 
        * po/ja.po: Updated Japanese translation.
index 3a27952..5b9bd61 100644 (file)
@@ -39,9 +39,11 @@ if test "${RELOCATING}"; then
   R_CRT_XP='*(SORT(.CRT$XP*))  /* Pre-termination */'
   R_CRT_XT='*(SORT(.CRT$XT*))  /* Termination */'
   R_TLS='
+    *(.tls$AAA)    
     *(.tls)
     *(.tls$)
-    *(SORT(.tls$*))'
+    *(SORT(.tls$*))
+    *(.tls$ZZZ)'
   R_RSRC='*(SORT(.rsrc$*))'
 else
   R_TEXT=
@@ -179,6 +181,10 @@ SECTIONS
     ${RELOCATING+___crt_xt_end__ = . ;}
   }
 
+  /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be
+     at the end of section.  This is important because _tls_start MUST
+     be at the beginning of the section to enable SECREL32 relocations with TLS
+     data.  */
   .tls ${RELOCATING+BLOCK(__section_alignment__)} :
   {                                    
     ${RELOCATING+___tls_start__ = . ;}
index b2113fe..ff11153 100644 (file)
@@ -39,9 +39,11 @@ if test "${RELOCATING}"; then
   R_CRT_XP='*(SORT(.CRT$XP*))  /* Pre-termination */'
   R_CRT_XT='*(SORT(.CRT$XT*))  /* Termination */'
   R_TLS='
+    *(.tls$AAA)    
     *(.tls)
     *(.tls$)
-    *(SORT(.tls$*))'
+    *(SORT(.tls$*))
+    *(.tls$ZZZ)'
   R_RSRC='*(SORT(.rsrc$*))'
 else
   R_TEXT=
@@ -185,6 +187,10 @@ SECTIONS
     ${RELOCATING+___crt_xt_end__ = . ;}
   }
 
+  /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be
+     at the end of the .tls section.  This is important because _tls_start MUST
+     be at the beginning of the section to enable SECREL32 relocations with TLS
+     data.  */
   .tls ${RELOCATING+BLOCK(__section_alignment__)} :
   {                                    
     ${RELOCATING+___tls_start__ = . ;}