static boolean elfcore_grok_prxfpreg PARAMS ((bfd *, Elf_Internal_Note *));
static boolean elfcore_grok_note PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean elfcore_netbsd_get_lwpid PARAMS ((Elf_Internal_Note *, int *));
+static boolean elfcore_grok_netbsd_procinfo PARAMS ((bfd *,
+ Elf_Internal_Note *));
+static boolean elfcore_grok_netbsd_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
need to move into elfcode.h. */
/* First count the number of groups. If we have a SHT_GROUP
section with just a flag word (ie. sh_size is 4), ignore it. */
- shnum = elf_elfheader (abfd)->e_shnum;
+ shnum = elf_numsections (abfd);
num_group = 0;
for (i = 0; i < shnum; i++)
{
i_shdrp = elf_elfsections (abfd);
if (i_shdrp != NULL)
{
- shstrtab = bfd_elf_get_str_section
- (abfd, elf_elfheader (abfd)->e_shstrndx);
+ shstrtab = bfd_elf_get_str_section (abfd,
+ elf_elfheader (abfd)->e_shstrndx);
if (shstrtab != NULL)
{
- max = elf_elfheader (abfd)->e_shnum;
+ max = elf_numsections (abfd);
for (i = 1; i < max; i++)
if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
return i_shdrp[i];
return true;
}
\f
+/* Copy the program header and other data from one object module to
+ another. */
+
+boolean
+_bfd_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || (elf_elfheader (obfd)->e_flags
+ == elf_elfheader (ibfd)->e_flags));
+
+ elf_gp (obfd) = elf_gp (ibfd);
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
/* Print out the program headers. */
boolean
case PT_NOTE: pt = "NOTE"; break;
case PT_SHLIB: pt = "SHLIB"; break;
case PT_PHDR: pt = "PHDR"; break;
+ case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
}
fprintf (f, "%8s off 0x", pt);
section, so that objcopy can handle it. */
return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+ case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */
+ if (elf_symtab_shndx (abfd) == shindex)
+ return true;
+
+ /* Get the associated symbol table. */
+ if (! bfd_section_from_shdr (abfd, hdr->sh_link)
+ || hdr->sh_link != elf_onesymtab (abfd))
+ return false;
+
+ elf_symtab_shndx (abfd) = shindex;
+ elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
+ return true;
+
case SHT_STRTAB: /* A string table */
if (hdr->bfd_section != NULL)
return true;
return true;
}
{
- unsigned int i;
+ unsigned int i, num_sec;
- for (i = 1; i < ehdr->e_shnum; i++)
+ num_sec = elf_numsections (abfd);
+ for (i = 1; i < num_sec; i++)
{
Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
if (hdr2->sh_link == shindex)
{
asection *target_sect;
Elf_Internal_Shdr *hdr2;
+ unsigned int num_sec = elf_numsections (abfd);
/* Check for a bogus link to avoid crashing. */
- if (hdr->sh_link >= ehdr->e_shnum)
+ if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
+ || hdr->sh_link >= num_sec)
{
((*_bfd_error_handler)
(_("%s: invalid link %lu for reloc section %s (index %u)"),
if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
&& elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
{
- int scan;
+ unsigned int scan;
int found;
found = 0;
- for (scan = 1; scan < ehdr->e_shnum; scan++)
+ for (scan = 1; scan < num_sec; scan++)
{
if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
|| elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
asection *sec;
unsigned long r_symndx;
{
- unsigned char esym_shndx[2];
+ unsigned char esym_shndx[4];
unsigned int isym_shndx;
Elf_Internal_Shdr *symtab_hdr;
file_ptr pos;
{
pos += r_symndx * sizeof (Elf64_External_Sym);
pos += offsetof (Elf64_External_Sym, st_shndx);
+ amt = sizeof (((Elf64_External_Sym *) 0)->st_shndx);
}
else
{
pos += r_symndx * sizeof (Elf32_External_Sym);
pos += offsetof (Elf32_External_Sym, st_shndx);
+ amt = sizeof (((Elf32_External_Sym *) 0)->st_shndx);
}
- amt = sizeof (esym_shndx);
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
return NULL;
isym_shndx = H_GET_16 (abfd, esym_shndx);
+ if (isym_shndx == SHN_XINDEX)
+ {
+ Elf_Internal_Shdr *shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (shndx_hdr->sh_size != 0)
+ {
+ pos = shndx_hdr->sh_offset;
+ pos += r_symndx * sizeof (Elf_External_Sym_Shndx);
+ amt = sizeof (Elf_External_Sym_Shndx);
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
+ return NULL;
+ isym_shndx = H_GET_32 (abfd, esym_shndx);
+ }
+ }
+
if (cache->abfd != abfd)
{
memset (cache->indx, -1, sizeof (cache->indx));
}
cache->indx[ent] = r_symndx;
cache->sec[ent] = sec;
- if (isym_shndx > 0 && isym_shndx < SHN_LORESERVE)
+ if (isym_shndx < SHN_LORESERVE || isym_shndx > SHN_HIRESERVE)
{
asection *s;
s = bfd_section_from_elf_index (abfd, isym_shndx);
bfd *abfd;
unsigned int index;
{
- BFD_ASSERT (index > 0 && index < SHN_LORESERVE);
- if (index >= elf_elfheader (abfd)->e_shnum)
+ if (index >= elf_numsections (abfd))
return NULL;
return elf_elfsections (abfd)[index]->bfd_section;
}
{
struct bfd_elf_section_data *d = elf_section_data (sec);
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
d->this_idx = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
if ((sec->flags & SEC_RELOC) == 0)
d->rel_idx = 0;
else
{
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
d->rel_idx = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
}
if (d->rel_hdr2)
{
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
d->rel_idx2 = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
}
d->rel_idx2 = 0;
}
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
t->shstrtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
if (bfd_get_symcount (abfd) > 0)
{
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
t->symtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
+ if (section_number > SHN_LORESERVE - 2)
+ {
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ t->symtab_shndx_section = section_number++;
+ t->symtab_shndx_hdr.sh_name
+ = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+ ".symtab_shndx", false);
+ if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
+ return false;
+ }
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
t->strtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
}
_bfd_elf_strtab_finalize (elf_shstrtab (abfd));
t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
+
+ elf_numsections (abfd) = section_number;
elf_elfheader (abfd)->e_shnum = section_number;
+ if (section_number > SHN_LORESERVE)
+ elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;
/* Set up the list of section header pointers, in agreement with the
indices. */
if (bfd_get_symcount (abfd) > 0)
{
i_shdrp[t->symtab_section] = &t->symtab_hdr;
+ if (elf_numsections (abfd) > SHN_LORESERVE)
+ {
+ i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
+ t->symtab_shndx_hdr.sh_link = t->symtab_section;
+ }
i_shdrp[t->strtab_section] = &t->strtab_hdr;
t->symtab_hdr.sh_link = t->strtab_section;
}
}
for (secn = 1; secn < section_number; ++secn)
- i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
- i_shdrp[secn]->sh_name);
-
+ if (i_shdrp[secn] == NULL)
+ i_shdrp[secn] = i_shdrp[0];
+ else
+ i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
+ i_shdrp[secn]->sh_name);
return true;
}
hdr = &elf_tdata (abfd)->symtab_hdr;
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+ hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (hdr->sh_size != 0)
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+
hdr = &elf_tdata (abfd)->strtab_hdr;
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
asection **hdrpp;
boolean phdr_in_segment = true;
boolean writable;
- asection *dynsec;
+ asection *dynsec, *eh_frame_hdr;
bfd_size_type amt;
if (elf_tdata (abfd)->segment_map != NULL)
}
}
+ /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
+ segment. */
+ eh_frame_hdr = NULL;
+ if (elf_tdata (abfd)->eh_frame_hdr)
+ eh_frame_hdr = bfd_get_section_by_name (abfd, ".eh_frame_hdr");
+ if (eh_frame_hdr != NULL && (eh_frame_hdr->flags & SEC_LOAD))
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_EH_FRAME;
+ m->count = 1;
+ m->sections[0] = eh_frame_hdr;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
free (sections);
sections = NULL;
asection **secpp;
/* If elf_segment_map is not from map_sections_to_segments, the
- sections may not be correctly ordered. */
- if (m->count > 0)
+ sections may not be correctly ordered. NOTE: sorting should
+ not be done to the PT_NOTE section of a corefile, which may
+ contain several pseudo-sections artificially created by bfd.
+ Sorting these pseudo-sections breaks things badly. */
+ if (m->count > 1
+ && !(elf_elfheader (abfd)->e_type == ET_CORE
+ && m->p_type == PT_NOTE))
qsort (m->sections, (size_t) m->count, sizeof (asection *),
elf_sort_sections);
{
if (i == 0)
{
- (* _bfd_error_handler)
- (_("Error: First section in segment (%s) starts at 0x%x"),
- bfd_section_name (abfd, sec), sec->lma);
- (* _bfd_error_handler)
- (_(" whereas segment starts at 0x%x"),
- p->p_paddr);
-
+ (* _bfd_error_handler) (_("\
+Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"),
+ bfd_section_name (abfd, sec),
+ sec->lma,
+ p->p_paddr);
return false;
}
p->p_memsz += adjust;
++segs;
}
+ if (elf_tdata (abfd)->eh_frame_hdr
+ && bfd_get_section_by_name (abfd, ".eh_frame_hdr") != NULL)
+ {
+ /* We need a PT_GNU_EH_FRAME segment. */
+ ++segs;
+ }
+
for (s = abfd->sections; s != NULL; s = s->next)
{
if ((s->flags & SEC_LOAD) != 0
struct elf_obj_tdata * const tdata = elf_tdata (abfd);
Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
+ unsigned int num_sec = elf_numsections (abfd);
file_ptr off;
struct elf_backend_data *bed = get_elf_backend_data (abfd);
/* We are not creating an executable, which means that we are
not creating a program header, and that the actual order of
the sections in the file is unimportant. */
- for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
+ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
{
Elf_Internal_Shdr *hdr;
hdr = *hdrpp;
- if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
- {
- hdr->sh_offset = -1;
- continue;
- }
- if (i == tdata->symtab_section
+ if (hdr->sh_type == SHT_REL
+ || hdr->sh_type == SHT_RELA
+ || i == tdata->symtab_section
+ || i == tdata->symtab_shndx_section
|| i == tdata->strtab_section)
{
hdr->sh_offset = -1;
- continue;
}
+ else
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
- off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+ if (i == SHN_LORESERVE - 1)
+ {
+ i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ }
}
}
else
/* Assign file positions for the other sections. */
off = elf_tdata (abfd)->next_file_pos;
- for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
+ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
{
Elf_Internal_Shdr *hdr;
else if (hdr->sh_type == SHT_REL
|| hdr->sh_type == SHT_RELA
|| hdr == i_shdrpp[tdata->symtab_section]
+ || hdr == i_shdrpp[tdata->symtab_shndx_section]
|| hdr == i_shdrpp[tdata->strtab_section])
hdr->sh_offset = -1;
else
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+
+ if (i == SHN_LORESERVE - 1)
+ {
+ i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ }
}
}
bfd *abfd;
{
file_ptr off;
- unsigned int i;
+ unsigned int i, num_sec;
Elf_Internal_Shdr **shdrpp;
off = elf_tdata (abfd)->next_file_pos;
- for (i = 1, shdrpp = elf_elfsections (abfd) + 1;
- i < elf_elfheader (abfd)->e_shnum;
- i++, shdrpp++)
+ num_sec = elf_numsections (abfd);
+ for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
{
Elf_Internal_Shdr *shdrp;
Elf_Internal_Ehdr *i_ehdrp;
Elf_Internal_Shdr **i_shdrp;
boolean failed;
- unsigned int count;
+ unsigned int count, num_sec;
if (! abfd->output_has_begun
&& ! _bfd_elf_compute_section_file_positions
_bfd_elf_assign_file_positions_for_relocs (abfd);
/* After writing the headers, we need to write the sections too... */
- for (count = 1; count < i_ehdrp->e_shnum; count++)
+ num_sec = elf_numsections (abfd);
+ for (count = 1; count < num_sec; count++)
{
if (bed->elf_backend_section_processing)
(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
|| bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
return false;
}
+ if (count == SHN_LORESERVE - 1)
+ count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
}
/* Write out the section header names. */
Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
int index;
Elf_Internal_Shdr *hdr;
- int maxindex = elf_elfheader (abfd)->e_shnum;
+ int maxindex = elf_numsections (abfd);
+
+ if (elf_section_data (asect) != NULL
+ && elf_section_data (asect)->this_idx != 0)
+ return elf_section_data (asect)->this_idx;
+
+ if (bfd_is_abs_section (asect))
+ return SHN_ABS;
+ if (bfd_is_com_section (asect))
+ return SHN_COMMON;
+ if (bfd_is_und_section (asect))
+ return SHN_UNDEF;
- for (index = 0; index < maxindex; index++)
+ for (index = 1; index < maxindex; index++)
{
hdr = i_shdrp[index];
- if (hdr->bfd_section == asect)
+ if (hdr != NULL && hdr->bfd_section == asect)
return index;
}
int retval;
hdr = i_shdrp[index];
+ if (hdr == NULL)
+ continue;
+
retval = index;
if ((*bed->elf_backend_section_from_bfd_section)
(abfd, hdr, asect, &retval))
}
}
- if (bfd_is_abs_section (asect))
- return SHN_ABS;
- if (bfd_is_com_section (asect))
- return SHN_COMMON;
- if (bfd_is_und_section (asect))
- return SHN_UNDEF;
-
bfd_set_error (bfd_error_nonrepresentable_section);
- return -1;
+ return SHN_BAD;
}
/* Given a BFD symbol, return the index in the ELF symbol table, or -1
/* Scan through the segments specified in the program header
of the input BFD. For this first scan we look for overlaps
- in the loadable segments. These can be created by wierd
+ in the loadable segments. These can be created by weird
parameters to objcopy. */
for (i = 0, segment = elf_tdata (ibfd)->phdr;
i < num_segments;
elf_tdata (obfd)->segment_map = map_first;
/* If we had to estimate the number of program headers that were
- going to be needed, then check our estimate know and adjust
+ going to be needed, then check our estimate now and adjust
the offset if necessary. */
if (phdr_adjust_seg != NULL)
{
section indices; these definitions are interpreted by the
swap_out_syms function. */
-#define MAP_ONESYMTAB (SHN_LORESERVE - 1)
-#define MAP_DYNSYMTAB (SHN_LORESERVE - 2)
-#define MAP_STRTAB (SHN_LORESERVE - 3)
-#define MAP_SHSTRTAB (SHN_LORESERVE - 4)
+#define MAP_ONESYMTAB (SHN_HIOS + 1)
+#define MAP_DYNSYMTAB (SHN_HIOS + 2)
+#define MAP_STRTAB (SHN_HIOS + 3)
+#define MAP_SHSTRTAB (SHN_HIOS + 4)
+#define MAP_SYM_SHNDX (SHN_HIOS + 5)
boolean
_bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg)
shndx = MAP_STRTAB;
else if (shndx == elf_tdata (ibfd)->shstrtab_section)
shndx = MAP_SHSTRTAB;
+ else if (shndx == elf_tdata (ibfd)->symtab_shndx_section)
+ shndx = MAP_SYM_SHNDX;
osym->internal_elf_sym.st_shndx = shndx;
}
asymbol **syms;
struct bfd_strtab_hash *stt;
Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *symtab_shndx_hdr;
Elf_Internal_Shdr *symstrtab_hdr;
char *outbound_syms;
+ char *outbound_shndx;
int idx;
bfd_size_type amt;
return false;
symtab_hdr->contents = (PTR) outbound_syms;
+ outbound_shndx = NULL;
+ symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (symtab_shndx_hdr->sh_name != 0)
+ {
+ amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
+ outbound_shndx = bfd_alloc (abfd, amt);
+ if (outbound_shndx == NULL)
+ return false;
+ memset (outbound_shndx, 0, (unsigned long) amt);
+ symtab_shndx_hdr->contents = outbound_shndx;
+ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
+ symtab_shndx_hdr->sh_size = amt;
+ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
+ }
+
/* now generate the data (for "contents") */
{
/* Fill in zeroth symbol and swap it out. */
sym.st_info = 0;
sym.st_other = 0;
sym.st_shndx = SHN_UNDEF;
- bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
outbound_syms += bed->s->sizeof_sym;
+ if (outbound_shndx != NULL)
+ outbound_shndx += sizeof (Elf_External_Sym_Shndx);
}
syms = bfd_get_outsymbols (abfd);
case MAP_SHSTRTAB:
shndx = elf_tdata (abfd)->shstrtab_section;
break;
+ case MAP_SYM_SHNDX:
+ shndx = elf_tdata (abfd)->symtab_shndx_section;
+ break;
default:
break;
}
else
sym.st_other = 0;
- bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
outbound_syms += bed->s->sizeof_sym;
+ if (outbound_shndx != NULL)
+ outbound_shndx += sizeof (Elf_External_Sym_Shndx);
}
*sttp = stt;
}
}
+static boolean
+elfcore_netbsd_get_lwpid (note, lwpidp)
+ Elf_Internal_Note *note;
+ int *lwpidp;
+{
+ char *cp;
+
+ cp = strchr (note->namedata, '@');
+ if (cp != NULL)
+ {
+ *lwpidp = atoi(cp);
+ return true;
+ }
+ return false;
+}
+
+static boolean
+elfcore_grok_netbsd_procinfo (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+
+ /* Signal number at offset 0x08. */
+ elf_tdata (abfd)->core_signal
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
+
+ /* Process ID at offset 0x50. */
+ elf_tdata (abfd)->core_pid
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
+
+ /* Command name at 0x7c (max 32 bytes, including nul). */
+ elf_tdata (abfd)->core_command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
+
+ return true;
+}
+
+static boolean
+elfcore_grok_netbsd_note (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ int lwp;
+
+ if (elfcore_netbsd_get_lwpid (note, &lwp))
+ elf_tdata (abfd)->core_lwpid = lwp;
+
+ if (note->type == 1)
+ {
+ /* NetBSD-specific core "procinfo". Note that we expect to
+ find this note before any of the others, which is fine,
+ since the kernel writes this note out first when it
+ creates a core file. */
+
+ return elfcore_grok_netbsd_procinfo (abfd, note);
+ }
+
+ /* There are not currently any other machine-independent notes defined
+ for NetBSD ELF core files. If the note type is less than the start
+ of the machine-dependent note types, we don't understand it. */
+
+ if (note->type < 32)
+ return true;
+
+
+ switch (bfd_get_arch (abfd))
+ {
+ /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
+ PT_GETFPREGS == mach+2. */
+
+ case bfd_arch_alpha:
+ case bfd_arch_sparc:
+ switch (note->type)
+ {
+ case 32+0:
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ case 32+2:
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+ default:
+ return true;
+ }
+
+ /* On all other arch's, PT_GETREGS == mach+1 and
+ PT_GETFPREGS == mach+3. */
+
+ default:
+ switch (note->type)
+ {
+ case 32+1:
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ case 32+3:
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+ default:
+ return true;
+ }
+ }
+ /* NOTREACHED */
+}
+
static boolean
elfcore_read_notes (abfd, offset, size)
bfd *abfd;
in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
in.descpos = offset + (in.descdata - buf);
- if (! elfcore_grok_note (abfd, &in))
- goto error;
+ if (strncmp (in.namedata, "NetBSD-CORE", 11) == 0)
+ {
+ if (! elfcore_grok_netbsd_note (abfd, &in))
+ goto error;
+ }
+ else
+ {
+ if (! elfcore_grok_note (abfd, &in))
+ goto error;
+ }
p = in.descdata + BFD_ALIGN (in.descsz, 4);
}
+ sec->output_offset
+ sym->st_value);
if ((sec->flags & SEC_MERGE)
- && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && elf_section_data (sec)->sec_info_type == ELF_INFO_TYPE_MERGE)
{
asection *msec;
msec = sec;
rel->r_addend =
_bfd_merged_section_offset (abfd, &msec,
- elf_section_data (sec)->merge_info,
+ elf_section_data (sec)->sec_info,
sym->st_value + rel->r_addend,
(bfd_vma) 0)
- relocation;
}
return relocation;
}
+
+bfd_vma
+_bfd_elf_rel_local_sym (abfd, sym, psec, addend)
+ bfd *abfd;
+ Elf_Internal_Sym *sym;
+ asection **psec;
+ bfd_vma addend;
+{
+ asection *sec = *psec;
+
+ if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_MERGE)
+ return sym->st_value + addend;
+
+ return _bfd_merged_section_offset (abfd, psec,
+ elf_section_data (sec)->sec_info,
+ sym->st_value + addend, (bfd_vma) 0);
+}
+
+bfd_vma
+_bfd_elf_section_offset (abfd, info, sec, offset)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ bfd_vma offset;
+{
+ struct bfd_elf_section_data *sec_data;
+
+ sec_data = elf_section_data (sec);
+ switch (sec_data->sec_info_type)
+ {
+ case ELF_INFO_TYPE_STABS:
+ return _bfd_stab_section_offset
+ (abfd, &elf_hash_table (info)->merge_info, sec, &sec_data->sec_info,
+ offset);
+ case ELF_INFO_TYPE_EH_FRAME:
+ return _bfd_elf_eh_frame_section_offset (abfd, sec, offset);
+ default:
+ return offset;
+ }
+}