bfd/
[binutils-gdb.git] / bfd / section.c
index 72ffcd55ab77b8a69b1f62decfa333d1da4325c9..45ede06fc62e8ee1ec533c4e795e9f703e9c5b15 100644 (file)
@@ -1,6 +1,6 @@
 /* Object file "section" support for the BFD library.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004
+   2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -164,6 +164,9 @@ CODE_FRAGMENT
 .  {* The next section in the list belonging to the BFD, or NULL.  *}
 .  struct bfd_section *next;
 .
+.  {* The previous section in the list belonging to the BFD, or NULL.  *}
+.  struct bfd_section *prev;
+.
 .  {* The field flags contains attributes of the section. Some
 .     flags are read in from the object file, and some are
 .     synthesized from other information.  *}
@@ -183,23 +186,17 @@ CODE_FRAGMENT
 .     some relocation information too.  *}
 .#define SEC_RELOC      0x004
 .
-.  {* ELF reserves 4 processor specific bits and 8 operating system
-.     specific bits in sh_flags; at present we can get away with just
-.     one in communicating between the assembler and BFD, but this
-.     isn't a good long-term solution.  *}
-.#define SEC_ARCH_BIT_0 0x008
-.
 .  {* A signal to the OS that the section contains read only data.  *}
-.#define SEC_READONLY   0x010
+.#define SEC_READONLY   0x008
 .
 .  {* The section contains code only.  *}
-.#define SEC_CODE       0x020
+.#define SEC_CODE       0x010
 .
 .  {* The section contains data only.  *}
-.#define SEC_DATA       0x040
+.#define SEC_DATA       0x020
 .
 .  {* The section will reside in ROM.  *}
-.#define SEC_ROM        0x080
+.#define SEC_ROM        0x040
 .
 .  {* The section contains constructor information. This section
 .     type is used by the linker to create lists of constructors and
@@ -211,30 +208,19 @@ CODE_FRAGMENT
 .     sections called <<__CTOR_LIST__>> and relocate the data
 .     contained within - exactly the operations it would peform on
 .     standard data.  *}
-.#define SEC_CONSTRUCTOR 0x100
+.#define SEC_CONSTRUCTOR 0x080
 .
 .  {* The section has contents - a data section could be
 .     <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
 .     <<SEC_HAS_CONTENTS>>  *}
-.#define SEC_HAS_CONTENTS 0x200
+.#define SEC_HAS_CONTENTS 0x100
 .
 .  {* An instruction to the linker to not output the section
 .     even if it has information which would normally be written.  *}
-.#define SEC_NEVER_LOAD 0x400
-.
-.  {* The section is a COFF shared library section.  This flag is
-.     only for the linker.  If this type of section appears in
-.     the input file, the linker must copy it to the output file
-.     without changing the vma or size.  FIXME: Although this
-.     was originally intended to be general, it really is COFF
-.     specific (and the flag was renamed to indicate this).  It
-.     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 0x800
+.#define SEC_NEVER_LOAD 0x200
 .
 .  {* The section contains thread local data.  *}
-.#define SEC_THREAD_LOCAL 0x1000
+.#define SEC_THREAD_LOCAL 0x400
 .
 .  {* The section has GOT references.  This flag is only for the
 .     linker, and is currently only used by the elf32-hppa back end.
@@ -242,46 +228,46 @@ CODE_FRAGMENT
 .     in this section, which indicate to the linker that the section
 .     contains PIC code, and must be handled specially when doing a
 .     static link.  *}
-.#define SEC_HAS_GOT_REF 0x4000
+.#define SEC_HAS_GOT_REF 0x800
 .
 .  {* The section contains common symbols (symbols may be defined
 .     multiple times, the value of a symbol is the amount of
 .     space it requires, and the largest symbol value is the one
 .     used).  Most targets have exactly one of these (which we
 .     translate to bfd_com_section_ptr), but ECOFF has two.  *}
-.#define SEC_IS_COMMON 0x8000
+.#define SEC_IS_COMMON 0x1000
 .
 .  {* The section contains only debugging information.  For
 .     example, this is set for ELF .debug and .stab sections.
 .     strip tests this flag to see if a section can be
 .     discarded.  *}
-.#define SEC_DEBUGGING 0x10000
+.#define SEC_DEBUGGING 0x2000
 .
 .  {* The contents of this section are held in memory pointed to
 .     by the contents field.  This is checked by bfd_get_section_contents,
 .     and the data is retrieved from memory if appropriate.  *}
-.#define SEC_IN_MEMORY 0x20000
+.#define SEC_IN_MEMORY 0x4000
 .
 .  {* The contents of this section are to be excluded by the
 .     linker for executable and shared objects unless those
 .     objects are to be further relocated.  *}
-.#define SEC_EXCLUDE 0x40000
+.#define SEC_EXCLUDE 0x8000
 .
 .  {* The contents of this section are to be sorted based on the sum of
 .     the symbol and addend values specified by the associated relocation
 .     entries.  Entries without associated relocation entries will be
 .     appended to the end of the section in an unspecified order.  *}
-.#define SEC_SORT_ENTRIES 0x80000
+.#define SEC_SORT_ENTRIES 0x10000
 .
 .  {* When linking, duplicate sections of the same name should be
 .     discarded, rather than being combined into a single section as
 .     is usually done.  This is similar to how common symbols are
 .     handled.  See SEC_LINK_DUPLICATES below.  *}
-.#define SEC_LINK_ONCE 0x100000
+.#define SEC_LINK_ONCE 0x20000
 .
 .  {* If SEC_LINK_ONCE is set, this bitfield describes how the linker
 .     should handle duplicate sections.  *}
-.#define SEC_LINK_DUPLICATES 0x600000
+.#define SEC_LINK_DUPLICATES 0x40000
 .
 .  {* This value for SEC_LINK_DUPLICATES means that duplicate
 .     sections with the same name should simply be discarded.  *}
@@ -290,55 +276,69 @@ 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 0x200000
+.#define SEC_LINK_DUPLICATES_ONE_ONLY 0x80000
 .
 .  {* 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 0x400000
+.#define SEC_LINK_DUPLICATES_SAME_SIZE 0x100000
 .
 .  {* This value for SEC_LINK_DUPLICATES means that the linker
 .     should warn if any duplicate sections contain different
 .     contents.  *}
-.#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
+.#define SEC_LINK_DUPLICATES_SAME_CONTENTS \
+.  (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE)
 .
 .  {* This section was created by the linker as part of dynamic
 .     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 0x800000
+.#define SEC_LINKER_CREATED 0x200000
 .
 .  {* This section should not be subject to garbage collection.  *}
-.#define SEC_KEEP 0x1000000
+.#define SEC_KEEP 0x400000
 .
 .  {* This section contains "short" data, and should be placed
 .     "near" the GP.  *}
-.#define SEC_SMALL_DATA 0x2000000
-.
-.  {* This section contains data which may be shared with other
-.     executables or shared objects.  *}
-.#define SEC_SHARED 0x4000000
-.
-.  {* 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.  *}
-.#define SEC_BLOCK 0x8000000
-.
-.  {* Conditionally link this section; do not link if there are no
-.     references found to any symbol in the section.  *}
-.#define SEC_CLINK 0x10000000
+.#define SEC_SMALL_DATA 0x800000
 .
 .  {* Attempt to merge identical entities in the section.
 .     Entity size is given in the entsize field.  *}
-.#define SEC_MERGE 0x20000000
+.#define SEC_MERGE 0x1000000
 .
 .  {* 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 0x40000000
+.#define SEC_STRINGS 0x2000000
 .
 .  {* This section contains data about section groups.  *}
-.#define SEC_GROUP 0x80000000
+.#define SEC_GROUP 0x4000000
+.
+.  {* The section is a COFF shared library section.  This flag is
+.     only for the linker.  If this type of section appears in
+.     the input file, the linker must copy it to the output file
+.     without changing the vma or size.  FIXME: Although this
+.     was originally intended to be general, it really is COFF
+.     specific (and the flag was renamed to indicate this).  It
+.     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
+.
+.  {* This section contains data which may be shared with other
+.     executables or shared objects. This is for COFF only.  *}
+.#define SEC_COFF_SHARED 0x20000000
+.
+.  {* 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
+.
+.  {* 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
 .
 .  {*  End of section flags.  *}
 .
@@ -541,27 +541,73 @@ CODE_FRAGMENT
 .{* 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.  *}
-.#define bfd_section_list_remove(ABFD, PS) \
+.#define bfd_section_list_remove(ABFD, S) \
 .  do                                                  \
 .    {                                                 \
-.      asection **_ps = PS;                            \
-.      asection *_s = *_ps;                            \
-.      *_ps = _s->next;                                        \
-.      if (_s->next == NULL)                           \
-.        (ABFD)->section_tail = _ps;                   \
+.      asection *_s = S;                               \
+.      asection *_next = _s->next;                     \
+.      asection *_prev = _s->prev;                     \
+.      if (_prev)                                      \
+.        _prev->next = _next;                          \
+.      else                                            \
+.        (ABFD)->sections = _next;                     \
+.      if (_next)                                      \
+.        {                                             \
+.          _next->prev = _prev;                                \
+.          _s->next = NULL;                            \
+.        }                                             \
+.      else                                            \
+.        (ABFD)->section_last = _prev;                 \
+.    }                                                 \
+.  while (0)
+.#define bfd_section_list_append(ABFD, S) \
+.  do                                                  \
+.    {                                                 \
+.      asection *_s = S;                               \
+.      bfd *_abfd = ABFD;                              \
+.      _s->next = NULL;                                        \
+.      if (_abfd->section_last)                                \
+.        {                                             \
+.          _s->prev = _abfd->section_last;             \
+.          _abfd->section_last->next = _s;             \
+.        }                                             \
+.      else                                            \
+.        _abfd->sections = _s;                         \
+.      _abfd->section_last = _s;                       \
+.    }                                                 \
+.  while (0)
+.#define bfd_section_list_insert_after(ABFD, A, S) \
+.  do                                                  \
+.    {                                                 \
+.      asection *_a = A;                               \
+.      asection *_s = S;                               \
+.      asection *_next = _a->next;                     \
+.      _s->next = _next;                               \
+.      _s->prev = _a;                                  \
+.      _a->next = _s;                                  \
+.      if (_next)                                      \
+.        _s->next->prev = _s;                          \
+.      else                                            \
+.        (ABFD)->section_last = _s;                    \
 .    }                                                 \
 .  while (0)
-.#define bfd_section_list_insert(ABFD, PS, S) \
+.#define bfd_section_list_insert_before(ABFD, B, S) \
 .  do                                                  \
 .    {                                                 \
-.      asection **_ps = PS;                            \
+.      asection *_b = B;                               \
 .      asection *_s = S;                               \
-.      _s->next = *_ps;                                        \
-.      *_ps = _s;                                      \
-.      if (_s->next == NULL)                           \
-.        (ABFD)->section_tail = &_s->next;             \
+.      asection *_prev = _b->prev;                     \
+.      _s->prev = _prev;                               \
+.      _s->next = _b;                                  \
+.      _b->prev = _s;                                  \
+.      if (_prev)                                      \
+.        _prev->next = _s;                             \
+.      else                                            \
+.        (ABFD)->sections = _s;                                \
 .    }                                                 \
 .  while (0)
+.#define bfd_section_removed_from_list(ABFD, S) \
+.  ((S)->next == NULL && (S) != (ABFD)->section_last)
 .
 */
 
@@ -591,8 +637,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, flags, user_set_vma,                  */        \
-    { NAME,  IDX, 0,     NULL, FLAGS, 0,                               \
+    /* 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,                      \
@@ -704,8 +750,7 @@ bfd_section_init (bfd *abfd, asection *newsect)
 
   section_id++;
   abfd->section_count++;
-  *abfd->section_tail = newsect;
-  abfd->section_tail = &newsect->next;
+  bfd_section_list_append (abfd, newsect);
   return newsect;
 }
 
@@ -735,7 +780,7 @@ void
 bfd_section_list_clear (bfd *abfd)
 {
   abfd->sections = NULL;
-  abfd->section_tail = &abfd->sections;
+  abfd->section_last = NULL;
   abfd->section_count = 0;
   memset (abfd->section_htab.table, 0,
          abfd->section_htab.size * sizeof (struct bfd_hash_entry *));