[ARC] Parse NOTE section in core dump files
[deliverable/binutils-gdb.git] / bfd / section.c
index dc8225f39d3329997b32dba497ef54c086078ef9..70cb267910a07c34435689f7f0a361637627efd1 100644 (file)
@@ -1,7 +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
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-2016 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -157,10 +155,10 @@ CODE_FRAGMENT
 .  const char *name;
 .
 .  {* A unique sequence number.  *}
-.  int id;
+.  unsigned int id;
 .
 .  {* Which section in the bfd; 0..n-1 as sections are created in a bfd.  *}
-.  int index;
+.  unsigned int index;
 .
 .  {* The next section in the list belonging to the BFD, or NULL.  *}
 .  struct bfd_section *next;
@@ -327,10 +325,19 @@ CODE_FRAGMENT
 .     sections.  *}
 .#define SEC_COFF_SHARED_LIBRARY 0x4000000
 .
+.  {* This input section should be copied to output in reverse order
+.     as an array of pointers.  This is for ELF linker internal use
+.     only.  *}
+.#define SEC_ELF_REVERSE_COPY 0x4000000
+.
 .  {* This section contains data which may be shared with other
 .     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,
@@ -338,15 +345,25 @@ 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
 .
+.  {* Indicate that section has the purecode flag set.  *}
+.#define SEC_ELF_PURECODE 0x80000000
+.
 .  {*  End of section flags.  *}
 .
 .  {* Some internal packed boolean fields.  *}
@@ -364,6 +381,12 @@ CODE_FRAGMENT
 .  {* Mark flag used by some linker backends for garbage collection.  *}
 .  unsigned int gc_mark : 1;
 .
+.  {* Section compression status.  *}
+.  unsigned int compress_status : 2;
+.#define COMPRESS_SECTION_NONE    0
+.#define COMPRESS_SECTION_DONE    1
+.#define DECOMPRESS_SECTION_SIZED 2
+.
 .  {* The following flags are used by the ELF linker. *}
 .
 .  {* Mark sections which have been allocated to segments.  *}
@@ -371,11 +394,13 @@ CODE_FRAGMENT
 .
 .  {* Type of sec_info information.  *}
 .  unsigned int sec_info_type:3;
-.#define ELF_INFO_TYPE_NONE      0
-.#define ELF_INFO_TYPE_STABS     1
-.#define ELF_INFO_TYPE_MERGE     2
-.#define ELF_INFO_TYPE_EH_FRAME  3
-.#define ELF_INFO_TYPE_JUST_SYMS 4
+.#define SEC_INFO_TYPE_NONE      0
+.#define SEC_INFO_TYPE_STABS     1
+.#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;
@@ -383,20 +408,12 @@ CODE_FRAGMENT
 .  {* Bits used by various backends.  The generic code doesn't touch
 .     these fields.  *}
 .
-.  {* 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;
-.
-.  {* 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;
+.  unsigned int sec_flg0:1;
+.  unsigned int sec_flg1:1;
+.  unsigned int sec_flg2:1;
+.  unsigned int sec_flg3:1;
+.  unsigned int sec_flg4:1;
+.  unsigned int sec_flg5:1;
 .
 .  {* End of internal packed boolean fields.  *}
 .
@@ -413,7 +430,7 @@ CODE_FRAGMENT
 .      information.  *}
 .  bfd_vma lma;
 .
-.  {* The size of the section in octets, as it will be output.
+.  {* 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>>).  *}
 .  bfd_size_type size;
@@ -428,6 +445,16 @@ CODE_FRAGMENT
 .     section size calculated on a previous linker relaxation pass.  *}
 .  bfd_size_type rawsize;
 .
+.  {* The compressed size of the section in octets.  *}
+.  bfd_size_type compressed_size;
+.
+.  {* Relaxation table. *}
+.  struct relax_table *relax;
+.
+.  {* Count of used relaxation table entries. *}
+.  int relax_count;
+.
+.
 .  {* 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
 .     input section (byte ==> smallest addressable unit on the
@@ -517,30 +544,64 @@ CODE_FRAGMENT
 .  } map_head, map_tail;
 .} asection;
 .
+.{* Relax table contains information about instructions which can
+.   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)             \
@@ -643,20 +704,20 @@ CODE_FRAGMENT
 .  {* 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,                                \
+.  {* linker_mark, linker_has_input, gc_mark, decompress_status,    *} \
+.     0,           0,                1,       0,                       \
 .                                                                      \
-.  {* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       *} \
-.     0,            0,             0,          0,                      \
+.  {* segment_mark, sec_info_type, use_rela_p,                      *} \
+.     0,            0,             0,                                  \
 .                                                                      \
-.  {* has_tls_get_addr_call, has_gp_reloc, need_finalize_relax,     *} \
-.     0,                     0,            0,                          \
+.  {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,   *} \
+.     0,        0,        0,        0,        0,        0,             \
 .                                                                      \
-.  {* reloc_done, vma, lma, size, rawsize                           *} \
-.     0,          0,   0,   0,    0,                                   \
+.  {* 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,                        \
@@ -685,10 +746,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
@@ -696,20 +757,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.  */
@@ -762,13 +824,13 @@ _bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
   return TRUE;
 }
 
+static unsigned int section_id = 0x10;  /* id 0 to 3 used by STD_SECTION.  */
+
 /* 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;
@@ -812,6 +874,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;
 }
 
 /*
@@ -822,14 +885,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 *
@@ -844,6 +901,75 @@ 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 (bfd *ibfd, 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, or if no such section exists in the same BFD and
+       IBFD is non-NULL, the next section with the same name in any input
+       BFD following IBFD.  Return NULL on finding no section.
+*/
+
+asection *
+bfd_get_next_section_by_name (bfd *ibfd, 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;
+
+  if (ibfd != NULL)
+    {
+      while ((ibfd = ibfd->link.next) != NULL)
+       {
+         asection *s = bfd_get_section_by_name (ibfd, name);
+         if (s != NULL)
+           return s;
+       }
+    }
+
+  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 (NULL, sec);
+  return sec;
+}
+
 /*
 FUNCTION
        bfd_get_section_by_name_if
@@ -883,14 +1009,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;
 }
@@ -919,7 +1042,7 @@ bfd_get_unique_section_name (bfd *abfd, const char *templat, int *count)
   char *sname;
 
   len = strlen (templat);
-  sname = bfd_malloc (len + 8);
+  sname = (char *) bfd_malloc (len + 8);
   if (sname == NULL)
     return NULL;
   memcpy (sname, templat, len);
@@ -1165,6 +1288,23 @@ bfd_make_section (bfd *abfd, const char *name)
   return bfd_make_section_with_flags (abfd, name, 0);
 }
 
+/*
+FUNCTION
+       bfd_get_next_section_id
+
+SYNOPSIS
+       int bfd_get_next_section_id (void);
+
+DESCRIPTION
+       Returns the id that the next section created will have.
+*/
+
+int
+bfd_get_next_section_id (void)
+{
+  return section_id;
+}
+
 /*
 FUNCTION
        bfd_set_section_flags
@@ -1194,6 +1334,29 @@ bfd_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
   return TRUE;
 }
 
+/*
+FUNCTION
+       bfd_rename_section
+
+SYNOPSIS
+       void bfd_rename_section
+         (bfd *abfd, asection *sec, const char *newname);
+
+DESCRIPTION
+       Rename section @var{sec} in @var{abfd} to @var{newname}.
+*/
+
+void
+bfd_rename_section (bfd *abfd, sec_ptr sec, const char *newname)
+{
+  struct section_hash_entry *sh;
+
+  sh = (struct section_hash_entry *)
+    ((char *) sec - offsetof (struct section_hash_entry, section));
+  sh->section.name = newname;
+  bfd_hash_rename (&abfd->section_htab, newname, &sh->root);
+}
+
 /*
 FUNCTION
        bfd_map_over_sections
@@ -1214,7 +1377,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, ...)
 
@@ -1414,7 +1577,10 @@ bfd_get_section_contents (bfd *abfd,
       return TRUE;
     }
 
-  sz = section->rawsize ? section->rawsize : section->size;
+  if (abfd->direction != write_direction && section->rawsize != 0)
+    sz = section->rawsize;
+  else
+    sz = section->size;
   if ((bfd_size_type) offset > sz
       || count > sz
       || offset + count > sz
@@ -1445,8 +1611,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;
     }
 
@@ -1470,19 +1636,8 @@ DESCRIPTION
 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);
+  *buf = NULL;
+  return bfd_get_full_section_contents (abfd, sec, buf);
 }
 /*
 FUNCTION
This page took 0.037301 seconds and 4 git commands to generate.