* README: Mention problems with HP/UX.
[deliverable/binutils-gdb.git] / bfd / section.c
index fc64b2019fbe596fedc84acd8f51ea7a3ac6a8ed..b2a366a12b048778a79acd2000e7d734511d455f 100644 (file)
@@ -1,5 +1,6 @@
 /* Object file "section" support for the BFD library.
-   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -111,7 +112,6 @@ SUBSECTION
 |     size            0x103   |
 |     output_section  --------|
 
-
 SUBSECTION
        Link orders
 
@@ -133,7 +133,6 @@ SUBSECTION
 
 */
 
-
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
@@ -165,10 +164,6 @@ CODE_FRAGMENT
 .     specific code; it is not an index into the list returned by
 .     bfd_canonicalize_symtab.  *}
 .  long symbol;
-.
-.  {* If this section is being discarded, the linker uses this field
-.     to point to the input section which is being kept.  *}
-.  struct sec *sec;
 .};
 .
 .typedef struct sec
@@ -182,7 +177,7 @@ CODE_FRAGMENT
 .
 .  int id;
 .
-.  {* Which section is it; 0..nth.  *}
+.  {* Which section in the bfd; 0..n-1 as sections are created in a bfd.  *}
 .
 .  int index;
 .
@@ -210,9 +205,11 @@ CODE_FRAGMENT
 .     some relocation information too.  *}
 .#define SEC_RELOC      0x004
 .
-.#if 0   {* Obsolete ? *}
-.#define SEC_BALIGN     0x008
-.#endif
+.  {* 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
@@ -295,9 +292,10 @@ CODE_FRAGMENT
 .     objects are to be further relocated.  *}
 .#define SEC_EXCLUDE 0x40000
 .
-.  {* The contents of this section are to be sorted by the
-.     based on the address specified in the associated symbol
-.     table.  *}
+.  {* 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
 .
 .  {* When linking, duplicate sections of the same name should be
@@ -355,6 +353,18 @@ CODE_FRAGMENT
 .     references found to any symbol in the section.  *}
 .#define SEC_CLINK 0x10000000
 .
+.  {* Attempt to merge identical entities in the section.
+.     Entity size is given in the entsize field.  *}
+.#define SEC_MERGE 0x20000000
+.
+.  {* 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
+.
+.  {* This section contains data about section groups.  *}
+.#define SEC_GROUP 0x80000000
+.
 .  {*  End of section flags.  *}
 .
 .  {* Some internal packed boolean fields.  *}
@@ -368,10 +378,15 @@ CODE_FRAGMENT
 .  {* A mark flag used by some of the linker backends.  *}
 .  unsigned int linker_mark : 1;
 .
+.  {* Another mark flag used by some of the linker backends.  Set for
+.     output sections that have an input section.  *}
+.  unsigned int linker_has_input : 1;
+.
 .  {* A mark flag used by some linker backends for garbage collection.  *}
 .  unsigned int gc_mark : 1;
 .
-.  {* Used by the ELF code to mark sections which have been allocated to segments.  *}
+.  {* Used by the ELF code to mark sections which have been allocated
+.     to segments.  *}
 .  unsigned int segment_mark : 1;
 .
 .  {* End of internal packed boolean fields.  *}
@@ -467,6 +482,10 @@ CODE_FRAGMENT
 .
 .  unsigned int lineno_count;
 .
+.  {* Entity size for merging purposes.  *}
+.
+.  unsigned int entsize;
+.
 .  {* Optional information about a COMDAT entry; NULL if not COMDAT.  *}
 .
 .  struct bfd_comdat_info *comdat;
@@ -566,11 +585,14 @@ static const asymbol global_syms[] =
     /* name, id,  index, next, flags, user_set_vma, reloc_done,      */        \
     { NAME,  IDX, 0,     NULL, FLAGS, 0,            0,                 \
                                                                        \
-    /* linker_mark, gc_mark, segment_mark, vma, lma, _cooked_size,   */        \
-       0,           0,       0,            0,   0,   0,                \
+    /* linker_mark, linker_has_input, gc_mark, segment_mark,         */        \
+       0,           0,                1,       0,                      \
+                                                                       \
+    /* vma, lma, _cooked_size, _raw_size,                            */        \
+       0,   0,   0,            0,                                      \
                                                                        \
-    /* _raw_size, output_offset, output_section,    alignment_power, */ \
-       0,         0,           (struct sec *) &SEC, 0,                 \
+    /* output_offset, output_section,      alignment_power,          */        \
+       0,             (struct sec *) &SEC, 0,                          \
                                                                        \
     /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */        \
        NULL,       NULL,        0,           0,       0,               \
@@ -578,11 +600,11 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */        \
        0,            NULL,     NULL,     NULL,   0,                    \
                                                                        \
-    /* comdat, moving_line_filepos, target_index, used_by_bfd,       */        \
-       NULL,   0,                   0,            NULL,                        \
+    /* entsize, comdat, moving_line_filepos,                         */        \
+       0,       NULL,   0,                                             \
                                                                        \
-    /* constructor_chain, owner,                                     */        \
-       NULL,              NULL,                                                \
+    /* target_index, used_by_bfd, constructor_chain, owner,          */        \
+       0,            NULL,        NULL,              NULL,             \
                                                                        \
     /* symbol,                                                       */        \
        (struct symbol_cache_entry *) &global_syms[IDX],                        \
@@ -642,7 +664,6 @@ bfd_get_section_by_name (abfd, name)
   return NULL;
 }
 
-
 /*
 FUNCTION
        bfd_get_unique_section_name
@@ -671,7 +692,7 @@ bfd_get_unique_section_name (abfd, templat, count)
   char *sname;
 
   len = strlen (templat);
-  sname = bfd_malloc (len + 8);
+  sname = bfd_malloc ((bfd_size_type) len + 8);
   if (sname == NULL)
     return NULL;
   strcpy (sname, templat);
@@ -693,7 +714,6 @@ bfd_get_unique_section_name (abfd, templat, count)
   return sname;
 }
 
-
 /*
 FUNCTION
        bfd_make_section_old_way
@@ -719,7 +739,6 @@ DESCRIPTION
 
 */
 
-
 asection *
 bfd_make_section_old_way (abfd, name)
      bfd *abfd;
@@ -772,7 +791,7 @@ bfd_make_section_anyway (abfd, name)
       sect = sect->next;
     }
 
-  newsect = (asection *) bfd_zalloc (abfd, sizeof (asection));
+  newsect = (asection *) bfd_zalloc (abfd, (bfd_size_type) sizeof (asection));
   if (newsect == NULL)
     return NULL;
 
@@ -866,7 +885,6 @@ bfd_make_section (abfd, name)
   return bfd_make_section_anyway (abfd, name);
 }
 
-
 /*
 FUNCTION
        bfd_set_section_flags
@@ -910,14 +928,13 @@ bfd_set_section_flags (abfd, section, flags)
   return true;
 }
 
-
 /*
 FUNCTION
        bfd_map_over_sections
 
 SYNOPSIS
        void bfd_map_over_sections(bfd *abfd,
-                                  void (*func)(bfd *abfd,
+                                  void (*func) (bfd *abfd,
                                                asection *sect,
                                                PTR obj),
                                   PTR obj);
@@ -936,7 +953,6 @@ DESCRIPTION
 |         for (p = abfd->sections; p != NULL; p = p->next)
 |            func(abfd, p, ...)
 
-
 */
 
 /*VARARGS2*/
@@ -956,7 +972,6 @@ bfd_map_over_sections (abfd, operation, user_storage)
     abort ();
 }
 
-
 /*
 FUNCTION
        bfd_set_section_size
@@ -981,7 +996,7 @@ bfd_set_section_size (abfd, ptr, val)
      bfd_size_type val;
 {
   /* Once you've started writing to any section you cannot create or change
-     the size of any others. */
+     the size of any others.  */
 
   if (abfd->output_has_begun)
     {
@@ -1000,13 +1015,9 @@ FUNCTION
        bfd_set_section_contents
 
 SYNOPSIS
-       boolean bfd_set_section_contents
-         (bfd *abfd,
-         asection *section,
-         PTR data,
-         file_ptr offset,
-         bfd_size_type count);
-
+       boolean bfd_set_section_contents (bfd *abfd, asection *section,
+                                         PTR data, file_ptr offset,
+                                         bfd_size_type count);
 
 DESCRIPTION
        Sets the contents of the section @var{section} in BFD
@@ -1014,8 +1025,6 @@ DESCRIPTION
        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:
        o <<bfd_error_no_contents>> -
@@ -1026,7 +1035,6 @@ DESCRIPTION
        This routine is front end to the back end function
        <<_bfd_set_section_contents>>.
 
-
 */
 
 #define bfd_get_section_size_now(abfd,sec) \
@@ -1050,17 +1058,15 @@ bfd_set_section_contents (abfd, section, location, offset, count)
       return (false);
     }
 
-  if (offset < 0)
+  sz = bfd_get_section_size_now (abfd, section);
+  if ((bfd_size_type) offset > sz
+      || count > sz
+      || offset + count > sz
+      || count != (size_t) count)
     {
-    bad_val:
       bfd_set_error (bfd_error_bad_value);
       return false;
     }
-  sz = bfd_get_section_size_now (abfd, section);
-  if ((bfd_size_type) offset > sz
-      || count > sz
-      || offset + count > sz)
-    goto bad_val;
 
   switch (abfd->direction)
     {
@@ -1080,6 +1086,11 @@ bfd_set_section_contents (abfd, section, location, offset, count)
       break;
     }
 
+  /* Record a copy of the data in memory if desired.  */
+  if (section->contents
+      && location != section->contents + offset)
+    memcpy (section->contents + offset, location, (size_t) count);
+
   if (BFD_SEND (abfd, _bfd_set_section_contents,
                (abfd, section, location, offset, count)))
     {
@@ -1095,9 +1106,9 @@ FUNCTION
        bfd_get_section_contents
 
 SYNOPSIS
-       boolean bfd_get_section_contents
-        (bfd *abfd, asection *section, PTR location,
-         file_ptr offset, bfd_size_type count);
+       boolean bfd_get_section_contents (bfd *abfd, asection *section,
+                                         PTR location, file_ptr offset,
+                                         bfd_size_type count);
 
 DESCRIPTION
        Read data from @var{section} in BFD @var{abfd}
@@ -1111,8 +1122,6 @@ DESCRIPTION
        with zeroes. If no errors occur, <<true>> is returned, else
        <<false>>.
 
-
-
 */
 boolean
 bfd_get_section_contents (abfd, section, location, offset, count)
@@ -1126,21 +1135,21 @@ bfd_get_section_contents (abfd, section, location, offset, count)
 
   if (section->flags & SEC_CONSTRUCTOR)
     {
-      memset (location, 0, (unsigned) count);
+      memset (location, 0, (size_t) count);
       return true;
     }
 
-  if (offset < 0)
+  /* Even if reloc_done is true, this function reads unrelocated
+     contents, so we want the raw size.  */
+  sz = section->_raw_size;
+  if ((bfd_size_type) offset > sz
+      || count > sz
+      || offset + count > sz
+      || count != (size_t) count)
     {
-    bad_val:
       bfd_set_error (bfd_error_bad_value);
       return false;
     }
-  /* Even if reloc_done is true, this function reads unrelocated
-     contents, so we want the raw size.  */
-  sz = section->_raw_size;
-  if ((bfd_size_type) offset > sz || count > sz || offset + count > sz)
-    goto bad_val;
 
   if (count == 0)
     /* Don't bother.  */
@@ -1148,7 +1157,7 @@ bfd_get_section_contents (abfd, section, location, offset, count)
 
   if ((section->flags & SEC_HAS_CONTENTS) == 0)
     {
-      memset (location, 0, (unsigned) count);
+      memset (location, 0, (size_t) count);
       return true;
     }
 
@@ -1167,7 +1176,8 @@ FUNCTION
        bfd_copy_private_section_data
 
 SYNOPSIS
-       boolean bfd_copy_private_section_data(bfd *ibfd, asection *isec, bfd *obfd, asection *osec);
+       boolean bfd_copy_private_section_data (bfd *ibfd, asection *isec,
+                                              bfd *obfd, asection *osec);
 
 DESCRIPTION
        Copy private section information from @var{isec} in the BFD
@@ -1212,6 +1222,11 @@ _bfd_strip_section_from_output (info, s)
      orders have not yet been set up.  So why are we checking them? --
      Ian */
   os = s->output_section;
+
+  /* Handle a section that wasn't output.  */
+  if (os == NULL)
+    return;
+
   for (p = os->link_order_head, pp = NULL; p != NULL; pp = p, p = p->next)
     if (p->type == bfd_indirect_link_order
        && p->u.indirect.section == s)
This page took 0.039703 seconds and 4 git commands to generate.