Add .note.gnu.property runtime verification and merge support
[external/binutils.git] / bfd / elf-bfd.h
index 6c05b55..b8b0c42 100644 (file)
@@ -124,7 +124,8 @@ struct elf_link_hash_entry
   struct bfd_link_hash_entry root;
 
   /* Symbol index in output file.  This is initialized to -1.  It is
-     set to -2 if the symbol is used by a reloc.  */
+     set to -2 if the symbol is used by a reloc.  It is set to -3 if
+     this symbol is defined in a discarded section.  */
   long indx;
 
   /* Symbol index as a dynamic symbol.  Initialized to -1, and remains
@@ -702,9 +703,9 @@ struct elf_size_info {
 enum elf_reloc_type_class {
   reloc_class_normal,
   reloc_class_relative,
-  reloc_class_plt,
   reloc_class_copy,
-  reloc_class_ifunc
+  reloc_class_ifunc,
+  reloc_class_plt
 };
 
 struct elf_reloc_cookie
@@ -753,6 +754,42 @@ typedef asection * (*elf_gc_mark_hook_fn)
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
+enum elf_property_kind
+ {
+    /* A new property.  */
+    property_unknown = 0,
+    /* A property ignored by backend.  */
+    property_ignored,
+    /* A corrupt property reported by backend.  */
+    property_corrupt,
+    /* A property should be removed due to property merge.  */
+    property_remove,
+    /* A property which is a number.  */
+    property_number
+ };
+
+typedef struct elf_property
+{
+  unsigned int pr_type;
+  unsigned int pr_datasz;
+  union
+    {
+      /* For property_number, this is a number.  */
+      bfd_vma number;
+      /* Add a new one if elf_property_kind is updated.  */
+    } u;
+  enum elf_property_kind pr_kind;
+  const char *filename;
+} elf_property;
+
+typedef struct elf_property_list
+{
+  struct elf_property_list *next;
+  struct elf_property property;
+} elf_property_list;
+
+struct bfd_elf_section_reloc_data;
+
 struct elf_backend_data
 {
   /* The architecture for this backend.  */
@@ -1300,13 +1337,15 @@ struct elf_backend_data
   /* Return the section which RELOC_SEC applies to.  */
   asection *(*get_reloc_section) (asection *reloc_sec);
 
-  /* Called when setting the sh_link and sh_info fields of a section with a
-     type >= SHT_LOOS.  Returns TRUE if these fields were initialised in
-     OHEADER, FALSE otherwise.  IHEADER is the best guess matching section
-     from the input bfd IBFD.  */
-  bfd_boolean (*elf_backend_set_special_section_info_and_link)
-    (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *iheader,
-     Elf_Internal_Shdr *oheader);
+  /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
+     has a type >= SHT_LOOS.  Returns TRUE if the fields were initialised,
+     FALSE otherwise.  Can be called multiple times for a given section,
+     until it returns TRUE.  Most of the times it is called ISECTION will be
+     set to an input section that might be associated with the output section.
+     The last time that it is called, ISECTION will be set to NULL.  */
+  bfd_boolean (*elf_backend_copy_special_section_fields)
+    (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection,
+     Elf_Internal_Shdr *osection);
                
   /* Used to handle bad SHF_LINK_ORDER input.  */
   bfd_error_handler_type link_order_error_handler;
@@ -1357,6 +1396,19 @@ struct elf_backend_data
      or give an error and return FALSE.  */
   bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
 
+  /* Parse GNU properties.  Return the property kind.  If the property
+     is corrupt, issue an error message and return property_corrupt.  */
+  enum elf_property_kind (*parse_gnu_properties) (bfd *, unsigned int,
+                                                 bfd_byte *,
+                                                 unsigned int);
+
+  /* Merge GNU properties.  Return TRUE if property is updated.  */
+  bfd_boolean (*merge_gnu_properties) (bfd *, elf_property *,
+                                      elf_property *);
+
+  /* Set up GNU properties.  */
+  void (*setup_gnu_properties) (struct bfd_link_info *);
+
   /* Encoding used for compact EH tables.  */
   int (*compact_eh_encoding) (struct bfd_link_info *);
 
@@ -1758,6 +1810,10 @@ struct elf_obj_tdata
   /* Symbol buffer.  */
   void *symbuf;
 
+  /* List of GNU properties.  Will be updated by setup_gnu_properties
+     after all input GNU properties are merged for output.  */
+  elf_property_list *properties;
+
   obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
   obj_attribute_list *other_obj_attributes[2];
 
@@ -1842,6 +1898,7 @@ struct elf_obj_tdata
   (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
 #define elf_other_obj_attributes_proc(bfd) \
   (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -2046,22 +2103,24 @@ extern struct elf_strtab_hash * _bfd_elf_strtab_init
   (void);
 extern void _bfd_elf_strtab_free
   (struct elf_strtab_hash *);
-extern bfd_size_type _bfd_elf_strtab_add
+extern size_t _bfd_elf_strtab_add
   (struct elf_strtab_hash *, const char *, bfd_boolean);
 extern void _bfd_elf_strtab_addref
-  (struct elf_strtab_hash *, bfd_size_type);
+  (struct elf_strtab_hash *, size_t);
 extern void _bfd_elf_strtab_delref
-  (struct elf_strtab_hash *, bfd_size_type);
+  (struct elf_strtab_hash *, size_t);
 extern unsigned int _bfd_elf_strtab_refcount
-  (struct elf_strtab_hash *, bfd_size_type);
+  (struct elf_strtab_hash *, size_t);
 extern void _bfd_elf_strtab_clear_all_refs
-  (struct elf_strtab_hash *tab);
-extern void _bfd_elf_strtab_restore_size
-  (struct elf_strtab_hash *, bfd_size_type);
+  (struct elf_strtab_hash *);
+extern void *_bfd_elf_strtab_save
+  (struct elf_strtab_hash *);
+extern void _bfd_elf_strtab_restore
+  (struct elf_strtab_hash *, void *);
 extern bfd_size_type _bfd_elf_strtab_size
   (struct elf_strtab_hash *);
 extern bfd_size_type _bfd_elf_strtab_offset
-  (struct elf_strtab_hash *, bfd_size_type);
+  (struct elf_strtab_hash *, size_t);
 extern bfd_boolean _bfd_elf_strtab_emit
   (bfd *, struct elf_strtab_hash *);
 extern void _bfd_elf_strtab_finalize
@@ -2363,6 +2422,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
 extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
   (bfd * abfd, asection * section);
 
+/* PowerPC @tls opcode transform/validate.  */
+extern unsigned int _bfd_elf_ppc_at_tls_transform
+  (unsigned int, unsigned int);
+/* PowerPC @tprel opcode transform/validate.  */
+extern unsigned int _bfd_elf_ppc_at_tprel_transform
+  (unsigned int, unsigned int);
+/* PowerPC elf_object_p tweak.  */
+extern bfd_boolean _bfd_elf_ppc_set_arch (bfd *);
+
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
@@ -2482,6 +2550,13 @@ extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int);
 extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *);
 extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
 
+extern bfd_boolean _bfd_elf_parse_gnu_properties
+  (bfd *, Elf_Internal_Note *);
+extern elf_property * _bfd_elf_get_property
+  (bfd *, unsigned int, unsigned int);
+extern void _bfd_elf_link_setup_gnu_properties
+  (struct bfd_link_info *);
+
 /* The linker may need to keep track of the number of relocs that it
    decides to copy as dynamic relocs in check_relocs for each symbol.
    This is so that it can later discard them if they are found to be
@@ -2507,7 +2582,7 @@ extern bfd_boolean _bfd_elf_create_ifunc_sections
 extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
   (struct bfd_link_info *, struct elf_link_hash_entry *,
    struct elf_dyn_relocs **, bfd_boolean *, unsigned int,
-   unsigned int, unsigned int);
+   unsigned int, unsigned int, bfd_boolean);
 extern long _bfd_elf_ifunc_get_synthetic_symtab
   (bfd *, long, asymbol **, long, asymbol **, asymbol **, asection *,
    bfd_vma *(*) (bfd *, asymbol **, asection *, asection *));
@@ -2591,12 +2666,11 @@ extern asection _bfd_elf_large_com_section;
          bfd_boolean err;                                              \
          err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR  \
                 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);       \
-         if (!info->callbacks->undefined_symbol (info,                 \
-                                                 h->root.root.string,  \
-                                                 input_bfd,            \
-                                                 input_section,        \
-                                                 rel->r_offset, err))  \
-           return FALSE;                                               \
+         (*info->callbacks->undefined_symbol) (info,                   \
+                                               h->root.root.string,    \
+                                               input_bfd,              \
+                                               input_section,          \
+                                               rel->r_offset, err);    \
          warned = TRUE;                                                \
        }                                                               \
       (void) unresolved_reloc;                                         \