/* ELF executable support for BFD.
- Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software
- Foundation, Inc.
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999, 2000 Free
+ Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry)
#define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr)
#define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs)
+#define elf_write_relocs NAME(bfd_elf,write_relocs)
+#define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table)
#define elf_link_create_dynamic_sections \
NAME(bfd_elf,link_create_dynamic_sections)
#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
#define section_from_elf_index bfd_section_from_elf_index
-static boolean elf_slurp_reloc_table_from_section
+static boolean elf_slurp_reloc_table_from_section
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type,
arelent *, asymbol **, boolean));
-static boolean elf_slurp_reloc_table
- PARAMS ((bfd *, asection *, asymbol **, boolean));
-
-static void write_relocs PARAMS ((bfd *, asection *, PTR));
static boolean elf_file_p PARAMS ((Elf_External_Ehdr *));
const Elf_External_Sym *src;
Elf_Internal_Sym *dst;
{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name);
- dst->st_value = get_word (abfd, (bfd_byte *) src->st_value);
+ if (signed_vma)
+ dst->st_value = get_signed_word (abfd, (bfd_byte *) src->st_value);
+ else
+ dst->st_value = get_word (abfd, (bfd_byte *) src->st_value);
dst->st_size = get_word (abfd, (bfd_byte *) src->st_size);
dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info);
dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other);
const Elf_External_Ehdr *src;
Elf_Internal_Ehdr *dst;
{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type);
dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine);
dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version);
- dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry);
+ if (signed_vma)
+ dst->e_entry = get_signed_word (abfd, (bfd_byte *) src->e_entry);
+ else
+ dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry);
dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff);
dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff);
dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags);
const Elf_Internal_Ehdr *src;
Elf_External_Ehdr *dst;
{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
/* note that all elements of dst are *arrays of unsigned char* already... */
bfd_h_put_16 (abfd, src->e_type, dst->e_type);
bfd_h_put_16 (abfd, src->e_machine, dst->e_machine);
bfd_h_put_32 (abfd, src->e_version, dst->e_version);
- put_word (abfd, src->e_entry, dst->e_entry);
+ if (signed_vma)
+ put_signed_word (abfd, src->e_entry, dst->e_entry);
+ else
+ put_word (abfd, src->e_entry, dst->e_entry);
put_word (abfd, src->e_phoff, dst->e_phoff);
put_word (abfd, src->e_shoff, dst->e_shoff);
bfd_h_put_32 (abfd, src->e_flags, dst->e_flags);
const Elf_External_Shdr *src;
Elf_Internal_Shdr *dst;
{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name);
dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type);
dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags);
- dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr);
+ if (signed_vma)
+ dst->sh_addr = get_signed_word (abfd, (bfd_byte *) src->sh_addr);
+ else
+ dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr);
dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset);
dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size);
dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link);
const Elf_External_Phdr *src;
Elf_Internal_Phdr *dst;
{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type);
dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags);
dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset);
- dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr);
- dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr);
+ if (signed_vma)
+ {
+ dst->p_vaddr = get_signed_word (abfd, (bfd_byte *) src->p_vaddr);
+ dst->p_paddr = get_signed_word (abfd, (bfd_byte *) src->p_paddr);
+ }
+ else
+ {
+ dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr);
+ dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr);
+ }
dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz);
dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz);
dst->p_align = get_word (abfd, (bfd_byte *) src->p_align);
char *shstrtab; /* Internal copy of section header stringtab */
struct elf_backend_data *ebd;
struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
+ struct sec *preserved_sections = abfd->sections;
+ unsigned int preserved_section_count = abfd->section_count;
struct elf_obj_tdata *new_tdata = NULL;
asection *s;
+ /* Clear section information, since there might be a recognized bfd that
+ we now check if we can replace, and we don't want to append to it. */
+ abfd->sections = NULL;
+ abfd->section_count = 0;
+
/* Read in the ELF header in external format. */
if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
}
/* Remember the entry point specified in the ELF file header. */
- bfd_get_start_address (abfd) = i_ehdrp->e_entry;
+ bfd_set_start_address (abfd, i_ehdrp->e_entry);
/* Allocate space for a copy of the section header table in
internal form, seek to the section header table in the file,
if (new_tdata != NULL)
bfd_release (abfd, new_tdata);
elf_tdata (abfd) = preserved_tdata;
+ abfd->sections = preserved_sections;
+ abfd->section_count = preserved_section_count;
return (NULL);
}
\f
/* Write out the relocs. */
-static void
-write_relocs (abfd, sec, data)
+void
+elf_write_relocs (abfd, sec, data)
bfd *abfd;
asection *sec;
PTR data;
if (sym == last_sym)
n = last_sym_idx;
+ else if (bfd_is_abs_section (sym->section) && sym->value == 0)
+ n = STN_UNDEF;
else
{
last_sym = sym;
last_sym_idx = n;
}
- if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
+ && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
&& ! _bfd_elf_validate_reloc (abfd, ptr))
{
*failedp = true;
return -1;
}
-/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
+/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
them. */
static boolean
/* Read in and swap the external relocs. */
-static boolean
+boolean
elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
bfd *abfd;
asection *asect;
rel_hdr = &d->rel_hdr;
reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
rel_hdr2 = d->rel_hdr2;
- reloc_count2 = (rel_hdr2
+ reloc_count2 = (rel_hdr2
? (rel_hdr2->sh_size / rel_hdr2->sh_entsize)
: 0);
reloc_count2 = 0;
}
- relents = ((arelent *)
- bfd_alloc (abfd,
+ relents = ((arelent *)
+ bfd_alloc (abfd,
(reloc_count + reloc_count2) * sizeof (arelent)));
if (relents == NULL)
return false;
relents,
symbols, dynamic))
return false;
-
- if (rel_hdr2
+
+ if (rel_hdr2
&& !elf_slurp_reloc_table_from_section (abfd, asect,
rel_hdr2, reloc_count2,
relents + reloc_count,
symbols, dynamic))
return false;
-
+
asect->relocation = relents;
return true;
}
sizeof (Elf_External_Sym),
sizeof (Elf_External_Dyn),
sizeof (Elf_External_Note),
- ARCH_SIZE / 8,
+ 4,
1,
ARCH_SIZE, FILE_ALIGN,
ELFCLASS, EV_CURRENT,
elf_write_out_phdrs,
elf_write_shdrs_and_ehdr,
- write_relocs,
+ elf_write_relocs,
elf_swap_symbol_out,
elf_slurp_reloc_table,
elf_slurp_symbol_table,