* expr.c (make_expr_symbol): Fold FAKE_LABEL_NAME use into the
[deliverable/binutils-gdb.git] / bfd / elf.c
index 45c7d753cb3d334984828c818c48a8e1b8f88570..66383e7c0d4bdaabcfc16023ed24e961e2e275fb 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,6 +1,6 @@
 /* ELF executable support for BFD.
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -97,6 +97,12 @@ static bfd_boolean elfcore_grok_netbsd_procinfo
   PARAMS ((bfd *, Elf_Internal_Note *));
 static bfd_boolean elfcore_grok_netbsd_note
   PARAMS ((bfd *, Elf_Internal_Note *));
+static bfd_boolean elfcore_grok_nto_gregs
+  PARAMS ((bfd *, Elf_Internal_Note *, pid_t));
+static bfd_boolean elfcore_grok_nto_status
+  PARAMS ((bfd *, Elf_Internal_Note *, pid_t *));
+static bfd_boolean elfcore_grok_nto_note
+  PARAMS ((bfd *, Elf_Internal_Note *));
 
 /* Swap version information in and out.  The version information is
    currently size independent.  If that ever changes, this code will
@@ -265,7 +271,7 @@ bfd_elf_hash (namearg)
          h ^= g;
        }
     }
-  return h;
+  return h & 0xffffffff;
 }
 
 /* Read a specified number of bytes at a specified offset in an ELF
@@ -476,6 +482,23 @@ bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset,
   return intsym_buf;
 }
 
+/* Look up a symbol name.  */
+const char *
+bfd_elf_local_sym_name (abfd, isym)
+     bfd *abfd;
+     Elf_Internal_Sym *isym;
+{
+  unsigned int iname = isym->st_name;
+  unsigned int shindex = elf_tdata (abfd)->symtab_hdr.sh_link;
+  if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+    {
+      iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
+      shindex = elf_elfheader (abfd)->e_shstrndx;
+    }
+
+  return bfd_elf_string_from_elf_section (abfd, shindex, iname);
+}
+
 /* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
    sections.  The first element is the flags, the rest are section
    pointers.  */
@@ -497,8 +520,6 @@ group_signature (abfd, ghdr)
   unsigned char esym[sizeof (Elf64_External_Sym)];
   Elf_External_Sym_Shndx eshndx;
   Elf_Internal_Sym isym;
-  unsigned int iname;
-  unsigned int shindex;
 
   /* First we need to ensure the symbol table is available.  */
   if (! bfd_section_from_shdr (abfd, ghdr->sh_link))
@@ -510,16 +531,7 @@ group_signature (abfd, ghdr)
                            &isym, esym, &eshndx) == NULL)
     return NULL;
 
-  /* Look up the symbol name.  */
-  iname = isym.st_name;
-  shindex = hdr->sh_link;
-  if (iname == 0 && ELF_ST_TYPE (isym.st_info) == STT_SECTION)
-    {
-      iname = elf_elfsections (abfd)[isym.st_shndx]->sh_name;
-      shindex = elf_elfheader (abfd)->e_shstrndx;
-    }
-
-  return bfd_elf_string_from_elf_section (abfd, shindex, iname);
+  return bfd_elf_local_sym_name (abfd, &isym);
 }
 
 /* Set next_in_group list pointer, and group name for NEWSECT.  */
@@ -969,11 +981,8 @@ merge_sections_remove_hook (abfd, sec)
      bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
 {
-  struct bfd_elf_section_data *sec_data;
-
-  sec_data = elf_section_data (sec);
-  BFD_ASSERT (sec_data->sec_info_type == ELF_INFO_TYPE_MERGE);
-  sec_data->sec_info_type = ELF_INFO_TYPE_NONE;
+  BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE);
+  sec->sec_info_type = ELF_INFO_TYPE_NONE;
 }
 
 /* Finish SHF_MERGE section merging.  */
@@ -1001,7 +1010,7 @@ _bfd_elf_link_just_syms (sec, info)
   if (!is_elf_hash_table (info))
     return;
 
-  elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_JUST_SYMS;
+  sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS;
 }
 \f
 /* Copy the program header and other data from one object module to
@@ -1423,8 +1432,8 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
       ret->vtable_entries_size = 0;
       ret->vtable_entries_used = NULL;
       ret->vtable_parent = NULL;
-      ret->got.refcount = htab->init_refcount;
-      ret->plt.refcount = htab->init_refcount;
+      ret->got = htab->init_refcount;
+      ret->plt = htab->init_refcount;
       ret->size = 0;
       ret->type = STT_NOTYPE;
       ret->other = 0;
@@ -1499,7 +1508,7 @@ _bfd_elf_link_hash_hide_symbol (info, h, force_local)
      struct elf_link_hash_entry *h;
      bfd_boolean force_local;
 {
-  h->plt.offset = (bfd_vma) -1;
+  h->plt = elf_hash_table (info)->init_offset;
   h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
   if (force_local)
     {
@@ -1529,8 +1538,9 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc)
   table->dynobj = NULL;
   /* Make sure can_refcount is extended to the width and signedness of
      init_refcount before we subtract one from it.  */
-  table->init_refcount = get_elf_backend_data (abfd)->can_refcount;
-  --table->init_refcount;
+  table->init_refcount.refcount = get_elf_backend_data (abfd)->can_refcount;
+  table->init_refcount.refcount -= 1;
+  table->init_offset.offset = -(bfd_vma) 1;
   /* The first dynamic symbol is a dummy.  */
   table->dynsymcount = 1;
   table->dynstr = NULL;
@@ -1606,7 +1616,7 @@ bfd_elf_get_needed_list (abfd, info)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
-  if (info->hash->creator->flavour != bfd_target_elf_flavour)
+  if (! is_elf_hash_table (info))
     return NULL;
   return elf_hash_table (info)->needed;
 }
@@ -1619,7 +1629,7 @@ bfd_elf_get_runpath_list (abfd, info)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
-  if (info->hash->creator->flavour != bfd_target_elf_flavour)
+  if (! is_elf_hash_table (info))
     return NULL;
   return elf_hash_table (info)->runpath;
 }
@@ -2007,8 +2017,7 @@ bfd_section_from_shdr (abfd, shindex)
        /* In the section to which the relocations apply, mark whether
           its relocations are of the REL or RELA variety.  */
        if (hdr->sh_size != 0)
-         elf_section_data (target_sect)->use_rela_p
-           = (hdr->sh_type == SHT_RELA);
+         target_sect->use_rela_p = hdr->sh_type == SHT_RELA;
        abfd->flags |= HAS_RELOC;
        return TRUE;
       }
@@ -2136,16 +2145,19 @@ _bfd_elf_new_section_hook (abfd, sec)
      asection *sec;
 {
   struct bfd_elf_section_data *sdata;
-  bfd_size_type amt = sizeof (*sdata);
 
-  sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, amt);
-  if (!sdata)
-    return FALSE;
-  sec->used_by_bfd = (PTR) sdata;
+  sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
+  if (sdata == NULL)
+    {
+      bfd_size_type amt = sizeof (*sdata);
+      sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, amt);
+      if (sdata == NULL)
+       return FALSE;
+      sec->used_by_bfd = (PTR) sdata;
+    }
 
   /* Indicate whether or not this section should use RELA relocations.  */
-  sdata->use_rela_p
-    = get_elf_backend_data (abfd)->default_use_rela_p;
+  sec->use_rela_p = get_elf_backend_data (abfd)->default_use_rela_p;
 
   return TRUE;
 }
@@ -2280,6 +2292,10 @@ bfd_section_from_phdr (abfd, hdr, index)
     case PT_PHDR:
       return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr");
 
+    case PT_GNU_EH_FRAME:
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
+                                             "eh_frame_hdr");
+
     default:
       /* Check for any processor-specific program segment types.
          If no handler for them, default to making "segment" sections.  */
@@ -2319,7 +2335,7 @@ _bfd_elf_init_reloc_shdr (abfd, rel_hdr, asect, use_rela_p)
   rel_hdr->sh_entsize = (use_rela_p
                         ? bed->s->sizeof_rela
                         : bed->s->sizeof_rel);
-  rel_hdr->sh_addralign = bed->s->file_align;
+  rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
   rel_hdr->sh_flags = 0;
   rel_hdr->sh_addr = 0;
   rel_hdr->sh_size = 0;
@@ -2349,9 +2365,9 @@ elf_fake_sections (abfd, asect, failedptrarg)
 
   this_hdr = &elf_section_data (asect)->this_hdr;
 
-  this_hdr->sh_name = (unsigned long) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-                                                          asect->name, FALSE);
-  if (this_hdr->sh_name == (unsigned long) -1)
+  this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+                                                         asect->name, FALSE);
+  if (this_hdr->sh_name == (unsigned int) -1)
     {
       *failedptr = TRUE;
       return;
@@ -2503,7 +2519,7 @@ elf_fake_sections (abfd, asect, failedptrarg)
       && !_bfd_elf_init_reloc_shdr (abfd,
                                    &elf_section_data (asect)->rel_hdr,
                                    asect,
-                                   elf_section_data (asect)->use_rela_p))
+                                   asect->use_rela_p))
     *failedptr = TRUE;
 }
 
@@ -3518,6 +3534,7 @@ elf_sort_sections (arg1, arg2)
 {
   const asection *sec1 = *(const asection **) arg1;
   const asection *sec2 = *(const asection **) arg2;
+  bfd_size_type size1, size2;
 
   /* Sort by LMA first, since this is the address used to
      place the section into a segment.  */
@@ -3535,7 +3552,7 @@ elf_sort_sections (arg1, arg2)
 
   /* Put !SEC_LOAD sections after SEC_LOAD ones.  */
 
-#define TOEND(x) (((x)->flags & SEC_LOAD) == 0)
+#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
 
   if (TOEND (sec1))
     {
@@ -3557,9 +3574,12 @@ elf_sort_sections (arg1, arg2)
   /* Sort by size, to put zero sized sections
      before others at the same address.  */
 
-  if (sec1->_raw_size < sec2->_raw_size)
+  size1 = (sec1->flags & SEC_LOAD) ? sec1->_raw_size : 0;
+  size2 = (sec2->flags & SEC_LOAD) ? sec2->_raw_size : 0;
+
+  if (size1 < size2)
     return -1;
-  if (sec1->_raw_size > sec2->_raw_size)
+  if (size1 > size2)
     return 1;
 
   return sec1->target_index - sec2->target_index;
@@ -3728,7 +3748,7 @@ assign_file_positions_for_segments (abfd)
          && (abfd->flags & D_PAGED) != 0)
        p->p_align = bed->maxpagesize;
       else if (m->count == 0)
-       p->p_align = bed->s->file_align;
+       p->p_align = 1 << bed->s->log_file_align;
       else
        p->p_align = 0;
 
@@ -3840,9 +3860,15 @@ assign_file_positions_for_segments (abfd)
              bfd_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
 
              p->p_memsz += adjust;
-             off += adjust;
-             voff += adjust;
-             if ((flags & SEC_LOAD) != 0)
+             if (p->p_type == PT_LOAD
+                 || (p->p_type == PT_NOTE
+                     && bfd_get_format (abfd) == bfd_core))
+               {
+                 off += adjust;
+                 voff += adjust;
+               }
+             if ((flags & SEC_LOAD) != 0
+                 || (flags & SEC_THREAD_LOCAL) != 0)
                p->p_filesz += adjust;
            }
 
@@ -3899,7 +3925,9 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a
                  || (flags & SEC_HAS_CONTENTS) != 0)
                off += sec->_raw_size;
 
-             if ((flags & SEC_ALLOC) != 0)
+             if ((flags & SEC_ALLOC) != 0
+                 && ((flags & SEC_LOAD) != 0
+                     || (flags & SEC_THREAD_LOCAL) == 0))
                voff += sec->_raw_size;
            }
 
@@ -3926,6 +3954,9 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a
            }
          else
            {
+             if ((sec->flags & SEC_LOAD) != 0
+                 || (sec->flags & SEC_THREAD_LOCAL) == 0
+                 || p->p_type == PT_TLS)
              p->p_memsz += sec->_raw_size;
 
              if ((flags & SEC_LOAD) != 0)
@@ -4214,7 +4245,7 @@ assign_file_positions_except_relocs (abfd)
     }
 
   /* Place the section headers.  */
-  off = align_file_position (off, bed->s->file_align);
+  off = align_file_position (off, 1 << bed->s->log_file_align);
   i_ehdrp->e_shoff = off;
   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
 
@@ -4569,18 +4600,23 @@ copy_private_bfd_data (ibfd, obfd)
   (start + (segment->p_memsz > segment->p_filesz                       \
            ? segment->p_memsz : segment->p_filesz))
 
+#define SECTION_SIZE(section, segment)                                 \
+  (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL))           \
+    != SEC_THREAD_LOCAL || segment->p_type == PT_TLS)                  \
+   ? section->_raw_size : 0)
+
   /* Returns TRUE if the given section is contained within
      the given segment.  VMA addresses are compared.  */
 #define IS_CONTAINED_BY_VMA(section, segment)                          \
   (section->vma >= segment->p_vaddr                                    \
-   && (section->vma + section->_raw_size                               \
+   && (section->vma + SECTION_SIZE (section, segment)                  \
        <= (SEGMENT_END (segment, segment->p_vaddr))))
 
   /* Returns TRUE if the given section is contained within
      the given segment.  LMA addresses are compared.  */
 #define IS_CONTAINED_BY_LMA(section, segment, base)                    \
   (section->lma >= base                                                        \
-   && (section->lma + section->_raw_size                               \
+   && (section->lma + SECTION_SIZE (section, segment)                  \
        <= SEGMENT_END (segment, base)))
 
   /* Special case: corefile "NOTE" section containing regs, prpsinfo etc.  */
@@ -4612,7 +4648,9 @@ copy_private_bfd_data (ibfd, obfd)
           if that is set for the segment and the VMA otherwise,
        2. It is an allocated segment,
        3. There is an output section associated with it,
-       4. The section has not already been allocated to a previous segment.  */
+       4. The section has not already been allocated to a previous segment.
+       5. PT_TLS segment includes only SHF_TLS sections.
+       6. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.  */
 #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)              \
   ((((segment->p_paddr                                                 \
       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)       \
@@ -4620,16 +4658,28 @@ copy_private_bfd_data (ibfd, obfd)
      && (section->flags & SEC_ALLOC) != 0)                             \
     || IS_COREFILE_NOTE (segment, section))                            \
    && section->output_section != NULL                                  \
+   && (segment->p_type != PT_TLS                                       \
+       || (section->flags & SEC_THREAD_LOCAL))                         \
+   && (segment->p_type == PT_LOAD                                      \
+       || segment->p_type == PT_TLS                                    \
+       || (section->flags & SEC_THREAD_LOCAL) == 0)                    \
    && ! section->segment_mark)
 
   /* Returns TRUE iff seg1 starts after the end of seg2.  */
-#define SEGMENT_AFTER_SEGMENT(seg1, seg2)                              \
-  (seg1->p_vaddr >= SEGMENT_END (seg2, seg2->p_vaddr))
-
-  /* Returns TRUE iff seg1 and seg2 overlap.  */
+#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)                       \
+  (seg1->field >= SEGMENT_END (seg2, seg2->field))
+
+  /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
+     their VMA address ranges and their LMA address ranges overlap.
+     It is possible to have overlapping VMA ranges without overlapping LMA
+     ranges.  RedBoot images for example can have both .data and .bss mapped
+     to the same VMA range, but with the .data section mapped to a different
+     LMA.  */
 #define SEGMENT_OVERLAPS(seg1, seg2)                                   \
-  (!(SEGMENT_AFTER_SEGMENT (seg1, seg2)                                        \
-     || SEGMENT_AFTER_SEGMENT (seg2, seg1)))
+  (   !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr)                    \
+        || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr))                \
+   && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr)                    \
+        || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
 
   /* Initialise the segment mark field.  */
   for (section = ibfd->sections; section != NULL; section = section->next)
@@ -4727,13 +4777,14 @@ copy_private_bfd_data (ibfd, obfd)
        continue;
 
       /* Compute how many sections might be placed into this segment.  */
-      section_count = 0;
-      for (section = ibfd->sections; section != NULL; section = section->next)
+      for (section = ibfd->sections, section_count = 0;
+          section != NULL;
+          section = section->next)
        if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
          ++section_count;
 
-      /* Allocate a segment map big enough to contain all of the
-        sections we have selected.  */
+      /* Allocate a segment map big enough to contain
+        all of the sections we have selected.  */
       amt = sizeof (struct elf_segment_map);
       amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
       map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
@@ -4805,7 +4856,7 @@ copy_private_bfd_data (ibfd, obfd)
            and possibly its LMA changed, and a new segment or segments will
            have to be created to contain the other sections.
 
-        4. The sections have been moved, but not be the same amount.
+        4. The sections have been moved, but not by the same amount.
            In this case we can change the segment's LMA to match the LMA
            of the first section and we will have to create a new segment
            or segments to contain the other sections.
@@ -5021,7 +5072,10 @@ copy_private_bfd_data (ibfd, obfd)
              amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
              map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
              if (map == NULL)
-               return FALSE;
+               {
+                 free (sections);
+                 return FALSE;
+               }
 
              /* Initialise the fields of the segment map.  Set the physical
                 physical address to the LMA of the first section that has
@@ -5049,10 +5103,8 @@ copy_private_bfd_data (ibfd, obfd)
     if (map->p_paddr != 0)
       break;
   if (map == NULL)
-    {
-      for (map = map_first; map != NULL; map = map->next)
-       map->p_paddr_valid = 0;
-    }
+    for (map = map_first; map != NULL; map = map->next)
+      map->p_paddr_valid = 0;
 
   elf_tdata (obfd)->segment_map = map_first;
 
@@ -5097,6 +5149,7 @@ copy_private_bfd_data (ibfd, obfd)
 #endif
 
 #undef SEGMENT_END
+#undef SECTION_SIZE
 #undef IS_CONTAINED_BY_VMA
 #undef IS_CONTAINED_BY_LMA
 #undef IS_COREFILE_NOTE
@@ -5158,8 +5211,7 @@ _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec)
   elf_next_in_group (osec) = elf_next_in_group (isec);
   elf_group_name (osec) = elf_group_name (isec);
 
-  elf_section_data (osec)->use_rela_p
-    = elf_section_data (isec)->use_rela_p;
+  osec->use_rela_p = isec->use_rela_p;
 
   return TRUE;
 }
@@ -5250,7 +5302,7 @@ swap_out_syms (abfd, sttp, relocatable_p)
   symtab_hdr->sh_entsize = bed->s->sizeof_sym;
   symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
   symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
-  symtab_hdr->sh_addralign = bed->s->file_align;
+  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
 
   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
   symstrtab_hdr->sh_type = SHT_STRTAB;
@@ -5258,7 +5310,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
   amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
   outbound_syms = bfd_alloc (abfd, amt);
   if (outbound_syms == NULL)
-    return FALSE;
+    {
+      _bfd_stringtab_free (stt);
+      return FALSE;
+    }
   symtab_hdr->contents = (PTR) outbound_syms;
 
   outbound_shndx = NULL;
@@ -5268,7 +5323,11 @@ swap_out_syms (abfd, sttp, relocatable_p)
       amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
       outbound_shndx = bfd_zalloc (abfd, amt);
       if (outbound_shndx == NULL)
-       return FALSE;
+       {
+         _bfd_stringtab_free (stt);
+         return FALSE;
+       }
+
       symtab_shndx_hdr->contents = outbound_shndx;
       symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
       symtab_shndx_hdr->sh_size = amt;
@@ -5276,7 +5335,7 @@ swap_out_syms (abfd, sttp, relocatable_p)
       symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
     }
 
-  /* now generate the data (for "contents") */
+  /* Now generate the data (for "contents").  */
   {
     /* Fill in zeroth symbol and swap it out.  */
     Elf_Internal_Sym sym;
@@ -5312,7 +5371,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
                                                            syms[idx]->name,
                                                            TRUE, FALSE);
          if (sym.st_name == (unsigned long) -1)
-           return FALSE;
+           {
+             _bfd_stringtab_free (stt);
+             return FALSE;
+           }
        }
 
       type_ptr = elf_symbol_from (abfd, syms[idx]);
@@ -5342,6 +5404,7 @@ swap_out_syms (abfd, sttp, relocatable_p)
              value += sec->output_offset;
              sec = sec->output_section;
            }
+
          /* Don't add in the section vma for relocatable output.  */
          if (! relocatable_p)
            value += sec->vma;
@@ -5393,7 +5456,17 @@ swap_out_syms (abfd, sttp, relocatable_p)
                     section of a symbol to be a section that is
                     actually in the output file.  */
                  sec2 = bfd_get_section_by_name (abfd, sec->name);
-                 BFD_ASSERT (sec2 != 0);
+                 if (sec2 == NULL)
+                   {
+                     _bfd_error_handler (_("\
+Unable to find equivalent output section for symbol '%s' from section '%s'"),
+                                         syms[idx]->name ? syms[idx]->name : "<Local sym>",
+                                         sec->name);
+                     bfd_set_error (bfd_error_invalid_operation);
+                     _bfd_stringtab_free (stt);
+                     return FALSE;
+                   }
+
                  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
                  BFD_ASSERT (shndx != -1);
                }
@@ -5414,7 +5487,7 @@ swap_out_syms (abfd, sttp, relocatable_p)
       if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
        type = STT_TLS;
 
-      /* Processor-specific types */
+      /* Processor-specific types */
       if (type_ptr != NULL
          && bed->elf_backend_get_symbol_type)
        type = ((*bed->elf_backend_get_symbol_type)
@@ -5851,7 +5924,7 @@ _bfd_elf_slurp_version_tables (abfd)
   return TRUE;
 
  error_return:
-  if (contents == NULL)
+  if (contents != NULL)
     free (contents);
   return FALSE;
 }
@@ -6811,6 +6884,20 @@ elfcore_grok_note (abfd, note)
 #else
       return TRUE;
 #endif
+
+    case NT_AUXV:
+      {
+       asection *sect = bfd_make_section (abfd, ".auxv");
+
+       if (sect == NULL)
+         return FALSE;
+       sect->_raw_size = note->descsz;
+       sect->filepos = note->descpos;
+       sect->flags = SEC_HAS_CONTENTS;
+       sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
+
+       return TRUE;
+      }
     }
 }
 
@@ -6918,6 +7005,104 @@ elfcore_grok_netbsd_note (abfd, note)
     /* NOTREACHED */
 }
 
+static bfd_boolean
+elfcore_grok_nto_status (abfd, note, tid)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+     pid_t *tid;
+{
+  void *ddata = note->descdata;
+  char buf[100];
+  char *name;
+  asection *sect;
+
+  /* nto_procfs_status 'pid' field is at offset 0.  */
+  elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
+
+  /* nto_procfs_status 'tid' field is at offset 4.  */
+  elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
+
+  /* nto_procfs_status 'what' field is at offset 14.  */
+  elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, (bfd_byte *) ddata + 14);
+
+  /* Pass tid back.  */
+  *tid = elf_tdata (abfd)->core_lwpid;
+
+  /* Make a ".qnx_core_status/%d" section.  */
+  sprintf (buf, ".qnx_core_status/%d", *tid);
+
+  name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
+  if (name == NULL)
+    return FALSE;
+  strcpy (name, buf);
+
+  sect = bfd_make_section (abfd, name);
+  if (sect == NULL)
+    return FALSE;
+
+  sect->_raw_size       = note->descsz;
+  sect->filepos         = note->descpos;
+  sect->flags           = SEC_HAS_CONTENTS;
+  sect->alignment_power = 2;
+
+  return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
+}
+
+static bfd_boolean
+elfcore_grok_nto_gregs (abfd, note, tid)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+     pid_t tid;
+{
+  char buf[100];
+  char *name;
+  asection *sect;
+
+  /* Make a ".reg/%d" section.  */
+  sprintf (buf, ".reg/%d", tid);
+
+  name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
+  if (name == NULL)
+    return FALSE;
+  strcpy (name, buf);
+
+  sect = bfd_make_section (abfd, name);
+  if (sect == NULL)
+    return FALSE;
+
+  sect->_raw_size       = note->descsz;
+  sect->filepos         = note->descpos;
+  sect->flags           = SEC_HAS_CONTENTS;
+  sect->alignment_power = 2;
+
+  return elfcore_maybe_make_sect (abfd, ".reg", sect);
+}
+
+#define BFD_QNT_CORE_INFO      7
+#define BFD_QNT_CORE_STATUS    8
+#define BFD_QNT_CORE_GREG      9
+#define BFD_QNT_CORE_FPREG     10
+
+static bfd_boolean
+elfcore_grok_nto_note (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  /* Every GREG section has a STATUS section before it.  Store the
+     tid from the previous call to pass down to the next gregs
+     function.  */
+  static pid_t tid = 1;
+
+  switch (note->type)
+    {
+    case BFD_QNT_CORE_INFO:   return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
+    case BFD_QNT_CORE_STATUS: return elfcore_grok_nto_status (abfd, note, &tid);
+    case BFD_QNT_CORE_GREG:   return elfcore_grok_nto_gregs (abfd, note, tid);
+    case BFD_QNT_CORE_FPREG:  return elfcore_grok_prfpreg (abfd, note);
+    default:                  return TRUE;
+    }
+}
+
 /* Function: elfcore_write_note
 
    Inputs:
@@ -6954,7 +7139,7 @@ elfcore_write_note (abfd, buf, bufsiz, name, type, input, size)
 
       namesz = strlen (name) + 1;
       bed = get_elf_backend_data (abfd);
-      pad = -namesz & (bed->s->file_align - 1);
+      pad = -namesz & ((1 << bed->s->log_file_align) - 1);
     }
 
   newspace = sizeof (Elf_External_Note) - 1 + namesz + pad + size;
@@ -7157,6 +7342,11 @@ elfcore_read_notes (abfd, offset, size)
           if (! elfcore_grok_netbsd_note (abfd, &in))
             goto error;
         }
+      else if (strncmp (in.namedata, "QNX", 3) == 0)
+       {
+         if (! elfcore_grok_nto_note (abfd, &in))
+           goto error;
+       }
       else
         {
           if (! elfcore_grok_note (abfd, &in))
@@ -7304,7 +7494,7 @@ _bfd_elf_rela_local_sym (abfd, sym, sec, rel)
                + sym->st_value);
   if ((sec->flags & SEC_MERGE)
       && ELF_ST_TYPE (sym->st_info) == STT_SECTION
-      && elf_section_data (sec)->sec_info_type == ELF_INFO_TYPE_MERGE)
+      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
     {
       asection *msec;
 
@@ -7329,7 +7519,7 @@ _bfd_elf_rel_local_sym (abfd, sym, psec, addend)
 {
   asection *sec = *psec;
 
-  if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_MERGE)
+  if (sec->sec_info_type != ELF_INFO_TYPE_MERGE)
     return sym->st_value + addend;
 
   return _bfd_merged_section_offset (abfd, psec,
@@ -7347,7 +7537,7 @@ _bfd_elf_section_offset (abfd, info, sec, offset)
   struct bfd_elf_section_data *sec_data;
 
   sec_data = elf_section_data (sec);
-  switch (sec_data->sec_info_type)
+  switch (sec->sec_info_type)
     {
     case ELF_INFO_TYPE_STABS:
       return _bfd_stab_section_offset (abfd,
@@ -7359,3 +7549,27 @@ _bfd_elf_section_offset (abfd, info, sec, offset)
       return offset;
     }
 }
+\f
+/* Create a new BFD as if by bfd_openr.  Rather than opening a file,
+   reconstruct an ELF file by reading the segments out of remote memory
+   based on the ELF file header at EHDR_VMA and the ELF program headers it
+   points to.  If not null, *LOADBASEP is filled in with the difference
+   between the VMAs from which the segments were read, and the VMAs the
+   file headers (and hence BFD's idea of each section's VMA) put them at.
+
+   The function TARGET_READ_MEMORY is called to copy LEN bytes from the
+   remote memory at target address VMA into the local buffer at MYADDR; it
+   should return zero on success or an `errno' code on failure.  TEMPL must
+   be a BFD for an ELF target with the word size and byte order found in
+   the remote memory.  */
+
+bfd *
+bfd_elf_bfd_from_remote_memory (templ, ehdr_vma, loadbasep, target_read_memory)
+     bfd *templ;
+     bfd_vma ehdr_vma;
+     bfd_vma *loadbasep;
+     int (*target_read_memory) PARAMS ((bfd_vma vma, char *myaddr, int len));
+{
+  return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
+    (templ, ehdr_vma, loadbasep, target_read_memory);
+}
This page took 0.03443 seconds and 4 git commands to generate.