static boolean prep_headers PARAMS ((bfd *));
static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int));
static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));
-static char *elf_read PARAMS ((bfd *, long, unsigned int));
+static char *elf_read PARAMS ((bfd *, file_ptr, bfd_size_type));
+static boolean setup_group PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
+static void set_group_contents PARAMS ((bfd *, asection *, PTR));
static boolean assign_section_numbers PARAMS ((bfd *));
static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));
static boolean elf_map_symbols PARAMS ((bfd *));
static bfd_size_type get_program_header_size PARAMS ((bfd *));
-static boolean elfcore_read_notes PARAMS ((bfd *, bfd_vma, bfd_vma));
-static boolean elf_find_function PARAMS ((bfd *, asection *,
- asymbol **,
- bfd_vma, const char **,
- const char **));
+static boolean elfcore_read_notes PARAMS ((bfd *, file_ptr, bfd_size_type));
+static boolean elf_find_function PARAMS ((bfd *, asection *, asymbol **,
+ bfd_vma, const char **,
+ const char **));
+static int elfcore_make_pid PARAMS ((bfd *));
+static boolean elfcore_maybe_make_sect PARAMS ((bfd *, char *, asection *));
+static boolean elfcore_make_note_pseudosection PARAMS ((bfd *, char *,
+ Elf_Internal_Note *));
+static boolean elfcore_grok_prfpreg PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean elfcore_grok_prxfpreg PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean elfcore_grok_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
const Elf_External_Verdef *src;
Elf_Internal_Verdef *dst;
{
- dst->vd_version = bfd_h_get_16 (abfd, src->vd_version);
- dst->vd_flags = bfd_h_get_16 (abfd, src->vd_flags);
- dst->vd_ndx = bfd_h_get_16 (abfd, src->vd_ndx);
- dst->vd_cnt = bfd_h_get_16 (abfd, src->vd_cnt);
- dst->vd_hash = bfd_h_get_32 (abfd, src->vd_hash);
- dst->vd_aux = bfd_h_get_32 (abfd, src->vd_aux);
- dst->vd_next = bfd_h_get_32 (abfd, src->vd_next);
+ dst->vd_version = H_GET_16 (abfd, src->vd_version);
+ dst->vd_flags = H_GET_16 (abfd, src->vd_flags);
+ dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx);
+ dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt);
+ dst->vd_hash = H_GET_32 (abfd, src->vd_hash);
+ dst->vd_aux = H_GET_32 (abfd, src->vd_aux);
+ dst->vd_next = H_GET_32 (abfd, src->vd_next);
}
/* Swap out a Verdef structure. */
const Elf_Internal_Verdef *src;
Elf_External_Verdef *dst;
{
- bfd_h_put_16 (abfd, src->vd_version, dst->vd_version);
- bfd_h_put_16 (abfd, src->vd_flags, dst->vd_flags);
- bfd_h_put_16 (abfd, src->vd_ndx, dst->vd_ndx);
- bfd_h_put_16 (abfd, src->vd_cnt, dst->vd_cnt);
- bfd_h_put_32 (abfd, src->vd_hash, dst->vd_hash);
- bfd_h_put_32 (abfd, src->vd_aux, dst->vd_aux);
- bfd_h_put_32 (abfd, src->vd_next, dst->vd_next);
+ H_PUT_16 (abfd, src->vd_version, dst->vd_version);
+ H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
+ H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
+ H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
+ H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
+ H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
+ H_PUT_32 (abfd, src->vd_next, dst->vd_next);
}
/* Swap in a Verdaux structure. */
const Elf_External_Verdaux *src;
Elf_Internal_Verdaux *dst;
{
- dst->vda_name = bfd_h_get_32 (abfd, src->vda_name);
- dst->vda_next = bfd_h_get_32 (abfd, src->vda_next);
+ dst->vda_name = H_GET_32 (abfd, src->vda_name);
+ dst->vda_next = H_GET_32 (abfd, src->vda_next);
}
/* Swap out a Verdaux structure. */
const Elf_Internal_Verdaux *src;
Elf_External_Verdaux *dst;
{
- bfd_h_put_32 (abfd, src->vda_name, dst->vda_name);
- bfd_h_put_32 (abfd, src->vda_next, dst->vda_next);
+ H_PUT_32 (abfd, src->vda_name, dst->vda_name);
+ H_PUT_32 (abfd, src->vda_next, dst->vda_next);
}
/* Swap in a Verneed structure. */
const Elf_External_Verneed *src;
Elf_Internal_Verneed *dst;
{
- dst->vn_version = bfd_h_get_16 (abfd, src->vn_version);
- dst->vn_cnt = bfd_h_get_16 (abfd, src->vn_cnt);
- dst->vn_file = bfd_h_get_32 (abfd, src->vn_file);
- dst->vn_aux = bfd_h_get_32 (abfd, src->vn_aux);
- dst->vn_next = bfd_h_get_32 (abfd, src->vn_next);
+ dst->vn_version = H_GET_16 (abfd, src->vn_version);
+ dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt);
+ dst->vn_file = H_GET_32 (abfd, src->vn_file);
+ dst->vn_aux = H_GET_32 (abfd, src->vn_aux);
+ dst->vn_next = H_GET_32 (abfd, src->vn_next);
}
/* Swap out a Verneed structure. */
const Elf_Internal_Verneed *src;
Elf_External_Verneed *dst;
{
- bfd_h_put_16 (abfd, src->vn_version, dst->vn_version);
- bfd_h_put_16 (abfd, src->vn_cnt, dst->vn_cnt);
- bfd_h_put_32 (abfd, src->vn_file, dst->vn_file);
- bfd_h_put_32 (abfd, src->vn_aux, dst->vn_aux);
- bfd_h_put_32 (abfd, src->vn_next, dst->vn_next);
+ H_PUT_16 (abfd, src->vn_version, dst->vn_version);
+ H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
+ H_PUT_32 (abfd, src->vn_file, dst->vn_file);
+ H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
+ H_PUT_32 (abfd, src->vn_next, dst->vn_next);
}
/* Swap in a Vernaux structure. */
const Elf_External_Vernaux *src;
Elf_Internal_Vernaux *dst;
{
- dst->vna_hash = bfd_h_get_32 (abfd, src->vna_hash);
- dst->vna_flags = bfd_h_get_16 (abfd, src->vna_flags);
- dst->vna_other = bfd_h_get_16 (abfd, src->vna_other);
- dst->vna_name = bfd_h_get_32 (abfd, src->vna_name);
- dst->vna_next = bfd_h_get_32 (abfd, src->vna_next);
+ dst->vna_hash = H_GET_32 (abfd, src->vna_hash);
+ dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
+ dst->vna_other = H_GET_16 (abfd, src->vna_other);
+ dst->vna_name = H_GET_32 (abfd, src->vna_name);
+ dst->vna_next = H_GET_32 (abfd, src->vna_next);
}
/* Swap out a Vernaux structure. */
const Elf_Internal_Vernaux *src;
Elf_External_Vernaux *dst;
{
- bfd_h_put_32 (abfd, src->vna_hash, dst->vna_hash);
- bfd_h_put_16 (abfd, src->vna_flags, dst->vna_flags);
- bfd_h_put_16 (abfd, src->vna_other, dst->vna_other);
- bfd_h_put_32 (abfd, src->vna_name, dst->vna_name);
- bfd_h_put_32 (abfd, src->vna_next, dst->vna_next);
+ H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
+ H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
+ H_PUT_16 (abfd, src->vna_other, dst->vna_other);
+ H_PUT_32 (abfd, src->vna_name, dst->vna_name);
+ H_PUT_32 (abfd, src->vna_next, dst->vna_next);
}
/* Swap in a Versym structure. */
const Elf_External_Versym *src;
Elf_Internal_Versym *dst;
{
- dst->vs_vers = bfd_h_get_16 (abfd, src->vs_vers);
+ dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
}
/* Swap out a Versym structure. */
const Elf_Internal_Versym *src;
Elf_External_Versym *dst;
{
- bfd_h_put_16 (abfd, src->vs_vers, dst->vs_vers);
+ H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
}
/* Standard ELF hash function. Do not change this function; you will
static char *
elf_read (abfd, offset, size)
bfd *abfd;
- long offset;
- unsigned int size;
+ file_ptr offset;
+ bfd_size_type size;
{
char *buf;
if ((buf = bfd_alloc (abfd, size)) == NULL)
return NULL;
- if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
return NULL;
- if (bfd_read ((PTR) buf, size, 1, abfd) != size)
+ if (bfd_bread ((PTR) buf, size, abfd) != size)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_file_truncated);
{
/* This just does initialization. */
/* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
- elf_tdata (abfd) = (struct elf_obj_tdata *)
- bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
+ bfd_size_type amt = sizeof (struct elf_obj_tdata);
+ elf_tdata (abfd) = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt);
if (elf_tdata (abfd) == 0)
return false;
/* Since everything is done at close time, do we need any
{
Elf_Internal_Shdr **i_shdrp;
char *shstrtab = NULL;
- unsigned int offset;
- unsigned int shstrtabsize;
+ file_ptr offset;
+ bfd_size_type shstrtabsize;
i_shdrp = elf_elfsections (abfd);
if (i_shdrp == 0 || i_shdrp[shindex] == 0)
{
(*_bfd_error_handler)
(_("%s: invalid string offset %u >= %lu for section `%s'"),
- bfd_get_filename (abfd), strindex, (unsigned long) hdr->sh_size,
+ bfd_archive_filename (abfd), strindex, (unsigned long) hdr->sh_size,
((shindex == elf_elfheader(abfd)->e_shstrndx
&& strindex == hdr->sh_name)
? ".shstrtab"
return ((char *) hdr->contents) + strindex;
}
+/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
+ sections. The first element is the flags, the rest are section
+ pointers. */
+
+typedef union elf_internal_group {
+ Elf_Internal_Shdr *shdr;
+ unsigned int flags;
+} Elf_Internal_Group;
+
+/* Set next_in_group list pointer, and group name for NEWSECT. */
+
+static boolean
+setup_group (abfd, hdr, newsect)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ asection *newsect;
+{
+ unsigned int num_group = elf_tdata (abfd)->num_group;
+
+ /* If num_group is zero, read in all SHT_GROUP sections. The count
+ is set to -1 if there are no SHT_GROUP sections. */
+ if (num_group == 0)
+ {
+ unsigned int i, shnum;
+
+ /* 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;
+ num_group = 0;
+ for (i = 0; i < shnum; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
+ if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
+ num_group += 1;
+ }
+
+ if (num_group == 0)
+ num_group = -1;
+ elf_tdata (abfd)->num_group = num_group;
+
+ if (num_group > 0)
+ {
+ /* We keep a list of elf section headers for group sections,
+ so we can find them quickly. */
+ bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *);
+ elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt);
+ if (elf_tdata (abfd)->group_sect_ptr == NULL)
+ return false;
+
+ num_group = 0;
+ for (i = 0; i < shnum; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
+ if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
+ {
+ char *src;
+ Elf_Internal_Group *dest;
+
+ /* Add to list of sections. */
+ elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
+ num_group += 1;
+
+ /* Read the raw contents. */
+ BFD_ASSERT (sizeof (*dest) >= 4);
+ amt = shdr->sh_size * sizeof (*dest) / 4;
+ shdr->contents = bfd_alloc (abfd, amt);
+ if (shdr->contents == NULL
+ || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
+ || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
+ != shdr->sh_size))
+ return false;
+
+ /* Translate raw contents, a flag word followed by an
+ array of elf section indices all in target byte order,
+ to the flag word followed by an array of elf section
+ pointers. */
+ src = shdr->contents + shdr->sh_size;
+ dest = (Elf_Internal_Group *) (shdr->contents + amt);
+ while (1)
+ {
+ unsigned int idx;
+
+ src -= 4;
+ --dest;
+ idx = H_GET_32 (abfd, src);
+ if (src == shdr->contents)
+ {
+ dest->flags = idx;
+ break;
+ }
+ if (idx >= shnum)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: invalid SHT_GROUP entry"),
+ bfd_archive_filename (abfd)));
+ idx = 0;
+ }
+ dest->shdr = elf_elfsections (abfd)[idx];
+ }
+ }
+ }
+ }
+ }
+
+ if (num_group != (unsigned) -1)
+ {
+ unsigned int i;
+
+ for (i = 0; i < num_group; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
+ Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
+ unsigned int n_elt = shdr->sh_size / 4;
+
+ /* Look through this group's sections to see if current
+ section is a member. */
+ while (--n_elt != 0)
+ if ((++idx)->shdr == hdr)
+ {
+ asection *s;
+
+ /* We are a member of this group. Go looking through
+ other members to see if any others are linked via
+ next_in_group. */
+ idx = (Elf_Internal_Group *) shdr->contents;
+ n_elt = shdr->sh_size / 4;
+ while (--n_elt != 0)
+ if ((s = (++idx)->shdr->bfd_section) != NULL
+ && elf_next_in_group (s) != NULL)
+ break;
+ if (n_elt != 0)
+ {
+ /* Snarf the group name from other member, and
+ insert current section in circular list. */
+ elf_group_name (newsect) = elf_group_name (s);
+ elf_next_in_group (newsect) = elf_next_in_group (s);
+ elf_next_in_group (s) = newsect;
+ }
+ else
+ {
+ struct elf_backend_data *bed;
+ file_ptr pos;
+ unsigned char ename[4];
+ unsigned long iname;
+ const char *gname;
+
+ /* Humbug. Get the name from the group signature
+ symbol. Why isn't the signature just a string?
+ Fortunately, the name index is at the same
+ place in the external symbol for both 32 and 64
+ bit ELF. */
+ bed = get_elf_backend_data (abfd);
+ pos = elf_tdata (abfd)->symtab_hdr.sh_offset;
+ pos += shdr->sh_info * bed->s->sizeof_sym;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bread (ename, 4, abfd) != 4)
+ return false;
+ iname = H_GET_32 (abfd, ename);
+ gname = elf_string_from_elf_strtab (abfd, iname);
+ elf_group_name (newsect) = gname;
+
+ /* Start a circular list with one element. */
+ elf_next_in_group (newsect) = newsect;
+ }
+ if (shdr->bfd_section != NULL)
+ elf_next_in_group (shdr->bfd_section) = newsect;
+ i = num_group - 1;
+ break;
+ }
+ }
+ }
+
+ if (elf_group_name (newsect) == NULL)
+ {
+ (*_bfd_error_handler) (_("%s: no group info for section %s"),
+ bfd_archive_filename (abfd), newsect->name);
+ }
+ return true;
+}
+
/* Make a BFD section from an ELF section. We store a pointer to the
BFD section in the bfd_section field of the header. */
if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
|| ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
|| ! bfd_set_section_alignment (abfd, newsect,
- bfd_log2 (hdr->sh_addralign)))
+ bfd_log2 ((bfd_vma) hdr->sh_addralign)))
return false;
flags = SEC_NO_FLAGS;
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
+ if (hdr->sh_type == SHT_GROUP)
+ flags |= SEC_GROUP | SEC_EXCLUDE;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
flags |= SEC_ALLOC;
if ((hdr->sh_flags & SHF_STRINGS) != 0)
flags |= SEC_STRINGS;
}
+ if (hdr->sh_flags & SHF_GROUP)
+ if (!setup_group (abfd, hdr, newsect))
+ return false;
/* The debugging sections appear to be recognized only by name, not
any sort of flag. */
bfd *abfd;
struct bfd_link_info *info;
{
+ if (!is_elf_hash_table (info))
+ return false;
if (elf_hash_table (info)->merge_info)
_bfd_merge_sections (abfd, elf_hash_table (info)->merge_info);
return true;
c = elf_elfheader (abfd)->e_phnum;
for (i = 0; i < c; i++, p++)
{
- const char *s;
+ const char *pt;
char buf[20];
switch (p->p_type)
{
- case PT_NULL: s = "NULL"; break;
- case PT_LOAD: s = "LOAD"; break;
- case PT_DYNAMIC: s = "DYNAMIC"; break;
- case PT_INTERP: s = "INTERP"; break;
- case PT_NOTE: s = "NOTE"; break;
- case PT_SHLIB: s = "SHLIB"; break;
- case PT_PHDR: s = "PHDR"; break;
- default: sprintf (buf, "0x%lx", p->p_type); s = buf; break;
+ case PT_NULL: pt = "NULL"; break;
+ case PT_LOAD: pt = "LOAD"; break;
+ case PT_DYNAMIC: pt = "DYNAMIC"; break;
+ case PT_INTERP: pt = "INTERP"; break;
+ case PT_NOTE: pt = "NOTE"; break;
+ case PT_SHLIB: pt = "SHLIB"; break;
+ case PT_PHDR: pt = "PHDR"; break;
+ default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
}
- fprintf (f, "%8s off 0x", s);
- fprintf_vma (f, p->p_offset);
+ fprintf (f, "%8s off 0x", pt);
+ bfd_fprintf_vma (abfd, f, p->p_offset);
fprintf (f, " vaddr 0x");
- fprintf_vma (f, p->p_vaddr);
+ bfd_fprintf_vma (abfd, f, p->p_vaddr);
fprintf (f, " paddr 0x");
- fprintf_vma (f, p->p_paddr);
+ bfd_fprintf_vma (abfd, f, p->p_paddr);
fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
fprintf (f, " filesz 0x");
- fprintf_vma (f, p->p_filesz);
+ bfd_fprintf_vma (abfd, f, p->p_filesz);
fprintf (f, " memsz 0x");
- fprintf_vma (f, p->p_memsz);
+ bfd_fprintf_vma (abfd, f, p->p_memsz);
fprintf (f, " flags %c%c%c",
(p->p_flags & PF_R) != 0 ? 'r' : '-',
(p->p_flags & PF_W) != 0 ? 'w' : '-',
(p->p_flags & PF_X) != 0 ? 'x' : '-');
- if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0)
- fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X));
+ if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
+ fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
fprintf (f, "\n");
}
}
if (s != NULL)
{
int elfsec;
- unsigned long link;
+ unsigned long shlink;
bfd_byte *extdyn, *extdynend;
size_t extdynsize;
void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
if (elfsec == -1)
goto error_return;
- link = elf_elfsections (abfd)[elfsec]->sh_link;
+ shlink = elf_elfsections (abfd)[elfsec]->sh_link;
extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
else
{
const char *string;
+ unsigned int tagv = dyn.d_un.d_val;
- string = bfd_elf_string_from_elf_section (abfd, link,
- dyn.d_un.d_val);
+ string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
if (string == NULL)
goto error_return;
fprintf (f, "%s", string);
break;
case bfd_print_symbol_more:
fprintf (file, "elf ");
- fprintf_vma (file, symbol->value);
+ bfd_fprintf_vma (abfd, file, symbol->value);
fprintf (file, " %lx", (long) symbol->flags);
break;
case bfd_print_symbol_all:
const char *name = NULL;
struct elf_backend_data *bed;
unsigned char st_other;
+ bfd_vma val;
section_name = symbol->section ? symbol->section->name : "(*none*)";
if (name == NULL)
{
name = symbol->name;
- bfd_print_symbol_vandf ((PTR) file, symbol);
+ bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
}
fprintf (file, " %s\t", section_name);
we've already printed the size; now print the alignment.
For other symbols, we have no specified alignment, and
we've printed the address; now print the size. */
- fprintf_vma (file,
- (bfd_is_com_section (symbol->section)
- ? ((elf_symbol_type *) symbol)->internal_elf_sym.st_value
- : ((elf_symbol_type *) symbol)->internal_elf_sym.st_size));
+ if (bfd_is_com_section (symbol->section))
+ val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
+ else
+ val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
+ bfd_fprintf_vma (abfd, file, val);
/* If we have version information, print it. */
if (elf_tdata (abfd)->dynversym_section != 0
struct bfd_hash_table *table;
const char *string;
{
- struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
-
/* Allocate the structure if it has not already been allocated by a
subclass. */
- if (ret == (struct elf_link_hash_entry *) NULL)
- ret = ((struct elf_link_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)));
- if (ret == (struct elf_link_hash_entry *) NULL)
- return (struct bfd_hash_entry *) ret;
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
/* Call the allocation method of the superclass. */
- ret = ((struct elf_link_hash_entry *)
- _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
- table, string));
- if (ret != (struct elf_link_hash_entry *) NULL)
+ entry = _bfd_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
{
+ struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
+ struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
+
/* Set local fields. */
ret->indx = -1;
ret->size = 0;
ret->dynindx = -1;
ret->dynstr_index = 0;
ret->weakdef = NULL;
- ret->got.offset = (bfd_vma) -1;
- ret->plt.offset = (bfd_vma) -1;
- ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
+ ret->got.refcount = htab->init_refcount;
+ ret->plt.refcount = htab->init_refcount;
+ ret->linker_section_pointer = NULL;
ret->verinfo.verdef = NULL;
ret->vtable_entries_used = NULL;
ret->vtable_entries_size = 0;
ret->elf_link_hash_flags = ELF_LINK_NON_ELF;
}
- return (struct bfd_hash_entry *) ret;
+ return entry;
}
/* Copy data from an indirect symbol to its direct symbol, hiding the
- old indirect symbol. */
+ old indirect symbol. Also used for copying flags to a weakdef. */
void
_bfd_elf_link_hash_copy_indirect (dir, ind)
struct elf_link_hash_entry *dir, *ind;
{
+ bfd_signed_vma tmp;
+
/* Copy down any references that we may have already seen to the
symbol which just became indirect. */
| ELF_LINK_HASH_REF_REGULAR_NONWEAK
| ELF_LINK_NON_GOT_REF));
- /* Copy over the global and procedure linkage table offset entries.
+ if (dir == ind->weakdef)
+ return;
+
+ /* Copy over the global and procedure linkage table refcount entries.
These may have been already set up by a check_relocs routine. */
- if (dir->got.offset == (bfd_vma) -1)
+ tmp = dir->got.refcount;
+ if (tmp <= 0)
{
- dir->got.offset = ind->got.offset;
- ind->got.offset = (bfd_vma) -1;
+ dir->got.refcount = ind->got.refcount;
+ ind->got.refcount = tmp;
}
- BFD_ASSERT (ind->got.offset == (bfd_vma) -1);
+ else
+ BFD_ASSERT (ind->got.refcount <= 0);
- if (dir->plt.offset == (bfd_vma) -1)
+ tmp = dir->plt.refcount;
+ if (tmp <= 0)
{
- dir->plt.offset = ind->plt.offset;
- ind->plt.offset = (bfd_vma) -1;
+ dir->plt.refcount = ind->plt.refcount;
+ ind->plt.refcount = tmp;
}
- BFD_ASSERT (ind->plt.offset == (bfd_vma) -1);
+ else
+ BFD_ASSERT (ind->plt.refcount <= 0);
if (dir->dynindx == -1)
{
ind->dynindx = -1;
ind->dynstr_index = 0;
}
- BFD_ASSERT (ind->dynindx == -1);
+ else
+ BFD_ASSERT (ind->dynindx == -1);
}
void
struct bfd_hash_table *,
const char *));
{
+ boolean ret;
+
table->dynamic_sections_created = false;
table->dynobj = NULL;
+ table->init_refcount = get_elf_backend_data (abfd)->can_refcount - 1;
/* The first dynamic symbol is a dummy. */
table->dynsymcount = 1;
table->dynstr = NULL;
table->stab_info = NULL;
table->merge_info = NULL;
table->dynlocal = NULL;
- return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+ ret = _bfd_link_hash_table_init (& table->root, abfd, newfunc);
+ table->root.type = bfd_link_elf_hash_table;
+
+ return ret;
}
/* Create an ELF linker hash table. */
bfd *abfd;
{
struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
- ret = ((struct elf_link_hash_table *)
- bfd_alloc (abfd, sizeof (struct elf_link_hash_table)));
+ ret = (struct elf_link_hash_table *) bfd_alloc (abfd, amt);
if (ret == (struct elf_link_hash_table *) NULL)
return NULL;
asection *s;
bfd_byte *dynbuf = NULL;
int elfsec;
- unsigned long link;
+ unsigned long shlink;
bfd_byte *extdyn, *extdynend;
size_t extdynsize;
void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
if (elfsec == -1)
goto error_return;
- link = elf_elfsections (abfd)[elfsec]->sh_link;
+ shlink = elf_elfsections (abfd)[elfsec]->sh_link;
extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
{
const char *string;
struct bfd_link_needed_list *l;
+ unsigned int tagv = dyn.d_un.d_val;
+ bfd_size_type amt;
- string = bfd_elf_string_from_elf_section (abfd, link,
- dyn.d_un.d_val);
+ string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
if (string == NULL)
goto error_return;
- l = (struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof *l);
+ amt = sizeof *l;
+ l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
if (l == NULL)
goto error_return;
{
((*_bfd_error_handler)
(_("%s: invalid link %lu for reloc section %s (index %u)"),
- bfd_get_filename (abfd), hdr->sh_link, name, shindex));
+ bfd_archive_filename (abfd), hdr->sh_link, name, shindex));
return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
}
hdr2 = &elf_section_data (target_sect)->rel_hdr;
else
{
+ bfd_size_type amt;
BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
- hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
+ amt = sizeof (*hdr2);
+ hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
elf_section_data (target_sect)->rel_hdr2 = hdr2;
}
*hdr2 = *hdr;
case SHT_SHLIB:
return true;
+ case SHT_GROUP:
+ /* Make a section for objcopy and relocatable links. */
+ if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+ if (hdr->contents != NULL)
+ {
+ Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
+ unsigned int n_elt = hdr->sh_size / 4;
+ asection *s;
+
+ while (--n_elt != 0)
+ if ((s = (++idx)->shdr->bfd_section) != NULL
+ && elf_next_in_group (s) != NULL)
+ {
+ elf_next_in_group (hdr->bfd_section) = s;
+ break;
+ }
+ }
+ break;
+
default:
/* Check for any processor-specific section types. */
{
asection *sec;
{
struct bfd_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
- sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, sizeof (*sdata));
+ sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, amt);
if (!sdata)
return false;
sec->used_by_bfd = (PTR) sdata;
&& (hdr->p_filesz > 0)
&& (hdr->p_memsz > hdr->p_filesz));
sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
- name = bfd_alloc (abfd, strlen (namebuf) + 1);
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
if (!name)
return false;
strcpy (name, namebuf);
if (split)
{
sprintf (namebuf, "%s%db", typename, index);
- name = bfd_alloc (abfd, strlen (namebuf) + 1);
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
if (!name)
return false;
strcpy (name, namebuf);
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 (! elfcore_read_notes (abfd, (file_ptr) hdr->p_offset, hdr->p_filesz))
return false;
return true;
boolean use_rela_p;
{
char *name;
- struct elf_backend_data *bed;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
- bed = get_elf_backend_data (abfd);
- name = bfd_alloc (abfd, sizeof ".rela" + strlen (asect->name));
+ name = bfd_alloc (abfd, amt);
if (name == NULL)
return false;
sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
|| this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
}
+ else if ((asect->flags & SEC_GROUP) != 0)
+ {
+ this_hdr->sh_type = SHT_GROUP;
+ this_hdr->sh_entsize = 4;
+ }
else if ((asect->flags & SEC_ALLOC) != 0
&& ((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0))
this_hdr->sh_type = SHT_NOBITS;
if ((asect->flags & SEC_STRINGS) != 0)
this_hdr->sh_flags |= SHF_STRINGS;
}
+ if (elf_group_name (asect) != NULL)
+ this_hdr->sh_flags |= SHF_GROUP;
/* Check for processor-specific section types. */
if (bed->elf_backend_fake_sections)
*failedptr = true;
}
+/* Fill in the contents of a SHT_GROUP section. */
+
+static void
+set_group_contents (abfd, sec, failedptrarg)
+ bfd *abfd;
+ asection *sec;
+ PTR failedptrarg ATTRIBUTE_UNUSED;
+{
+ boolean *failedptr = (boolean *) failedptrarg;
+ unsigned long symindx;
+ asection *elt;
+ unsigned char *loc;
+ struct bfd_link_order *l;
+
+ if (elf_section_data (sec)->this_hdr.sh_type != SHT_GROUP
+ || *failedptr)
+ return;
+
+ /* If called from the assembler, swap_out_syms will have set up
+ elf_section_syms; If called for "ld -r", the symbols won't yet
+ be mapped, so emulate elf_bfd_final_link. */
+ if (elf_section_syms (abfd) != NULL)
+ symindx = elf_section_syms (abfd)[sec->index]->udata.i;
+ else
+ symindx = elf_section_data (sec)->this_idx;
+ elf_section_data (sec)->this_hdr.sh_info = symindx;
+
+ /* Nor will the contents be allocated for "ld -r". */
+ if (sec->contents == NULL)
+ {
+ sec->contents = bfd_alloc (abfd, sec->_raw_size);
+ if (sec->contents == NULL)
+ {
+ *failedptr = true;
+ return;
+ }
+ }
+
+ loc = sec->contents + sec->_raw_size;
+
+ /* Get the pointer to the first section in the group that we
+ squirreled away here. */
+ elt = elf_next_in_group (sec);
+
+ /* First element is a flag word. Rest of section is elf section
+ indices for all the sections of the group. Write them backwards
+ just to keep the group in the same order as given in .section
+ directives, not that it matters. */
+ while (elt != NULL)
+ {
+ loc -= 4;
+ H_PUT_32 (abfd, elf_section_data (elt)->this_idx, loc);
+ elt = elf_next_in_group (elt);
+ }
+
+ /* If this is a relocatable link, then the above did nothing because
+ SEC is the output section. Look through the input sections
+ instead. */
+ for (l = sec->link_order_head; l != NULL; l = l->next)
+ if (l->type == bfd_indirect_link_order
+ && (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
+ do
+ {
+ loc -= 4;
+ H_PUT_32 (abfd,
+ elf_section_data (elt->output_section)->this_idx, loc);
+ elt = elf_next_in_group (elt);
+ /* During a relocatable link, the lists are circular. */
+ }
+ while (elt != elf_next_in_group (l->u.indirect.section));
+
+ loc -= 4;
+ H_PUT_32 (abfd, 0, loc);
+
+ BFD_ASSERT (loc == sec->contents);
+}
+
/* Assign all ELF section numbers. The dummy first section is handled here
too. The link/info pointers for the standard section types are filled
in here too, while we're at it. */
asection *sec;
unsigned int section_number;
Elf_Internal_Shdr **i_shdrp;
+ bfd_size_type amt;
section_number = 1;
/* Set up the list of section header pointers, in agreement with the
indices. */
- i_shdrp = ((Elf_Internal_Shdr **)
- bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *)));
+ amt = section_number * sizeof (Elf_Internal_Shdr *);
+ i_shdrp = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
if (i_shdrp == NULL)
return false;
- i_shdrp[0] = ((Elf_Internal_Shdr *)
- bfd_alloc (abfd, sizeof (Elf_Internal_Shdr)));
+ amt = sizeof (Elf_Internal_Shdr);
+ i_shdrp[0] = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
if (i_shdrp[0] == NULL)
{
bfd_release (abfd, i_shdrp);
char *alc;
len = strlen (sec->name);
- alc = (char *) bfd_malloc (len - 2);
+ alc = (char *) bfd_malloc ((bfd_size_type) len - 2);
if (alc == NULL)
return false;
strncpy (alc, sec->name, len - 3);
if (s != NULL)
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
break;
+
+ case SHT_GROUP:
+ d->this_hdr.sh_link = t->symtab_section;
}
}
elf_map_symbols (abfd)
bfd *abfd;
{
- int symcount = bfd_get_symcount (abfd);
+ unsigned int symcount = bfd_get_symcount (abfd);
asymbol **syms = bfd_get_outsymbols (abfd);
asymbol **sect_syms;
- int num_locals = 0;
- int num_globals = 0;
- int num_locals2 = 0;
- int num_globals2 = 0;
+ unsigned int num_locals = 0;
+ unsigned int num_globals = 0;
+ unsigned int num_locals2 = 0;
+ unsigned int num_globals2 = 0;
int max_index = 0;
- int num_sections = 0;
- int idx;
+ unsigned int num_sections = 0;
+ unsigned int idx;
asection *asect;
asymbol **new_syms;
- asymbol *sym;
+ bfd_size_type amt;
#ifdef DEBUG
fprintf (stderr, "elf_map_symbols\n");
}
max_index++;
- sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *));
+ amt = max_index * sizeof (asymbol *);
+ sect_syms = (asymbol **) bfd_zalloc (abfd, amt);
if (sect_syms == NULL)
return false;
elf_section_syms (abfd) = sect_syms;
+ elf_num_section_syms (abfd) = max_index;
for (idx = 0; idx < symcount; idx++)
{
- sym = syms[idx];
+ asymbol *sym = syms[idx];
if ((sym->flags & BSF_SECTION_SYM) != 0
&& sym->value == 0)
for (asect = abfd->sections; asect; asect = asect->next)
{
+ asymbol *sym;
+
if (sect_syms[asect->index] != NULL)
continue;
}
/* Now sort the symbols so the local symbols are first. */
- new_syms = ((asymbol **)
- bfd_alloc (abfd,
- (num_locals + num_globals) * sizeof (asymbol *)));
+ amt = (num_locals + num_globals) * sizeof (asymbol *);
+ new_syms = (asymbol **) bfd_alloc (abfd, amt);
+
if (new_syms == NULL)
return false;
for (idx = 0; idx < symcount; idx++)
{
asymbol *sym = syms[idx];
- int i;
+ unsigned int i;
if (!sym_is_global (abfd, sym))
i = num_locals2++;
&& sect_syms[asect->index]->flags == 0)
{
asymbol *sym = sect_syms[asect->index];
- int i;
+ unsigned int i;
sym->flags = BSF_SECTION_SYM;
if (!sym_is_global (abfd, sym))
return false;
}
+ if (link_info == NULL || link_info->relocateable)
+ {
+ bfd_map_over_sections (abfd, set_group_contents, &failed);
+ if (failed)
+ return false;
+ }
+
shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
/* sh_name was set in prep_headers. */
shstrtab_hdr->sh_type = SHT_STRTAB;
struct elf_segment_map *m;
unsigned int i;
asection **hdrpp;
+ bfd_size_type amt;
- m = ((struct elf_segment_map *)
- bfd_zalloc (abfd,
- (sizeof (struct elf_segment_map)
- + (to - from - 1) * sizeof (asection *))));
+ amt = sizeof (struct elf_segment_map);
+ amt += (to - from - 1) * sizeof (asection *);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
return NULL;
m->next = NULL;
boolean phdr_in_segment = true;
boolean writable;
asection *dynsec;
+ bfd_size_type amt;
if (elf_tdata (abfd)->segment_map != NULL)
return true;
/* Select the allocated sections, and sort them. */
- sections = (asection **) bfd_malloc (bfd_count_sections (abfd)
- * sizeof (asection *));
+ amt = bfd_count_sections (abfd) * sizeof (asection *);
+ sections = (asection **) bfd_malloc (amt);
if (sections == NULL)
goto error_return;
s = bfd_get_section_by_name (abfd, ".interp");
if (s != NULL && (s->flags & SEC_LOAD) != 0)
{
- m = ((struct elf_segment_map *)
- bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
goto error_return;
m->next = NULL;
*pm = m;
pm = &m->next;
- m = ((struct elf_segment_map *)
- bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
goto error_return;
m->next = NULL;
/* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */
if (dynsec != NULL)
{
- m = ((struct elf_segment_map *)
- bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
goto error_return;
m->next = NULL;
if ((s->flags & SEC_LOAD) != 0
&& strncmp (s->name, ".note", 5) == 0)
{
- m = ((struct elf_segment_map *)
- bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
goto error_return;
m->next = NULL;
if (TOEND (sec1))
{
if (TOEND (sec2))
- return sec1->target_index - sec2->target_index;
+ {
+ /* If the indicies are the same, do not return 0
+ here, but continue to try the next comparison. */
+ if (sec1->target_index - sec2->target_index != 0)
+ return sec1->target_index - sec2->target_index;
+ }
else
return 1;
}
-
- if (TOEND (sec2))
+ else if (TOEND (sec2))
return -1;
#undef TOEND
- /* Sort by size, to put zero sized sections before others at the
- same address. */
+ /* Sort by size, to put zero sized sections
+ before others at the same address. */
if (sec1->_raw_size < sec2->_raw_size)
return -1;
bfd_vma filehdr_vaddr, filehdr_paddr;
bfd_vma phdrs_vaddr, phdrs_paddr;
Elf_Internal_Phdr *p;
+ bfd_size_type amt;
if (elf_tdata (abfd)->segment_map == NULL)
{
if (alloc == 0)
alloc = count;
- phdrs = ((Elf_Internal_Phdr *)
- bfd_alloc (abfd, alloc * sizeof (Elf_Internal_Phdr)));
+ amt = alloc * sizeof (Elf_Internal_Phdr);
+ phdrs = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
if (phdrs == NULL)
return false;
elf_tdata (abfd)->next_file_pos = off;
/* Write out the program headers. */
- if (bfd_seek (abfd, bed->s->sizeof_ehdr, SEEK_SET) != 0
+ if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
|| bed->s->write_out_phdrs (abfd, phdrs, alloc) != 0)
return false;
case bfd_arch_unknown:
i_ehdrp->e_machine = EM_NONE;
break;
- case bfd_arch_sparc:
- if (bfd_get_arch_size (abfd) == 64)
- i_ehdrp->e_machine = EM_SPARCV9;
- else
- i_ehdrp->e_machine = EM_SPARC;
- break;
- case bfd_arch_i370:
- i_ehdrp->e_machine = EM_S370;
- break;
- case bfd_arch_i386:
- if (bfd_get_arch_size (abfd) == 64)
- i_ehdrp->e_machine = EM_X86_64;
- else
- i_ehdrp->e_machine = EM_386;
- break;
- case bfd_arch_ia64:
- i_ehdrp->e_machine = EM_IA_64;
- break;
- case bfd_arch_m68hc11:
- i_ehdrp->e_machine = EM_68HC11;
- break;
- case bfd_arch_m68hc12:
- i_ehdrp->e_machine = EM_68HC12;
- break;
- case bfd_arch_s390:
- i_ehdrp->e_machine = EM_S390;
- break;
- case bfd_arch_m68k:
- i_ehdrp->e_machine = EM_68K;
- break;
- case bfd_arch_m88k:
- i_ehdrp->e_machine = EM_88K;
- break;
- case bfd_arch_i860:
- i_ehdrp->e_machine = EM_860;
- break;
- case bfd_arch_i960:
- i_ehdrp->e_machine = EM_960;
- break;
- case bfd_arch_mips: /* MIPS Rxxxx */
- i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */
- break;
- case bfd_arch_hppa:
- i_ehdrp->e_machine = EM_PARISC;
- break;
- case bfd_arch_powerpc:
- i_ehdrp->e_machine = EM_PPC;
- break;
- case bfd_arch_alpha:
- i_ehdrp->e_machine = EM_ALPHA;
- break;
- case bfd_arch_sh:
- i_ehdrp->e_machine = EM_SH;
- break;
- case bfd_arch_d10v:
- i_ehdrp->e_machine = EM_CYGNUS_D10V;
- break;
- case bfd_arch_d30v:
- i_ehdrp->e_machine = EM_CYGNUS_D30V;
- break;
- case bfd_arch_fr30:
- i_ehdrp->e_machine = EM_CYGNUS_FR30;
- break;
- case bfd_arch_mcore:
- i_ehdrp->e_machine = EM_MCORE;
- break;
- case bfd_arch_avr:
- i_ehdrp->e_machine = EM_AVR;
- break;
- case bfd_arch_v850:
- switch (bfd_get_mach (abfd))
- {
- default:
- case 0: i_ehdrp->e_machine = EM_CYGNUS_V850; break;
- }
- break;
- case bfd_arch_arc:
- i_ehdrp->e_machine = EM_CYGNUS_ARC;
- break;
- case bfd_arch_arm:
- i_ehdrp->e_machine = EM_ARM;
- break;
- case bfd_arch_m32r:
- i_ehdrp->e_machine = EM_CYGNUS_M32R;
- break;
- case bfd_arch_mn10200:
- i_ehdrp->e_machine = EM_CYGNUS_MN10200;
- break;
- case bfd_arch_mn10300:
- i_ehdrp->e_machine = EM_CYGNUS_MN10300;
- break;
- case bfd_arch_pj:
- i_ehdrp->e_machine = EM_PJ;
- break;
- case bfd_arch_cris:
- i_ehdrp->e_machine = EM_CRIS;
- break;
- case bfd_arch_openrisc:
- i_ehdrp->e_machine = EM_OPENRISC;
- break;
- /* Also note that EM_M32, AT&T WE32100 is unknown to bfd. */
+
+ /* There used to be a long list of cases here, each one setting
+ e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
+ in the corresponding bfd definition. To avoid duplication,
+ the switch was removed. Machines that need special handling
+ can generally do it in elf_backend_final_write_processing(),
+ unless they need the information earlier than the final write.
+ Such need can generally be supplied by replacing the tests for
+ e_machine with the conditions used to determine it. */
default:
- i_ehdrp->e_machine = EM_NONE;
- }
+ if (get_elf_backend_data (abfd) != NULL)
+ i_ehdrp->e_machine = get_elf_backend_data (abfd)->elf_machine_code;
+ else
+ i_ehdrp->e_machine = EM_NONE;
+ }
+
i_ehdrp->e_version = bed->s->ev_current;
i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
if (i_shdrp[count]->contents)
{
+ bfd_size_type amt = i_shdrp[count]->sh_size;
+
if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
- || (bfd_write (i_shdrp[count]->contents, i_shdrp[count]->sh_size,
- 1, abfd)
- != i_shdrp[count]->sh_size))
+ || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
return false;
}
}
indx = asym_ptr->section->output_section->index;
else
indx = asym_ptr->section->index;
- if (elf_section_syms (abfd)[indx])
+ if (indx < elf_num_section_syms (abfd)
+ && elf_section_syms (abfd)[indx] != NULL)
asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
}
which is used in a relocation entry. */
(*_bfd_error_handler)
(_("%s: symbol `%s' required but not present"),
- bfd_get_filename (abfd), bfd_asymbol_name (asym_ptr));
+ bfd_archive_filename (abfd), bfd_asymbol_name (asym_ptr));
bfd_set_error (bfd_error_no_symbols);
return -1;
}
bfd_vma matching_lma;
bfd_vma suggested_lma;
unsigned int j;
+ bfd_size_type amt;
if (segment->p_type == PT_NULL)
continue;
/* Allocate a segment map big enough to contain all of the
sections we have selected. */
- map = ((struct elf_segment_map *)
- bfd_alloc (obfd,
- (sizeof (struct elf_segment_map)
- + ((size_t) section_count - 1) * sizeof (asection *))));
+ amt = sizeof (struct elf_segment_map);
+ amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+ map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
if (map == NULL)
return false;
if (segment->p_type == PT_LOAD)
_bfd_error_handler
(_("%s: warning: Empty loadable segment detected\n"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
map->count = 0;
*pointer_to_map = map;
pointers that we are interested in. As these sections get assigned
to a segment, they are removed from this array. */
- sections = (asection **) bfd_malloc
- (sizeof (asection *) * section_count);
+ amt = (bfd_size_type) section_count * sizeof (asection *);
+ sections = (asection **) bfd_malloc (amt);
if (sections == NULL)
return false;
/* We still have not allocated all of the sections to
segments. Create a new segment here, initialise it
and carry on looping. */
- map = ((struct elf_segment_map *)
- bfd_alloc (obfd,
- (sizeof (struct elf_segment_map)
- + ((size_t) section_count - 1)
- * sizeof (asection *))));
+ amt = sizeof (struct elf_segment_map);
+ amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+ map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
if (map == NULL)
return false;
Elf_Internal_Shdr *symstrtab_hdr;
char *outbound_syms;
int idx;
+ bfd_size_type amt;
stt = _bfd_elf_stringtab_init ();
if (stt == NULL)
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
symstrtab_hdr->sh_type = SHT_STRTAB;
- outbound_syms = bfd_alloc (abfd,
- (1 + symcount) * bed->s->sizeof_sym);
+ amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
+ outbound_syms = bfd_alloc (abfd, amt);
if (outbound_syms == NULL)
return false;
symtab_hdr->contents = (PTR) outbound_syms;
{
arelent *tblptr;
unsigned int i;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
- if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd,
- section,
- symbols,
- false))
+ if (! bed->s->slurp_reloc_table (abfd, section, symbols, false))
return -1;
tblptr = section->relocation;
bfd *abfd;
asymbol **alocation;
{
- long symcount = get_elf_backend_data (abfd)->s->slurp_symbol_table
- (abfd, alocation, false);
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ long symcount = bed->s->slurp_symbol_table (abfd, alocation, false);
if (symcount >= 0)
bfd_get_symcount (abfd) = symcount;
bfd *abfd;
asymbol **alocation;
{
- return get_elf_backend_data (abfd)->s->slurp_symbol_table
- (abfd, alocation, true);
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ return bed->s->slurp_symbol_table (abfd, alocation, true);
}
/* Return the size required for the dynamic reloc entries. Any
bfd *abfd;
{
bfd_byte *contents = NULL;
+ bfd_size_type amt;
if (elf_dynverdef (abfd) != 0)
{
if (contents == NULL)
goto error_return;
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
- || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
+ || bfd_bread ((PTR) contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return;
/* We know the number of entries in the section but not the maximum
((bfd_byte *) everdef + iverdefmem.vd_next));
}
- elf_tdata (abfd)->verdef =
- ((Elf_Internal_Verdef *)
- bfd_zalloc (abfd, maxidx * sizeof (Elf_Internal_Verdef)));
+ amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef);
+ elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
if (elf_tdata (abfd)->verdef == NULL)
goto error_return;
iverdef->vd_bfd = abfd;
- iverdef->vd_auxptr = ((Elf_Internal_Verdaux *)
- bfd_alloc (abfd,
- (iverdef->vd_cnt
- * sizeof (Elf_Internal_Verdaux))));
+ amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux);
+ iverdef->vd_auxptr = (Elf_Internal_Verdaux *) bfd_alloc (abfd, amt);
if (iverdef->vd_auxptr == NULL)
goto error_return;
hdr = &elf_tdata (abfd)->dynverref_hdr;
+ amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
elf_tdata (abfd)->verref =
- ((Elf_Internal_Verneed *)
- bfd_zalloc (abfd, hdr->sh_info * sizeof (Elf_Internal_Verneed)));
+ (Elf_Internal_Verneed *) bfd_zalloc (abfd, amt);
if (elf_tdata (abfd)->verref == NULL)
goto error_return;
if (contents == NULL)
goto error_return;
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
- || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
+ || bfd_bread ((PTR) contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return;
everneed = (Elf_External_Verneed *) contents;
if (iverneed->vn_filename == NULL)
goto error_return;
- iverneed->vn_auxptr =
- ((Elf_Internal_Vernaux *)
- bfd_alloc (abfd,
- iverneed->vn_cnt * sizeof (Elf_Internal_Vernaux)));
+ amt = iverneed->vn_cnt;
+ amt *= sizeof (Elf_Internal_Vernaux);
+ iverneed->vn_auxptr = (Elf_Internal_Vernaux *) bfd_alloc (abfd, amt);
evernaux = ((Elf_External_Vernaux *)
((bfd_byte *) everneed + iverneed->vn_aux));
bfd *abfd;
{
elf_symbol_type *newsym;
+ bfd_size_type amt = sizeof (elf_symbol_type);
- newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type));
+ newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt);
if (!newsym)
return NULL;
else
bfd_size_type count;
{
Elf_Internal_Shdr *hdr;
+ bfd_signed_vma pos;
if (! abfd->output_has_begun
&& ! _bfd_elf_compute_section_file_positions
return false;
hdr = &elf_section_data (section)->this_hdr;
-
- if (bfd_seek (abfd, hdr->sh_offset + offset, SEEK_SET) == -1)
- return false;
- if (bfd_write (location, 1, count, abfd) != count)
+ pos = hdr->sh_offset + offset;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (location, count, abfd) != count)
return false;
return true;
fail:
(*_bfd_error_handler)
(_("%s: unsupported relocation type %s"),
- bfd_get_filename (abfd), areloc->howto->name);
+ bfd_archive_filename (abfd), areloc->howto->name);
bfd_set_error (bfd_error_bad_value);
return false;
}
# include <sys/procfs.h>
#endif
-/* Define offsetof for those systems which lack it. */
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-#endif
-
/* FIXME: this is kinda wrong, but it's what gdb wants. */
static int
_bfd_elfcore_make_pseudosection (abfd, name, size, filepos)
bfd *abfd;
char *name;
- int size;
- int filepos;
+ size_t size;
+ ufile_ptr filepos;
{
char buf[100];
char *threaded_name;
/* Build the section name. */
sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
- threaded_name = bfd_alloc (abfd, strlen (buf) + 1);
+ threaded_name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
if (threaded_name == NULL)
return false;
strcpy (threaded_name, buf);
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
- if (! elfcore_maybe_make_sect (abfd, name, sect))
- return false;
-
- return true;
+ return elfcore_maybe_make_sect (abfd, name, sect);
}
/* prstatus_t exists on:
*/
#if defined (HAVE_PRSTATUS_T)
+static boolean elfcore_grok_prstatus PARAMS ((bfd *, Elf_Internal_Note *));
+
static boolean
elfcore_grok_prstatus (abfd, note)
bfd *abfd;
Elf_Internal_Note *note;
{
- int raw_size;
+ size_t raw_size;
int offset;
if (note->descsz == sizeof (prstatus_t))
}
/* Make a ".reg/999" section and a ".reg" section. */
- if (! _bfd_elfcore_make_pseudosection (abfd, ".reg",
- raw_size, note->descpos + offset));
- return false;
-
- return true;
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ raw_size, note->descpos + offset);
}
#endif /* defined (HAVE_PRSTATUS_T) */
char *name;
Elf_Internal_Note *note;
{
- return _bfd_elfcore_make_pseudosection (abfd, name, note->descsz, note->descpos);
+ return _bfd_elfcore_make_pseudosection (abfd, name,
+ note->descsz, note->descpos);
}
/* There isn't a consistent prfpregset_t across platforms,
most MAX bytes long, possibly without a terminating '\0'.
the copy will always have a terminating '\0'. */
-char*
+char *
_bfd_elfcore_strndup (abfd, start, max)
bfd *abfd;
char *start;
- int max;
+ size_t max;
{
- char *dup;
+ char *dups;
char *end = memchr (start, '\0', max);
- int len;
+ size_t len;
if (end == NULL)
len = max;
else
len = end - start;
- dup = bfd_alloc (abfd, len + 1);
- if (dup == NULL)
+ dups = bfd_alloc (abfd, (bfd_size_type) len + 1);
+ if (dups == NULL)
return NULL;
- memcpy (dup, start, len);
- dup[len] = '\0';
+ memcpy (dups, start, len);
+ dups[len] = '\0';
- return dup;
+ return dups;
}
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+static boolean elfcore_grok_psinfo PARAMS ((bfd *, Elf_Internal_Note *));
static boolean
elfcore_grok_psinfo (abfd, note)
memcpy (&psinfo, note->descdata, sizeof (psinfo));
elf_tdata (abfd)->core_program
- = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
+ sizeof (psinfo.pr_fname));
elf_tdata (abfd)->core_command
- = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
+ sizeof (psinfo.pr_psargs));
}
#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
else if (note->descsz == sizeof (elfcore_psinfo32_t))
memcpy (&psinfo, note->descdata, sizeof (psinfo));
elf_tdata (abfd)->core_program
- = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
+ sizeof (psinfo.pr_fname));
elf_tdata (abfd)->core_command
- = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
+ sizeof (psinfo.pr_psargs));
}
#endif
/* Make a ".reg/999" section. */
sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
- name = bfd_alloc (abfd, strlen (buf) + 1);
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
if (name == NULL)
return false;
strcpy (name, buf);
/* Make a ".reg2/999" section */
sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
- name = bfd_alloc (abfd, strlen (buf) + 1);
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
if (name == NULL)
return false;
strcpy (name, buf);
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
- if (!elfcore_maybe_make_sect (abfd, ".reg2", sect))
- return false;
-
- return true;
+ return elfcore_maybe_make_sect (abfd, ".reg2", sect);
}
#endif /* defined (HAVE_LWPSTATUS_T) */
/* Make a ".reg/999" section. */
sprintf (buf, ".reg/%d", pstatus.data.thread_info.tid);
- name = bfd_alloc (abfd, strlen (buf) + 1);
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
if (name == NULL)
return false;
/* Make a ".module/xxxxxxxx" section. */
sprintf (buf, ".module/%08x", pstatus.data.module_info.base_address);
- name = bfd_alloc (abfd, strlen (buf) + 1);
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
if (name == NULL)
return false;
static boolean
elfcore_read_notes (abfd, offset, size)
bfd *abfd;
- bfd_vma offset;
- bfd_vma size;
+ file_ptr offset;
+ bfd_size_type size;
{
char *buf;
char *p;
if (size <= 0)
return true;
- if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
return false;
- buf = bfd_malloc ((size_t) size);
+ buf = bfd_malloc (size);
if (buf == NULL)
return false;
- if (bfd_read (buf, size, 1, abfd) != size)
+ if (bfd_bread (buf, size, abfd) != size)
{
error:
free (buf);
Elf_External_Note *xnp = (Elf_External_Note *) p;
Elf_Internal_Note in;
- in.type = bfd_h_get_32 (abfd, (bfd_byte *) xnp->type);
+ in.type = H_GET_32 (abfd, xnp->type);
- in.namesz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->namesz);
+ in.namesz = H_GET_32 (abfd, xnp->namesz);
in.namedata = xnp->name;
- in.descsz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->descsz);
+ in.descsz = H_GET_32 (abfd, xnp->descsz);
in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
in.descpos = offset + (in.descdata - buf);
free (buf);
return true;
}
-
-/* FIXME: This function is now unnecessary. Callers can just call
- bfd_section_from_phdr directly. */
-
-boolean
-_bfd_elfcore_section_from_phdr (abfd, phdr, sec_num)
- bfd *abfd;
- Elf_Internal_Phdr* phdr;
- int sec_num;
-{
- if (! bfd_section_from_phdr (abfd, phdr, sec_num))
- return false;
-
- return true;
-}
\f
/* Providing external access to the ELF program header table. */
return -1;
}
- return (elf_elfheader (abfd)->e_phnum
- * sizeof (Elf_Internal_Phdr));
+ return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
}
/* Copy ABFD's program header table entries to *PHDRS. The entries
return num_phdrs;
}
+
+void
+_bfd_elf_sprintf_vma (abfd, buf, value)
+ 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 (abfd, stream, value)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ PTR 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 (rela)
+ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED;
+{
+ return reloc_class_normal;
+}