bfd_get_section_by_name_if hash chain traversal
[deliverable/binutils-gdb.git] / bfd / section.c
index 9eb7f690aafa41c2ae106d30e18d94896d8a2086..aa652a41d79ac3b08f699d40644e69a880bdd407 100644 (file)
@@ -1,8 +1,5 @@
 /* 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, 2006, 2007, 2008, 2009, 2010, 2011,
-   2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -337,6 +334,10 @@ CODE_FRAGMENT
 .     executables or shared objects. This is for COFF only.  *}
 .#define SEC_COFF_SHARED 0x8000000
 .
+.  {* This section should be compressed.  This is for ELF linker
+.     internal use only.  *}
+.#define SEC_ELF_COMPRESS 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,
@@ -344,11 +345,18 @@ CODE_FRAGMENT
 .     TMS320C54X only.  *}
 .#define SEC_TIC54X_BLOCK 0x10000000
 .
+.  {* This section should be renamed.  This is for ELF linker
+.     internal use only.  *}
+.#define SEC_ELF_RENAME 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 0x20000000
 .
+.  {* This section contains vliw code.  This is for Toshiba MeP only.  *}
+.#define SEC_MEP_VLIW 0x20000000
+.
 .  {* Indicate that section has the no read flag set. This happens
 .     when memory read flag isn't set. *}
 .#define SEC_COFF_NOREAD 0x40000000
@@ -388,6 +396,8 @@ CODE_FRAGMENT
 .#define SEC_INFO_TYPE_MERGE     2
 .#define SEC_INFO_TYPE_EH_FRAME  3
 .#define SEC_INFO_TYPE_JUST_SYMS 4
+.#define SEC_INFO_TYPE_TARGET    5
+.#define SEC_INFO_TYPE_EH_FRAME_ENTRY 6
 .
 .  {* Nonzero if this section uses RELA relocations, rather than REL.  *}
 .  unsigned int use_rela_p:1;
@@ -517,9 +527,6 @@ CODE_FRAGMENT
 .  {* The BFD which owns the section.  *}
 .  bfd *owner;
 .
-.  {* INPUT_SECTION_FLAGS if specified in the linker script.  *}
-.  struct flag_info *section_flag_info;
-.
 .  {* A symbol which points at this section only.  *}
 .  struct bfd_symbol *symbol;
 .  struct bfd_symbol **symbol_ptr_ptr;
@@ -535,40 +542,63 @@ CODE_FRAGMENT
 .} asection;
 .
 .{* Relax table contains information about instructions which can
-.   be removed by relaxation -- replacing a long address with a 
+.   be removed by relaxation -- replacing a long address with a
 .   short address.  *}
 .struct relax_table {
 .  {* Address where bytes may be deleted. *}
 .  bfd_vma addr;
-.  
+.
 .  {* Number of bytes to be deleted.  *}
 .  int size;
 .};
 .
+.{* Note: the following are provided as inline functions rather than macros
+.   because not all callers use the return value.  A macro implementation
+.   would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
+.   compilers will complain about comma expressions that have no effect.  *}
+.static inline bfd_boolean
+.bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
+.{
+.  ptr->userdata = val;
+.  return TRUE;
+.}
+.
+.static inline bfd_boolean
+.bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
+.{
+.  ptr->vma = ptr->lma = val;
+.  ptr->user_set_vma = TRUE;
+.  return TRUE;
+.}
+.
+.static inline bfd_boolean
+.bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
+.{
+.  ptr->alignment_power = val;
+.  return TRUE;
+.}
+.
 .{* These sections are global, and are managed by BFD.  The application
 .   and target back end are not permitted to change the values in
-.   these sections.  New code should use the section_ptr macros rather
-.   than referring directly to the const sections.  The const sections
-.   may eventually vanish.  *}
+.   these sections.  *}
+.extern asection _bfd_std_section[4];
+.
 .#define BFD_ABS_SECTION_NAME "*ABS*"
 .#define BFD_UND_SECTION_NAME "*UND*"
 .#define BFD_COM_SECTION_NAME "*COM*"
 .#define BFD_IND_SECTION_NAME "*IND*"
 .
-.{* The absolute section.  *}
-.extern asection bfd_abs_section;
-.#define bfd_abs_section_ptr ((asection *) &bfd_abs_section)
-.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
-.{* Pointer to the undefined section.  *}
-.extern asection bfd_und_section;
-.#define bfd_und_section_ptr ((asection *) &bfd_und_section)
-.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
 .{* Pointer to the common section.  *}
-.extern asection bfd_com_section;
-.#define bfd_com_section_ptr ((asection *) &bfd_com_section)
+.#define bfd_com_section_ptr (&_bfd_std_section[0])
+.{* Pointer to the undefined section.  *}
+.#define bfd_und_section_ptr (&_bfd_std_section[1])
+.{* Pointer to the absolute section.  *}
+.#define bfd_abs_section_ptr (&_bfd_std_section[2])
 .{* Pointer to the indirect section.  *}
-.extern asection bfd_ind_section;
-.#define bfd_ind_section_ptr ((asection *) &bfd_ind_section)
+.#define bfd_ind_section_ptr (&_bfd_std_section[3])
+.
+.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
 .#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
 .
 .#define bfd_is_const_section(SEC)             \
@@ -683,8 +713,8 @@ CODE_FRAGMENT
 .  {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \
 .     0,   0,   0,    0,       0,               0,     0,              \
 .                                                                      \
-.  {* output_offset, output_section,              alignment_power,  *} \
-.     0,             (struct bfd_section *) &SEC, 0,                   \
+.  {* output_offset, output_section, alignment_power,               *} \
+.     0,             &SEC,           0,                                        \
 .                                                                      \
 .  {* relocation, orelocation, reloc_count, filepos, rel_filepos,   *} \
 .     NULL,       NULL,        0,           0,       0,                        \
@@ -698,9 +728,6 @@ CODE_FRAGMENT
 .  {* target_index, used_by_bfd, constructor_chain, owner,          *} \
 .     0,            NULL,        NULL,              NULL,              \
 .                                                                      \
-.  {* flag_info,                                                   *}  \
-.     NULL,                                                            \
-.                                                                      \
 .  {* symbol,                    symbol_ptr_ptr,                    *} \
 .     (struct bfd_symbol *) SYM, &SEC.symbol,                          \
 .                                                                      \
@@ -716,10 +743,10 @@ CODE_FRAGMENT
  /* the_bfd, name, value, attr, section [, udata] */
 #ifdef __STDC__
 #define GLOBAL_SYM_INIT(NAME, SECTION) \
-  { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION, { 0 }}
+  { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }}
 #else
 #define GLOBAL_SYM_INIT(NAME, SECTION) \
-  { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION }
+  { 0, NAME, 0, BSF_SECTION_SYM, SECTION }
 #endif
 
 /* These symbols are global, not specific to any BFD.  Therefore, anything
@@ -727,20 +754,21 @@ CODE_FRAGMENT
 
 static const asymbol global_syms[] =
 {
-  GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, &bfd_com_section),
-  GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, &bfd_und_section),
-  GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, &bfd_abs_section),
-  GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section)
+  GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, bfd_com_section_ptr),
+  GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, bfd_und_section_ptr),
+  GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, bfd_abs_section_ptr),
+  GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, bfd_ind_section_ptr)
 };
 
-#define STD_SECTION(SEC, FLAGS, NAME, IDX)                             \
-  asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX],       \
-                                 NAME, IDX)
+#define STD_SECTION(NAME, IDX, FLAGS) \
+  BFD_FAKE_SECTION(_bfd_std_section[IDX], FLAGS, &global_syms[IDX], NAME, IDX)
 
-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);
+asection _bfd_std_section[] = {
+  STD_SECTION (BFD_COM_SECTION_NAME, 0, SEC_IS_COMMON),
+  STD_SECTION (BFD_UND_SECTION_NAME, 1, 0),
+  STD_SECTION (BFD_ABS_SECTION_NAME, 2, 0),
+  STD_SECTION (BFD_IND_SECTION_NAME, 3, 0)
+};
 #undef STD_SECTION
 
 /* Initialize an entry in the section hash table.  */
@@ -843,6 +871,7 @@ bfd_section_list_clear (bfd *abfd)
   abfd->section_count = 0;
   memset (abfd->section_htab.table, 0,
          abfd->section_htab.size * sizeof (struct bfd_hash_entry *));
+  abfd->section_htab.count = 0;
 }
 
 /*
@@ -853,14 +882,8 @@ SYNOPSIS
        asection *bfd_get_section_by_name (bfd *abfd, const char *name);
 
 DESCRIPTION
-       Run through @var{abfd} and return the one of the
-       <<asection>>s whose name matches @var{name}, otherwise <<NULL>>.
-       @xref{Sections}, for more information.
-
-       This should only be used in special cases; the normal way to process
-       all sections of a given name is to use <<bfd_map_over_sections>> and
-       <<strcmp>> on the name (or better yet, base it on the section flags
-       or something else) for each section.
+       Return the most recently created section attached to @var{abfd}
+       named @var{name}.  Return NULL if no such section exists.
 */
 
 asection *
@@ -875,6 +898,63 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
   return NULL;
 }
 
+/*
+FUNCTION
+       bfd_get_next_section_by_name
+
+SYNOPSIS
+       asection *bfd_get_next_section_by_name (asection *sec);
+
+DESCRIPTION
+       Given @var{sec} is a section returned by @code{bfd_get_section_by_name},
+       return the next most recently created section attached to the same
+       BFD with the same name.  Return NULL if no such section exists.
+*/
+
+asection *
+bfd_get_next_section_by_name (asection *sec)
+{
+  struct section_hash_entry *sh;
+  const char *name;
+  unsigned long hash;
+
+  sh = ((struct section_hash_entry *)
+       ((char *) sec - offsetof (struct section_hash_entry, section)));
+
+  hash = sh->root.hash;
+  name = sec->name;
+  for (sh = (struct section_hash_entry *) sh->root.next;
+       sh != NULL;
+       sh = (struct section_hash_entry *) sh->root.next)
+    if (sh->root.hash == hash
+       && strcmp (sh->root.string, name) == 0)
+      return &sh->section;
+
+  return NULL;
+}
+
+/*
+FUNCTION
+       bfd_get_linker_section
+
+SYNOPSIS
+       asection *bfd_get_linker_section (bfd *abfd, const char *name);
+
+DESCRIPTION
+       Return the linker created section attached to @var{abfd}
+       named @var{name}.  Return NULL if no such section exists.
+*/
+
+asection *
+bfd_get_linker_section (bfd *abfd, const char *name)
+{
+  asection *sec = bfd_get_section_by_name (abfd, name);
+
+  while (sec != NULL && (sec->flags & SEC_LINKER_CREATED) == 0)
+    sec = bfd_get_next_section_by_name (sec);
+  return sec;
+}
+
 /*
 FUNCTION
        bfd_get_section_by_name_if
@@ -914,14 +994,11 @@ bfd_get_section_by_name_if (bfd *abfd, const char *name,
     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);
+  for (; sh != NULL; sh = (struct section_hash_entry *) sh->root.next)
+    if (sh->root.hash == hash
+       && strcmp (sh->root.string, name) == 0
+       && (*operation) (abfd, &sh->section, user_storage))
+      return &sh->section;
 
   return NULL;
 }
@@ -1268,7 +1345,7 @@ DESCRIPTION
        This is the preferred method for iterating over sections; an
        alternative would be to use a loop:
 
-|         section *p;
+|         asection *p;
 |         for (p = abfd->sections; p != NULL; p = p->next)
 |            func (abfd, p, ...)
 
@@ -1502,8 +1579,8 @@ bfd_get_section_contents (bfd *abfd,
          bfd_set_error (bfd_error_invalid_operation);
          return FALSE;
        }
-      
-      memcpy (location, section->contents + offset, (size_t) count);
+
+      memmove (location, section->contents + offset, (size_t) count);
       return TRUE;
     }
 
This page took 0.027184 seconds and 4 git commands to generate.