#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command)
#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal)
-#define elf_core_file_matches_executable_p NAME(bfd_elf,core_file_matches_executable_p)
+#define elf_core_file_matches_executable_p \
+ NAME(bfd_elf,core_file_matches_executable_p)
#define elf_object_p NAME(bfd_elf,object_p)
#define elf_core_file_p NAME(bfd_elf,core_file_p)
#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound)
+#define elf_get_dynamic_symtab_upper_bound \
+ NAME(bfd_elf,get_dynamic_symtab_upper_bound)
#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound)
#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc)
#define elf_get_symtab NAME(bfd_elf,get_symtab)
+#define elf_canonicalize_dynamic_symtab \
+ NAME(bfd_elf,canonicalize_dynamic_symtab)
#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol)
#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info)
#define elf_print_symbol NAME(bfd_elf,print_symbol)
static int elf_section_from_bfd_section PARAMS ((bfd *, struct sec *));
-static boolean elf_slurp_symbol_table PARAMS ((bfd *, asymbol **));
+static long elf_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean));
static int elf_symbol_from_bfd_symbol PARAMS ((bfd *,
struct symbol_cache_entry **));
abfd->flags |= HAS_SYMS;
return true;
+ case SHT_DYNSYM: /* A dynamic symbol table */
+ if (elf_dynsymtab (abfd) == shindex)
+ return true;
+
+ BFD_ASSERT (hdr->sh_entsize == sizeof (Elf_External_Sym));
+ BFD_ASSERT (elf_dynsymtab (abfd) == 0);
+ elf_dynsymtab (abfd) = shindex;
+ elf_tdata (abfd)->dynsymtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynsymtab_hdr;
+ abfd->flags |= HAS_SYMS;
+ return true;
+
case SHT_STRTAB: /* A string table */
if (hdr->rawdata)
return true;
elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
return true;
}
+ if (elf_dynsymtab (abfd) == i)
+ {
+ elf_tdata (abfd)->dynstrtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynstrtab_hdr;
+ return true;
+ }
#if 0 /* Not handling other string tables specially right now. */
hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */
/* We have a strtab for some random other section. */
break;
case SHT_HASH:
- case SHT_DYNSYM: /* could treat this like symtab... */
#if 0
fprintf (stderr, "Dynamic Linking sections not yet supported.\n");
BFD_FAIL ();
dst_rela.r_offset = ptr->address;
sym = *ptr->sym_ptr_ptr;
+
+ /* If SYM is a section symbol for an input section, which
+ has been combined with other similar input sections (ld -r),
+ then adjust the addend by the output_offset of sym->section.
+
+ Apparently elf_symbol_from_bfd_symbol doesn't provide a 1:1
+ mapping from bfd symbol to elf symbols in this case. */
+ if ((sym->flags & BSF_SECTION_SYM)
+ && sym->section)
+ ptr->addend += sym->section->output_offset;
+
if (sym == last_sym)
n = last_sym_idx;
else
for (i = 0; i < phdr_cnt; i++)
{
elf_swap_phdr_out (abfd, i_phdrp + i, &x_phdr);
- bfd_seek (abfd, outbase, SEEK_SET);
- bfd_write ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd);
+ if (bfd_seek (abfd, outbase, SEEK_SET) != 0
+ || (bfd_write ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd)
+ != sizeof (x_phdr)))
+ return false;
outbase += sizeof (x_phdr);
}
}
if (exec_p
+ && (abfd->flags & D_PAGED) != 0
&& get_elf_backend_data (abfd)->maxpagesize > 1
&& i_shdrp->sh_type == SHT_PROGBITS
&& (i_shdrp->sh_flags & SHF_ALLOC)
elf_debug_file (i_ehdrp);
#endif
elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);
- bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
- bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd);
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd)
+ != sizeof (x_ehdr)))
+ return false;
/* at this point we've concocted all the ELF sections... */
x_shdrp = (Elf_External_Shdr *)
#endif
elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count);
}
- bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET);
- bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd);
+ if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
+ || (bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd)
+ != sizeof (*x_shdrp) * i_ehdrp->e_shnum))
+ return false;
+
/* need to dump the string table too... */
return true;
if (abfd->output_has_begun == false)
{
+ /* Do any elf backend specific processing first. */
+ if (bed->elf_backend_begin_write_processing)
+ (*bed->elf_backend_begin_write_processing) (abfd);
+
if (prep_headers (abfd) == false)
return false;
if (elf_compute_section_file_positions (abfd) == false)
(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
if (i_shdrp[count]->contents)
{
- bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET);
- bfd_write (i_shdrp[count]->contents, i_shdrp[count]->sh_size, 1,
- abfd);
+ 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))
+ return false;
}
}
return idx;
}
-static boolean
-elf_slurp_symbol_table (abfd, symptrs)
+static long
+elf_slurp_symbol_table (abfd, symptrs, dynamic)
bfd *abfd;
asymbol **symptrs; /* Buffer for generated bfd symbols */
+ boolean dynamic;
{
- Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
+ Elf_Internal_Shdr *hdr;
long symcount; /* Number of external ELF symbols */
elf_symbol_type *sym; /* Pointer to current bfd symbol */
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
Elf_Internal_Sym i_sym;
Elf_External_Sym *x_symp = NULL;
- /* this is only valid because there is only one symtab... */
- /* FIXME: This is incorrect, there may also be a dynamic symbol
- table which is a subset of the full symbol table. We either need
- to be prepared to read both (and merge them) or ensure that we
- only read the full symbol table. Currently we only get called to
- read the full symbol table. -fnf */
-
/* Read each raw ELF symbol, converting from external ELF form to
internal ELF form, and then using the information to create a
canonical bfd symbol table entry.
space left over at the end. When we have all the symbols, we
build the caller's pointer vector. */
+ if (dynamic)
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->symtab_hdr;
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
- return false;
+ return -1;
symcount = hdr->sh_size / sizeof (Elf_External_Sym);
long i;
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
- return false;
+ return -1;
symbase = ((elf_symbol_type *)
bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type)));
if (symbase == (elf_symbol_type *) NULL)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return -1;
}
sym = symbase;
break;
}
+ if (dynamic)
+ sym->symbol.flags |= BSF_DYNAMIC;
+
/* Do some backend-specific processing on this symbol. */
{
struct elf_backend_data *ebd = get_elf_backend_data (abfd);
/* We rely on the zalloc to clear out the final symbol entry. */
- bfd_get_symcount (abfd) = symcount = sym - symbase;
+ symcount = sym - symbase;
/* Fill in the user's symbol pointer vector if needed. */
if (symptrs)
{
+ long l = symcount;
+
sym = symbase;
- while (symcount-- > 0)
+ while (l-- > 0)
{
*symptrs++ = &sym->symbol;
sym++;
if (x_symp != NULL)
free (x_symp);
- return true;
+ return symcount;
error_return:
if (x_symp != NULL)
free (x_symp);
- return false;
+ return -1;
}
/* Return the number of bytes required to hold the symtab vector.
return symtab_size;
}
+long
+elf_get_dynamic_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ long symcount;
+ long symtab_size;
+ Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / sizeof (Elf_External_Sym);
+ symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *));
+
+ return symtab_size;
+}
+
/*
This function return the number of bytes required to store the
relocation information associated with section <<sect>>
if (asect->flags & SEC_CONSTRUCTOR)
return true;
- bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
+ if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+ return false;
native_relocs = (Elf_External_Rela *)
bfd_alloc (abfd, asect->reloc_count * sizeof (Elf_External_Rela));
if (!native_relocs)
bfd_set_error (bfd_error_no_memory);
return false;
}
- bfd_read ((PTR) native_relocs,
- sizeof (Elf_External_Rela), asect->reloc_count, abfd);
+ if (bfd_read ((PTR) native_relocs,
+ sizeof (Elf_External_Rela), asect->reloc_count, abfd)
+ != sizeof (Elf_External_Rela) * asect->reloc_count)
+ return false;
reloc_cache = (arelent *)
bfd_alloc (abfd, (size_t) (asect->reloc_count * sizeof (arelent)));
if (asect->flags & SEC_CONSTRUCTOR)
return true;
- bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
+ if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+ return false;
native_relocs = (Elf_External_Rel *)
bfd_alloc (abfd, asect->reloc_count * sizeof (Elf_External_Rel));
if (!native_relocs)
bfd_set_error (bfd_error_no_memory);
return false;
}
- bfd_read ((PTR) native_relocs,
- sizeof (Elf_External_Rel), asect->reloc_count, abfd);
+ if (bfd_read ((PTR) native_relocs,
+ sizeof (Elf_External_Rel), asect->reloc_count, abfd)
+ != sizeof (Elf_External_Rel) * asect->reloc_count)
+ return false;
reloc_cache = (arelent *)
bfd_alloc (abfd, (size_t) (asect->reloc_count * sizeof (arelent)));
}
tblptr = section->relocation;
- if (!tblptr)
- return -1;
for (; count++ < section->reloc_count;)
*relptr++ = tblptr++;
bfd *abfd;
asymbol **alocation;
{
- if (!elf_slurp_symbol_table (abfd, alocation))
- return -1;
+ long symcount = elf_slurp_symbol_table (abfd, alocation, false);
+
+ if (symcount >= 0)
+ bfd_get_symcount (abfd) = symcount;
+ return symcount;
+}
- return bfd_get_symcount (abfd);
+long
+elf_canonicalize_dynamic_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ return elf_slurp_symbol_table (abfd, alocation, true);
}
asymbol *
if (abfd->output_has_begun == false) /* set by bfd.c handler? */
{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ /* Do any elf backend specific processing first. */
+ if (bed->elf_backend_begin_write_processing)
+ (*bed->elf_backend_begin_write_processing) (abfd);
+
/* do setup calculations (FIXME) */
if (prep_headers (abfd) == false)
return false;