* som.c (SOM_HOWTO): Define.
[deliverable/binutils-gdb.git] / bfd / section.c
index dcb240f897cfe6530598e3db355a691f9277baaf..b3b760802d3e95d249a29a1bffda733e0b563eda 100644 (file)
@@ -1,5 +1,5 @@
 /* Object file "section" support for the BFD library.
-   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -150,6 +150,27 @@ SUBSECTION
 
 CODE_FRAGMENT
 .
+. {* This structure is used for a comdat section, as in PE.  A comdat
+.    section is associated with a particular symbol.  When the linker
+.    sees a comdat section, it keeps only one of the sections with a
+.    given name and associated with a given symbol. *}
+.
+.struct bfd_comdat_info
+.{
+.  {* The name of the symbol associated with a comdat section.  *}
+.  const char *name;
+.
+.  {* The local symbol table index of the symbol associated with a
+.     comdat section.  This is only meaningful to the object file format
+.     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
 .{
 .        {* The name of the section; the name isn't a copy, the pointer is
@@ -309,7 +330,11 @@ CODE_FRAGMENT
 .
 .      {* This section contains "short" data, and should be placed
 .         "near" the GP.  *}
-.#define SEC_SHORT 0x2000000
+.#define SEC_SMALL_DATA 0x2000000
+.
+.      {* This section contains data which may be shared with other
+.         executables or shared objects.  *}
+.#define SEC_SHARED 0x4000000
 .
 .      {*  End of section flags.  *}
 .
@@ -344,22 +369,25 @@ CODE_FRAGMENT
 .
 .   bfd_vma lma;
 .
-.        {* The size of the section in bytes, as it will be output.
-.           contains a value even if the section has no contents (e.g., the
-.           size of <<.bss>>). This will be filled in after relocation *}
+.        {* 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>>).  This will be filled in after relocation.  *}
 .
 .   bfd_size_type _cooked_size;
 .
-.        {* The original size on disk of the section, in bytes.  Normally this
+.        {* The original size on disk of the section, in octets.  Normally this
 .          value is the same as the size, but if some relaxing has
 .          been done, then this value will be bigger.  *}
 .
 .   bfd_size_type _raw_size;
 .
 .        {* If this section is going to be output, then this value is the
-.           offset into the output section of the first byte in the input
-.           section. E.g., if this was going to start at the 100th byte in
-.           the output section, this value would be 100. *}
+.           offset in *bytes* into the output section of the first byte in the
+.           input section (byte ==> smallest addressable unit on the
+.           target).  In most cases, if this was going to start at the
+.           100th octet (8-bit quantity) in the output section, this value
+.           would be 100.  However, if the target byte size is 16 bits
+.           (bfd_octets_per_byte is "2"), this value would be 50. *}
 .
 .   bfd_vma output_offset;
 .
@@ -417,6 +445,10 @@ CODE_FRAGMENT
 .
 .   unsigned int lineno_count;
 .
+.       {* Optional information about a COMDAT entry; NULL if not COMDAT *}
+.
+.   struct bfd_comdat_info *comdat;
+.
 .        {* When a section is being output, this value changes as more
 .           linenumbers are written out *}
 .
@@ -476,28 +508,60 @@ CODE_FRAGMENT
 .extern const struct symbol_cache_entry * const bfd_und_symbol;
 .extern const struct symbol_cache_entry * const bfd_ind_symbol;
 .#define bfd_get_section_size_before_reloc(section) \
-.     (section->reloc_done ? (abort(),1): (section)->_raw_size)
+.     ((section)->reloc_done ? (abort (), (bfd_size_type) 1) \
+.                            : (section)->_raw_size)
 .#define bfd_get_section_size_after_reloc(section) \
-.     ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
+.     ((section)->reloc_done ? (section)->_cooked_size \
+.                            : (abort (), (bfd_size_type) 1))
 */
 
+/* We use a macro to initialize the static asymbol structures because
+   traditional C does not permit us to initialize a union member while
+   gcc warns if we don't initialize it.  */
+ /* the_bfd, name, value, attr, section [, udata] */
+#ifdef __STDC__
+#define GLOBAL_SYM_INIT(NAME, SECTION) \
+  { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION, { 0 }}
+#else
+#define GLOBAL_SYM_INIT(NAME, SECTION) \
+  { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION }
+#endif
+
 /* These symbols are global, not specific to any BFD.  Therefore, anything
    that tries to change them is broken, and should be repaired.  */
+
 static const asymbol global_syms[] =
 {
- /* the_bfd, name, value, attr, section [, udata] */
-  {0, BFD_COM_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_com_section},
-  {0, BFD_UND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_und_section},
-  {0, BFD_ABS_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_abs_section},
-  {0, BFD_IND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_ind_section},
+  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)
 };
 
 #define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)        \
   const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \
   const asection SEC = \
-    { NAME, 0, 0, FLAGS, 0, 0, 0, 0, 0, 0, 0, 0, 0, (asection *) &SEC, \
-      0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, \
-      (asymbol *) &global_syms[IDX], (asymbol **) &SYM, 0, 0 }
+    /* name, index, next, flags, set_vma, reloc_done, linker_mark, gc_mark */ \
+    { NAME,  0,     0,    FLAGS, 0,       0,          0,           0,        \
+                                                                             \
+    /* vma, lma, _cooked_size, _raw_size, output_offset, output_section, */   \
+       0,   0,   0,            0,         0,             (struct sec *) &SEC, \
+                                                                             \
+    /* alig..., reloc..., orel..., reloc_count, filepos, rel_..., line_... */ \
+       0,       0,        0,       0,           0,       0,       0,         \
+                                                                             \
+    /* userdata, contents, lineno, lineno_count */                           \
+       0,        0,        0,      0,                                        \
+                                                                             \
+    /* comdat_info, moving_line_filepos, target_index, used_by_bfd,  */       \
+       NULL,        0,                   0,            0,                    \
+                                                                             \
+    /* cons..., owner, symbol */                                             \
+       0,       0,     (struct symbol_cache_entry *) &global_syms[IDX],       \
+                                                                             \
+    /* symbol_ptr_ptr,                      link_order_head, ..._tail */      \
+       (struct symbol_cache_entry **) &SYM, 0,               0                \
+    }
 
 STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
             BFD_COM_SECTION_NAME, 0);
@@ -640,6 +704,7 @@ bfd_make_section_anyway (abfd, name)
   newsect->reloc_count = 0;
   newsect->line_filepos = 0;
   newsect->owner = abfd;
+  newsect->comdat = 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
@@ -737,7 +802,7 @@ DESCRIPTION
 /*ARGSUSED*/
 boolean
 bfd_set_section_flags (abfd, section, flags)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      sec_ptr section;
      flagword flags;
 {
@@ -860,7 +925,7 @@ 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} bytes.
+       @var{offset} for @var{count} octets.
 
 
 
@@ -1037,20 +1102,28 @@ FUNCTION
 
 SYNOPSIS
        void _bfd_strip_section_from_output
-       (asection *section);
+       (struct bfd_link_info *info, asection *section);
 
 DESCRIPTION
-       Remove @var{section} from the output.  If the output section becomes
-       empty, remove it from the output bfd.
+       Remove @var{section} from the output.  If the output section
+       becomes empty, remove it from the output bfd.  @var{info} may
+       be NULL; if it is not, it is used to decide whether the output
+       section is empty.
 */
 void
-_bfd_strip_section_from_output (s)
+_bfd_strip_section_from_output (info, s)
+     struct bfd_link_info *info;
      asection *s;
 {
   asection **spp, *os;
   struct bfd_link_order *p, *pp;
+  boolean keep_os;
+
+  /* Excise the input section from the link order.
 
-  /* Excise the input section from the link order.  */
+     FIXME: For all calls that I can see to this function, the link
+     orders have not yet been set up.  So why are we checking them? --
+     Ian */
   os = s->output_section;
   for (p = os->link_order_head, pp = NULL; p != NULL; pp = p, p = p->next)
     if (p->type == bfd_indirect_link_order
@@ -1065,8 +1138,30 @@ _bfd_strip_section_from_output (s)
        break;
       }
 
-  /* If the output section is empty, remove it too.  */
-  if (!os->link_order_head)
+  keep_os = os->link_order_head != NULL;
+
+  if (! keep_os && info != NULL)
+    {
+      bfd *abfd;
+      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+       {
+         asection *is;
+         for (is = abfd->sections; is != NULL; is = is->next)
+           {
+             if (is != s && is->output_section == os)
+               break;
+           }
+         if (is != NULL)
+           break;
+       }
+      if (abfd != NULL)
+       keep_os = true;
+    }
+
+  /* If the output section is empty, remove it too.  Careful about sections
+     that have been discarded in the link script -- they are mapped to 
+     bfd_abs_section, which has no owner.  */
+  if (!keep_os && os->owner != NULL)
     {
       for (spp = &os->owner->sections; *spp; spp = &(*spp)->next)
        if (*spp == os)
This page took 0.03038 seconds and 4 git commands to generate.