]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/section.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / bfd / section.c
index 9547eb2c5d70fdcd17c96acda1846a9ad4675fac..d42c2b4287ef6e7504e40dde6eafda8e90fc1c14 100644 (file)
@@ -1,5 +1,5 @@
 /* Object file "section" support for the BFD library.
-   Copyright (C) 1990-2017 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -65,10 +65,7 @@ SUBSECTION
        data in place until a <<bfd_get_section_contents>> call is
        made. Other back ends may read in all the data at once.  For
        example, an S-record file has to be read once to determine the
-       size of the data. An IEEE-695 file doesn't contain raw data in
-       sections, but data and relocation expressions intermixed, so
-       the data area has to be parsed to get out the data and
-       relocations.
+       size of the data.
 
 INODE
 Section Output, typedef asection, Section Input, Sections
@@ -221,13 +218,10 @@ CODE_FRAGMENT
 .  {* The section contains thread local data.  *}
 .#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.
-.     It will be set if global offset table references were detected
-.     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                 0x800
+.  {* The section's size is fixed.  Generic linker code will not
+.     recalculate it and it is up to whoever has set this flag to
+.     get the size right.  *}
+.#define SEC_FIXED_SIZE                  0x800
 .
 .  {* The section contains common symbols (symbols may be defined
 .     multiple times, the value of a symbol is the amount of
@@ -357,6 +351,11 @@ CODE_FRAGMENT
 .  {* This section contains vliw code.  This is for Toshiba MeP only.  *}
 .#define SEC_MEP_VLIW               0x20000000
 .
+.  {* All symbols, sizes and relocations in this section are octets
+.     instead of bytes.  Required for DWARF debug sections as DWARF
+.     information is organized in octets, not bytes.  *}
+.#define SEC_ELF_OCTETS             0x40000000
+.
 .  {* Indicate that section has the no read flag set. This happens
 .     when memory read flag isn't set. *}
 .#define SEC_COFF_NOREAD            0x40000000
@@ -555,31 +554,83 @@ CODE_FRAGMENT
 .  int size;
 .};
 .
+.static inline const char *
+.bfd_section_name (const asection *sec)
+.{
+.  return sec->name;
+.}
+.
+.static inline bfd_size_type
+.bfd_section_size (const asection *sec)
+.{
+.  return sec->size;
+.}
+.
+.static inline bfd_vma
+.bfd_section_vma (const asection *sec)
+.{
+.  return sec->vma;
+.}
+.
+.static inline bfd_vma
+.bfd_section_lma (const asection *sec)
+.{
+.  return sec->lma;
+.}
+.
+.static inline unsigned int
+.bfd_section_alignment (const asection *sec)
+.{
+.  return sec->alignment_power;
+.}
+.
+.static inline flagword
+.bfd_section_flags (const asection *sec)
+.{
+.  return sec->flags;
+.}
+.
+.static inline void *
+.bfd_section_userdata (const asection *sec)
+.{
+.  return sec->userdata;
+.}
+.static inline bfd_boolean
+.bfd_is_com_section (const asection *sec)
+.{
+.  return (sec->flags & SEC_IS_COMMON) != 0;
+.}
+.
 .{* 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)
+.bfd_set_section_userdata (asection *sec, void *val)
+.{
+.  sec->userdata = val;
+.  return TRUE;
+.}
+.
+.static inline bfd_boolean
+.bfd_set_section_vma (asection *sec, bfd_vma val)
 .{
-.  ptr->userdata = val;
+.  sec->vma = sec->lma = val;
+.  sec->user_set_vma = TRUE;
 .  return TRUE;
 .}
 .
 .static inline bfd_boolean
-.bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
+.bfd_set_section_lma (asection *sec, bfd_vma val)
 .{
-.  ptr->vma = ptr->lma = val;
-.  ptr->user_set_vma = TRUE;
+.  sec->lma = val;
 .  return TRUE;
 .}
 .
 .static inline bfd_boolean
-.bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr,
-.                          unsigned int val)
+.bfd_set_section_alignment (asection *sec, unsigned int val)
 .{
-.  ptr->alignment_power = val;
+.  sec->alignment_power = val;
 .  return TRUE;
 .}
 .
@@ -602,105 +653,39 @@ CODE_FRAGMENT
 .{* Pointer to the indirect 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)             \
-. (   ((SEC) == bfd_abs_section_ptr)           \
-.  || ((SEC) == bfd_und_section_ptr)           \
-.  || ((SEC) == bfd_com_section_ptr)           \
-.  || ((SEC) == bfd_ind_section_ptr))
-.
-.{* 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, S) \
-.  do                                                  \
-.    {                                                 \
-.      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;                          \
-.      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                                            \
-.        {                                             \
-.          _s->prev = NULL;                            \
-.          _abfd->sections = _s;                       \
-.        }                                             \
-.      _abfd->section_last = _s;                       \
-.    }                                                 \
-.  while (0)
-.#define bfd_section_list_prepend(ABFD, S) \
-.  do                                                  \
-.    {                                                 \
-.      asection *_s = S;                               \
-.      bfd *_abfd = ABFD;                              \
-.      _s->prev = NULL;                                        \
-.      if (_abfd->sections)                            \
-.        {                                             \
-.          _s->next = _abfd->sections;                 \
-.          _abfd->sections->prev = _s;                 \
-.        }                                             \
-.      else                                            \
-.        {                                             \
-.          _s->next = NULL;                            \
-.          _abfd->section_last = _s;                   \
-.        }                                             \
-.      _abfd->sections = _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)                                      \
-.        _next->prev = _s;                             \
-.      else                                            \
-.        (ABFD)->section_last = _s;                    \
-.    }                                                 \
-.  while (0)
-.#define bfd_section_list_insert_before(ABFD, B, S) \
-.  do                                                  \
-.    {                                                 \
-.      asection *_b = B;                               \
-.      asection *_s = S;                               \
-.      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 ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
+.static inline bfd_boolean
+.bfd_is_und_section (const asection *sec)
+.{
+.  return sec == bfd_und_section_ptr;
+.}
+.
+.static inline bfd_boolean
+.bfd_is_abs_section (const asection *sec)
+.{
+.  return sec == bfd_abs_section_ptr;
+.}
+.
+.static inline bfd_boolean
+.bfd_is_ind_section (const asection *sec)
+.{
+.  return sec == bfd_ind_section_ptr;
+.}
+.
+.static inline bfd_boolean
+.bfd_is_const_section (const asection *sec)
+.{
+.  return sec >= bfd_abs_section_ptr && sec <= bfd_ind_section_ptr;
+.}
+.
+.{* Return TRUE if input section SEC has been discarded.  *}
+.static inline bfd_boolean
+.discarded_section (const asection *sec)
+.{
+.  return (!bfd_is_abs_section (sec)
+.          && bfd_is_abs_section (sec->output_section)
+.          && sec->sec_info_type != SEC_INFO_TYPE_MERGE
+.          && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS);
+.}
 .
 .#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS)                  \
 .  {* name, id,  index, next, prev, flags, user_set_vma,            *} \
@@ -826,21 +811,21 @@ _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.  */
+unsigned int _bfd_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)
 {
-  newsect->id = section_id;
+  newsect->id = _bfd_section_id;
   newsect->index = abfd->section_count;
   newsect->owner = abfd;
 
   if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
     return NULL;
 
-  section_id++;
+  _bfd_section_id++;
   abfd->section_count++;
   bfd_section_list_append (abfd, newsect);
   return newsect;
@@ -1290,35 +1275,17 @@ 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
 
 SYNOPSIS
-       bfd_boolean bfd_set_section_flags
-         (bfd *abfd, asection *sec, flagword flags);
+       bfd_boolean bfd_set_section_flags (asection *sec, flagword flags);
 
 DESCRIPTION
-       Set the attributes of the section @var{sec} in the BFD
-       @var{abfd} to the value @var{flags}. Return <<TRUE>> on success,
-       <<FALSE>> on error. Possible error returns are:
+       Set the attributes of the section @var{sec} to the value @var{flags}.
+       Return <<TRUE>> on success, <<FALSE>> on error.  Possible error
+       returns are:
 
        o <<bfd_error_invalid_operation>> -
        The section cannot have one or more of the attributes
@@ -1328,9 +1295,7 @@ DESCRIPTION
 */
 
 bfd_boolean
-bfd_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
-                      sec_ptr section,
-                      flagword flags)
+bfd_set_section_flags (asection *section, flagword flags)
 {
   section->flags = flags;
   return TRUE;
@@ -1342,21 +1307,21 @@ FUNCTION
 
 SYNOPSIS
        void bfd_rename_section
-         (bfd *abfd, asection *sec, const char *newname);
+         (asection *sec, const char *newname);
 
 DESCRIPTION
-       Rename section @var{sec} in @var{abfd} to @var{newname}.
+       Rename section @var{sec} to @var{newname}.
 */
 
 void
-bfd_rename_section (bfd *abfd, sec_ptr sec, const char *newname)
+bfd_rename_section (asection *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);
+  bfd_hash_rename (&sec->owner->section_htab, newname, &sh->root);
 }
 
 /*
@@ -1440,8 +1405,7 @@ FUNCTION
        bfd_set_section_size
 
 SYNOPSIS
-       bfd_boolean bfd_set_section_size
-         (bfd *abfd, asection *sec, bfd_size_type val);
+       bfd_boolean bfd_set_section_size (asection *sec, bfd_size_type val);
 
 DESCRIPTION
        Set @var{sec} to the size @var{val}. If the operation is
@@ -1454,18 +1418,18 @@ DESCRIPTION
 */
 
 bfd_boolean
-bfd_set_section_size (bfd *abfd, sec_ptr ptr, bfd_size_type val)
+bfd_set_section_size (asection *sec, bfd_size_type val)
 {
   /* Once you've started writing to any section you cannot create or change
      the size of any others.  */
 
-  if (abfd->output_has_begun)
+  if (sec->owner == NULL || sec->owner->output_has_begun)
     {
       bfd_set_error (bfd_error_invalid_operation);
       return FALSE;
     }
 
-  ptr->size = val;
+  sec->size = val;
   return TRUE;
 }
 
@@ -1480,16 +1444,20 @@ SYNOPSIS
 
 DESCRIPTION
        Sets the contents of the section @var{section} in BFD
-       @var{abfd} to the data starting in memory at @var{data}. The
-       data is written to the output section starting at offset
+       @var{abfd} to the data starting in memory at @var{location}.
+       The data is written to the output section starting at offset
        @var{offset} for @var{count} octets.
 
-       Normally <<TRUE>> is returned, else <<FALSE>>. Possible error
-       returns are:
+       Normally <<TRUE>> is returned, but <<FALSE>> is returned if
+       there was an error.  Possible error returns are:
        o <<bfd_error_no_contents>> -
        The output section does not have the <<SEC_HAS_CONTENTS>>
        attribute, so nothing can be written to it.
-       o and some more too
+       o <<bfd_error_bad_value>> -
+       The section is unable to contain all of the data.
+       o <<bfd_error_invalid_operation>> -
+       The BFD is not writeable.
+       o and some more too.
 
        This routine is front end to the back end function
        <<_bfd_set_section_contents>>.
@@ -1505,7 +1473,7 @@ bfd_set_section_contents (bfd *abfd,
 {
   bfd_size_type sz;
 
-  if (!(bfd_get_section_flags (abfd, section) & SEC_HAS_CONTENTS))
+  if (!(bfd_section_flags (section) & SEC_HAS_CONTENTS))
     {
       bfd_set_error (bfd_error_no_contents);
       return FALSE;
@@ -1681,6 +1649,24 @@ bfd_generic_is_group_section (bfd *abfd ATTRIBUTE_UNUSED,
   return FALSE;
 }
 
+/*
+FUNCTION
+       bfd_generic_group_name
+
+SYNOPSIS
+       const char *bfd_generic_group_name (bfd *, const asection *sec);
+
+DESCRIPTION
+       Returns group name if @var{sec} is a member of a group.
+*/
+
+const char *
+bfd_generic_group_name (bfd *abfd ATTRIBUTE_UNUSED,
+                       const asection *sec ATTRIBUTE_UNUSED)
+{
+  return NULL;
+}
+
 /*
 FUNCTION
        bfd_generic_discard_group
@@ -1698,3 +1684,13 @@ bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED,
 {
   return TRUE;
 }
+
+bfd_boolean
+_bfd_nowrite_set_section_contents (bfd *abfd,
+                                  sec_ptr section ATTRIBUTE_UNUSED,
+                                  const void *location ATTRIBUTE_UNUSED,
+                                  file_ptr offset ATTRIBUTE_UNUSED,
+                                  bfd_size_type count ATTRIBUTE_UNUSED)
+{
+  return _bfd_bool_bfd_false_error (abfd);
+}