bfd/
[external/binutils.git] / bfd / section.c
index 0236f08..b9272db 100644 (file)
@@ -149,23 +149,6 @@ SUBSECTION
 
 CODE_FRAGMENT
 .
-.{* This structure is used for a comdat section, as in PE.  A comdat
-.   section is associated with a particular symbol.  When the linker
-.   sees a comdat section, it keeps only one of the sections with a
-.   given name and associated with a given symbol.  *}
-.
-.struct bfd_comdat_info
-.{
-.  {* The name of the symbol associated with a comdat section.  *}
-.  const char *name;
-.
-.  {* The local symbol table index of the symbol associated with a
-.     comdat section.  This is only meaningful to the object file format
-.     specific code; it is not an index into the list returned by
-.     bfd_canonicalize_symtab.  *}
-.  long symbol;
-.};
-.
 .typedef struct bfd_section
 .{
 .  {* The name of the section; the name isn't a copy, the pointer is
@@ -364,9 +347,6 @@ CODE_FRAGMENT
 .  {* See the vma field.  *}
 .  unsigned int user_set_vma : 1;
 .
-.  {* Whether relocations have been processed.  *}
-.  unsigned int reloc_done : 1;
-.
 .  {* A mark flag used by some of the linker backends.  *}
 .  unsigned int linker_mark : 1;
 .
@@ -394,21 +374,18 @@ CODE_FRAGMENT
 .  unsigned int use_rela_p:1;
 .
 .  {* Bits used by various backends.  *}
-.  unsigned int has_tls_reloc:1;
 .
-.  {* Nonzero if this section needs the relax finalize pass.  *}
-.  unsigned int need_finalize_relax:1;
+.  {* Nonzero if this section has TLS related relocations.  *}
+.  unsigned int has_tls_reloc:1;
 .
 .  {* Nonzero if this section has a gp reloc.  *}
 .  unsigned int has_gp_reloc:1;
 .
-.  {* Unused bits.  *}
-.  unsigned int flag13:1;
-.  unsigned int flag14:1;
-.  unsigned int flag15:1;
-.  unsigned int flag16:4;
-.  unsigned int flag20:4;
-.  unsigned int flag24:8;
+.  {* Nonzero if this section needs the relax finalize pass.  *}
+.  unsigned int need_finalize_relax:1;
+.
+.  {* Whether relocations have been processed.  *}
+.  unsigned int reloc_done : 1;
 .
 .  {* End of internal packed boolean fields.  *}
 .
@@ -427,13 +404,18 @@ CODE_FRAGMENT
 .
 .  {* The size of the section in octets, as it will be output.
 .     Contains a value even if the section has no contents (e.g., the
-.     size of <<.bss>>).  This will be filled in after relocation.  *}
-.  bfd_size_type _cooked_size;
-.
-.  {* The original size on disk of the section, in octets.  Normally this
-.     value is the same as the size, but if some relaxing has
-.     been done, then this value will be bigger.  *}
-.  bfd_size_type _raw_size;
+.     size of <<.bss>>).  *}
+.  bfd_size_type size;
+.
+.  {* For input sections, the original size on disk of the section, in
+.     octets.  This field is used by the linker relaxation code.  It is
+.     currently only set for sections where the linker relaxation scheme
+.     doesn't cache altered section and reloc contents (stabs, eh_frame,
+.     SEC_MERGE, some coff relaxing targets), and thus the original size
+.     needs to be kept to read the section multiple times.
+.     For output sections, rawsize holds the section size calculated on
+.     a previous linker relaxation pass.  *}
+.  bfd_size_type rawsize;
 .
 .  {* If this section is going to be output, then this value is the
 .     offset in *bytes* into the output section of the first byte in the
@@ -490,9 +472,6 @@ CODE_FRAGMENT
 .  {* Entity size for merging purposes.  *}
 .  unsigned int entsize;
 .
-.  {* Optional information about a COMDAT entry; NULL if not COMDAT.  *}
-.  struct bfd_comdat_info *comdat;
-.
 .  {* Points to the kept section if this section is a link-once section,
 .     and is discarded.  *}
 .  struct bfd_section *kept_section;
@@ -557,11 +536,6 @@ CODE_FRAGMENT
 .extern const struct bfd_symbol * const bfd_com_symbol;
 .extern const struct bfd_symbol * const bfd_und_symbol;
 .extern const struct bfd_symbol * const bfd_ind_symbol;
-.#define bfd_get_section_size_before_reloc(section) \
-.     ((section)->_raw_size)
-.#define bfd_get_section_size_after_reloc(section) \
-.     ((section)->reloc_done ? (section)->_cooked_size \
-.                            : (abort (), (bfd_size_type) 1))
 .
 .{* Macros to handle insertion and deletion of a bfd's sections.  These
 .   only handle the list pointers, ie. do not adjust section_count,
@@ -616,25 +590,22 @@ 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, flags, user_set_vma, reloc_done,      */        \
-    { NAME,  IDX, 0,     NULL, FLAGS, 0,            0,                 \
+    /* name, id,  index, next, flags, user_set_vma,                  */        \
+    { NAME,  IDX, 0,     NULL, FLAGS, 0,                               \
                                                                        \
     /* linker_mark, linker_has_input, gc_mark, segment_mark,         */        \
        0,           0,                1,       0,                      \
                                                                        \
-    /* sec_info_type, use_rela_p, has_tls_reloc,                     */ \
-       0,            0,          0,                                    \
+    /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc,       */ \
+       0,            0,          0,             0,                     \
                                                                        \
-    /* need_finalize_relax, has_gp_reloc,                            */ \
+    /* need_finalize_relax, reloc_done,                              */ \
        0,                  0,                                          \
                                                                        \
-    /* flag13, flag14, flag15, flag16, flag20, flag24,               */ \
-       0,      0,      0,      0,      0,      0,                      \
-                                                                       \
-    /* vma, lma, _cooked_size, _raw_size,                            */        \
-       0,   0,   0,            0,                                      \
+    /* vma, lma, size, rawsize                                       */        \
+       0,   0,   0,    0,                                              \
                                                                        \
-    /* output_offset, output_section,      alignment_power,          */        \
+    /* output_offset, output_section,              alignment_power,  */        \
        0,             (struct bfd_section *) &SEC, 0,                  \
                                                                        \
     /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */        \
@@ -643,8 +614,8 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */        \
        0,            NULL,     NULL,     NULL,   0,                    \
                                                                        \
-    /* entsize, comdat, kept_section, moving_line_filepos,           */        \
-       0,       NULL,   NULL,        0,                                \
+    /* entsize, kept_section, moving_line_filepos,                */   \
+       0,       NULL,        0,                                        \
                                                                        \
     /* target_index, used_by_bfd, constructor_chain, owner,          */        \
        0,            NULL,        NULL,              NULL,             \
@@ -801,6 +772,57 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
 
 /*
 FUNCTION
+       bfd_get_section_by_name_if
+
+SYNOPSIS
+       asection *bfd_get_section_by_name_if
+         (bfd *abfd,
+          const char *name,
+          bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+          void *obj);
+
+DESCRIPTION
+       Call the provided function @var{func} for each section
+       attached to the BFD @var{abfd} whose name matches @var{name},
+       passing @var{obj} as an argument. The function will be called
+       as if by
+
+|      func (abfd, the_section, obj);
+
+       It returns the first section for which @var{func} returns true,
+       otherwise <<NULL>>.
+
+*/
+
+asection *
+bfd_get_section_by_name_if (bfd *abfd, const char *name,
+                           bfd_boolean (*operation) (bfd *,
+                                                     asection *,
+                                                     void *),
+                           void *user_storage)
+{
+  struct section_hash_entry *sh;
+  unsigned long hash;
+
+  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+  if (sh == NULL)
+    return NULL;
+
+  hash = sh->root.hash;
+  do
+    {
+      if ((*operation) (abfd, &sh->section, user_storage))
+       return &sh->section;
+      sh = (struct section_hash_entry *) sh->root.next;
+    }
+  while (sh != NULL && sh->root.hash == hash
+        && strcmp (sh->root.string, name) == 0);
+
+  return NULL;
+}
+
+/*
+FUNCTION
        bfd_get_unique_section_name
 
 SYNOPSIS
@@ -955,7 +977,7 @@ bfd_make_section_anyway (bfd *abfd, const char *name)
       if (new_sh == NULL)
        return NULL;
 
-      new_sh->root.next = sh->root.next;
+      new_sh->root = sh->root;
       sh->root.next = &new_sh->root;
       newsect = &new_sh->section;
     }
@@ -1159,9 +1181,7 @@ bfd_set_section_size (bfd *abfd, sec_ptr ptr, bfd_size_type val)
       return FALSE;
     }
 
-  ptr->_cooked_size = val;
-  ptr->_raw_size = val;
-
+  ptr->size = val;
   return TRUE;
 }
 
@@ -1192,11 +1212,6 @@ DESCRIPTION
 
 */
 
-#define bfd_get_section_size_now(abfd, sec) \
-  (sec->reloc_done \
-   ? bfd_get_section_size_after_reloc (sec) \
-   : bfd_get_section_size_before_reloc (sec))
-
 bfd_boolean
 bfd_set_section_contents (bfd *abfd,
                          sec_ptr section,
@@ -1212,7 +1227,7 @@ bfd_set_section_contents (bfd *abfd,
       return FALSE;
     }
 
-  sz = bfd_get_section_size_now (abfd, section);
+  sz = section->size;
   if ((bfd_size_type) offset > sz
       || count > sz
       || offset + count > sz
@@ -1292,9 +1307,7 @@ bfd_get_section_contents (bfd *abfd,
       return TRUE;
     }
 
-  /* Even if reloc_done is TRUE, this function reads unrelocated
-     contents, so we want the raw size.  */
-  sz = section->_raw_size;
+  sz = section->rawsize ? section->rawsize : section->size;
   if ((bfd_size_type) offset > sz
       || count > sz
       || offset + count > sz
@@ -1326,6 +1339,36 @@ bfd_get_section_contents (bfd *abfd,
 
 /*
 FUNCTION
+       bfd_malloc_and_get_section
+
+SYNOPSIS
+       bfd_boolean bfd_malloc_and_get_section
+         (bfd *abfd, asection *section, bfd_byte **buf);
+
+DESCRIPTION
+       Read all data from @var{section} in BFD @var{abfd}
+       into a buffer, *@var{buf}, malloc'd by this function.
+*/
+
+bfd_boolean
+bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf)
+{
+  bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
+  bfd_byte *p = NULL;
+
+  *buf = p;
+  if (sz == 0)
+    return TRUE;
+
+  p = bfd_malloc (sec->rawsize > sec->size ? sec->rawsize : sec->size);
+  if (p == NULL)
+    return FALSE;
+  *buf = p;
+
+  return bfd_get_section_contents (abfd, sec, p, 0, sz);
+}
+/*
+FUNCTION
        bfd_copy_private_section_data
 
 SYNOPSIS