2005-07-25 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 25 Jul 2005 15:35:37 +0000 (15:35 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 25 Jul 2005 15:35:37 +0000 (15:35 +0000)
* elf-bfd.h (elf_backend_data): Add common_definition,
common_section_index, common_section, and merge_symbol.
(_bfd_elf_common_definition): New.
(_bfd_elf_common_section_index): New.
(_bfd_elf_common_section): New.

* elf.c (elf_fake_sections): Don't clear sh_flags.

* elflink.c (_bfd_elf_merge_symbol): Call backend merge_symbol
if it is available.
(is_global_data_symbol_definition): Call backend
common_definition instead of checking SHN_COMMON.
(elf_link_add_object_symbols): Likewise.
(elf_link_output_extsym): Call backend common_section_index
for common section index.
(_bfd_elf_common_definition): New.
(_bfd_elf_common_section_index): New.
(_bfd_elf_common_section): New.

* elfxx-target.h (elf_backend_common_definition): New.
(elf_backend_common_section_index): New.
(elf_backend_common_section): New.
(elf_backend_merge_symbol): New.
(elfNN_bed): Initialize common_definition, common_section_index,
common_section, and merge_symbol.

* section.c (BFD_FAKE_SECTION): New.
(STD_SECTION): Use it.
* bfd-in2.h: Regenerated.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf-bfd.h
bfd/elf.c
bfd/elflink.c
bfd/elfxx-target.h
bfd/section.c

index 495ea9547cba99e7ff47afbfa2e39e698a6f2cec..64d98178e16d6382256c539f54dcf734b7c22373 100644 (file)
@@ -1,3 +1,35 @@
+2005-07-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf-bfd.h (elf_backend_data): Add common_definition,
+       common_section_index, common_section, and merge_symbol.
+       (_bfd_elf_common_definition): New.
+       (_bfd_elf_common_section_index): New.
+       (_bfd_elf_common_section): New.
+
+       * elf.c (elf_fake_sections): Don't clear sh_flags.
+
+       * elflink.c (_bfd_elf_merge_symbol): Call backend merge_symbol
+       if it is available.
+       (is_global_data_symbol_definition): Call backend
+       common_definition instead of checking SHN_COMMON.
+       (elf_link_add_object_symbols): Likewise.
+       (elf_link_output_extsym): Call backend common_section_index
+       for common section index.
+       (_bfd_elf_common_definition): New.
+       (_bfd_elf_common_section_index): New.
+       (_bfd_elf_common_section): New.
+
+       * elfxx-target.h (elf_backend_common_definition): New.
+       (elf_backend_common_section_index): New.
+       (elf_backend_common_section): New.
+       (elf_backend_merge_symbol): New.
+       (elfNN_bed): Initialize common_definition, common_section_index,
+       common_section, and merge_symbol.
+
+       * section.c (BFD_FAKE_SECTION): New.
+       (STD_SECTION): Use it.
+       * bfd-in2.h: Regenerated.
+
 2005-07-23  Olaf Hering <olh@suse.de>
 
        * elflink.c (elf_link_input_bfd): Add '\n' for linker einfo
index c9c75c2b8f187bd0f689577f982fc7d2903c0bc7..7dbfe95cb6c317c692402c302003eab7370b8f1f 100644 (file)
@@ -1551,6 +1551,47 @@ extern const struct bfd_symbol * const bfd_ind_symbol;
 #define bfd_section_removed_from_list(ABFD, S) \
   ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
 
+#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX)          \
+  /* name, id,  index, next, prev, flags, user_set_vma,            */  \
+  { NAME,  IDX, 0,     NULL, NULL, FLAGS, 0,                           \
+                                                                       \
+  /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh,      */  \
+     0,           0,                1,       0,                        \
+                                                                       \
+  /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       */  \
+     0,            0,             0,          0,                       \
+                                                                       \
+  /* has_gp_reloc, need_finalize_relax, reloc_done,                */  \
+     0,            0,                   0,                             \
+                                                                       \
+  /* vma, lma, size, rawsize                                       */  \
+     0,   0,   0,    0,                                                \
+                                                                       \
+  /* output_offset, output_section,              alignment_power,  */  \
+     0,             (struct bfd_section *) &SEC, 0,                    \
+                                                                       \
+  /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */  \
+     NULL,       NULL,        0,           0,       0,                 \
+                                                                       \
+  /* line_filepos, userdata, contents, lineno, lineno_count,       */  \
+     0,            NULL,     NULL,     NULL,   0,                      \
+                                                                       \
+  /* entsize, kept_section, moving_line_filepos,                    */ \
+     0,       NULL,          0,                                        \
+                                                                       \
+  /* target_index, used_by_bfd, constructor_chain, owner,          */  \
+     0,            NULL,        NULL,              NULL,               \
+                                                                       \
+  /* symbol,                                                       */  \
+     (struct bfd_symbol *) SYM,                                        \
+                                                                       \
+  /* symbol_ptr_ptr,                                               */  \
+     (struct bfd_symbol **) SYM_PTR,                                   \
+                                                                       \
+  /* map_head, map_tail                                            */  \
+     { NULL }, { NULL }                                                \
+    }
+
 void bfd_section_list_clear (bfd *);
 
 asection *bfd_get_section_by_name (bfd *abfd, const char *name);
index 2bbc1c923dec1c7f940d6edfb17748d54caf86c0..f7bab5ca82392e6f2f53ffc7b5a550dfa0e55ab1 100644 (file)
@@ -969,6 +969,30 @@ struct elf_backend_data
      see elf.c.  */
   bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *);
 
+  /* Is symbol defined in common section?  */
+  bfd_boolean (*common_definition) (Elf_Internal_Sym *);
+
+  /* Return a common section index for section.  */
+  unsigned int (*common_section_index) (asection *);
+
+  /* Return a common section for section.  */
+  asection *(*common_section) (asection *);
+
+  /* Return TRUE if we can merge 2 definitions.  */
+  bfd_boolean (*merge_symbol) (struct bfd_link_info *,
+                              struct elf_link_hash_entry **,
+                              struct elf_link_hash_entry *,
+                              Elf_Internal_Sym *, asection **,
+                              bfd_vma *, unsigned int *,
+                              bfd_boolean *, bfd_boolean *,
+                              bfd_boolean *, bfd_boolean *,
+                              bfd_boolean *, bfd_boolean *,
+                              bfd_boolean *, bfd_boolean *,
+                              bfd *, asection **,
+                              bfd_boolean *, bfd_boolean *,
+                              bfd_boolean *, bfd_boolean *,
+                              bfd *, asection **);
+
   /* Used to handle bad SHF_LINK_ORDER input.  */
   bfd_error_handler_type link_order_error_handler;
 
@@ -1741,6 +1765,15 @@ extern int bfd_elf_link_record_local_dynamic_symbol
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
+extern bfd_boolean _bfd_elf_common_definition
+  (Elf_Internal_Sym *);
+
+extern unsigned int _bfd_elf_common_section_index
+  (asection *);
+
+extern asection *_bfd_elf_common_section
+  (asection *);
+
 extern void _bfd_dwarf2_cleanup_debug_info
   (bfd *);
 
index ff46a5e2ea97ee11a30826fab7b82da610f5b376..3e47b021aa17b6da29d0784d17a9759b520a9075 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2618,7 +2618,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
       return;
     }
 
-  this_hdr->sh_flags = 0;
+  /* Don't clear sh_flags. Assembler may set additional bits.  */
 
   if ((asect->flags & SEC_ALLOC) != 0
       || asect->user_set_vma)
index 901b5280657739ad66800f8b9aa7ee5e935423b0..f52d3070ca2490bf7e5342563677cdbaa4c8b44b 100644 (file)
@@ -780,6 +780,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   bfd *oldbfd;
   bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
   bfd_boolean newweak, oldweak;
+  const struct elf_backend_data *bed;
 
   *skip = FALSE;
   *override = FALSE;
@@ -1121,6 +1122,19 @@ _bfd_elf_merge_symbol (bfd *abfd,
   else
     olddyncommon = FALSE;
 
+  /* We now know everything about the old and new symbols.  We ask the
+     backend to check if we can merge them.  */
+  bed = get_elf_backend_data (abfd);
+  if (bed->merge_symbol
+      && !bed->merge_symbol (info, sym_hash, h, sym, psec, pvalue,
+                            pold_alignment, skip, override,
+                            type_change_ok, size_change_ok,
+                            &newdyn, &newdef, &newdyncommon, &newweak,
+                            abfd, &sec,
+                            &olddyn, &olddef, &olddyncommon, &oldweak,
+                            oldbfd, &oldsec))
+    return FALSE;
+
   /* If both the old and the new symbols look like common symbols in a
      dynamic object, set the size of the symbol to the larger of the
      two.  */
@@ -1197,7 +1211,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
       newdef = FALSE;
       newdyncommon = FALSE;
       *pvalue = sym->st_size;
-      *psec = sec = bfd_com_section_ptr;
+      *psec = sec = bed->common_section (oldsec);
       *size_change_ok = TRUE;
     }
 
@@ -2641,6 +2655,8 @@ static bfd_boolean
 is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED,
                                  Elf_Internal_Sym *sym)
 {
+  const struct elf_backend_data *bed;
+
   /* Local symbols do not count, but target specific ones might.  */
   if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL
       && ELF_ST_BIND (sym->st_info) < STB_LOOS)
@@ -2656,7 +2672,8 @@ is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED,
 
   /* If the symbol is defined in the common section, then
      it is a common definition and so does not count.  */
-  if (sym->st_shndx == SHN_COMMON)
+  bed = get_elf_backend_data (abfd);
+  if (bed->common_definition (sym))
     return FALSE;
 
   /* If the symbol is in a target specific section then we
@@ -3548,6 +3565,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       bfd_boolean type_change_ok;
       bfd_boolean new_weakdef;
       bfd_boolean override;
+      bfd_boolean common;
       unsigned int old_alignment;
       bfd *old_bfd;
 
@@ -3557,6 +3575,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       sec = NULL;
       value = isym->st_value;
       *sym_hash = NULL;
+      common = bed->common_definition (isym);
 
       bind = ELF_ST_BIND (isym->st_info);
       if (bind == STB_LOCAL)
@@ -3569,8 +3588,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
        }
       else if (bind == STB_GLOBAL)
        {
-         if (isym->st_shndx != SHN_UNDEF
-             && isym->st_shndx != SHN_COMMON)
+         if (isym->st_shndx != SHN_UNDEF && !common)
            flags = BSF_GLOBAL;
        }
       else if (bind == STB_WEAK)
@@ -3861,13 +3879,12 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
        }
 
       /* Set the alignment of a common symbol.  */
-      if ((isym->st_shndx == SHN_COMMON
-          || bfd_is_com_section (sec))
+      if ((common || bfd_is_com_section (sec))
          && h->root.type == bfd_link_hash_common)
        {
          unsigned int align;
 
-         if (isym->st_shndx == SHN_COMMON)
+         if (common)
            align = bfd_log2 (isym->st_value);
          else
            {
@@ -3893,7 +3910,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
             definition or a common symbol is ignored due to the old
             normal definition. We need to make sure the maximum
             alignment is maintained.  */
-         if ((old_alignment || isym->st_shndx == SHN_COMMON)
+         if ((old_alignment || common)
              && h->root.type != bfd_link_hash_common)
            {
              unsigned int common_align;
@@ -6498,7 +6515,7 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
 
     case bfd_link_hash_common:
       input_sec = h->root.u.c.p->section;
-      sym.st_shndx = SHN_COMMON;
+      sym.st_shndx = bed->common_section_index (input_sec);
       sym.st_value = 1 << h->root.u.c.p->alignment_power;
       break;
 
@@ -9900,3 +9917,21 @@ _bfd_elf_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
 {
   bfd_link_hash_traverse (info->hash, fix_syms, obfd);
 }
+
+bfd_boolean
+_bfd_elf_common_definition (Elf_Internal_Sym *sym)
+{
+  return sym->st_shndx == SHN_COMMON;
+}
+
+unsigned int
+_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED)
+{
+  return SHN_COMMON;
+}
+
+asection *
+_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED)
+{
+  return bfd_com_section_ptr;
+}
index cd63244033e8dfff18fad7a967ad09db10ab3b12..0268e62eb38f36558ca36b936069950de35a39f1 100644 (file)
 #define elf_backend_link_order_error_handler _bfd_default_error_handler
 #endif
 
+#ifndef elf_backend_common_definition
+#define elf_backend_common_definition _bfd_elf_common_definition
+#endif
+
+#ifndef elf_backend_common_section_index
+#define elf_backend_common_section_index _bfd_elf_common_section_index
+#endif
+
+#ifndef elf_backend_common_section
+#define elf_backend_common_section _bfd_elf_common_section
+#endif
+
+#ifndef elf_backend_merge_symbol
+#define elf_backend_merge_symbol NULL
+#endif
+
 extern const struct elf_size_info _bfd_elfNN_size_info;
 
 #ifndef INCLUDED_TARGET_FILE
@@ -590,6 +606,10 @@ static const struct elf_backend_data elfNN_bed =
   elf_backend_ecoff_debug_swap,
   elf_backend_bfd_from_remote_memory,
   elf_backend_plt_sym_val,
+  elf_backend_common_definition,
+  elf_backend_common_section_index,
+  elf_backend_common_section,
+  elf_backend_merge_symbol,
   elf_backend_link_order_error_handler,
   elf_backend_relplt_name,
   ELF_MACHINE_ALT1,
index aeb63a67425aa4be93a55a843ede13d47401c106..42554b9a63e788a44f3225660cee435303a937c2 100644 (file)
@@ -635,6 +635,47 @@ CODE_FRAGMENT
 .#define bfd_section_removed_from_list(ABFD, S) \
 .  ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
 .
+.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX)         \
+.  {* name, id,  index, next, prev, flags, user_set_vma,            *} \
+.  { NAME,  IDX, 0,     NULL, NULL, FLAGS, 0,                          \
+.                                                                      \
+.  {* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh,      *} \
+.     0,           0,                1,       0,                       \
+.                                                                      \
+.  {* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       *} \
+.     0,            0,             0,          0,                      \
+.                                                                      \
+.  {* has_gp_reloc, need_finalize_relax, reloc_done,                *} \
+.     0,            0,                   0,                            \
+.                                                                      \
+.  {* vma, lma, size, rawsize                                       *} \
+.     0,   0,   0,    0,                                               \
+.                                                                      \
+.  {* output_offset, output_section,              alignment_power,  *} \
+.     0,             (struct bfd_section *) &SEC, 0,                   \
+.                                                                      \
+.  {* relocation, orelocation, reloc_count, filepos, rel_filepos,   *} \
+.     NULL,       NULL,        0,           0,       0,                        \
+.                                                                      \
+.  {* line_filepos, userdata, contents, lineno, lineno_count,       *} \
+.     0,            NULL,     NULL,     NULL,   0,                     \
+.                                                                      \
+.  {* entsize, kept_section, moving_line_filepos,                   *} \
+.     0,       NULL,         0,                                        \
+.                                                                      \
+.  {* target_index, used_by_bfd, constructor_chain, owner,          *} \
+.     0,            NULL,        NULL,              NULL,              \
+.                                                                      \
+.  {* symbol,                                                       *} \
+.     (struct bfd_symbol *) SYM,                                       \
+.                                                                      \
+.  {* symbol_ptr_ptr,                                               *} \
+.     (struct bfd_symbol **) SYM_PTR,                                  \
+.                                                                      \
+.  {* map_head, map_tail                                            *} \
+.     { NULL }, { NULL }                                               \
+.    }
+.
 */
 
 /* We use a macro to initialize the static asymbol structures because
@@ -662,46 +703,8 @@ static const asymbol global_syms[] =
 
 #define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)                                \
   const asymbol * const SYM = (asymbol *) &global_syms[IDX];           \
-  asection SEC =                                                       \
-    /* name, id,  index, next, prev, flags, user_set_vma,            */        \
-    { NAME,  IDX, 0,     NULL, NULL, FLAGS, 0,                         \
-                                                                       \
-    /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh,      */        \
-       0,           0,                1,       0,                      \
-                                                                       \
-    /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       */        \
-       0,            0,             0,          0,                     \
-                                                                       \
-    /* has_gp_reloc, need_finalize_relax, reloc_done,                */        \
-       0,            0,                   0,                           \
-                                                                       \
-    /* vma, lma, size, rawsize                                       */        \
-       0,   0,   0,    0,                                              \
-                                                                       \
-    /* output_offset, output_section,              alignment_power,  */        \
-       0,             (struct bfd_section *) &SEC, 0,                  \
-                                                                       \
-    /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */        \
-       NULL,       NULL,        0,           0,       0,               \
-                                                                       \
-    /* line_filepos, userdata, contents, lineno, lineno_count,       */        \
-       0,            NULL,     NULL,     NULL,   0,                    \
-                                                                       \
-    /* entsize, kept_section, moving_line_filepos,                   */        \
-       0,       NULL,         0,                                       \
-                                                                       \
-    /* target_index, used_by_bfd, constructor_chain, owner,          */        \
-       0,            NULL,        NULL,              NULL,             \
-                                                                       \
-    /* symbol,                                                       */        \
-       (struct bfd_symbol *) &global_syms[IDX],                                \
-                                                                       \
-    /* symbol_ptr_ptr,                                               */        \
-       (struct bfd_symbol **) &SYM,                                    \
-                                                                       \
-    /* map_head, map_tail                                            */        \
-       { NULL }, { NULL }                                              \
-    }
+  asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], &SYM, \
+                                 NAME, IDX)
 
 STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
             BFD_COM_SECTION_NAME, 0);
This page took 0.04319 seconds and 4 git commands to generate.