include/elf/
authorNick Clifton <nickc@redhat.com>
Wed, 3 Dec 2008 14:51:00 +0000 (14:51 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 3 Dec 2008 14:51:00 +0000 (14:51 +0000)
            * common.h (STT_IFUNC): Define.
elfcpp/
            * elfcpp.h (enum STT): Add STT_IFUNC.
bfd/
            * syms.c (struct bfd_symbol): Add new flag BSF_INDIRECT_FUNCTION.
            Remove redundant flag BFD_FORT_COMM_DEFAULT_VALUE.  Renumber flags
            to remove gaps.
            (bfd_print_symbol_vandf): Return 'i' for BSF_INDIRECT_FUNCTION.
            (bfd_decode_symclass): Likewise.
            * elf.c (swap_out_syms): Translate BSF_INDIRECT_FUNCTION into
            STT_IFUNC.
            (elf_find_function): Treat STT_IFUNC in the same way as STT_FUNC.
            (_bfd_elf_is_function_type): Likewise.
            * elf32-arm.c (arm_elf_find_function): Likewise.
            (elf32_arm_adjust_dynamic_symbol): Likewise.
            (elf32_arm_swap_symbol_in): Likewise.
            (elf32_arm_additional_program_headers): Likewise.
            * elf32-i386.c (is_indirect_symbol): New function.
            (elf_i386_check_relocs): Also generate dynamic relocs for
            relocations against STT_IFUNC symbols.
            (allocate_dynrelocs): Likewise.
            (elf_i386_relocate_section): Likewise.
            * elf64-x86-64.c (is_indirect_symbol): New function.
            (elf64_x86_64_check_relocs): Also generate dynamic relocs for
            relocations against STT_IFUNC symbols.
            (allocate_dynrelocs): Likewise.
            (elf64_x86_64_relocate_section): Likewise.
            * elfcode.h (elf_slurp_symbol_table): Translate STT_IFUNC into
            BSF_INDIRECT_FUNCTION.
            * elflink.c (_bfd_elf_adjust_dynamic_reloc_section): Add support
            for STT_IFUNC symbols.
            (get_ifunc_reloc_section_name): New function.
            (_bfd_elf_make_ifunc_reloc_section): New function.
            * elf-bfd.h (struct bfd_elf_section_data): Add indirect_relocs field.
            * bfd-in2.h: Regenerate.
gas/
            * config/obj-elf.c (obj_elf_type): Add support for STT_IFUNC type.
            * doc/as.texinfo: Document new feature.
            * NEWS: Mention new feature.
gas/testsuite/
            * gas/elf/type.s: Add test of STT_IFUNC symbol type.
            * gas/elf/type.e: Update expected disassembly.
            * gas/elf/elf.exp: Update grep of symbol types.
ld/
            * NEWS: Mention new feature.
            * pe-dll.c (process_def_file): Replace use of redundant
            BFD_FORT_COMM_DEFAULT_VALUE with 0.
            * scripttempl/elf.sc: Add .rel.ifunc.dyn and .rela.ifunc.dyn
            sections.
ld/testsuite/
            * ld-mips-elf/reloc-1-n32.d: Updated expected output for reloc
            descriptions.
            * ld-mips-elf/reloc-1-n64.d: Likewise.
            * ld-i386/ifunc.d: New test.
            * ld-i386/ifunc.s: Source file for the new test.
            * ld-i386/i386.exp: Run the new test.

32 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-arm.c
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfcode.h
bfd/elflink.c
bfd/syms.c
elfcpp/ChangeLog
elfcpp/elfcpp.h
gas/ChangeLog
gas/NEWS
gas/config/obj-elf.c
gas/doc/as.texinfo
gas/testsuite/ChangeLog
gas/testsuite/gas/elf/elf.exp
gas/testsuite/gas/elf/type.e
gas/testsuite/gas/elf/type.s
include/elf/ChangeLog
include/elf/common.h
ld/ChangeLog
ld/NEWS
ld/pe-dll.c
ld/scripttempl/elf.sc
ld/testsuite/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/ifunc.d [new file with mode: 0644]
ld/testsuite/ld-i386/ifunc.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/reloc-1-n32.d
ld/testsuite/ld-mips-elf/reloc-1-n64.d

index 27327e7b676299a809f2738d0a723c90a263c1d7..73615b7a31d5faba270e191b653181b592704d22 100644 (file)
@@ -1,3 +1,37 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * syms.c (struct bfd_symbol): Add new flag BSF_INDIRECT_FUNCTION.
+       Remove redundant flag BFD_FORT_COMM_DEFAULT_VALUE.  Renumber flags
+       to remove gaps.
+       (bfd_print_symbol_vandf): Return 'i' for BSF_INDIRECT_FUNCTION.
+       (bfd_decode_symclass): Likewise.
+       * elf.c (swap_out_syms): Translate BSF_INDIRECT_FUNCTION into
+       STT_IFUNC.
+       (elf_find_function): Treat STT_IFUNC in the same way as STT_FUNC.
+       (_bfd_elf_is_function_type): Likewise.
+       * elf32-arm.c (arm_elf_find_function): Likewise.
+       (elf32_arm_adjust_dynamic_symbol): Likewise.
+       (elf32_arm_swap_symbol_in): Likewise.
+       (elf32_arm_additional_program_headers): Likewise.
+       * elf32-i386.c (is_indirect_symbol): New function.
+       (elf_i386_check_relocs): Also generate dynamic relocs for
+       relocations against STT_IFUNC symbols.
+       (allocate_dynrelocs): Likewise.
+       (elf_i386_relocate_section): Likewise.
+       * elf64-x86-64.c (is_indirect_symbol): New function.
+       (elf64_x86_64_check_relocs): Also generate dynamic relocs for
+       relocations against STT_IFUNC symbols.
+       (allocate_dynrelocs): Likewise.
+       (elf64_x86_64_relocate_section): Likewise.
+       * elfcode.h (elf_slurp_symbol_table): Translate STT_IFUNC into
+       BSF_INDIRECT_FUNCTION.
+       * elflink.c (_bfd_elf_adjust_dynamic_reloc_section): Add support
+       for STT_IFUNC symbols.
+       (get_ifunc_reloc_section_name): New function.
+       (_bfd_elf_make_ifunc_reloc_section): New function.
+       * elf-bfd.h (struct bfd_elf_section_data): Add indirect_relocs field.
+       * bfd-in2.h: Regenerate.
+
 2008-12-02  Tristan Gingold  <gingold@adacore.com>
 
        * config.bfd: Add x86_64-*-darwin*
index 917b8bc205c0e2cc87fdfd141fd60c13647dfca2..b1451c9e56a93e9dae89dae37b1db527e4ead9ff 100644 (file)
@@ -4445,100 +4445,104 @@ typedef struct bfd_symbol
   symvalue value;
 
   /* Attributes of a symbol.  */
-#define BSF_NO_FLAGS    0x00
+#define BSF_NO_FLAGS           0x00
 
   /* The symbol has local scope; <<static>> in <<C>>. The value
      is the offset into the section of the data.  */
-#define BSF_LOCAL      0x01
+#define BSF_LOCAL              (1 << 0)
 
   /* The symbol has global scope; initialized data in <<C>>. The
      value is the offset into the section of the data.  */
-#define BSF_GLOBAL     0x02
+#define BSF_GLOBAL             (1 << 1)
 
   /* The symbol has global scope and is exported. The value is
      the offset into the section of the data.  */
 #define BSF_EXPORT     BSF_GLOBAL /* No real difference.  */
 
   /* A normal C symbol would be one of:
-     <<BSF_LOCAL>>, <<BSF_FORT_COMM>>,  <<BSF_UNDEFINED>> or
+     <<BSF_LOCAL>>, <<BSF_COMMON>>,  <<BSF_UNDEFINED>> or
      <<BSF_GLOBAL>>.  */
 
   /* The symbol is a debugging record. The value has an arbitrary
      meaning, unless BSF_DEBUGGING_RELOC is also set.  */
-#define BSF_DEBUGGING  0x08
+#define BSF_DEBUGGING          (1 << 2)
 
   /* The symbol denotes a function entry point.  Used in ELF,
      perhaps others someday.  */
-#define BSF_FUNCTION    0x10
-
+#define BSF_FUNCTION           (1 << 3)
+
+  /* The symbol is an indirect code object.  Unrelated to BSF_INDIRECT.
+     Relocations against a symbol with this flag have to evaluated at
+     run-time, where the function pointed to by this symbol is invoked
+     in order to determine the value to be used in the relocation.
+     BSF_FUNCTION must also be set for symbols with this flag.  */
+#define BSF_INDIRECT_FUNCTION  (1 << 4)
   /* Used by the linker.  */
-#define BSF_KEEP        0x20
-#define BSF_KEEP_G      0x40
+#define BSF_KEEP               (1 << 5)
+#define BSF_KEEP_G             (1 << 6)
 
   /* A weak global symbol, overridable without warnings by
      a regular global symbol of the same name.  */
-#define BSF_WEAK        0x80
+#define BSF_WEAK               (1 << 7)
 
   /* This symbol was created to point to a section, e.g. ELF's
      STT_SECTION symbols.  */
-#define BSF_SECTION_SYM 0x100
+#define BSF_SECTION_SYM        (1 << 8)
 
   /* The symbol used to be a common symbol, but now it is
      allocated.  */
-#define BSF_OLD_COMMON  0x200
-
-  /* The default value for common data.  */
-#define BFD_FORT_COMM_DEFAULT_VALUE 0
+#define BSF_OLD_COMMON         (1 << 9)
 
   /* In some files the type of a symbol sometimes alters its
      location in an output file - ie in coff a <<ISFCN>> symbol
      which is also <<C_EXT>> symbol appears where it was
      declared and not at the end of a section.  This bit is set
      by the target BFD part to convey this information.  */
-#define BSF_NOT_AT_END    0x400
+#define BSF_NOT_AT_END         (1 << 10)
 
   /* Signal that the symbol is the label of constructor section.  */
-#define BSF_CONSTRUCTOR   0x800
+#define BSF_CONSTRUCTOR        (1 << 11)
 
   /* Signal that the symbol is a warning symbol.  The name is a
      warning.  The name of the next symbol is the one to warn about;
      if a reference is made to a symbol with the same name as the next
      symbol, a warning is issued by the linker.  */
-#define BSF_WARNING       0x1000
+#define BSF_WARNING            (1 << 12)
 
   /* Signal that the symbol is indirect.  This symbol is an indirect
      pointer to the symbol with the same name as the next symbol.  */
-#define BSF_INDIRECT      0x2000
+#define BSF_INDIRECT           (1 << 13)
 
   /* BSF_FILE marks symbols that contain a file name.  This is used
      for ELF STT_FILE symbols.  */
-#define BSF_FILE          0x4000
+#define BSF_FILE               (1 << 14)
 
   /* Symbol is from dynamic linking information.  */
-#define BSF_DYNAMIC       0x8000
+#define BSF_DYNAMIC            (1 << 15)
 
   /* The symbol denotes a data object.  Used in ELF, and perhaps
      others someday.  */
-#define BSF_OBJECT        0x10000
+#define BSF_OBJECT             (1 << 16)
 
   /* This symbol is a debugging symbol.  The value is the offset
      into the section of the data.  BSF_DEBUGGING should be set
      as well.  */
-#define BSF_DEBUGGING_RELOC 0x20000
+#define BSF_DEBUGGING_RELOC    (1 << 17)
 
   /* This symbol is thread local.  Used in ELF.  */
-#define BSF_THREAD_LOCAL  0x40000
+#define BSF_THREAD_LOCAL       (1 << 18)
 
   /* This symbol represents a complex relocation expression,
      with the expression tree serialized in the symbol name.  */
-#define BSF_RELC 0x80000
+#define BSF_RELC               (1 << 19)
 
   /* This symbol represents a signed complex relocation expression,
      with the expression tree serialized in the symbol name.  */
-#define BSF_SRELC 0x100000
+#define BSF_SRELC              (1 << 20)
 
   /* This symbol was created by bfd_get_synthetic_symtab.  */
-#define BSF_SYNTHETIC 0x200000
+#define BSF_SYNTHETIC          (1 << 21)
 
   flagword flags;
 
index 5418e7f82eff34a8daac37b5b5fc84ceb680af20..effa34478b3c63a38dc3057e4808f39f856b8595 100644 (file)
@@ -1287,6 +1287,9 @@ struct bfd_elf_section_data
   /* A pointer to the bfd section used for dynamic relocs.  */
   asection *sreloc;
 
+  /* A pointer to the bfd section used for dynamic relocs against ifunc symbols.  */
+  asection *indirect_relocs;
+
   union {
     /* Group name, if this section is a member of a group.  */
     const char *name;
@@ -1768,6 +1771,8 @@ extern asection * _bfd_elf_get_dynamic_reloc_section
   (bfd *, asection *, bfd_boolean);
 extern asection * _bfd_elf_make_dynamic_reloc_section
   (asection *, bfd *, unsigned int, bfd *, bfd_boolean);
+extern asection * _bfd_elf_make_ifunc_reloc_section
+  (bfd *, asection *, bfd *, unsigned int);
 extern long _bfd_elf_get_dynamic_reloc_upper_bound
   (bfd *);
 extern long _bfd_elf_canonicalize_dynamic_reloc
index 70ed7656d0bfee8aada78425608c9b0f5503712a..7597d010ca9aadbff4937e187a575e9f5e631cb6 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6427,6 +6427,8 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
 
       if ((flags & BSF_THREAD_LOCAL) != 0)
        type = STT_TLS;
+      else if ((flags & BSF_INDIRECT_FUNCTION) != 0)
+       type = STT_IFUNC;
       else if ((flags & BSF_FUNCTION) != 0)
        type = STT_FUNC;
       else if ((flags & BSF_OBJECT) != 0)
@@ -7120,6 +7122,7 @@ elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
          continue;
        case STT_NOTYPE:
        case STT_FUNC:
+       case STT_IFUNC:
          if (bfd_get_section (&q->symbol) == section
              && q->symbol.value >= low_func
              && q->symbol.value <= offset)
@@ -8938,10 +8941,10 @@ _bfd_elf_set_osabi (bfd * abfd,
 
 /* Return TRUE for ELF symbol types that represent functions.
    This is the default version of this function, which is sufficient for
-   most targets.  It returns true if TYPE is STT_FUNC.  */
+   most targets.  It returns true if TYPE is STT_FUNC or STT_IFUNC.  */
 
 bfd_boolean
 _bfd_elf_is_function_type (unsigned int type)
 {
-  return (type == STT_FUNC);
+  return (type == STT_FUNC || type == STT_IFUNC);
 }
index cd5a9bfc0712879ad8ae01c9da114ceccf5aee42..dacbc16c60edd1c613640c9952fed4c6bd490bc2 100644 (file)
@@ -9430,6 +9430,7 @@ arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
          filename = bfd_asymbol_name (&q->symbol);
          break;
        case STT_FUNC:
+       case STT_IFUNC:
        case STT_ARM_TFUNC:
        case STT_NOTYPE:
          /* Skip mapping symbols.  */
@@ -9555,7 +9556,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later,
      when we know the address of the .got section.  */
-  if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC
+  if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC || h->type == STT_IFUNC
       || h->needs_plt)
     {
       if (h->plt.refcount <= 0
@@ -11729,7 +11730,8 @@ elf32_arm_swap_symbol_in (bfd * abfd,
 
   /* New EABI objects mark thumb function symbols by setting the low bit of
      the address.  Turn these into STT_ARM_TFUNC.  */
-  if (ELF_ST_TYPE (dst->st_info) == STT_FUNC
+  if ((ELF_ST_TYPE (dst->st_info) == STT_FUNC
+       || ELF_ST_TYPE (dst->st_info) == STT_IFUNC)
       && (dst->st_value & 1))
     {
       dst->st_info = ELF_ST_INFO (ELF_ST_BIND (dst->st_info), STT_ARM_TFUNC);
@@ -11830,7 +11832,7 @@ elf32_arm_additional_program_headers (bfd *abfd,
 static bfd_boolean
 elf32_arm_is_function_type (unsigned int type)
 {
-  return (type == STT_FUNC) || (type == STT_ARM_TFUNC);
+  return (type == STT_FUNC) || (type == STT_ARM_TFUNC) || (type == STT_IFUNC);
 }
 
 /* We use this to override swap_symbol_in and swap_symbol_out.  */
index 7d14fef561d8ddd32249105bd146d59905cfa627..ec0c16fd83ebad84eca5665f34d2dd23e0cefd11 100644 (file)
@@ -1193,6 +1193,26 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
   return TRUE;
 }
 
+/* Returns true if the hash entry refers to a symbol
+   marked for indirect handling during reloc processing.  */
+
+static bfd_boolean
+is_indirect_symbol (bfd * abfd, struct elf_link_hash_entry * h)
+{
+  const struct elf_backend_data * bed;
+
+  if (abfd == NULL || h == NULL)
+    return FALSE;
+
+  bed = get_elf_backend_data (abfd);
+
+  return h->type == STT_IFUNC
+    && bed != NULL
+    && (bed->elf_osabi == ELFOSABI_LINUX
+       /* GNU/Linux is still using the default value 0.  */
+       || bed->elf_osabi == ELFOSABI_NONE);
+}
+
 /* Look through the relocs for a section during the first phase, and
    calculate needed space in the global offset table, procedure linkage
    table, and dynamic reloc sections.  */
@@ -1452,7 +1472,8 @@ elf_i386_check_relocs (bfd *abfd,
                  && (sec->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && (h->root.type == bfd_link_hash_defweak
-                     || !h->def_regular)))
+                     || !h->def_regular))
+             || is_indirect_symbol (abfd, h))        
            {
              struct elf_i386_dyn_relocs *p;
              struct elf_i386_dyn_relocs **head;
@@ -1472,6 +1493,9 @@ elf_i386_check_relocs (bfd *abfd,
                    return FALSE;
                }
 
+             if (is_indirect_symbol (abfd, h))
+               (void) _bfd_elf_make_ifunc_reloc_section (abfd, sec, htab->elf.dynobj, 2);
+
              /* If this is a global symbol, we count the number of
                 relocations we need for this symbol.  */
              if (h != NULL)
@@ -2033,6 +2057,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
            }
        }
     }
+  else if (is_indirect_symbol (info->output_bfd, h))
+    {
+      if (h->dynindx == -1
+         && !h->forced_local)
+       {
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
+           return FALSE;
+       }
+    }
   else if (ELIMINATE_COPY_RELOCS)
     {
       /* For the non-shared case, discard space for relocs against
@@ -2069,7 +2102,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   /* Finally, allocate space.  */
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
-      asection *sreloc = elf_section_data (p->sec)->sreloc;
+      asection *sreloc;
+
+      if (! info->shared
+         && is_indirect_symbol (info->output_bfd, h))
+       sreloc = elf_section_data (p->sec)->indirect_relocs;
+      else
+       sreloc = elf_section_data (p->sec)->sreloc;
+
+      BFD_ASSERT (sreloc != NULL);
       sreloc->size += p->count * sizeof (Elf32_External_Rel);
     }
 
@@ -2248,7 +2289,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
-  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
+  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
 
   /* For every jump slot reserved in the sgotplt, reloc_count is
      incremented.  However, when we reserve space for TLS descriptors,
@@ -2361,8 +2402,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
          if ((info->flags & DF_TEXTREL) == 0)
-           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
-                                   (PTR) info);
+           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
@@ -2879,7 +2919,8 @@ elf_i386_relocate_section (bfd *output_bfd,
                  && ((h->def_dynamic
                       && !h->def_regular)
                      || h->root.type == bfd_link_hash_undefweak
-                     || h->root.type == bfd_link_hash_undefined)))
+                     || h->root.type == bfd_link_hash_undefined))
+             || is_indirect_symbol (output_bfd, h))
            {
              Elf_Internal_Rela outrel;
              bfd_byte *loc;
@@ -2919,19 +2960,23 @@ elf_i386_relocate_section (bfd *output_bfd,
                  outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
                }
 
-             sreloc = elf_section_data (input_section)->sreloc;
-             if (sreloc == NULL)
-               abort ();
+             if ((! info->shared) && is_indirect_symbol (output_bfd, h))
+               sreloc = elf_section_data (input_section)->indirect_relocs;
+             else
+               sreloc = elf_section_data (input_section)->sreloc;
+
+             BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
 
              loc = sreloc->contents;
              loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
+
              bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
 
              /* If this reloc is against an external symbol, we do
                 not want to fiddle with the addend.  Otherwise, we
                 need to include the symbol value so that it becomes
                 an addend for the dynamic reloc.  */
-             if (! relocate)
+             if (! relocate || is_indirect_symbol (output_bfd, h))
                continue;
            }
          break;
index 7eecb22ea3a2beb0831e3537b5181e4d2580862a..1ea033bda04c38beba4ee35933145e8fdd18940a 100644 (file)
@@ -974,6 +974,26 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
   return TRUE;
 }
 
+/* Returns true if the hash entry refers to a symbol
+   marked for indirect handling during reloc processing.  */
+
+static bfd_boolean
+is_indirect_symbol (bfd * abfd, struct elf_link_hash_entry * h)
+{
+  const struct elf_backend_data * bed;
+
+  if (abfd == NULL || h == NULL)
+    return FALSE;
+
+  bed = get_elf_backend_data (abfd);
+
+  return h->type == STT_IFUNC
+    && bed != NULL
+    && (bed->elf_osabi == ELFOSABI_LINUX
+       /* GNU/Linux is still using the default value 0.  */
+       || bed->elf_osabi == ELFOSABI_NONE);
+}
+
 /* Look through the relocs for a section during the first phase, and
    calculate needed space in the global offset table, procedure
    linkage table, and dynamic reloc sections.  */
@@ -1255,7 +1275,10 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
             If on the other hand, we are creating an executable, we
             may need to keep relocations for symbols satisfied by a
             dynamic library if we manage to avoid copy relocs for the
-            symbol.  */
+            symbol.
+
+            Also we must keep any relocations against IFUNC symbols as
+            they will be evaluated at load time.  */
          if ((info->shared
               && (sec->flags & SEC_ALLOC) != 0
               && (((r_type != R_X86_64_PC8)
@@ -1271,7 +1294,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  && (sec->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && (h->root.type == bfd_link_hash_defweak
-                     || !h->def_regular)))
+                     || !h->def_regular))
+             || is_indirect_symbol (abfd, h))
            {
              struct elf64_x86_64_dyn_relocs *p;
              struct elf64_x86_64_dyn_relocs **head;
@@ -1291,6 +1315,9 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    return FALSE;
                }
 
+             if (is_indirect_symbol (abfd, h))
+               (void) _bfd_elf_make_ifunc_reloc_section (abfd, sec, htab->elf.dynobj, 2);
+
              /* If this is a global symbol, we count the number of
                 relocations we need for this symbol.  */
              if (h != NULL)
@@ -1830,6 +1857,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
            }
        }
     }
+  else if (is_indirect_symbol (info->output_bfd, h))
+    {
+      if (h->dynindx == -1
+         && ! h->forced_local
+         && ! bfd_elf_link_record_dynamic_symbol (info, h))
+       return FALSE;    
+    }
   else if (ELIMINATE_COPY_RELOCS)
     {
       /* For the non-shared case, discard space for relocs against
@@ -1866,7 +1900,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   /* Finally, allocate space.  */
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
-      asection *sreloc = elf_section_data (p->sec)->sreloc;
+      asection * sreloc;
+
+      if (! info->shared
+         && is_indirect_symbol (info->output_bfd, h))
+       sreloc = elf_section_data (p->sec)->indirect_relocs;
+      else
+       sreloc = elf_section_data (p->sec)->sreloc;
+
+      BFD_ASSERT (sreloc != NULL);
+
       sreloc->size += p->count * sizeof (Elf64_External_Rela);
     }
 
@@ -1970,7 +2013,6 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                  srel->size += p->count * sizeof (Elf64_External_Rela);
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
                    info->flags |= DF_TEXTREL;
-
                }
            }
        }
@@ -2039,7 +2081,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
-  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
+  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
 
   /* For every jump slot reserved in the sgotplt, reloc_count is
      incremented.  However, when we reserve space for TLS descriptors,
@@ -2170,8 +2212,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
          if ((info->flags & DF_TEXTREL) == 0)
-           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
-                                   (PTR) info);
+           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
@@ -2680,7 +2721,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                  && ((h->def_dynamic
                       && !h->def_regular)
                      || h->root.type == bfd_link_hash_undefweak
-                     || h->root.type == bfd_link_hash_undefined)))
+                     || h->root.type == bfd_link_hash_undefined))
+             || is_indirect_symbol (output_bfd, h))
            {
              Elf_Internal_Rela outrel;
              bfd_byte *loc;
@@ -2766,9 +2808,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                    }
                }
 
-             sreloc = elf_section_data (input_section)->sreloc;
-             if (sreloc == NULL)
-               abort ();
+             if ((! info->shared) && is_indirect_symbol (output_bfd, h))
+               sreloc = elf_section_data (input_section)->indirect_relocs;
+             else
+               sreloc = elf_section_data (input_section)->sreloc;
+               
+             BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
 
              loc = sreloc->contents;
              loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
@@ -2778,7 +2823,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                 not want to fiddle with the addend.  Otherwise, we
                 need to include the symbol value so that it becomes
                 an addend for the dynamic reloc.  */
-             if (! relocate)
+             if (! relocate || is_indirect_symbol (output_bfd, h))
                continue;
            }
 
index b42229f007b7ea136a6f226b281d2634d1e8b328..cd8ffe4d8058d3ee3fff6dad095232ee9d19a47a 100644 (file)
@@ -1311,6 +1311,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
            case STT_SRELC:
              sym->symbol.flags |= BSF_SRELC;
              break;
+           case STT_IFUNC:
+             sym->symbol.flags |= BSF_INDIRECT_FUNCTION;
+             break;
            }
 
          if (dynamic)
index 43379c71a6e6a1c7beb9676e0c15e28090b627d4..952b4e0bb97f0ba8cfe8350b922ec097c9c933ab 100644 (file)
@@ -2652,6 +2652,13 @@ _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
 
   dynobj = elf_hash_table (eif->info)->dynobj;
   bed = get_elf_backend_data (dynobj);
+
+  if (h->type == STT_IFUNC
+      && (bed->elf_osabi == ELFOSABI_LINUX
+         /* GNU/Linux is still using the default value 0.  */
+         || bed->elf_osabi == ELFOSABI_NONE))
+    h->needs_plt = 1;
+
   if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
     {
       eif->failed = TRUE;
@@ -12400,3 +12407,71 @@ _bfd_elf_make_dynamic_reloc_section (asection *         sec,
 
   return reloc_sec;
 }
+
+#define IFUNC_INFIX ".ifunc"
+
+/* Returns the name of the ifunc-using-dynamic-reloc section associated with SEC.  */
+
+static const char *
+get_ifunc_reloc_section_name (bfd *       abfd,
+                             asection *  sec)
+{
+  const char *  dot;
+  char *        name;
+  const char *  base_name;
+  unsigned int  strndx = elf_elfheader (abfd)->e_shstrndx;
+  unsigned int  shnam = elf_section_data (sec)->rel_hdr.sh_name;
+
+  base_name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
+  if (base_name == NULL)
+    return NULL;
+
+  dot = strchr (base_name + 1, '.');
+  name = bfd_alloc (abfd, strlen (base_name) + strlen (IFUNC_INFIX) + 1);
+  sprintf (name, "%.*s%s%s", (int)(dot - base_name), base_name, IFUNC_INFIX, dot);
+
+  return name;
+}
+
+/* Like _bfd_elf_make_dynamic_reloc_section but it creates a
+   section for holding relocs against symbols with the STT_IFUNC
+   type.  The section is attached to the OWNER bfd but it is created
+   with a name based on SEC from ABFD.  */
+
+asection *
+_bfd_elf_make_ifunc_reloc_section (bfd *         abfd,
+                                  asection *    sec,
+                                  bfd *         owner,
+                                  unsigned int  align)
+{
+  asection * reloc_sec = elf_section_data (sec)->indirect_relocs;
+
+  if (reloc_sec == NULL)
+    {
+      const char * name = get_ifunc_reloc_section_name (abfd, sec);
+
+      if (name == NULL)
+       return NULL;
+
+      reloc_sec = bfd_get_section_by_name (owner, name);
+
+      if (reloc_sec == NULL)
+       {
+         flagword flags;
+
+         flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+         if ((sec->flags & SEC_ALLOC) != 0)
+           flags |= SEC_ALLOC | SEC_LOAD;
+
+         reloc_sec = bfd_make_section_with_flags (owner, name, flags);
+         
+         if (reloc_sec != NULL
+             && ! bfd_set_section_alignment (owner, reloc_sec, align))
+           reloc_sec = NULL;
+       }
+
+      elf_section_data (sec)->indirect_relocs = reloc_sec;
+    }
+
+  return reloc_sec;
+}
index 371916b9404d834e6356d21b88f0f27429c80c39..9b4c6524497b1bf7bd5c75cfcc2f625dcc1a91fb 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic symbol-table support for the BFD library.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2007
+   2000, 2001, 2002, 2003, 2004, 2007, 2008
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -205,100 +205,104 @@ CODE_FRAGMENT
 .  symvalue value;
 .
 .  {* Attributes of a symbol.  *}
-.#define BSF_NO_FLAGS    0x00
+.#define BSF_NO_FLAGS          0x00
 .
 .  {* The symbol has local scope; <<static>> in <<C>>. The value
 .     is the offset into the section of the data.  *}
-.#define BSF_LOCAL     0x01
+.#define BSF_LOCAL             (1 << 0)
 .
 .  {* The symbol has global scope; initialized data in <<C>>. The
 .     value is the offset into the section of the data.  *}
-.#define BSF_GLOBAL    0x02
+.#define BSF_GLOBAL            (1 << 1)
 .
 .  {* The symbol has global scope and is exported. The value is
 .     the offset into the section of the data.  *}
 .#define BSF_EXPORT    BSF_GLOBAL {* No real difference.  *}
 .
 .  {* A normal C symbol would be one of:
-.     <<BSF_LOCAL>>, <<BSF_FORT_COMM>>,  <<BSF_UNDEFINED>> or
+.     <<BSF_LOCAL>>, <<BSF_COMMON>>,  <<BSF_UNDEFINED>> or
 .     <<BSF_GLOBAL>>.  *}
 .
 .  {* The symbol is a debugging record. The value has an arbitrary
 .     meaning, unless BSF_DEBUGGING_RELOC is also set.  *}
-.#define BSF_DEBUGGING 0x08
+.#define BSF_DEBUGGING         (1 << 2)
 .
 .  {* The symbol denotes a function entry point.  Used in ELF,
 .     perhaps others someday.  *}
-.#define BSF_FUNCTION    0x10
+.#define BSF_FUNCTION          (1 << 3)
 .
+.  {* The symbol is an indirect code object.  Unrelated to BSF_INDIRECT.
+.     Relocations against a symbol with this flag have to evaluated at
+.     run-time, where the function pointed to by this symbol is invoked
+.     in order to determine the value to be used in the relocation.
+.     BSF_FUNCTION must also be set for symbols with this flag.  *}
+.#define BSF_INDIRECT_FUNCTION (1 << 4)
+. 
 .  {* Used by the linker.  *}
-.#define BSF_KEEP        0x20
-.#define BSF_KEEP_G      0x40
+.#define BSF_KEEP              (1 << 5)
+.#define BSF_KEEP_G            (1 << 6)
 .
 .  {* A weak global symbol, overridable without warnings by
 .     a regular global symbol of the same name.  *}
-.#define BSF_WEAK        0x80
+.#define BSF_WEAK              (1 << 7)
 .
 .  {* This symbol was created to point to a section, e.g. ELF's
 .     STT_SECTION symbols.  *}
-.#define BSF_SECTION_SYM 0x100
+.#define BSF_SECTION_SYM       (1 << 8)
 .
 .  {* The symbol used to be a common symbol, but now it is
 .     allocated.  *}
-.#define BSF_OLD_COMMON  0x200
-.
-.  {* The default value for common data.  *}
-.#define BFD_FORT_COMM_DEFAULT_VALUE 0
+.#define BSF_OLD_COMMON                (1 << 9)
 .
 .  {* In some files the type of a symbol sometimes alters its
 .     location in an output file - ie in coff a <<ISFCN>> symbol
 .     which is also <<C_EXT>> symbol appears where it was
 .     declared and not at the end of a section.  This bit is set
 .     by the target BFD part to convey this information.  *}
-.#define BSF_NOT_AT_END    0x400
+.#define BSF_NOT_AT_END                (1 << 10)
 .
 .  {* Signal that the symbol is the label of constructor section.  *}
-.#define BSF_CONSTRUCTOR   0x800
+.#define BSF_CONSTRUCTOR       (1 << 11)
 .
 .  {* Signal that the symbol is a warning symbol.  The name is a
 .     warning.  The name of the next symbol is the one to warn about;
 .     if a reference is made to a symbol with the same name as the next
 .     symbol, a warning is issued by the linker.  *}
-.#define BSF_WARNING       0x1000
+.#define BSF_WARNING           (1 << 12)
 .
 .  {* Signal that the symbol is indirect.  This symbol is an indirect
 .     pointer to the symbol with the same name as the next symbol.  *}
-.#define BSF_INDIRECT      0x2000
+.#define BSF_INDIRECT          (1 << 13)
 .
 .  {* BSF_FILE marks symbols that contain a file name.  This is used
 .     for ELF STT_FILE symbols.  *}
-.#define BSF_FILE          0x4000
+.#define BSF_FILE              (1 << 14)
 .
 .  {* Symbol is from dynamic linking information.  *}
-.#define BSF_DYNAMIC      0x8000
+.#define BSF_DYNAMIC           (1 << 15)
 .
 .  {* The symbol denotes a data object.  Used in ELF, and perhaps
 .     others someday.  *}
-.#define BSF_OBJECT       0x10000
+.#define BSF_OBJECT            (1 << 16)
 .
 .  {* This symbol is a debugging symbol.  The value is the offset
 .     into the section of the data.  BSF_DEBUGGING should be set
 .     as well.  *}
-.#define BSF_DEBUGGING_RELOC 0x20000
+.#define BSF_DEBUGGING_RELOC   (1 << 17)
 .
 .  {* This symbol is thread local.  Used in ELF.  *}
-.#define BSF_THREAD_LOCAL  0x40000
+.#define BSF_THREAD_LOCAL      (1 << 18)
 .
 .  {* This symbol represents a complex relocation expression,
 .     with the expression tree serialized in the symbol name.  *}
-.#define BSF_RELC 0x80000
+.#define BSF_RELC              (1 << 19)
 .
 .  {* This symbol represents a signed complex relocation expression,
 .     with the expression tree serialized in the symbol name.  *}
-.#define BSF_SRELC 0x100000
+.#define BSF_SRELC             (1 << 20)
 .
 .  {* This symbol was created by bfd_get_synthetic_symtab.  *}
-.#define BSF_SYNTHETIC 0x200000
+.#define BSF_SYNTHETIC         (1 << 21)
 .
 .  flagword flags;
 .
@@ -486,7 +490,7 @@ bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
           (type & BSF_WEAK) ? 'w' : ' ',
           (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
           (type & BSF_WARNING) ? 'W' : ' ',
-          (type & BSF_INDIRECT) ? 'I' : ' ',
+          (type & BSF_INDIRECT) ? 'I' : (type & BSF_INDIRECT_FUNCTION) ? 'i' : ' ',
           (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
           ((type & BSF_FUNCTION)
            ? 'F'
@@ -672,6 +676,8 @@ bfd_decode_symclass (asymbol *symbol)
     }
   if (bfd_is_ind_section (symbol->section))
     return 'I';
+  if (symbol->flags & BSF_INDIRECT_FUNCTION)
+    return 'i';
   if (symbol->flags & BSF_WEAK)
     {
       /* If weak, determine if it's specifically an object
index 949ffeb34547ae7f16b195e7e247a6c2b0d889ae..830cd6fb5d49dcc2ab9f995b412c86bdb4c9b42b 100644 (file)
@@ -1,3 +1,7 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * elfcpp.h (enum STT): Add STT_IFUNC.
+
 2008-06-12  David S. Miller  <davem@davemloft.net>
 
        * powerpc.h: New file.
index 080eef152024eaa2d34d83532d3bbcbda12e1968..739ca1d00f395f04ea124efe048d4dc70d2a6a8f 100644 (file)
@@ -1,6 +1,6 @@
 // elfcpp.h -- main header file for elfcpp    -*- C++ -*-
 
-// Copyright 2006, 2007, Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of elfcpp.
@@ -476,6 +476,7 @@ enum STT
   STT_COMMON = 5,
   STT_TLS = 6,
   STT_LOOS = 10,
+  STT_IFUNC = 10,
   STT_HIOS = 12,
   STT_LOPROC = 13,
   STT_HIPROC = 15,
index d89a87e94644e22a2f75bb5371ecaab268b0fb12..c2abca58ad9f0243d19530b703158309f560f547 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * config/obj-elf.c (obj_elf_type): Add support for STT_IFUNC type.
+       * doc/as.texinfo: Document new feature.
+       * NEWS: Mention new feature.
+
 2008-11-29  Kai Tietz  <kai.tietz@onevision.com>
 
        * config/tc-i386.c (i386_target_format): For coff flavour in TE_PEP
index 16324d6ce3ae472806b5e0908cf11a50242f2026..327782f29851438875b3e3db3cd8e1548e8ea441 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,10 @@
 -*- text -*-
 
+* The .type pseudo-op now accepts a type of STT_IFUNC which can be used to
+  indicate that if the symbol is the target of a relocation, its value should
+  not be used.  Instead the function should be invoked and its result used as
+  the value.
 Changes in 2.19:
 
 * New pseudo op .cfi_val_encoded_addr, to record constant addresses in unwind
index cf3177087ab2c3bf99c098c9f469d208721eedc3..0f0c7d30406db2f3f8b4167410b2d94cc1c3131d 100644 (file)
@@ -1663,6 +1663,20 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
            }
        }
     }
+  else if (strcmp (typename, "indirect_function") == 0
+      || strcmp (typename, "10") == 0
+      || strcmp (typename, "STT_IFUNC") == 0)
+    {
+      const struct elf_backend_data *bed;
+
+      bed = get_elf_backend_data (stdoutput);
+      if (!(bed->elf_osabi == ELFOSABI_LINUX
+           /* GNU/Linux is still using the default value 0.  */
+           || bed->elf_osabi == ELFOSABI_NONE))
+       as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
+               typename);
+      type = BSF_FUNCTION | BSF_INDIRECT_FUNCTION;
+    }
 #ifdef md_elf_symbol_type
   else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1)
     ;
index fef736a21bd83da36e0e77d18bb20773a39758cd..5a655a5bfa18869a5cbe21ad62b455c520c989b7 100644 (file)
@@ -6267,7 +6267,7 @@ The syntaxes supported are:
   .type <name> STT_<TYPE_IN_UPPER_CASE>
   .type <name>,#<type>
   .type <name>,@@<type>
-  .type <name>,%>type>
+  .type <name>,%<type>
   .type <name>,"<type>"
 @end smallexample
 
@@ -6289,6 +6289,15 @@ Mark the symbol as being a thead-local data object.
 @item STT_COMMON
 @itemx common
 Mark the symbol as being a common data object.
+
+@item STT_NOTYPE
+@itemx notype
+Does not mark the symbol in any way.  It is supported just for completeness.
+
+@item STT_IFUNC
+@itemx indirect_function
+Mark the symbol as an indirect function when evaluated during reloc
+processing.  (This is only supported on Linux targeted assemblers).
 @end table
 
 Note: Some targets support extra types in addition to those listed above.
index 60b8c907cee4add0bd4f71b550337977187a6a05..523275aa66c283de9e0dc50b836a8ca4c0bb934b 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * gas/elf/type.s: Add test of STT_IFUNC symbol type.
+       * gas/elf/type.e: Update expected disassembly.
+       * gas/elf/elf.exp: Update grep of symbol types.
+
 2008-11-27  M R Swami Reddy  <MR.Swami.Reddy@nsc.com>
 
        * gas/cr16/pic-1.s: New.
index 55069035c76cbba2cfc0f8d83bb620b9636602f1..637ce9a7d82ae6094fd495970a10f5290e06d8cd 100644 (file)
@@ -114,7 +114,7 @@ if { ([istarget "*-*-*elf*"]
     run_elf_list_test "section5" "" "-al" "-SW" "| grep \" \\\\.test\\\[0-9\\\]\""
     run_dump_test "struct" 
     run_dump_test "symver" 
-    run_elf_list_test "type" "" "" "-s" "| grep \"1 \\\[FONTC\\\]\""
+    run_elf_list_test "type" "" "" "-s" "| grep \"1 \\\[FIONTC\\\]\""
     run_dump_test "section6" 
     run_dump_test "section7" 
 }
index 50a49ab9572786301ced9f2c50f2749ba9bc6ef8..2eb352d1d0663d593640582692a327e9a2097369 100644 (file)
@@ -1,4 +1,5 @@
      .: 0+0     1 FUNC    LOCAL  DEFAULT    . function
+     .: 0+1     1 IFUNC   LOCAL  DEFAULT    . indirect_function
      .: 0+0     1 OBJECT  LOCAL  DEFAULT    . object
      .: 0+1     1 TLS     LOCAL  DEFAULT    . tls_object
      .: 0+2     1 NOTYPE  LOCAL  DEFAULT    . notype
index 11f75bf53c7d4116d6f1b7e3e474bf52ed3f3cbf..5a6476cd20c30186c4110676be17549bca7c827c 100644 (file)
@@ -2,6 +2,10 @@
         .size   function,1
         .type   function,%function
 function:
+       .byte   0x0
+        .size   indirect_function,1
+        .type   indirect_function,%indirect_function
+indirect_function:
        .byte   0x0
         .data
         .type   object,%object
index 23b6ee147a3b447d7331ff421b9d75c63bb26cac..23434c70fe3c177adb3539b55c0edea41fc0ba16 100644 (file)
@@ -1,3 +1,7 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * common.h (STT_IFUNC): Define.
+
 2008-11-27  M R Swami Reddy <MR.Swami.Reddy@nsc.com>
 
        * cr16.h (R_CR16_GOT_REGREL20, R_CR16_GOTC_REGREL20 and
index 5a0c322996dc8732ba5fdf5233582706db6accad..2424e64549d2ac1c04ad76cb707a0dcd099c5805 100644 (file)
 #define STT_RELC       8               /* Complex relocation expression */
 #define STT_SRELC      9               /* Signed Complex relocation expression */
 #define STT_LOOS       10              /* OS-specific semantics */
+#define STT_IFUNC      10              /* Symbol is an indirect code object */
 #define STT_HIOS       12              /* OS-specific semantics */
 #define STT_LOPROC     13              /* Application-specific semantics */
 #define STT_HIPROC     15              /* Application-specific semantics */
index 2adfb63ef27a1414ee0c76bf31846cf6dafb1fe1..b7d0cf2f00eb7cc10c140608869061ccdfee0854 100644 (file)
@@ -1,3 +1,11 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * NEWS: Mention new feature.
+       * pe-dll.c (process_def_file): Replace use of redundant
+       BFD_FORT_COMM_DEFAULT_VALUE with 0.
+       * scripttempl/elf.sc: Add .rel.ifunc.dyn and .rela.ifunc.dyn
+       sections.
+
 2008-12-02  Kai Tietz  <kai.tietz@onevision.com>
 
        * pe-dll.c (make_runtime_pseudo_reloc): Make symtab big enough to
diff --git a/ld/NEWS b/ld/NEWS
index e838b4ddd4182000d6aeec18bce550e43033813b..4c7dc1e6dd9995c50c7f6bf943abbb20eb178d03 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,4 +1,7 @@
 -*- text -*-
+* For GNU/Linux systems the linker will now forego processing any relocations
+  made against symbols of the STT_IFUNC type and instead emit them into
+  the resulting binary for processing by the loader.
 
 * Add CR16 ELF --embedded-relocs (used to embedded relocations into binaries 
   for Embedded-PIC code) option.
index 3e670680a8ef37f872435bd3b0931042696b5038..f5aa9dd19c6b7d5b7009c05dca4f758b163ce766 100644 (file)
@@ -633,7 +633,7 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
                 We should not export undefined symbols.  */
              if (symbols[j]->section != &bfd_und_section
                  && ((symbols[j]->flags & BSF_GLOBAL)
-                     || (symbols[j]->flags == BFD_FORT_COMM_DEFAULT_VALUE)))
+                     || (symbols[j]->flags == 0)))
                {
                  const char *sn = symbols[j]->name;
 
index 120db06490327c76d73c8c4deceb8ef7e7272c60..bb8c8080b26bdf27d6c705584fadbbb7a3fde9b1 100644 (file)
@@ -333,12 +333,20 @@ EOF
 sed -e '/^[    ]*[{}][         ]*$/d;/:[       ]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/      \1/' $COMBRELOC >> ldscripts/dyntmp.$$
 cat >> ldscripts/dyntmp.$$ <<EOF
     }
+  .rel.ifunc.dyn      ${RELOCATING-0} :
+    {
+      *(.rel.ifunc.*)
+    }
   .rela.dyn     ${RELOCATING-0} :
     {
 EOF
 sed -e '/^[    ]*[{}][         ]*$/d;/:[       ]*$/d;/\.rel\./d;s/^.*: { *\(.*\)}/      \1/' $COMBRELOC >> ldscripts/dyntmp.$$
 cat >> ldscripts/dyntmp.$$ <<EOF
     }
+  .rela.ifunc.dyn     ${RELOCATING-0} :
+    {
+      *(.rela.ifunc.*)
+    }
 EOF
 fi
 
index 7157245a24654d1ce3521cf0337a978bb5395ffb..6fd87dbf88a5d8dc23b5d7ec5ca5f809d52e9553 100644 (file)
@@ -1,3 +1,12 @@
+2008-12-03  Nick Clifton  <nickc@redhat.com>
+
+       * ld-mips-elf/reloc-1-n32.d: Updated expected output for reloc
+       descriptions.
+       * ld-mips-elf/reloc-1-n64.d: Likewise.
+       * ld-i386/ifunc.d: New test.
+       * ld-i386/ifunc.s: Source file for the new test.
+       * ld-i386/i386.exp: Run the new test.
+
 2008-11-25  Joseph Myers  <joseph@codesourcery.com>
 
        * ld-arm/thumb2-bl-undefweak.d, ld-arm/thumb2-bl-undefweak.s: New.
index 6f75f3ae375313d143ff8baaef73839c6954bf5f..0446f18fff0d0ed5ae0fa45ddb2c9931e94d5d59 100644 (file)
@@ -138,3 +138,4 @@ run_dump_test "hidden3"
 run_dump_test "protected1"
 run_dump_test "protected2"
 run_dump_test "protected3"
+run_dump_test "ifunc"
diff --git a/ld/testsuite/ld-i386/ifunc.d b/ld/testsuite/ld-i386/ifunc.d
new file mode 100644 (file)
index 0000000..4edf95d
--- /dev/null
@@ -0,0 +1,14 @@
+#name: Generatiion of dynamic relocs for STT_IFUNC symbols
+#source: ifunc.s
+#as: --32
+#ld: -melf_i386 -lc --defsym _start=0 -L/usr/lib
+#readelf: --relocs --syms
+
+Relocation section '.rel.ifunc.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+[0-9a-f]+  00000202 R_386_PC32        func\(\)     func
+[0-9a-f]+  00000102 R_386_PC32        long_fun\(\) long_func_name
+#...
+    ..: 080482e0    29 IFUNC   GLOBAL DEFAULT   10 long_func_name
+    ..: 08048300    29 IFUNC   GLOBAL DEFAULT   10 func
+#pass
diff --git a/ld/testsuite/ld-i386/ifunc.s b/ld/testsuite/ld-i386/ifunc.s
new file mode 100644 (file)
index 0000000..3f34cfb
--- /dev/null
@@ -0,0 +1,128 @@
+       .file   "ifunc.c"
+#APP
+       .type func, %indirect_function
+       .type long_func_name, %indirect_function
+       .section        .rodata.str1.1,"aMS",@progbits,1
+.LC0:
+       .string "arg is %d\n"
+#NO_APP
+       .text
+       .p2align 4,,15
+.globl bar
+       .type   bar, @function
+bar:
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $8, %esp
+       movl    8(%ebp), %eax
+       movl    $.LC0, (%esp)
+       movl    %eax, 4(%esp)
+       call    printf
+       leave
+       ret
+       .size   bar, .-bar
+       .section        .rodata.str1.1
+.LC1:
+       .string "main: calling func"
+       .section        .rodata.str1.4,"aMS",@progbits,1
+       .align 4
+.LC2:
+       .string "main: func finished, calling long_func_name"
+       .section        .rodata.str1.1
+.LC3:
+       .string "main: long_func_name finished"
+       .text
+       .p2align 4,,15
+.globl main
+       .type   main, @function
+main:
+       leal    4(%esp), %ecx
+       andl    $-16, %esp
+       pushl   -4(%ecx)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ecx
+       subl    $4, %esp
+       movl    $.LC1, (%esp)
+       call    puts
+       call    func
+       movl    $.LC2, (%esp)
+       call    puts
+       call    long_func_name
+       movl    $.LC3, (%esp)
+       call    puts
+       addl    $4, %esp
+       xorl    %eax, %eax
+       popl    %ecx
+       popl    %ebp
+       leal    -4(%ecx), %esp
+       ret
+       .size   main, .-main
+       .p2align 4,,15
+.globl long_func_name
+       .type   long_func_name, @function
+long_func_name:
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $8, %esp
+       call    rand
+       movl    $func0, %edx
+       testl   %eax, %eax
+       jne     .L7
+       movl    $func1, %edx
+.L7:
+       movl    %edx, %eax
+       leave
+       ret
+       .size   long_func_name, .-long_func_name
+       .p2align 4,,15
+.globl func
+       .type   func, @function
+func:
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $8, %esp
+       call    rand
+       movl    $func0, %edx
+       testl   %eax, %eax
+       jne     .L12
+       movl    $func1, %edx
+.L12:
+       movl    %edx, %eax
+       leave
+       ret
+       .size   func, .-func
+       .section        .rodata.str1.1
+.LC4:
+       .string "func1\n"
+       .text
+       .p2align 4,,15
+.globl func1
+       .type   func1, @function
+func1:
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $8, %esp
+       movl    $.LC4, (%esp)
+       call    puts
+       leave
+       ret
+       .size   func1, .-func1
+       .section        .rodata.str1.1
+.LC5:
+       .string "func0\n"
+       .text
+       .p2align 4,,15
+.globl func0
+       .type   func0, @function
+func0:
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $8, %esp
+       movl    $.LC5, (%esp)
+       call    puts
+       leave
+       ret
+       .size   func0, .-func0
+       .ident  "GCC: (GNU) 4.3.0 20080428 (Red Hat 4.3.0-8)"
+       .section        .note.GNU-stack,"",@progbits
index dd41822d502c4f3ca891515b31b60db4a2d32e77..87a55f9226ee2e3be2b6e1dd4052cfd3fc7401eb 100644 (file)
@@ -8,10 +8,10 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against tstarta
 #
-.* R_MIPS_HI16 .* \.text \+ ffff7ff0
-.* R_MIPS_LO16 .* \.text \+ ffff7ff0
-.* R_MIPS_HI16 .* \.text \+ ffff8000
-.* R_MIPS_LO16 .* \.text \+ ffff8000
+.* R_MIPS_HI16 .* \.text \- 8010
+.* R_MIPS_LO16 .* \.text \- 8010
+.* R_MIPS_HI16 .* \.text \8000
+.* R_MIPS_LO16 .* \.text \8000
 .* R_MIPS_HI16 .* \.text \+ 0
 .* R_MIPS_LO16 .* \.text \+ 0
 .* R_MIPS_HI16 .* \.text \+ 7ff0
@@ -21,10 +21,10 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against t32a
 #
-.* R_MIPS_HI16 .* \.text \+ ffff8010
-.* R_MIPS_LO16 .* \.text \+ ffff8010
-.* R_MIPS_HI16 .* \.text \+ ffff8020
-.* R_MIPS_LO16 .* \.text \+ ffff8020
+.* R_MIPS_HI16 .* \.text \- 7ff0
+.* R_MIPS_LO16 .* \.text \- 7ff0
+.* R_MIPS_HI16 .* \.text \- 7fe0
+.* R_MIPS_LO16 .* \.text \- 7fe0
 .* R_MIPS_HI16 .* \.text \+ 20
 .* R_MIPS_LO16 .* \.text \+ 20
 .* R_MIPS_HI16 .* \.text \+ 8010
@@ -34,10 +34,10 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_HI16 .* _start \+ ffff7ff0
-.* R_MIPS_LO16 .* _start \+ ffff7ff0
-.* R_MIPS_HI16 .* _start \+ ffff8000
-.* R_MIPS_LO16 .* _start \+ ffff8000
+.* R_MIPS_HI16 .* _start \- 8010
+.* R_MIPS_LO16 .* _start \- 8010
+.* R_MIPS_HI16 .* _start \8000
+.* R_MIPS_LO16 .* _start \8000
 .* R_MIPS_HI16 .* _start \+ 0
 .* R_MIPS_LO16 .* _start \+ 0
 .* R_MIPS_HI16 .* _start \+ 7ff0
@@ -47,10 +47,10 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against tstarta
 #
-.* R_MIPS_GOT16 .* \.text \+ ffff7ff0
-.* R_MIPS_LO16 .* \.text \+ ffff7ff0
-.* R_MIPS_GOT16 .* \.text \+ ffff8000
-.* R_MIPS_LO16 .* \.text \+ ffff8000
+.* R_MIPS_GOT16 .* \.text \- 8010
+.* R_MIPS_LO16 .* \.text \- 8010
+.* R_MIPS_GOT16 .* \.text \8000
+.* R_MIPS_LO16 .* \.text \8000
 .* R_MIPS_GOT16 .* \.text \+ 0
 .* R_MIPS_LO16 .* \.text \+ 0
 .* R_MIPS_GOT16 .* \.text \+ 7ff0
@@ -60,10 +60,10 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against t32a
 #
-.* R_MIPS_GOT16 .* \.text \+ ffff8010
-.* R_MIPS_LO16 .* \.text \+ ffff8010
-.* R_MIPS_GOT16 .* \.text \+ ffff8020
-.* R_MIPS_LO16 .* \.text \+ ffff8020
+.* R_MIPS_GOT16 .* \.text \- 7ff0
+.* R_MIPS_LO16 .* \.text \- 7ff0
+.* R_MIPS_GOT16 .* \.text \- 7fe0
+.* R_MIPS_LO16 .* \.text \- 7fe0
 .* R_MIPS_GOT16 .* \.text \+ 20
 .* R_MIPS_LO16 .* \.text \+ 20
 .* R_MIPS_GOT16 .* \.text \+ 8010
@@ -73,20 +73,20 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against sdg
 #
-.* R_MIPS_GPREL16 .* sdg \+ fffffffc
+.* R_MIPS_GPREL16 .* sdg \- 4
 .* R_MIPS_GPREL16 .* sdg \+ 0
 .* R_MIPS_GPREL16 .* sdg \+ 4
 #
 # Relocations against sdla.  .sdata should be the first piece of gp-relative
 # data, which the linker script should put _gp - 0x7ff0.
 #
-.* R_MIPS_GPREL16 .* \.sdata \+ ffff801c
-.* R_MIPS_GPREL16 .* \.sdata \+ ffff8020
-.* R_MIPS_GPREL16 .* \.sdata \+ ffff8024
+.* R_MIPS_GPREL16 .* \.sdata \- 7fe4
+.* R_MIPS_GPREL16 .* \.sdata \- 7fe0
+.* R_MIPS_GPREL16 .* \.sdata \- 7fdc
 #
 # Relocations against tstarta
 #
-.* R_MIPS_26 .* \.text \+ fffffffc
+.* R_MIPS_26 .* \.text \- 4
 .* R_MIPS_26 .* \.text \+ 0
 .* R_MIPS_26 .* \.text \+ 4
 #
@@ -98,7 +98,7 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_26 .* _start \+ fffffffc
+.* R_MIPS_26 .* _start \- 4
 .* R_MIPS_26 .* _start \+ 0
 .* R_MIPS_26 .* _start \+ 4
 #
@@ -130,10 +130,10 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_HI16 .* _start \+ ffff7ff0
-.* R_MIPS_LO16 .* _start \+ ffff7ff0
-.* R_MIPS_HI16 .* _start \+ ffff8000
-.* R_MIPS_LO16 .* _start \+ ffff8000
+.* R_MIPS_HI16 .* _start \- 8010
+.* R_MIPS_LO16 .* _start \- 8010
+.* R_MIPS_HI16 .* _start \8000
+.* R_MIPS_LO16 .* _start \8000
 .* R_MIPS_HI16 .* _start \+ 0
 .* R_MIPS_LO16 .* _start \+ 0
 .* R_MIPS_HI16 .* _start \+ 7ff0
@@ -169,15 +169,15 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against sdg
 #
-.* R_MIPS_GPREL16 .* sdg \+ fffffffc
+.* R_MIPS_GPREL16 .* sdg \- 4
 .* R_MIPS_GPREL16 .* sdg \+ 0
 .* R_MIPS_GPREL16 .* sdg \+ 4
 #
 # Relocations against sdlb
 #
-.* R_MIPS_GPREL16 .* \.sdata \+ ffff803c
-.* R_MIPS_GPREL16 .* \.sdata \+ ffff8040
-.* R_MIPS_GPREL16 .* \.sdata \+ ffff8044
+.* R_MIPS_GPREL16 .* \.sdata \- 7fc4
+.* R_MIPS_GPREL16 .* \.sdata \- 7fc0
+.* R_MIPS_GPREL16 .* \.sdata \- 7fbc
 #
 # Relocations against tstartb
 #
@@ -193,7 +193,7 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_26 .* _start \+ fffffffc
+.* R_MIPS_26 .* _start \- 4
 .* R_MIPS_26 .* _start \+ 0
 .* R_MIPS_26 .* _start \+ 4
 #pass
index 42d74ea6be204f527d0549417f667032f46bb012..2cfbe9a525037ad3c7bb1e353e80cc6bc7340a0a 100644 (file)
@@ -8,16 +8,16 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against tstarta
 #
-.* R_MIPS_HI16 .* \.text \+ f+7ff0
+.* R_MIPS_HI16 .* \.text \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+7ff0
+.* R_MIPS_LO16 .* \.text \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_HI16 .* \.text \+ f+8000
+.* R_MIPS_HI16 .* \.text \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+8000
+.* R_MIPS_LO16 .* \.text \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_HI16 .* \.text \+ 0
@@ -41,16 +41,16 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against t32a
 #
-.* R_MIPS_HI16 .* \.text \+ f+8010
+.* R_MIPS_HI16 .* \.text \- 7ff0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+8010
+.* R_MIPS_LO16 .* \.text \- 7ff0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_HI16 .* \.text \+ f+8020
+.* R_MIPS_HI16 .* \.text \- 7fe0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+8020
+.* R_MIPS_LO16 .* \.text \- 7fe0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_HI16 .* \.text \+ 20
@@ -74,16 +74,16 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_HI16 .* _start \+ f+7ff0
+.* R_MIPS_HI16 .* _start \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* _start \+ f+7ff0
+.* R_MIPS_LO16 .* _start \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_HI16 .* _start \+ f+8000
+.* R_MIPS_HI16 .* _start \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* _start \+ f+8000
+.* R_MIPS_LO16 .* _start \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_HI16 .* _start \+ 0
@@ -107,16 +107,16 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against tstarta
 #
-.* R_MIPS_GOT16 .* \.text \+ f+7ff0
+.* R_MIPS_GOT16 .* \.text \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+7ff0
+.* R_MIPS_LO16 .* \.text \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_GOT16 .* \.text \+ f+8000
+.* R_MIPS_GOT16 .* \.text \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+8000
+.* R_MIPS_LO16 .* \.text \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_GOT16 .* \.text \+ 0
@@ -140,16 +140,16 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against t32a
 #
-.* R_MIPS_GOT16 .* \.text \+ f+8010
+.* R_MIPS_GOT16 .* \.text \- 7ff0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+8010
+.* R_MIPS_LO16 .* \.text \- 7ff0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_GOT16 .* \.text \+ f+8020
+.* R_MIPS_GOT16 .* \.text \- 7fe0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* \.text \+ f+8020
+.* R_MIPS_LO16 .* \.text \- 7fe0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_GOT16 .* \.text \+ 20
@@ -173,7 +173,7 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against sdg
 #
-.* R_MIPS_GPREL16 .* sdg \+ f+fffc
+.* R_MIPS_GPREL16 .* sdg \- 4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_GPREL16 .* sdg \+ 0
@@ -186,19 +186,19 @@ Relocation section '\.rela\.text' .*
 # Relocations against sdla.  .sdata should be the first piece of gp-relative
 # data, which the linker script should put _gp - 0x7ff0.
 #
-.* R_MIPS_GPREL16 .* \.sdata \+ f+801c
+.* R_MIPS_GPREL16 .* \.sdata \- 7fe4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_GPREL16 .* \.sdata \+ f+8020
+.* R_MIPS_GPREL16 .* \.sdata \- 7fe0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_GPREL16 .* \.sdata \+ f+8024
+.* R_MIPS_GPREL16 .* \.sdata \- 7fdc
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 #
 # Relocations against tstarta
 #
-.* R_MIPS_26 .* \.text \+ f+fffc
+.* R_MIPS_26 .* \.text \- 4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_26 .* \.text \+ 0
@@ -222,7 +222,7 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_26 .* _start \+ f+fffc
+.* R_MIPS_26 .* _start \- 4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_26 .* _start \+ 0
@@ -300,16 +300,16 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_HI16 .* _start \+ f+7ff0
+.* R_MIPS_HI16 .* _start \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* _start \+ f+7ff0
+.* R_MIPS_LO16 .* _start \- 8010
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_HI16 .* _start \+ f+8000
+.* R_MIPS_HI16 .* _start \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_LO16 .* _start \+ f+8000
+.* R_MIPS_LO16 .* _start \8000
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_HI16 .* _start \+ 0
@@ -399,7 +399,7 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against sdg
 #
-.* R_MIPS_GPREL16 .* sdg \+ f+fffc
+.* R_MIPS_GPREL16 .* sdg \- 4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_GPREL16 .* sdg \+ 0
@@ -411,13 +411,13 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against sdlb
 #
-.* R_MIPS_GPREL16 .* \.sdata \+ f+803c
+.* R_MIPS_GPREL16 .* \.sdata \- 7fc4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_GPREL16 .* \.sdata \+ f+8040
+.* R_MIPS_GPREL16 .* \.sdata \- 7fc0
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
-.* R_MIPS_GPREL16 .* \.sdata \+ f+8044
+.* R_MIPS_GPREL16 .* \.sdata \- 7fbc
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 #
@@ -447,7 +447,7 @@ Relocation section '\.rela\.text' .*
 #
 # Relocations against _start
 #
-.* R_MIPS_26 .* _start \+ f+fffc
+.* R_MIPS_26 .* _start \- 4
 .* R_MIPS_NONE *
 .* R_MIPS_NONE *
 .* R_MIPS_26 .* _start \+ 0