include/elf/
[deliverable/binutils-gdb.git] / bfd / section.c
index b3b6230f7b8df5efa6fd47f34dc5a1e915b2f539..d804dd614b7a0c6d2d5f1008e85a62d25e725807 100644 (file)
@@ -1,24 +1,25 @@
 /* Object file "section" support for the BFD library.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02110-1301, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 /*
 SECTION
@@ -133,8 +134,8 @@ SUBSECTION
 
 */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 
@@ -267,7 +268,7 @@ CODE_FRAGMENT
 .
 .  {* If SEC_LINK_ONCE is set, this bitfield describes how the linker
 .     should handle duplicate sections.  *}
-.#define SEC_LINK_DUPLICATES 0x40000
+.#define SEC_LINK_DUPLICATES 0xc0000
 .
 .  {* This value for SEC_LINK_DUPLICATES means that duplicate
 .     sections with the same name should simply be discarded.  *}
@@ -276,11 +277,11 @@ CODE_FRAGMENT
 .  {* This value for SEC_LINK_DUPLICATES means that the linker
 .     should warn if there are any duplicate sections, although
 .     it should still only link one copy.  *}
-.#define SEC_LINK_DUPLICATES_ONE_ONLY 0x80000
+.#define SEC_LINK_DUPLICATES_ONE_ONLY 0x40000
 .
 .  {* This value for SEC_LINK_DUPLICATES means that the linker
 .     should warn if any duplicate sections are a different size.  *}
-.#define SEC_LINK_DUPLICATES_SAME_SIZE 0x100000
+.#define SEC_LINK_DUPLICATES_SAME_SIZE 0x80000
 .
 .  {* This value for SEC_LINK_DUPLICATES means that the linker
 .     should warn if any duplicate sections contain different
@@ -292,26 +293,28 @@ CODE_FRAGMENT
 .     relocation or other arcane processing.  It is skipped when
 .     going through the first-pass output, trusting that someone
 .     else up the line will take care of it later.  *}
-.#define SEC_LINKER_CREATED 0x200000
+.#define SEC_LINKER_CREATED 0x100000
 .
-.  {* This section should not be subject to garbage collection.  *}
-.#define SEC_KEEP 0x400000
+.  {* This section should not be subject to garbage collection.
+.     Also set to inform the linker that this section should not be
+.     listed in the link map as discarded.  *}
+.#define SEC_KEEP 0x200000
 .
 .  {* This section contains "short" data, and should be placed
 .     "near" the GP.  *}
-.#define SEC_SMALL_DATA 0x800000
+.#define SEC_SMALL_DATA 0x400000
 .
 .  {* Attempt to merge identical entities in the section.
 .     Entity size is given in the entsize field.  *}
-.#define SEC_MERGE 0x1000000
+.#define SEC_MERGE 0x800000
 .
 .  {* If given with SEC_MERGE, entities to merge are zero terminated
 .     strings where entsize specifies character size instead of fixed
 .     size entries.  *}
-.#define SEC_STRINGS 0x2000000
+.#define SEC_STRINGS 0x1000000
 .
 .  {* This section contains data about section groups.  *}
-.#define SEC_GROUP 0x4000000
+.#define SEC_GROUP 0x2000000
 .
 .  {* The section is a COFF shared library section.  This flag is
 .     only for the linker.  If this type of section appears in
@@ -322,23 +325,23 @@ CODE_FRAGMENT
 .     might be cleaner to have some more general mechanism to
 .     allow the back end to control what the linker does with
 .     sections.  *}
-.#define SEC_COFF_SHARED_LIBRARY 0x10000000
+.#define SEC_COFF_SHARED_LIBRARY 0x4000000
 .
 .  {* This section contains data which may be shared with other
 .     executables or shared objects. This is for COFF only.  *}
-.#define SEC_COFF_SHARED 0x20000000
+.#define SEC_COFF_SHARED 0x8000000
 .
 .  {* When a section with this flag is being linked, then if the size of
 .     the input section is less than a page, it should not cross a page
 .     boundary.  If the size of the input section is one page or more,
 .     it should be aligned on a page boundary.  This is for TI
 .     TMS320C54X only.  *}
-.#define SEC_TIC54X_BLOCK 0x40000000
+.#define SEC_TIC54X_BLOCK 0x10000000
 .
 .  {* Conditionally link this section; do not link if there are no
 .     references found to any symbol in the section.  This is for TI
 .     TMS320C54X only.  *}
-.#define SEC_TIC54X_CLINK 0x80000000
+.#define SEC_TIC54X_CLINK 0x20000000
 .
 .  {*  End of section flags.  *}
 .
@@ -354,7 +357,7 @@ CODE_FRAGMENT
 .     output sections that have an input section.  *}
 .  unsigned int linker_has_input : 1;
 .
-.  {* A mark flag used by some linker backends for garbage collection.  *}
+.  {* Mark flag used by some linker backends for garbage collection.  *}
 .  unsigned int gc_mark : 1;
 .
 .  {* The following flags are used by the ELF linker. *}
@@ -379,6 +382,9 @@ CODE_FRAGMENT
 .  {* Nonzero if this section has TLS related relocations.  *}
 .  unsigned int has_tls_reloc:1;
 .
+.  {* Nonzero if this section has a call to __tls_get_addr.  *}
+.  unsigned int has_tls_get_addr_call:1;
+.
 .  {* Nonzero if this section has a gp reloc.  *}
 .  unsigned int has_gp_reloc:1;
 .
@@ -409,13 +415,13 @@ CODE_FRAGMENT
 .  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.  *}
+.     octets.  This field should be set for any section whose size is
+.     changed by linker relaxation.  It is required 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
@@ -539,11 +545,6 @@ CODE_FRAGMENT
 .  || ((SEC) == bfd_com_section_ptr)           \
 .  || ((SEC) == bfd_ind_section_ptr))
 .
-.extern const struct bfd_symbol * const bfd_abs_symbol;
-.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;
-.
 .{* Macros to handle insertion and deletion of a bfd's sections.  These
 .   only handle the list pointers, ie. do not adjust section_count,
 .   target_index etc.  *}
@@ -634,6 +635,44 @@ 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, 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,                       *} \
+.     0,           0,                1,                                \
+.                                                                      \
+.  {* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       *} \
+.     0,            0,             0,          0,                      \
+.                                                                      \
+.  {* has_tls_get_addr_call, has_gp_reloc, need_finalize_relax,     *} \
+.     0,                     0,            0,                          \
+.                                                                      \
+.  {* reloc_done, vma, lma, size, rawsize                           *} \
+.     0,          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,                    symbol_ptr_ptr,                    *} \
+.     (struct bfd_symbol *) SYM, &SEC.symbol,                          \
+.                                                                      \
+.  {* map_head, map_tail                                            *} \
+.     { NULL }, { NULL }                                               \
+.    }
+.
 */
 
 /* We use a macro to initialize the static asymbol structures because
@@ -659,62 +698,16 @@ static const asymbol global_syms[] =
   GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section)
 };
 
-#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, segment_mark,         */        \
-       0,           0,                1,       0,                      \
-                                                                       \
-    /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc,       */ \
-       0,            0,          0,             0,                     \
-                                                                       \
-    /* need_finalize_relax, reloc_done,                              */ \
-       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 }                                              \
-    }
+#define STD_SECTION(SEC, FLAGS, NAME, IDX)                             \
+  asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX],       \
+                                 NAME, IDX)
 
-STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
-            BFD_COM_SECTION_NAME, 0);
-STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1);
-STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2);
-STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3);
+STD_SECTION (bfd_com_section, SEC_IS_COMMON, BFD_COM_SECTION_NAME, 0);
+STD_SECTION (bfd_und_section, 0, BFD_UND_SECTION_NAME, 1);
+STD_SECTION (bfd_abs_section, 0, BFD_ABS_SECTION_NAME, 2);
+STD_SECTION (bfd_ind_section, 0, BFD_IND_SECTION_NAME, 3);
 #undef STD_SECTION
 
-struct section_hash_entry
-{
-  struct bfd_hash_entry root;
-  asection section;
-};
-
 /* Initialize an entry in the section hash table.  */
 
 struct bfd_hash_entry *
@@ -745,23 +738,16 @@ bfd_section_hash_newfunc (struct bfd_hash_entry *entry,
   ((struct section_hash_entry *) \
    bfd_hash_lookup ((table), (string), (create), (copy)))
 
-/* Initializes a new section.  NEWSECT->NAME is already set.  */
+/* Create a symbol whose only job is to point to this section.  This
+   is useful for things like relocs which are relative to the base
+   of a section.  */
 
-static asection *
-bfd_section_init (bfd *abfd, asection *newsect)
+bfd_boolean
+_bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
 {
-  static int section_id = 0x10;  /* id 0 to 3 used by STD_SECTION.  */
-
-  newsect->id = section_id;
-  newsect->index = abfd->section_count;
-  newsect->owner = abfd;
-
-  /* Create a symbol whose only job is to point to this section.  This
-     is useful for things like relocs which are relative to the base
-     of a section.  */
   newsect->symbol = bfd_make_empty_symbol (abfd);
   if (newsect->symbol == NULL)
-    return NULL;
+    return FALSE;
 
   newsect->symbol->name = newsect->name;
   newsect->symbol->value = 0;
@@ -769,6 +755,19 @@ bfd_section_init (bfd *abfd, asection *newsect)
   newsect->symbol->flags = BSF_SECTION_SYM;
 
   newsect->symbol_ptr_ptr = &newsect->symbol;
+  return TRUE;
+}
+
+/* Initializes a new section.  NEWSECT->NAME is already set.  */
+
+static asection *
+bfd_section_init (bfd *abfd, asection *newsect)
+{
+  static int section_id = 0x10;  /* id 0 to 3 used by STD_SECTION.  */
+
+  newsect->id = section_id;
+  newsect->index = abfd->section_count;
+  newsect->owner = abfd;
 
   if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
     return NULL;
@@ -966,7 +965,6 @@ DESCRIPTION
 asection *
 bfd_make_section_old_way (bfd *abfd, const char *name)
 {
-  struct section_hash_entry *sh;
   asection *newsect;
 
   if (abfd->output_has_begun)
@@ -976,43 +974,53 @@ bfd_make_section_old_way (bfd *abfd, const char *name)
     }
 
   if (strcmp (name, BFD_ABS_SECTION_NAME) == 0)
-    return bfd_abs_section_ptr;
-
-  if (strcmp (name, BFD_COM_SECTION_NAME) == 0)
-    return bfd_com_section_ptr;
-
-  if (strcmp (name, BFD_UND_SECTION_NAME) == 0)
-    return bfd_und_section_ptr;
+    newsect = bfd_abs_section_ptr;
+  else if (strcmp (name, BFD_COM_SECTION_NAME) == 0)
+    newsect = bfd_com_section_ptr;
+  else if (strcmp (name, BFD_UND_SECTION_NAME) == 0)
+    newsect = bfd_und_section_ptr;
+  else if (strcmp (name, BFD_IND_SECTION_NAME) == 0)
+    newsect = bfd_ind_section_ptr;
+  else
+    {
+      struct section_hash_entry *sh;
 
-  if (strcmp (name, BFD_IND_SECTION_NAME) == 0)
-    return bfd_ind_section_ptr;
+      sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+      if (sh == NULL)
+       return NULL;
 
-  sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
-  if (sh == NULL)
-    return NULL;
+      newsect = &sh->section;
+      if (newsect->name != NULL)
+       {
+         /* Section already exists.  */
+         return newsect;
+       }
 
-  newsect = &sh->section;
-  if (newsect->name != NULL)
-    {
-      /* Section already exists.  */
-      return newsect;
+      newsect->name = name;
+      return bfd_section_init (abfd, newsect);
     }
 
-  newsect->name = name;
-  return bfd_section_init (abfd, newsect);
+  /* Call new_section_hook when "creating" the standard abs, com, und
+     and ind sections to tack on format specific section data.
+     Also, create a proper section symbol.  */
+  if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
+    return NULL;
+  return newsect;
 }
 
 /*
 FUNCTION
-       bfd_make_section_anyway
+       bfd_make_section_anyway_with_flags
 
 SYNOPSIS
-       asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+       asection *bfd_make_section_anyway_with_flags
+         (bfd *abfd, const char *name, flagword flags);
 
 DESCRIPTION
    Create a new empty section called @var{name} and attach it to the end of
    the chain of sections for @var{abfd}.  Create a new section even if there
-   is already a section with that name.
+   is already a section with that name.  Also set the attributes of the
+   new section to the value @var{flags}.
 
    Return <<NULL>> and set <<bfd_error>> on error; possible errors are:
    o <<bfd_error_invalid_operation>> - If output has already started for @var{abfd}.
@@ -1020,7 +1028,8 @@ DESCRIPTION
 */
 
 sec_ptr
-bfd_make_section_anyway (bfd *abfd, const char *name)
+bfd_make_section_anyway_with_flags (bfd *abfd, const char *name,
+                                   flagword flags)
 {
   struct section_hash_entry *sh;
   asection *newsect;
@@ -1053,26 +1062,53 @@ bfd_make_section_anyway (bfd *abfd, const char *name)
       newsect = &new_sh->section;
     }
 
+  newsect->flags = flags;
   newsect->name = name;
   return bfd_section_init (abfd, newsect);
 }
 
 /*
 FUNCTION
-       bfd_make_section
+       bfd_make_section_anyway
 
 SYNOPSIS
-       asection *bfd_make_section (bfd *, const char *name);
+       asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+
+DESCRIPTION
+   Create a new empty section called @var{name} and attach it to the end of
+   the chain of sections for @var{abfd}.  Create a new section even if there
+   is already a section with that name.
+
+   Return <<NULL>> and set <<bfd_error>> on error; possible errors are:
+   o <<bfd_error_invalid_operation>> - If output has already started for @var{abfd}.
+   o <<bfd_error_no_memory>> - If memory allocation fails.
+*/
+
+sec_ptr
+bfd_make_section_anyway (bfd *abfd, const char *name)
+{
+  return bfd_make_section_anyway_with_flags (abfd, name, 0);
+}
+
+/*
+FUNCTION
+       bfd_make_section_with_flags
+
+SYNOPSIS
+       asection *bfd_make_section_with_flags
+         (bfd *, const char *name, flagword flags);
 
 DESCRIPTION
    Like <<bfd_make_section_anyway>>, but return <<NULL>> (without calling
    bfd_set_error ()) without changing the section chain if there is already a
-   section named @var{name}.  If there is an error, return <<NULL>> and set
+   section named @var{name}.  Also set the attributes of the new section to
+   the value @var{flags}.  If there is an error, return <<NULL>> and set
    <<bfd_error>>.
 */
 
 asection *
-bfd_make_section (bfd *abfd, const char *name)
+bfd_make_section_with_flags (bfd *abfd, const char *name,
+                            flagword flags)
 {
   struct section_hash_entry *sh;
   asection *newsect;
@@ -1101,9 +1137,30 @@ bfd_make_section (bfd *abfd, const char *name)
     }
 
   newsect->name = name;
+  newsect->flags = flags;
   return bfd_section_init (abfd, newsect);
 }
 
+/*
+FUNCTION
+       bfd_make_section
+
+SYNOPSIS
+       asection *bfd_make_section (bfd *, const char *name);
+
+DESCRIPTION
+   Like <<bfd_make_section_anyway>>, but return <<NULL>> (without calling
+   bfd_set_error ()) without changing the section chain if there is already a
+   section named @var{name}.  If there is an error, return <<NULL>> and set
+   <<bfd_error>>.
+*/
+
+asection *
+bfd_make_section (bfd *abfd, const char *name)
+{
+  return bfd_make_section_with_flags (abfd, name, 0);
+}
+
 /*
 FUNCTION
        bfd_set_section_flags
@@ -1295,22 +1352,10 @@ bfd_set_section_contents (bfd *abfd,
       return FALSE;
     }
 
-  switch (abfd->direction)
+  if (!bfd_write_p (abfd))
     {
-    case read_direction:
-    case no_direction:
       bfd_set_error (bfd_error_invalid_operation);
       return FALSE;
-
-    case write_direction:
-      break;
-
-    case both_direction:
-      /* File is opened for update. `output_has_begun' some time ago when
-          the file was created.  Do not recompute sections sizes or alignments
-          in _bfd_set_section_content.  */
-      abfd->output_has_begun = TRUE;
-      break;
     }
 
   /* Record a copy of the data in memory if desired.  */
This page took 0.031276 seconds and 4 git commands to generate.