Add a flag to asection, linker_has_input, and use it to reliably
[deliverable/binutils-gdb.git] / bfd / section.c
index 9006d195f84de30f8cec3b997be01ab1be053495..ad9046285e60d54daa5dcb5a210a419b2996dea8 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
@@ -264,6 +259,14 @@ CODE_FRAGMENT
 .     sections.  *}
 .#define SEC_COFF_SHARED_LIBRARY 0x800
 .
+.  {* 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 0x4000
+.
 .  {* The section contains common symbols (symbols may be defined
 .     multiple times, the value of a symbol is the amount of
 .     space it requires, and the largest symbol value is the one
@@ -347,6 +350,15 @@ 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
+.
 .  {*  End of section flags.  *}
 .
 .  {* Some internal packed boolean fields.  *}
@@ -360,9 +372,16 @@ 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 a 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.  *}
+.  unsigned int segment_mark : 1;
+.
 .  {* End of internal packed boolean fields.  *}
 .
 .  {*  The virtual memory address of the section - where it will be
@@ -456,10 +475,18 @@ 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;
 .
+.  {* Points to the kept section if this section is a link-once section,
+.     and is discarded.  *}
+.  struct sec *kept_section;
+.
 .  {* When a section is being output, this value changes as more
 .     linenumbers are written out.  *}
 .
@@ -549,14 +576,17 @@ static const asymbol global_syms[] =
   GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section)
 };
 
-#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)        \
-  const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \
-  const asection SEC = \
+#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)                                \
+  const asymbol * const SYM = (asymbol *) &global_syms[IDX];           \
+  const asection SEC =                                                         \
     /* name, id,  index, next, flags, user_set_vma, reloc_done,      */        \
     { NAME,  IDX, 0,     NULL, FLAGS, 0,            0,                 \
                                                                        \
-    /* linker_mark, gc_mark, vma, lma, _cooked_size, _raw_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,                                      \
                                                                        \
     /* output_offset, output_section,      alignment_power,          */        \
        0,             (struct sec *) &SEC, 0,                          \
@@ -567,11 +597,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, kept_section, moving_line_filepos,           */        \
+       0,       NULL,   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],                        \
@@ -631,6 +661,55 @@ bfd_get_section_by_name (abfd, name)
   return NULL;
 }
 
+/*
+FUNCTION
+       bfd_get_unique_section_name
+
+SYNOPSIS
+       char *bfd_get_unique_section_name(bfd *abfd,
+                                         const char *templat,
+                                         int *count);
+
+DESCRIPTION
+       Invent a section name that is unique in @var{abfd} by tacking
+       a dot and a digit suffix onto the original @var{templat}.  If
+       @var{count} is non-NULL, then it specifies the first number
+       tried as a suffix to generate a unique name.  The value
+       pointed to by @var{count} will be incremented in this case.
+*/
+
+char *
+bfd_get_unique_section_name (abfd, templat, count)
+     bfd *abfd;
+     const char *templat;
+     int *count;
+{
+  int num;
+  unsigned int len;
+  char *sname;
+
+  len = strlen (templat);
+  sname = bfd_malloc (len + 8);
+  if (sname == NULL)
+    return NULL;
+  strcpy (sname, templat);
+  num = 1;
+  if (count != NULL)
+    num = *count;
+
+  do
+    {
+      /* If we have a million sections, something is badly wrong.  */
+      if (num > 999999)
+       abort ();
+      sprintf (sname + len, ".%d", num++);
+    }
+  while (bfd_get_section_by_name (abfd, sname) != NULL);
+
+  if (count != NULL)
+    *count = num;
+  return sname;
+}
 
 /*
 FUNCTION
@@ -657,7 +736,6 @@ DESCRIPTION
 
 */
 
-
 asection *
 bfd_make_section_old_way (abfd, name)
      bfd *abfd;
@@ -727,13 +805,17 @@ bfd_make_section_anyway (abfd, name)
   newsect->line_filepos = 0;
   newsect->owner = abfd;
   newsect->comdat = NULL;
+  newsect->kept_section = NULL;
 
   /* Create a symbol whos only job is to point to this section. This is
      useful for things like relocs which are relative to the base of a
      section.  */
   newsect->symbol = bfd_make_empty_symbol (abfd);
   if (newsect->symbol == NULL)
-    return NULL;
+    {
+      bfd_release (abfd, newsect);
+      return NULL;
+    }
   newsect->symbol->name = name;
   newsect->symbol->value = 0;
   newsect->symbol->section = newsect;
@@ -743,7 +825,7 @@ bfd_make_section_anyway (abfd, name)
 
   if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true)
     {
-      free (newsect);
+      bfd_release (abfd, newsect);
       return NULL;
     }
 
@@ -801,7 +883,6 @@ bfd_make_section (abfd, name)
   return bfd_make_section_anyway (abfd, name);
 }
 
-
 /*
 FUNCTION
        bfd_set_section_flags
@@ -845,14 +926,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);
@@ -871,7 +951,6 @@ DESCRIPTION
 |         for (p = abfd->sections; p != NULL; p = p->next)
 |            func(abfd, p, ...)
 
-
 */
 
 /*VARARGS2*/
@@ -891,7 +970,6 @@ bfd_map_over_sections (abfd, operation, user_storage)
     abort ();
 }
 
-
 /*
 FUNCTION
        bfd_set_section_size
@@ -916,7 +994,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)
     {
@@ -942,15 +1020,12 @@ SYNOPSIS
          file_ptr offset,
          bfd_size_type count);
 
-
 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{offset} for @var{count} octets.
 
-
-
        Normally <<true>> is returned, else <<false>>. Possible error
        returns are:
        o <<bfd_error_no_contents>> -
@@ -961,7 +1036,6 @@ DESCRIPTION
        This routine is front end to the back end function
        <<_bfd_set_section_contents>>.
 
-
 */
 
 #define bfd_get_section_size_now(abfd,sec) \
@@ -1015,6 +1089,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, count);
+
   if (BFD_SEND (abfd, _bfd_set_section_contents,
                (abfd, section, location, offset, count)))
     {
@@ -1046,8 +1125,6 @@ DESCRIPTION
        with zeroes. If no errors occur, <<true>> is returned, else
        <<false>>.
 
-
-
 */
 boolean
 bfd_get_section_contents (abfd, section, location, offset, count)
This page took 0.030159 seconds and 4 git commands to generate.