Fix illegal memory access parsing a corrupt MACH-O format file.
[deliverable/binutils-gdb.git] / bfd / section.c
index 161ed33edc47d8e96929fb6e00a195b96b2f3010..a35348833d9c7456edfa3fc8f3bd583fd47694e0 100644 (file)
@@ -1,5 +1,5 @@
 /* Object file "section" support for the BFD library.
-   Copyright (C) 1990-2020 Free Software Foundation, Inc.
+   Copyright (C) 1990-2021 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -292,7 +292,7 @@ CODE_FRAGMENT
 .#define SEC_LINKER_CREATED           0x100000
 .
 .  {* This section contains a section ID to distinguish different
-.     sections withe the same section name.  *}
+.     sections with the same section name.  *}
 .#define SEC_ASSEMBLER_SECTION_ID     0x100000
 .
 .  {* This section should not be subject to garbage collection.
@@ -544,11 +544,17 @@ CODE_FRAGMENT
 .  {* Early in the link process, map_head and map_tail are used to build
 .     a list of input sections attached to an output section.  Later,
 .     output sections use these fields for a list of bfd_link_order
-.     structs.  *}
+.     structs.  The linked_to_symbol_name field is for ELF assembler
+.     internal use.  *}
 .  union {
 .    struct bfd_link_order *link_order;
 .    struct bfd_section *s;
+.    const char *linked_to_symbol_name;
 .  } map_head, map_tail;
+. {* Points to the output section this section is already assigned to, if any.
+.    This is used when support for non-contiguous memory regions is enabled.  *}
+. struct bfd_section *already_assigned;
+.
 .} asection;
 .
 .{* Relax table contains information about instructions which can
@@ -603,7 +609,7 @@ CODE_FRAGMENT
 .{
 .  return sec->userdata;
 .}
-.static inline bfd_boolean
+.static inline bool
 .bfd_is_com_section (const asection *sec)
 .{
 .  return (sec->flags & SEC_IS_COMMON) != 0;
@@ -613,33 +619,33 @@ CODE_FRAGMENT
 .   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
+.static inline bool
 .bfd_set_section_userdata (asection *sec, void *val)
 .{
 .  sec->userdata = val;
-.  return TRUE;
+.  return true;
 .}
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_set_section_vma (asection *sec, bfd_vma val)
 .{
 .  sec->vma = sec->lma = val;
-.  sec->user_set_vma = TRUE;
-.  return TRUE;
+.  sec->user_set_vma = true;
+.  return true;
 .}
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_set_section_lma (asection *sec, bfd_vma val)
 .{
 .  sec->lma = val;
-.  return TRUE;
+.  return true;
 .}
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_set_section_alignment (asection *sec, unsigned int val)
 .{
 .  sec->alignment_power = val;
-.  return TRUE;
+.  return true;
 .}
 .
 .{* These sections are global, and are managed by BFD.  The application
@@ -661,32 +667,34 @@ CODE_FRAGMENT
 .{* Pointer to the indirect section.  *}
 .#define bfd_ind_section_ptr (&_bfd_std_section[3])
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_is_und_section (const asection *sec)
 .{
 .  return sec == bfd_und_section_ptr;
 .}
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_is_abs_section (const asection *sec)
 .{
 .  return sec == bfd_abs_section_ptr;
 .}
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_is_ind_section (const asection *sec)
 .{
 .  return sec == bfd_ind_section_ptr;
 .}
 .
-.static inline bfd_boolean
+.static inline bool
 .bfd_is_const_section (const asection *sec)
 .{
-.  return sec >= bfd_abs_section_ptr && sec <= bfd_ind_section_ptr;
+.  return (sec >= _bfd_std_section
+.          && sec < _bfd_std_section + (sizeof (_bfd_std_section)
+.                                       / sizeof (_bfd_std_section[0])));
 .}
 .
 .{* Return TRUE if input section SEC has been discarded.  *}
-.static inline bfd_boolean
+.static inline bool
 .discarded_section (const asection *sec)
 .{
 .  return (!bfd_is_abs_section (sec)
@@ -699,38 +707,39 @@ CODE_FRAGMENT
 .  {* name, id,  section_id, index, next, prev, flags, user_set_vma, *}        \
 .  {  NAME, IDX, 0,          0,     NULL, NULL, FLAGS, 0,              \
 .                                                                      \
-.  {* linker_mark, linker_has_input, gc_mark, decompress_status,    *} \
+.  {* linker_mark, linker_has_input, gc_mark, decompress_status,     *}        \
 .     0,           0,                1,       0,                       \
 .                                                                      \
-.  {* segment_mark, sec_info_type, use_rela_p,                      *} \
+.  {* segment_mark, sec_info_type, use_rela_p,                       *}        \
 .     0,            0,             0,                                  \
 .                                                                      \
-.  {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,   *} \
+.  {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,    *}        \
 .     0,        0,        0,        0,        0,        0,             \
 .                                                                      \
-.  {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \
+.  {* vma, lma, size, rawsize, compressed_size, relax, relax_count,  *}        \
 .     0,   0,   0,    0,       0,               0,     0,              \
 .                                                                      \
-.  {* output_offset, output_section, alignment_power,               *} \
+.  {* output_offset, output_section, alignment_power,                *}        \
 .     0,             &SEC,           0,                                        \
 .                                                                      \
-.  {* relocation, orelocation, reloc_count, filepos, rel_filepos,   *} \
+.  {* relocation, orelocation, reloc_count, filepos, rel_filepos,    *}        \
 .     NULL,       NULL,        0,           0,       0,                        \
 .                                                                      \
-.  {* line_filepos, userdata, contents, lineno, lineno_count,       *} \
+.  {* line_filepos, userdata, contents, lineno, lineno_count,        *}        \
 .     0,            NULL,     NULL,     NULL,   0,                     \
 .                                                                      \
-.  {* entsize, kept_section, moving_line_filepos,                   *} \
-.     0,       NULL,         0,                                        \
+.  {* entsize, kept_section, moving_line_filepos,                    *}        \
+.     0,       NULL,         0,                                                \
 .                                                                      \
-.  {* target_index, used_by_bfd, constructor_chain, owner,          *} \
+.  {* target_index, used_by_bfd, constructor_chain, owner,           *}        \
 .     0,            NULL,        NULL,              NULL,              \
 .                                                                      \
-.  {* symbol,                    symbol_ptr_ptr,                    *} \
+.  {* symbol,                    symbol_ptr_ptr,                     *}        \
 .     (struct bfd_symbol *) SYM, &SEC.symbol,                          \
 .                                                                      \
-.  {* map_head, map_tail                                            *} \
-.     { NULL }, { NULL }                                               \
+.  {* map_head, map_tail, already_assigned                           *}        \
+.     { NULL }, { NULL }, NULL                                         \
+.                                                                      \
 .    }
 .
 .{* We use a macro to initialize the static asymbol structures because
@@ -803,12 +812,12 @@ bfd_section_hash_newfunc (struct bfd_hash_entry *entry,
    is useful for things like relocs which are relative to the base
    of a section.  */
 
-bfd_boolean
+bool
 _bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
 {
   newsect->symbol = bfd_make_empty_symbol (abfd);
   if (newsect->symbol == NULL)
-    return FALSE;
+    return false;
 
   newsect->symbol->name = newsect->name;
   newsect->symbol->value = 0;
@@ -816,7 +825,7 @@ _bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
   newsect->symbol->flags = BSF_SECTION_SYM;
 
   newsect->symbol_ptr_ptr = &newsect->symbol;
-  return TRUE;
+  return true;
 }
 
 unsigned int _bfd_section_id = 0x10;  /* id 0 to 3 used by STD_SECTION.  */
@@ -889,7 +898,7 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
 {
   struct section_hash_entry *sh;
 
-  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+  sh = section_hash_lookup (&abfd->section_htab, name, false, false);
   if (sh != NULL)
     return &sh->section;
 
@@ -973,7 +982,7 @@ SYNOPSIS
        asection *bfd_get_section_by_name_if
          (bfd *abfd,
           const char *name,
-          bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+          bool (*func) (bfd *abfd, asection *sect, void *obj),
           void *obj);
 
 DESCRIPTION
@@ -991,15 +1000,13 @@ DESCRIPTION
 
 asection *
 bfd_get_section_by_name_if (bfd *abfd, const char *name,
-                           bfd_boolean (*operation) (bfd *,
-                                                     asection *,
-                                                     void *),
+                           bool (*operation) (bfd *, asection *, void *),
                            void *user_storage)
 {
   struct section_hash_entry *sh;
   unsigned long hash;
 
-  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+  sh = section_hash_lookup (&abfd->section_htab, name, false, false);
   if (sh == NULL)
     return NULL;
 
@@ -1052,7 +1059,7 @@ bfd_get_unique_section_name (bfd *abfd, const char *templat, int *count)
        abort ();
       sprintf (sname + len, ".%d", num++);
     }
-  while (section_hash_lookup (&abfd->section_htab, sname, FALSE, FALSE));
+  while (section_hash_lookup (&abfd->section_htab, sname, false, false));
 
   if (count != NULL)
     *count = num;
@@ -1107,7 +1114,7 @@ bfd_make_section_old_way (bfd *abfd, const char *name)
     {
       struct section_hash_entry *sh;
 
-      sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+      sh = section_hash_lookup (&abfd->section_htab, name, true, false);
       if (sh == NULL)
        return NULL;
 
@@ -1162,7 +1169,7 @@ bfd_make_section_anyway_with_flags (bfd *abfd, const char *name,
       return NULL;
     }
 
-  sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+  sh = section_hash_lookup (&abfd->section_htab, name, true, false);
   if (sh == NULL)
     return NULL;
 
@@ -1247,7 +1254,7 @@ bfd_make_section_with_flags (bfd *abfd, const char *name,
       || strcmp (name, BFD_IND_SECTION_NAME) == 0)
     return NULL;
 
-  sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+  sh = section_hash_lookup (&abfd->section_htab, name, true, false);
   if (sh == NULL)
     return NULL;
 
@@ -1288,7 +1295,7 @@ FUNCTION
        bfd_set_section_flags
 
 SYNOPSIS
-       bfd_boolean bfd_set_section_flags (asection *sec, flagword flags);
+       bool bfd_set_section_flags (asection *sec, flagword flags);
 
 DESCRIPTION
        Set the attributes of the section @var{sec} to the value @var{flags}.
@@ -1302,11 +1309,11 @@ DESCRIPTION
 
 */
 
-bfd_boolean
+bool
 bfd_set_section_flags (asection *section, flagword flags)
 {
   section->flags = flags;
-  return TRUE;
+  return true;
 }
 
 /*
@@ -1380,7 +1387,7 @@ FUNCTION
 SYNOPSIS
        asection *bfd_sections_find_if
          (bfd *abfd,
-          bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj),
+          bool (*operation) (bfd *abfd, asection *sect, void *obj),
           void *obj);
 
 DESCRIPTION
@@ -1396,7 +1403,7 @@ DESCRIPTION
 
 asection *
 bfd_sections_find_if (bfd *abfd,
-                     bfd_boolean (*operation) (bfd *, asection *, void *),
+                     bool (*operation) (bfd *, asection *, void *),
                      void *user_storage)
 {
   asection *sect;
@@ -1413,7 +1420,7 @@ FUNCTION
        bfd_set_section_size
 
 SYNOPSIS
-       bfd_boolean bfd_set_section_size (asection *sec, bfd_size_type val);
+       bool bfd_set_section_size (asection *sec, bfd_size_type val);
 
 DESCRIPTION
        Set @var{sec} to the size @var{val}. If the operation is
@@ -1425,7 +1432,7 @@ DESCRIPTION
 
 */
 
-bfd_boolean
+bool
 bfd_set_section_size (asection *sec, bfd_size_type val)
 {
   /* Once you've started writing to any section you cannot create or change
@@ -1434,11 +1441,11 @@ bfd_set_section_size (asection *sec, bfd_size_type val)
   if (sec->owner == NULL || sec->owner->output_has_begun)
     {
       bfd_set_error (bfd_error_invalid_operation);
-      return FALSE;
+      return false;
     }
 
   sec->size = val;
-  return TRUE;
+  return true;
 }
 
 /*
@@ -1446,7 +1453,7 @@ FUNCTION
        bfd_set_section_contents
 
 SYNOPSIS
-       bfd_boolean bfd_set_section_contents
+       bool bfd_set_section_contents
          (bfd *abfd, asection *section, const void *data,
           file_ptr offset, bfd_size_type count);
 
@@ -1472,7 +1479,7 @@ DESCRIPTION
 
 */
 
-bfd_boolean
+bool
 bfd_set_section_contents (bfd *abfd,
                          sec_ptr section,
                          const void *location,
@@ -1484,23 +1491,22 @@ bfd_set_section_contents (bfd *abfd,
   if (!(bfd_section_flags (section) & SEC_HAS_CONTENTS))
     {
       bfd_set_error (bfd_error_no_contents);
-      return FALSE;
+      return false;
     }
 
   sz = section->size;
   if ((bfd_size_type) offset > sz
-      || count > sz
-      || offset + count > sz
+      || count > sz - offset
       || count != (size_t) count)
     {
       bfd_set_error (bfd_error_bad_value);
-      return FALSE;
+      return false;
     }
 
   if (!bfd_write_p (abfd))
     {
       bfd_set_error (bfd_error_invalid_operation);
-      return FALSE;
+      return false;
     }
 
   /* Record a copy of the data in memory if desired.  */
@@ -1511,11 +1517,11 @@ bfd_set_section_contents (bfd *abfd,
   if (BFD_SEND (abfd, _bfd_set_section_contents,
                (abfd, section, location, offset, count)))
     {
-      abfd->output_has_begun = TRUE;
-      return TRUE;
+      abfd->output_has_begun = true;
+      return true;
     }
 
-  return FALSE;
+  return false;
 }
 
 /*
@@ -1523,7 +1529,7 @@ FUNCTION
        bfd_get_section_contents
 
 SYNOPSIS
-       bfd_boolean bfd_get_section_contents
+       bool bfd_get_section_contents
          (bfd *abfd, asection *section, void *location, file_ptr offset,
           bfd_size_type count);
 
@@ -1540,7 +1546,7 @@ DESCRIPTION
        <<FALSE>>.
 
 */
-bfd_boolean
+bool
 bfd_get_section_contents (bfd *abfd,
                          sec_ptr section,
                          void *location,
@@ -1552,7 +1558,7 @@ bfd_get_section_contents (bfd *abfd,
   if (section->flags & SEC_CONSTRUCTOR)
     {
       memset (location, 0, (size_t) count);
-      return TRUE;
+      return true;
     }
 
   if (abfd->direction != write_direction && section->rawsize != 0)
@@ -1560,22 +1566,21 @@ bfd_get_section_contents (bfd *abfd,
   else
     sz = section->size;
   if ((bfd_size_type) offset > sz
-      || count > sz
-      || offset + count > sz
+      || count > sz - offset
       || count != (size_t) count)
     {
       bfd_set_error (bfd_error_bad_value);
-      return FALSE;
+      return false;
     }
 
   if (count == 0)
     /* Don't bother.  */
-    return TRUE;
+    return true;
 
   if ((section->flags & SEC_HAS_CONTENTS) == 0)
     {
       memset (location, 0, (size_t) count);
-      return TRUE;
+      return true;
     }
 
   if ((section->flags & SEC_IN_MEMORY) != 0)
@@ -1587,11 +1592,11 @@ bfd_get_section_contents (bfd *abfd,
             error code.  */
          section->flags &= ~ SEC_IN_MEMORY;
          bfd_set_error (bfd_error_invalid_operation);
-         return FALSE;
+         return false;
        }
 
       memmove (location, section->contents + offset, (size_t) count);
-      return TRUE;
+      return true;
     }
 
   return BFD_SEND (abfd, _bfd_get_section_contents,
@@ -1603,7 +1608,7 @@ FUNCTION
        bfd_malloc_and_get_section
 
 SYNOPSIS
-       bfd_boolean bfd_malloc_and_get_section
+       bool bfd_malloc_and_get_section
          (bfd *abfd, asection *section, bfd_byte **buf);
 
 DESCRIPTION
@@ -1611,7 +1616,7 @@ DESCRIPTION
        into a buffer, *@var{buf}, malloc'd by this function.
 */
 
-bfd_boolean
+bool
 bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf)
 {
   *buf = NULL;
@@ -1622,7 +1627,7 @@ FUNCTION
        bfd_copy_private_section_data
 
 SYNOPSIS
-       bfd_boolean bfd_copy_private_section_data
+       bool bfd_copy_private_section_data
          (bfd *ibfd, asection *isec, bfd *obfd, asection *osec);
 
 DESCRIPTION
@@ -1644,17 +1649,17 @@ FUNCTION
        bfd_generic_is_group_section
 
 SYNOPSIS
-       bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+       bool bfd_generic_is_group_section (bfd *, const asection *sec);
 
 DESCRIPTION
        Returns TRUE if @var{sec} is a member of a group.
 */
 
-bfd_boolean
+bool
 bfd_generic_is_group_section (bfd *abfd ATTRIBUTE_UNUSED,
                              const asection *sec ATTRIBUTE_UNUSED)
 {
-  return FALSE;
+  return false;
 }
 
 /*
@@ -1680,20 +1685,20 @@ FUNCTION
        bfd_generic_discard_group
 
 SYNOPSIS
-       bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
+       bool bfd_generic_discard_group (bfd *abfd, asection *group);
 
 DESCRIPTION
        Remove all members of @var{group} from the output.
 */
 
-bfd_boolean
+bool
 bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED,
                           asection *group ATTRIBUTE_UNUSED)
 {
-  return TRUE;
+  return true;
 }
 
-bfd_boolean
+bool
 _bfd_nowrite_set_section_contents (bfd *abfd,
                                   sec_ptr section ATTRIBUTE_UNUSED,
                                   const void *location ATTRIBUTE_UNUSED,
This page took 0.043242 seconds and 4 git commands to generate.