/* ELF executable support for BFD.
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
static bfd_boolean prep_headers (bfd *);
static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
-static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ;
+static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
+static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
+ file_ptr offset);
/* Swap version information in and out. The version information is
currently size independent. If that ever changes, this code will
return h & 0xffffffff;
}
+/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
+ the object_id field of an elf_obj_tdata field set to OBJECT_ID. */
bfd_boolean
-bfd_elf_mkobject (bfd *abfd)
+bfd_elf_allocate_object (bfd *abfd,
+ size_t object_size,
+ enum elf_object_id object_id)
{
+ BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
+ abfd->tdata.any = bfd_zalloc (abfd, object_size);
if (abfd->tdata.any == NULL)
- {
- abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
- if (abfd->tdata.any == NULL)
- return FALSE;
- }
-
- elf_tdata (abfd)->program_header_size = (bfd_size_type) -1;
+ return FALSE;
+ elf_object_id (abfd) = object_id;
+ elf_program_header_size (abfd) = (bfd_size_type) -1;
return TRUE;
}
+
+bfd_boolean
+bfd_elf_make_generic_object (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
+ GENERIC_ELF_TDATA);
+}
+
bfd_boolean
bfd_elf_mkcorefile (bfd *abfd)
{
/* I think this can be done just like an object file. */
- return bfd_elf_mkobject (abfd);
+ return bfd_elf_make_generic_object (abfd);
}
char *
SYMCOUNT specifies the number of symbols to read, starting from
symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
are non-NULL, they are used to store the internal symbols, external
- symbols, and symbol section index extensions, respectively. */
+ symbols, and symbol section index extensions, respectively.
+ Returns a pointer to the internal symbol buffer (malloced if necessary)
+ or NULL if there were no symbols or some kind of problem. */
Elf_Internal_Sym *
bfd_elf_get_elf_syms (bfd *ibfd,
bfd_size_type amt;
file_ptr pos;
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ abort ();
+
if (symcount == 0)
return intsym_buf;
if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
/* Check for a bogus st_shndx to avoid crashing. */
- && isym->st_shndx < elf_numsections (abfd)
- && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE))
+ && isym->st_shndx < elf_numsections (abfd))
{
iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
shindex = elf_elfheader (abfd)->e_shstrndx;
/* First we need to ensure the symbol table is available. Make sure
that it is a symbol table section. */
+ if (ghdr->sh_link >= elf_numsections (abfd))
+ return NULL;
hdr = elf_elfsections (abfd) [ghdr->sh_link];
if (hdr->sh_type != SHT_SYMTAB
|| ! bfd_section_from_shdr (abfd, ghdr->sh_link))
get the situation where elfsec is 0. */
if (elfsec == 0)
{
- const struct elf_backend_data *bed
- = get_elf_backend_data (abfd);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
if (bed->link_order_error_handler)
bed->link_order_error_handler
(_("%B: warning: sh_link not set for section `%A'"),
}
else
{
- asection *link;
+ asection *link = NULL;
- this_hdr = elf_elfsections (abfd)[elfsec];
+ if (elfsec < elf_numsections (abfd))
+ {
+ this_hdr = elf_elfsections (abfd)[elfsec];
+ link = this_hdr->bfd_section;
+ }
/* PR 1991, 2008:
Some strip/objcopy may leave an incorrect value in
sh_link. We don't want to proceed. */
- link = this_hdr->bfd_section;
if (link == NULL)
{
(*_bfd_error_handler)
if (! bfd_set_section_flags (abfd, newsect, flags))
return FALSE;
+ /* We do not parse the PT_NOTE segments as we are interested even in the
+ separate debug info files which may have the segments offsets corrupted.
+ PT_NOTEs from the core files are currently not parsed using BFD. */
+ if (hdr->sh_type == SHT_NOTE)
+ {
+ char *contents;
+
+ contents = bfd_malloc (hdr->sh_size);
+ if (!contents)
+ return FALSE;
+
+ if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
+ hdr->sh_size)
+ || !elf_parse_notes (abfd, contents, hdr->sh_size, -1))
+ {
+ free (contents);
+ return FALSE;
+ }
+
+ free (contents);
+ }
+
if ((flags & SEC_ALLOC) != 0)
{
Elf_Internal_Phdr *phdr;
s = bfd_get_section_by_name (abfd, ".dynamic");
if (s != NULL)
{
- int elfsec;
+ unsigned int elfsec;
unsigned long shlink;
bfd_byte *extdyn, *extdynend;
size_t extdynsize;
goto error_return;
elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
- if (elfsec == -1)
+ if (elfsec == SHN_BAD)
goto error_return;
shlink = elf_elfsections (abfd)[elfsec]->sh_link;
for (; extdyn < extdynend; extdyn += extdynsize)
{
Elf_Internal_Dyn dyn;
- const char *name;
+ const char *name = "";
char ab[20];
bfd_boolean stringp;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
(*swap_dyn_in) (abfd, extdyn, &dyn);
switch (dyn.d_tag)
{
default:
- sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
- name = ab;
+ if (bed->elf_backend_get_target_dtag)
+ name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
+
+ if (!strcmp (name, ""))
+ {
+ sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
+ name = ab;
+ }
break;
case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
case DT_GNU_HASH: name = "GNU_HASH"; break;
}
- fprintf (f, " %-11s ", name);
+ fprintf (f, " %-20s ", name);
if (! stringp)
fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
else
bfd_boolean
bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
{
- Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
- Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
- const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ Elf_Internal_Shdr *hdr;
+ Elf_Internal_Ehdr *ehdr;
+ const struct elf_backend_data *bed;
const char *name;
- name = bfd_elf_string_from_elf_section (abfd,
- elf_elfheader (abfd)->e_shstrndx,
+ if (shindex >= elf_numsections (abfd))
+ return FALSE;
+
+ hdr = elf_elfsections (abfd)[shindex];
+ ehdr = elf_elfheader (abfd);
+ name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
hdr->sh_name);
if (name == NULL)
return FALSE;
+ bed = get_elf_backend_data (abfd);
switch (hdr->sh_type)
{
case SHT_NULL:
return FALSE;
/* Check for a bogus link to avoid crashing. */
- if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
- || hdr->sh_link >= num_sec)
+ if (hdr->sh_link >= num_sec)
{
((*_bfd_error_handler)
(_("%B: invalid link %lu for reloc section %s (index %u)"),
section, an invalid section, or another reloc section. */
if (hdr->sh_link != elf_onesymtab (abfd)
|| hdr->sh_info == SHN_UNDEF
- || (hdr->sh_info >= SHN_LORESERVE && hdr->sh_info <= SHN_HIRESERVE)
|| hdr->sh_info >= num_sec
|| elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
|| elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
amt = sizeof (*hdr2);
hdr2 = bfd_alloc (abfd, amt);
+ if (hdr2 == NULL)
+ return FALSE;
elf_section_data (target_sect)->rel_hdr2 = hdr2;
}
*hdr2 = *hdr;
static const struct bfd_elf_special_section *special_sections[] =
{
special_sections_b, /* 'b' */
- special_sections_c, /* 'b' */
+ special_sections_c, /* 'c' */
special_sections_d, /* 'd' */
NULL, /* 'e' */
special_sections_f, /* 'f' */
case PT_NOTE:
if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
return FALSE;
- if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
+ if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
return FALSE;
return TRUE;
/* If the section type is unspecified, we set it based on
asect->flags. */
+ if ((asect->flags & SEC_GROUP) != 0)
+ sh_type = SHT_GROUP;
+ else if ((asect->flags & SEC_ALLOC) != 0
+ && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ || (asect->flags & SEC_NEVER_LOAD) != 0))
+ sh_type = SHT_NOBITS;
+ else
+ sh_type = SHT_PROGBITS;
+
if (this_hdr->sh_type == SHT_NULL)
- {
- if ((asect->flags & SEC_GROUP) != 0)
- this_hdr->sh_type = SHT_GROUP;
- else if ((asect->flags & SEC_ALLOC) != 0
- && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
- || (asect->flags & SEC_NEVER_LOAD) != 0))
- this_hdr->sh_type = SHT_NOBITS;
- else
- this_hdr->sh_type = SHT_PROGBITS;
+ this_hdr->sh_type = sh_type;
+ else if (this_hdr->sh_type == SHT_NOBITS
+ && sh_type == SHT_PROGBITS
+ && (asect->flags & SEC_ALLOC) != 0)
+ {
+ /* Warn if we are changing a NOBITS section to PROGBITS, but
+ allow the link to proceed. This can happen when users link
+ non-bss input sections to bss output sections, or emit data
+ to a bss output section via a linker script. */
+ (*_bfd_error_handler)
+ (_("warning: section `%A' type changed to PROGBITS"), asect);
+ this_hdr->sh_type = sh_type;
}
switch (this_hdr->sh_type)
abfd->section_count--;
}
else
- {
- if (section_number == SHN_LORESERVE)
- section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
- d->this_idx = section_number++;
- }
+ d->this_idx = section_number++;
}
}
}
d = elf_section_data (sec);
if (d->this_hdr.sh_type != SHT_GROUP)
- {
- if (section_number == SHN_LORESERVE)
- section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
- d->this_idx = section_number++;
- }
+ 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 - 2) & 0xFFFF))
{
- 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),
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);
}
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)
+ if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
{
i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
t->symtab_shndx_hdr.sh_link = t->symtab_section;
{
/* We need a PT_DYNAMIC segment. */
++segs;
+ }
- if (elf_tdata (abfd)->relro)
- {
- /* We need a PT_GNU_RELRO segment only when there is a
- PT_DYNAMIC segment. */
- ++segs;
- }
+ if (info->relro)
+ {
+ /* We need a PT_GNU_RELRO segment. */
+ ++segs;
}
if (elf_tdata (abfd)->eh_frame_hdr)
return segs * bed->s->sizeof_phdr;
}
+/* Find the segment that contains the output_section of section. */
+
+Elf_Internal_Phdr *
+_bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
+{
+ struct elf_segment_map *m;
+ Elf_Internal_Phdr *p;
+
+ for (m = elf_tdata (abfd)->segment_map,
+ p = elf_tdata (abfd)->phdr;
+ m != NULL;
+ m = m->next, p++)
+ {
+ int i;
+
+ for (i = m->count - 1; i >= 0; i--)
+ if (m->sections[i] == section)
+ return p;
+ }
+
+ return NULL;
+}
+
/* Create a mapping from a set of sections to a program segment. */
static struct elf_segment_map *
/* Possibly add or remove segments from the segment map. */
static bfd_boolean
-elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
+elf_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean remove_empty_load)
{
struct elf_segment_map **m;
const struct elf_backend_data *bed;
}
(*m)->count = new_count;
- if ((*m)->p_type == PT_LOAD && (*m)->count == 0)
+ if (remove_empty_load && (*m)->p_type == PT_LOAD && (*m)->count == 0)
*m = (*m)->next;
else
m = &(*m)->next;
struct elf_segment_map *m;
asection **sections = NULL;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_boolean no_user_phdrs;
- if (elf_tdata (abfd)->segment_map == NULL
- && bfd_count_sections (abfd) != 0)
+ no_user_phdrs = elf_tdata (abfd)->segment_map == NULL;
+ if (no_user_phdrs && bfd_count_sections (abfd) != 0)
{
asection *s;
unsigned int i;
pm = &m->next;
}
- if (dynsec != NULL && elf_tdata (abfd)->relro)
+ if (info->relro)
{
- /* We make a PT_GNU_RELRO segment only when there is a
- PT_DYNAMIC segment. */
- amt = sizeof (struct elf_segment_map);
- m = bfd_zalloc (abfd, amt);
- if (m == NULL)
- goto error_return;
- m->next = NULL;
- m->p_type = PT_GNU_RELRO;
- m->p_flags = PF_R;
- m->p_flags_valid = 1;
+ for (m = mfirst; m != NULL; m = m->next)
+ {
+ if (m->p_type == PT_LOAD)
+ {
+ asection *last = m->sections[m->count - 1];
+ bfd_vma vaddr = m->sections[0]->vma;
+ bfd_vma filesz = last->vma - vaddr + last->size;
- *pm = m;
- pm = &m->next;
+ if (vaddr < info->relro_end
+ && vaddr >= info->relro_start
+ && (vaddr + filesz) >= info->relro_end)
+ break;
+ }
+ }
+
+ /* Make a PT_GNU_RELRO segment only when it isn't empty. */
+ if (m != NULL)
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_RELRO;
+ m->p_flags = PF_R;
+ m->p_flags_valid = 1;
+
+ *pm = m;
+ pm = &m->next;
+ }
}
free (sections);
elf_tdata (abfd)->segment_map = mfirst;
}
- if (!elf_modify_segment_map (abfd, info))
+ if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
return FALSE;
for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
unsigned int i, j;
if (link_info == NULL
- && !elf_modify_segment_map (abfd, link_info))
+ && !elf_modify_segment_map (abfd, link_info, FALSE))
return FALSE;
alloc = 0;
p->p_align = maxpagesize;
}
- else if (m->count == 0)
- p->p_align = 1 << bed->s->log_file_align;
else if (m->p_align_valid)
p->p_align = m->p_align;
+ else if (m->count == 0)
+ p->p_align = 1 << bed->s->log_file_align;
else
p->p_align = 0;
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
+ /* Set the note section type to SHT_NOTE. */
+ else if (p->p_type == PT_NOTE)
+ for (i = 0; i < m->count; i++)
+ elf_section_type (m->sections[i]) = SHT_NOTE;
p->p_offset = 0;
p->p_filesz = 0;
p->p_memsz += this_hdr->sh_size;
}
- if (p->p_type == PT_GNU_RELRO)
- p->p_align = 1;
- else if (align > p->p_align
- && !m->p_align_valid
- && (p->p_type != PT_LOAD
- || (abfd->flags & D_PAGED) == 0))
+ if (align > p->p_align
+ && !m->p_align_valid
+ && (p->p_type != PT_LOAD
+ || (abfd->flags & D_PAGED) == 0))
p->p_align = align;
}
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;
- }
}
/* Now that we have set the section file positions, we can set up
if (m->count != 0)
{
if (p->p_type != PT_LOAD
- && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core))
+ && (p->p_type != PT_NOTE
+ || bfd_get_format (abfd) != bfd_core))
{
Elf_Internal_Shdr *hdr;
+ asection *sect;
+
BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
- hdr = &elf_section_data (m->sections[m->count - 1])->this_hdr;
- p->p_filesz = (m->sections[m->count - 1]->filepos
- - m->sections[0]->filepos);
+ sect = m->sections[m->count - 1];
+ hdr = &elf_section_data (sect)->this_hdr;
+ p->p_filesz = sect->filepos - m->sections[0]->filepos;
if (hdr->sh_type != SHT_NOBITS)
p->p_filesz += hdr->sh_size;
- p->p_offset = m->sections[0]->filepos;
+ if (p->p_type == PT_GNU_RELRO)
+ {
+ /* When we get here, we are copying executable
+ or shared library. But we need to use the same
+ linker logic. */
+ Elf_Internal_Phdr *lp;
+
+ for (lp = phdrs; lp < phdrs + count; ++lp)
+ {
+ if (lp->p_type == PT_LOAD
+ && lp->p_paddr == p->p_paddr)
+ break;
+ }
+
+ if (lp < phdrs + count)
+ {
+ /* We should use p_size if it is valid since it
+ may contain the first few bytes of the next
+ SEC_ALLOC section. */
+ if (m->p_size_valid)
+ p->p_filesz = m->p_size;
+ else
+ abort ();
+ p->p_vaddr = lp->p_vaddr;
+ p->p_offset = lp->p_offset;
+ p->p_memsz = p->p_filesz;
+ p->p_align = 1;
+ }
+ else
+ abort ();
+ }
+ else
+ p->p_offset = m->sections[0]->filepos;
}
}
else
}
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;
- }
}
}
else
{
Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
- Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
struct elf_strtab_hash *shstrtab;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
i_ehdrp = elf_elfheader (abfd);
- i_shdrp = elf_elfsections (abfd);
shstrtab = _bfd_elf_strtab_init ();
if (shstrtab == NULL)
|| 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. */
/* Given a section, search the header to find them. */
-int
+unsigned int
_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
{
const struct elf_backend_data *bed;
- int index;
+ unsigned int index;
if (elf_section_data (asect) != NULL
&& elf_section_data (asect)->this_idx != 0)
else if (bfd_is_und_section (asect))
index = SHN_UNDEF;
else
- index = -1;
+ index = SHN_BAD;
bed = get_elf_backend_data (abfd);
if (bed->elf_backend_section_from_bfd_section)
return retval;
}
- if (index == -1)
+ if (index == SHN_BAD)
bfd_set_error (bfd_error_nonrepresentable_section);
return index;
&& (section->lma + SECTION_SIZE (section, segment) \
<= SEGMENT_END (segment, base)))
- /* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */
-#define IS_COREFILE_NOTE(p, s) \
+ /* Handle PT_NOTE segment. */
+#define IS_NOTE(p, s) \
(p->p_type == PT_NOTE \
- && bfd_get_format (ibfd) == bfd_core \
- && s->vma == 0 && s->lma == 0 \
+ && elf_section_type (s) == SHT_NOTE \
&& (bfd_vma) s->filepos >= p->p_offset \
&& ((bfd_vma) s->filepos + s->size \
<= p->p_offset + p->p_filesz))
+ /* Special case: corefile "NOTE" section containing regs, prpsinfo
+ etc. */
+#define IS_COREFILE_NOTE(p, s) \
+ (IS_NOTE (p, s) \
+ && bfd_get_format (ibfd) == bfd_core \
+ && s->vma == 0 \
+ && s->lma == 0)
+
/* The complicated case when p_vaddr is 0 is to handle the Solaris
linker, which generates a PT_INTERP section with p_vaddr and
p_memsz set to 0. */
A section will be included if:
1. It is within the address space of the segment -- we use the LMA
if that is set for the segment and the VMA otherwise,
- 2. It is an allocated segment,
+ 2. It is an allocated section or a NOTE section in a PT_NOTE
+ segment.
3. There is an output section associated with it,
4. The section has not already been allocated to a previous segment.
5. PT_GNU_STACK segments do not include any sections.
? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
: IS_CONTAINED_BY_VMA (section, segment)) \
&& (section->flags & SEC_ALLOC) != 0) \
- || IS_COREFILE_NOTE (segment, section)) \
+ || IS_NOTE (segment, section)) \
&& segment->p_type != PT_GNU_STACK \
&& (segment->p_type != PT_TLS \
|| (section->flags & SEC_THREAD_LOCAL)) \
: segment->p_vaddr != section->vma) \
|| (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \
== 0)) \
- && ! section->segment_mark)
+ && !section->segment_mark)
/* If the output section of a section in the input segment is NULL,
it is removed from the corresponding output segment. */
}
if (segment->p_type != PT_LOAD)
- continue;
+ {
+ /* Remove PT_GNU_RELRO segment. */
+ if (segment->p_type == PT_GNU_RELRO)
+ segment->p_type = PT_NULL;
+ continue;
+ }
/* Determine if this segment overlaps any previous segments. */
- for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2 ++)
+ for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
{
bfd_signed_vma extra_length;
if (segment2->p_type != PT_LOAD
- || ! SEGMENT_OVERLAPS (segment, segment2))
+ || !SEGMENT_OVERLAPS (segment, segment2))
continue;
/* Merge the two segments together. */
{
/* Extend SEGMENT2 to include SEGMENT and then delete
SEGMENT. */
- extra_length =
- SEGMENT_END (segment, segment->p_vaddr)
- - SEGMENT_END (segment2, segment2->p_vaddr);
+ extra_length = (SEGMENT_END (segment, segment->p_vaddr)
+ - SEGMENT_END (segment2, segment2->p_vaddr));
if (extra_length > 0)
{
- segment2->p_memsz += extra_length;
+ segment2->p_memsz += extra_length;
segment2->p_filesz += extra_length;
}
{
/* Extend SEGMENT to include SEGMENT2 and then delete
SEGMENT2. */
- extra_length =
- SEGMENT_END (segment2, segment2->p_vaddr)
- - SEGMENT_END (segment, segment->p_vaddr);
+ extra_length = (SEGMENT_END (segment2, segment2->p_vaddr)
+ - SEGMENT_END (segment, segment->p_vaddr));
if (extra_length > 0)
{
- segment->p_memsz += extra_length;
+ segment->p_memsz += extra_length;
segment->p_filesz += extra_length;
}
/* The second scan attempts to assign sections to segments. */
for (i = 0, segment = elf_tdata (ibfd)->phdr;
i < num_segments;
- i ++, segment ++)
- {
- unsigned int section_count;
- asection ** sections;
- asection * output_section;
- unsigned int isec;
- bfd_vma matching_lma;
- bfd_vma suggested_lma;
- unsigned int j;
+ i++, segment++)
+ {
+ unsigned int section_count;
+ asection **sections;
+ asection *output_section;
+ unsigned int isec;
+ bfd_vma matching_lma;
+ bfd_vma suggested_lma;
+ unsigned int j;
bfd_size_type amt;
- asection * first_section;
+ asection *first_section;
+ bfd_boolean first_matching_lma;
+ bfd_boolean first_suggested_lma;
if (segment->p_type == PT_NULL)
continue;
/* Initialise the fields of the segment map. Default to
using the physical address of the segment in the input BFD. */
- map->next = NULL;
- map->p_type = segment->p_type;
- map->p_flags = segment->p_flags;
+ map->next = NULL;
+ map->p_type = segment->p_type;
+ map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
/* If the first section in the input segment is removed, there is
and if it contains the program headers themselves. */
map->includes_filehdr = (segment->p_offset == 0
&& segment->p_filesz >= iehdr->e_ehsize);
-
map->includes_phdrs = 0;
- if (! phdr_included || segment->p_type != PT_LOAD)
+ if (!phdr_included || segment->p_type != PT_LOAD)
{
map->includes_phdrs =
(segment->p_offset <= (bfd_vma) iehdr->e_phoff
something. They are allowed by the ELF spec however, so only
a warning is produced. */
if (segment->p_type == PT_LOAD)
- (*_bfd_error_handler)
- (_("%B: warning: Empty loadable segment detected, is this intentional ?\n"),
- ibfd);
+ (*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
+ " detected, is this intentional ?\n"),
+ ibfd);
map->count = 0;
*pointer_to_map = map;
isec = 0;
matching_lma = 0;
suggested_lma = 0;
+ first_matching_lma = TRUE;
+ first_suggested_lma = TRUE;
- for (j = 0, section = ibfd->sections;
+ for (section = ibfd->sections;
section != NULL;
section = section->next)
+ if (section == first_section)
+ break;
+
+ for (j = 0; section != NULL; section = section->next)
{
if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
{
output_section = section->output_section;
- sections[j ++] = section;
+ sections[j++] = section;
/* The Solaris native linker always sets p_paddr to 0.
We try to catch that case here, and set it to the
p_paddr be left as zero. */
if (segment->p_paddr == 0
&& segment->p_vaddr != 0
- && (! bed->want_p_paddr_set_to_zero)
+ && !bed->want_p_paddr_set_to_zero
&& isec == 0
&& output_section->lma != 0
- && (output_section->vma == (segment->p_vaddr
- + (map->includes_filehdr
- ? iehdr->e_ehsize
- : 0)
- + (map->includes_phdrs
- ? (iehdr->e_phnum
- * iehdr->e_phentsize)
- : 0))))
+ && output_section->vma == (segment->p_vaddr
+ + (map->includes_filehdr
+ ? iehdr->e_ehsize
+ : 0)
+ + (map->includes_phdrs
+ ? (iehdr->e_phnum
+ * iehdr->e_phentsize)
+ : 0)))
map->p_paddr = segment->p_vaddr;
/* Match up the physical address of the segment with the
LMA address of the output section. */
if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
|| IS_COREFILE_NOTE (segment, section)
- || (bed->want_p_paddr_set_to_zero &&
- IS_CONTAINED_BY_VMA (output_section, segment)))
+ || (bed->want_p_paddr_set_to_zero
+ && IS_CONTAINED_BY_VMA (output_section, segment)))
{
- if (matching_lma == 0 || output_section->lma < matching_lma)
- matching_lma = output_section->lma;
+ if (first_matching_lma || output_section->lma < matching_lma)
+ {
+ matching_lma = output_section->lma;
+ first_matching_lma = FALSE;
+ }
/* We assume that if the section fits within the segment
then it does not overlap any other section within that
segment. */
- map->sections[isec ++] = output_section;
+ map->sections[isec++] = output_section;
}
- else if (suggested_lma == 0)
- suggested_lma = output_section->lma;
+ else if (first_suggested_lma)
+ {
+ suggested_lma = output_section->lma;
+ first_suggested_lma = FALSE;
+ }
+
+ if (j == section_count)
+ break;
}
}
*pointer_to_map = map;
pointer_to_map = &map->next;
- if (matching_lma != map->p_paddr
+ if (!bed->want_p_paddr_set_to_zero
+ && matching_lma != map->p_paddr
&& !map->includes_filehdr && !map->includes_phdrs)
/* There is some padding before the first section in the
segment. So, we must account for that in the output
}
else
{
- if (matching_lma != 0)
+ if (!first_matching_lma)
{
/* At least one section fits inside the current segment.
Keep it, but modify its physical address to match the
{
map->count = 0;
suggested_lma = 0;
+ first_suggested_lma = TRUE;
/* Fill the current segment with sections that fit. */
for (j = 0; j < section_count; j++)
/* If the first section in a segment does not start at
the beginning of the segment, then something is
wrong. */
- if (output_section->lma !=
- (map->p_paddr
- + (map->includes_filehdr ? iehdr->e_ehsize : 0)
- + (map->includes_phdrs
- ? iehdr->e_phnum * iehdr->e_phentsize
- : 0)))
+ if (output_section->lma
+ != (map->p_paddr
+ + (map->includes_filehdr ? iehdr->e_ehsize : 0)
+ + (map->includes_phdrs
+ ? iehdr->e_phnum * iehdr->e_phentsize
+ : 0)))
abort ();
}
else
{
- asection * prev_sec;
+ asection *prev_sec;
prev_sec = map->sections[map->count - 1];
if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
maxpagesize)
< BFD_ALIGN (output_section->lma, maxpagesize))
- || ((prev_sec->lma + prev_sec->size)
+ || (prev_sec->lma + prev_sec->size
> output_section->lma))
{
- if (suggested_lma == 0)
- suggested_lma = output_section->lma;
+ if (first_suggested_lma)
+ {
+ suggested_lma = output_section->lma;
+ first_suggested_lma = FALSE;
+ }
continue;
}
sections[j] = NULL;
section->segment_mark = TRUE;
}
- else if (suggested_lma == 0)
- suggested_lma = output_section->lma;
+ else if (first_suggested_lma)
+ {
+ suggested_lma = output_section->lma;
+ first_suggested_lma = FALSE;
+ }
}
BFD_ASSERT (map->count > 0);
/* Initialise the fields of the segment map. Set the physical
physical address to the LMA of the first section that has
not yet been assigned. */
- map->next = NULL;
- map->p_type = segment->p_type;
- map->p_flags = segment->p_flags;
- map->p_flags_valid = 1;
- map->p_paddr = suggested_lma;
- map->p_paddr_valid = 1;
+ map->next = NULL;
+ map->p_type = segment->p_type;
+ map->p_flags = segment->p_flags;
+ map->p_flags_valid = 1;
+ map->p_paddr = suggested_lma;
+ map->p_paddr_valid = 1;
map->includes_filehdr = 0;
- map->includes_phdrs = 0;
+ map->includes_phdrs = 0;
}
}
while (isec < section_count);
#undef SECTION_SIZE
#undef IS_CONTAINED_BY_VMA
#undef IS_CONTAINED_BY_LMA
+#undef IS_NOTE
#undef IS_COREFILE_NOTE
#undef IS_SOLARIS_PT_INTERP
#undef IS_SECTION_IN_INPUT_SEGMENT
asection *first_section = NULL;
asection *lowest_section = NULL;
- /* FIXME: Do we need to copy PT_NULL segment? */
- if (segment->p_type == PT_NULL)
- continue;
-
/* Compute how many sections are in this segment. */
for (section = ibfd->sections, section_count = 0;
section != NULL;
map->p_align_valid = 1;
map->p_vaddr_offset = 0;
+ if (map->p_type == PT_GNU_RELRO
+ && segment->p_filesz == segment->p_memsz)
+ {
+ /* The PT_GNU_RELRO segment may contain the first a few
+ bytes in the .got.plt section even if the whole .got.plt
+ section isn't in the PT_GNU_RELRO segment. We won't
+ change the size of the PT_GNU_RELRO segment. */
+ map->p_size = segment->p_filesz;
+ map->p_size_valid = 1;
+ }
+
/* Determine if this segment contains the ELF file header
and if it contains the program headers themselves. */
map->includes_filehdr = (segment->p_offset == 0
asection *section, *osec;
unsigned int i, num_segments;
Elf_Internal_Shdr *this_hdr;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (ibfd);
+
+ /* Regenerate the segment map if p_paddr is set to 0. */
+ if (bed->want_p_paddr_set_to_zero)
+ goto rewrite;
/* Initialize the segment mark field. */
for (section = obfd->sections; section != NULL;
osym = elf_symbol_from (obfd, osymarg);
if (isym != NULL
+ && isym->internal_elf_sym.st_shndx != 0
&& osym != NULL
&& bfd_is_abs_section (isym->symbol.section))
{
else
{
asection *sec = syms[idx]->section;
- int shndx;
+ unsigned int shndx;
if (sec->output_section)
{
{
shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
- if (shndx == -1)
+ if (shndx == SHN_BAD)
{
asection *sec2;
}
shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
- BFD_ASSERT (shndx != -1);
+ BFD_ASSERT (shndx != SHN_BAD);
}
}
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
}
else if (bfd_is_com_section (syms[idx]->section))
- sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
+ {
+#ifdef USE_STT_COMMON
+ if (type == STT_OBJECT)
+ sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
+ else
+#else
+ sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
+#endif
+ }
else if (bfd_is_und_section (syms[idx]->section))
sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
? STB_WEAK
}
/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
- type of 5 (NT_PRXFPREG). Just include the whole note's contents
+ type of NT_PRXFPREG. Just include the whole note's contents
literally. */
static bfd_boolean
return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
}
+static bfd_boolean
+elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
+}
+
+
#if defined (HAVE_PRPSINFO_T)
typedef prpsinfo_t elfcore_psinfo_t;
#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */
}
#endif /* defined (HAVE_LWPSTATUS_T) */
-#if defined (HAVE_WIN32_PSTATUS_T)
static bfd_boolean
elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
{
char *name;
size_t len;
asection *sect;
- win32_pstatus_t pstatus;
+ int type;
+ int is_active_thread;
+ bfd_vma base_addr;
- if (note->descsz < sizeof (pstatus))
+ if (note->descsz < 728)
return TRUE;
- memcpy (&pstatus, note->descdata, sizeof (pstatus));
+ if (! CONST_STRNEQ (note->namedata, "win32"))
+ return TRUE;
- switch (pstatus.data_type)
+ type = bfd_get_32 (abfd, note->descdata);
+
+ switch (type)
{
- case NOTE_INFO_PROCESS:
+ case 1 /* NOTE_INFO_PROCESS */:
/* FIXME: need to add ->core_command. */
- elf_tdata (abfd)->core_signal = pstatus.data.process_info.signal;
- elf_tdata (abfd)->core_pid = pstatus.data.process_info.pid;
+ /* process_info.pid */
+ elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 8);
+ /* process_info.signal */
+ elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 12);
break;
- case NOTE_INFO_THREAD:
+ case 2 /* NOTE_INFO_THREAD */:
/* Make a ".reg/999" section. */
- sprintf (buf, ".reg/%ld", (long) pstatus.data.thread_info.tid);
+ /* thread_info.tid */
+ sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8));
len = strlen (buf) + 1;
name = bfd_alloc (abfd, len);
if (sect == NULL)
return FALSE;
- sect->size = sizeof (pstatus.data.thread_info.thread_context);
- sect->filepos = (note->descpos
- + offsetof (struct win32_pstatus,
- data.thread_info.thread_context));
+ /* sizeof (thread_info.thread_context) */
+ sect->size = 716;
+ /* offsetof (thread_info.thread_context) */
+ sect->filepos = note->descpos + 12;
sect->alignment_power = 2;
- if (pstatus.data.thread_info.is_active_thread)
+ /* thread_info.is_active_thread */
+ is_active_thread = bfd_get_32 (abfd, note->descdata + 8);
+
+ if (is_active_thread)
if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
return FALSE;
break;
- case NOTE_INFO_MODULE:
+ case 3 /* NOTE_INFO_MODULE */:
/* Make a ".module/xxxxxxxx" section. */
- sprintf (buf, ".module/%08lx",
- (long) pstatus.data.module_info.base_address);
+ /* module_info.base_address */
+ base_addr = bfd_get_32 (abfd, note->descdata + 4);
+ sprintf (buf, ".module/%08lx", (long) base_addr);
len = strlen (buf) + 1;
name = bfd_alloc (abfd, len);
return TRUE;
}
-#endif /* HAVE_WIN32_PSTATUS_T */
static bfd_boolean
elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */
return elfcore_grok_prfpreg (abfd, note);
-#if defined (HAVE_WIN32_PSTATUS_T)
case NT_WIN32PSTATUS:
return elfcore_grok_win32pstatus (abfd, note);
-#endif
case NT_PRXFPREG: /* Linux SSE extension */
if (note->namesz == 6
else
return TRUE;
+ case NT_PPC_VMX:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_ppc_vmx (abfd, note);
+ else
+ return TRUE;
+
case NT_PRPSINFO:
case NT_PSINFO:
if (bed->elf_backend_grok_psinfo)
}
}
+static bfd_boolean
+elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
+{
+ elf_tdata (abfd)->build_id_size = note->descsz;
+ elf_tdata (abfd)->build_id = bfd_alloc (abfd, note->descsz);
+ if (elf_tdata (abfd)->build_id == NULL)
+ return FALSE;
+
+ memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->type)
+ {
+ default:
+ return TRUE;
+
+ case NT_GNU_BUILD_ID:
+ return elfobj_grok_gnu_build_id (abfd, note);
+ }
+}
+
static bfd_boolean
elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
{
}
}
+static bfd_boolean
+elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ char *name;
+ asection *sect;
+ size_t len;
+
+ /* Use note name as section name. */
+ len = note->namesz;
+ name = bfd_alloc (abfd, len);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, note->namedata, len);
+ name[len - 1] = '\0';
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 1;
+
+ return TRUE;
+}
+
/* Function: elfcore_write_note
Inputs:
newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
buf = realloc (buf, *bufsiz + newspace);
+ if (buf == NULL)
+ return buf;
dest = buf + *bufsiz;
*bufsiz += newspace;
xnp = (Elf_External_Note *) dest;
note_name, NT_PRXFPREG, xfpregs, size);
}
+char *
+elfcore_write_ppc_vmx (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *ppc_vmx,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_PPC_VMX, ppc_vmx, size);
+}
+
static bfd_boolean
-elfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
+elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
{
- char *buf;
char *p;
- if (size <= 0)
- return TRUE;
-
- if (bfd_seek (abfd, offset, SEEK_SET) != 0)
- return FALSE;
-
- buf = bfd_malloc (size);
- if (buf == NULL)
- return FALSE;
-
- if (bfd_bread (buf, size, abfd) != size)
- {
- error:
- free (buf);
- return FALSE;
- }
-
p = buf;
while (p < buf + size)
{
in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
in.descpos = offset + (in.descdata - buf);
- if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
- {
- if (! elfcore_grok_netbsd_note (abfd, &in))
- goto error;
- }
- else if (CONST_STRNEQ (in.namedata, "QNX"))
- {
- if (! elfcore_grok_nto_note (abfd, &in))
- goto error;
- }
- else
- {
- if (! elfcore_grok_note (abfd, &in))
- goto error;
+ switch (bfd_get_format (abfd))
+ {
+ default:
+ return TRUE;
+
+ case bfd_core:
+ if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
+ {
+ if (! elfcore_grok_netbsd_note (abfd, &in))
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (in.namedata, "QNX"))
+ {
+ if (! elfcore_grok_nto_note (abfd, &in))
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (in.namedata, "SPU/"))
+ {
+ if (! elfcore_grok_spu_note (abfd, &in))
+ return FALSE;
+ }
+ else
+ {
+ if (! elfcore_grok_note (abfd, &in))
+ return FALSE;
+ }
+ break;
+
+ case bfd_object:
+ if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
+ {
+ if (! elfobj_grok_gnu_note (abfd, &in))
+ return FALSE;
+ }
+ break;
}
p = in.descdata + BFD_ALIGN (in.descsz, 4);
}
+ return TRUE;
+}
+
+static bfd_boolean
+elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
+{
+ char *buf;
+
+ if (size <= 0)
+ return TRUE;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+ return FALSE;
+
+ buf = bfd_malloc (size);
+ if (buf == NULL)
+ return FALSE;
+
+ if (bfd_bread (buf, size, abfd) != size
+ || !elf_parse_notes (abfd, buf, size, offset))
+ {
+ free (buf);
+ return FALSE;
+ }
+
free (buf);
return TRUE;
}
return num_phdrs;
}
-void
-_bfd_elf_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
-{
-#ifdef BFD64
- Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
-
- i_ehdrp = elf_elfheader (abfd);
- if (i_ehdrp == NULL)
- sprintf_vma (buf, value);
- else
- {
- if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
- {
-#if BFD_HOST_64BIT_LONG
- sprintf (buf, "%016lx", value);
-#else
- sprintf (buf, "%08lx%08lx", _bfd_int64_high (value),
- _bfd_int64_low (value));
-#endif
- }
- else
- sprintf (buf, "%08lx", (unsigned long) (value & 0xffffffff));
- }
-#else
- sprintf_vma (buf, value);
-#endif
-}
-
-void
-_bfd_elf_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
-{
-#ifdef BFD64
- Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
-
- i_ehdrp = elf_elfheader (abfd);
- if (i_ehdrp == NULL)
- fprintf_vma ((FILE *) stream, value);
- else
- {
- if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
- {
-#if BFD_HOST_64BIT_LONG
- fprintf ((FILE *) stream, "%016lx", value);
-#else
- fprintf ((FILE *) stream, "%08lx%08lx",
- _bfd_int64_high (value), _bfd_int64_low (value));
-#endif
- }
- else
- fprintf ((FILE *) stream, "%08lx",
- (unsigned long) (value & 0xffffffff));
- }
-#else
- fprintf_vma ((FILE *) stream, value);
-#endif
-}
-
enum elf_reloc_type_class
_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
{
names = (char *) (s + count);
p = relplt->relocation;
n = 0;
- for (i = 0; i < count; i++, s++, p++)
+ for (i = 0; i < count; i++, p++)
{
size_t len;
bfd_vma addr;
s->section = plt;
s->value = addr - plt->vma;
s->name = names;
+ s->udata.p = NULL;
len = strlen ((*p->sym_ptr_ptr)->name);
memcpy (names, (*p->sym_ptr_ptr)->name, len);
names += len;
memcpy (names, "@plt", sizeof ("@plt"));
names += sizeof ("@plt");
- ++n;
+ ++s, ++n;
}
return n;