/* ELF executable support for BFD.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003 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_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_bfd_discard_info NAME(bfd_elf,discard_info)
#define elf_reloc_symbol_deleted_p NAME(_bfd_elf,reloc_symbol_deleted_p)
#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link)
-#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section)
-#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section)
#define elf_gc_sections NAME(_bfd_elf,gc_sections)
#define elf_gc_common_finalize_got_offsets \
NAME(_bfd_elf,gc_common_finalize_got_offsets)
#define section_from_elf_index bfd_section_from_elf_index
-static boolean elf_slurp_reloc_table_from_section
+static bfd_boolean elf_slurp_reloc_table_from_section
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type,
- arelent *, asymbol **, boolean));
+ arelent *, asymbol **, bfd_boolean));
-static boolean elf_file_p PARAMS ((Elf_External_Ehdr *));
+static bfd_boolean elf_file_p PARAMS ((Elf_External_Ehdr *));
#ifdef DEBUG
static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *));
}
/* Translate an ELF reloc from external format to internal format. */
-INLINE void
-elf_swap_reloc_in (abfd, src, dst)
+void
+elf_swap_reloc_in (abfd, s, dst)
bfd *abfd;
- const Elf_External_Rel *src;
- Elf_Internal_Rel *dst;
+ const bfd_byte *s;
+ Elf_Internal_Rela *dst;
{
+ const Elf_External_Rel *src = (const Elf_External_Rel *) s;
dst->r_offset = H_GET_WORD (abfd, src->r_offset);
dst->r_info = H_GET_WORD (abfd, src->r_info);
+ dst->r_addend = 0;
}
-INLINE void
-elf_swap_reloca_in (abfd, src, dst)
+void
+elf_swap_reloca_in (abfd, s, dst)
bfd *abfd;
- const Elf_External_Rela *src;
+ const bfd_byte *s;
Elf_Internal_Rela *dst;
{
+ const Elf_External_Rela *src = (const Elf_External_Rela *) s;
dst->r_offset = H_GET_WORD (abfd, src->r_offset);
dst->r_info = H_GET_WORD (abfd, src->r_info);
dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend);
}
/* Translate an ELF reloc from internal format to external format. */
-INLINE void
-elf_swap_reloc_out (abfd, src, dst)
+void
+elf_swap_reloc_out (abfd, src, d)
bfd *abfd;
- const Elf_Internal_Rel *src;
- Elf_External_Rel *dst;
+ const Elf_Internal_Rela *src;
+ bfd_byte *d;
{
+ Elf_External_Rel *dst = (Elf_External_Rel *) d;
H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
H_PUT_WORD (abfd, src->r_info, dst->r_info);
}
-INLINE void
-elf_swap_reloca_out (abfd, src, dst)
+void
+elf_swap_reloca_out (abfd, src, d)
bfd *abfd;
const Elf_Internal_Rela *src;
- Elf_External_Rela *dst;
+ bfd_byte *d;
{
+ Elf_External_Rela *dst = (Elf_External_Rela *) d;
H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
H_PUT_WORD (abfd, src->r_info, dst->r_info);
H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);
First we validate the file by reading in the ELF header and checking
the magic number. */
-static INLINE boolean
+static INLINE bfd_boolean
elf_file_p (x_ehdrp)
Elf_External_Ehdr *x_ehdrp;
{
asection *sec;
PTR data;
{
- boolean *failedp = (boolean *) data;
+ bfd_boolean *failedp = (bfd_boolean *) data;
Elf_Internal_Shdr *rela_hdr;
- Elf_External_Rela *outbound_relocas;
- Elf_External_Rel *outbound_relocs;
+ bfd_vma addr_offset;
+ void (*swap_out) PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
+ size_t extsize;
+ bfd_byte *dst_rela;
unsigned int idx;
- int use_rela_p;
- asymbol *last_sym = 0;
- int last_sym_idx = 0;
+ asymbol *last_sym;
+ int last_sym_idx;
/* If we have already failed, don't do anything. */
if (*failedp)
rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
if (rela_hdr->contents == NULL)
{
- *failedp = true;
+ *failedp = TRUE;
return;
}
/* Figure out whether the relocations are RELA or REL relocations. */
if (rela_hdr->sh_type == SHT_RELA)
- use_rela_p = true;
+ {
+ swap_out = elf_swap_reloca_out;
+ extsize = sizeof (Elf_External_Rela);
+ }
else if (rela_hdr->sh_type == SHT_REL)
- use_rela_p = false;
+ {
+ swap_out = elf_swap_reloc_out;
+ extsize = sizeof (Elf_External_Rel);
+ }
else
/* Every relocation section should be either an SHT_RELA or an
SHT_REL section. */
abort ();
+ /* The address of an ELF reloc is section relative for an object
+ file, and absolute for an executable file or shared library.
+ The address of a BFD reloc is always section relative. */
+ addr_offset = 0;
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ addr_offset = sec->vma;
+
/* orelocation has the data, reloc_count has the count... */
- if (use_rela_p)
- {
- outbound_relocas = (Elf_External_Rela *) rela_hdr->contents;
+ last_sym = 0;
+ last_sym_idx = 0;
+ dst_rela = rela_hdr->contents;
- for (idx = 0; idx < sec->reloc_count; idx++)
+ for (idx = 0; idx < sec->reloc_count; idx++, dst_rela += extsize)
+ {
+ Elf_Internal_Rela src_rela;
+ arelent *ptr;
+ asymbol *sym;
+ int n;
+
+ ptr = sec->orelocation[idx];
+ sym = *ptr->sym_ptr_ptr;
+ if (sym == last_sym)
+ n = last_sym_idx;
+ else if (bfd_is_abs_section (sym->section) && sym->value == 0)
+ n = STN_UNDEF;
+ else
{
- Elf_Internal_Rela dst_rela;
- Elf_External_Rela *src_rela;
- arelent *ptr;
- asymbol *sym;
- int n;
-
- ptr = sec->orelocation[idx];
- src_rela = outbound_relocas + idx;
-
- /* The address of an ELF reloc is section relative for an object
- file, and absolute for an executable file or shared library.
- The address of a BFD reloc is always section relative. */
- if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
- dst_rela.r_offset = ptr->address;
- else
- dst_rela.r_offset = ptr->address + sec->vma;
-
- sym = *ptr->sym_ptr_ptr;
- 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;
+ n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
+ if (n < 0)
{
- last_sym = sym;
- n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
- if (n < 0)
- {
- *failedp = true;
- return;
- }
- last_sym_idx = n;
- }
-
- 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;
+ *failedp = TRUE;
return;
}
-
- dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
-
- dst_rela.r_addend = ptr->addend;
- elf_swap_reloca_out (abfd, &dst_rela, src_rela);
+ last_sym_idx = n;
}
- }
- else
- /* REL relocations */
- {
- outbound_relocs = (Elf_External_Rel *) rela_hdr->contents;
- for (idx = 0; idx < sec->reloc_count; idx++)
+ if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
+ && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
{
- Elf_Internal_Rel dst_rel;
- Elf_External_Rel *src_rel;
- arelent *ptr;
- int n;
- asymbol *sym;
-
- ptr = sec->orelocation[idx];
- sym = *ptr->sym_ptr_ptr;
- src_rel = outbound_relocs + idx;
-
- /* The address of an ELF reloc is section relative for an object
- file, and absolute for an executable file or shared library.
- The address of a BFD reloc is always section relative. */
- if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
- dst_rel.r_offset = ptr->address;
- else
- dst_rel.r_offset = ptr->address + sec->vma;
-
- 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;
- n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
- if (n < 0)
- {
- *failedp = true;
- return;
- }
- last_sym_idx = n;
- }
-
- 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;
- }
-
- dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type);
-
- elf_swap_reloc_out (abfd, &dst_rel, src_rel);
+ *failedp = TRUE;
+ return;
}
+
+ src_rela.r_offset = ptr->address + addr_offset;
+ src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
+ src_rela.r_addend = ptr->addend;
+ (*swap_out) (abfd, &src_rela, dst_rela);
}
}
/* Write out the section headers and the ELF file header. */
-boolean
+bfd_boolean
elf_write_shdrs_and_ehdr (abfd)
bfd *abfd;
{
amt = sizeof (x_ehdr);
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
|| bfd_bwrite ((PTR) & x_ehdr, amt, abfd) != amt)
- return false;
+ return FALSE;
/* Some fields in the first section header handle overflow of ehdr
fields. */
amt *= sizeof (*x_shdrp);
x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);
if (!x_shdrp)
- return false;
+ return FALSE;
for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)
{
elf_debug_section (count, *i_shdrp);
#endif
elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
-
+
if (count == SHN_LORESERVE - 1)
i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
}
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
|| bfd_bwrite ((PTR) x_shdrp, amt, abfd) != amt)
- return false;
+ return FALSE;
/* need to dump the string table too... */
- return true;
+ return TRUE;
}
long
elf_slurp_symbol_table (abfd, symptrs, dynamic)
bfd *abfd;
asymbol **symptrs; /* Buffer for generated bfd symbols */
- boolean dynamic;
+ bfd_boolean dynamic;
{
Elf_Internal_Shdr *hdr;
Elf_Internal_Shdr *verhdr;
else
sym->symbol.section = bfd_abs_section_ptr;
- /* If this is a relocateable file, then the symbol value is
+ /* If this is a relocatable file, then the symbol value is
already section relative. */
if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
sym->symbol.value -= sym->symbol.section->vma;
/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
them. */
-static boolean
+static bfd_boolean
elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,
relents, symbols, dynamic)
bfd *abfd;
bfd_size_type reloc_count;
arelent *relents;
asymbol **symbols;
- boolean dynamic;
+ bfd_boolean dynamic;
{
struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
PTR allocated = NULL;
i++, relent++, native_relocs += entsize)
{
Elf_Internal_Rela rela;
- Elf_Internal_Rel rel;
if (entsize == sizeof (Elf_External_Rela))
- elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela);
+ elf_swap_reloca_in (abfd, native_relocs, &rela);
else
- {
- elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel);
- rela.r_offset = rel.r_offset;
- rela.r_info = rel.r_info;
- rela.r_addend = 0;
- }
+ elf_swap_reloc_in (abfd, native_relocs, &rela);
/* The address of an ELF reloc is section relative for an object
file, and absolute for an executable file or shared library.
relent->addend = rela.r_addend;
- if (entsize == sizeof (Elf_External_Rela))
+ if ((entsize == sizeof (Elf_External_Rela)
+ && ebd->elf_info_to_howto != NULL)
+ || ebd->elf_info_to_howto_rel == NULL)
(*ebd->elf_info_to_howto) (abfd, relent, &rela);
else
- (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel);
+ (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela);
}
if (allocated != NULL)
free (allocated);
- return true;
+ return TRUE;
error_return:
if (allocated != NULL)
free (allocated);
- return false;
+ return FALSE;
}
/* Read in and swap the external relocs. */
-boolean
+bfd_boolean
elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
bfd *abfd;
asection *asect;
asymbol **symbols;
- boolean dynamic;
+ bfd_boolean dynamic;
{
struct bfd_elf_section_data * const d = elf_section_data (asect);
Elf_Internal_Shdr *rel_hdr;
bfd_size_type amt;
if (asect->relocation != NULL)
- return true;
+ return TRUE;
if (! dynamic)
{
if ((asect->flags & SEC_RELOC) == 0
|| asect->reloc_count == 0)
- return true;
+ return TRUE;
rel_hdr = &d->rel_hdr;
reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
dynamic symbol table, and in that case bfd_section_from_shdr
in elf.c does not update the RELOC_COUNT. */
if (asect->_raw_size == 0)
- return true;
+ return TRUE;
rel_hdr = &d->this_hdr;
reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
amt = (reloc_count + reloc_count2) * sizeof (arelent);
relents = (arelent *) bfd_alloc (abfd, amt);
if (relents == NULL)
- return false;
+ return FALSE;
if (!elf_slurp_reloc_table_from_section (abfd, asect,
rel_hdr, reloc_count,
relents,
symbols, dynamic))
- return false;
+ return FALSE;
if (rel_hdr2
&& !elf_slurp_reloc_table_from_section (abfd, asect,
rel_hdr2, reloc_count2,
relents + reloc_count,
symbols, dynamic))
- return false;
+ return FALSE;
asect->relocation = relents;
- return true;
+ return TRUE;
}
#ifdef DEBUG
}
#endif
\f
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote memory
+ based on the ELF file header at EHDR_VMA and the ELF program headers it
+ points to. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs the
+ file headers (and hence BFD's idea of each section's VMA) put them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from the
+ remote memory at target address VMA into the local buffer at MYADDR; it
+ should return zero on success or an `errno' code on failure. TEMPL must
+ be a BFD for a target with the word size and byte order found in the
+ remote memory. */
+
+bfd *
+NAME(_bfd_elf,bfd_from_remote_memory) (templ, ehdr_vma, loadbasep,
+ target_read_memory)
+ bfd *templ;
+ bfd_vma ehdr_vma;
+ bfd_vma *loadbasep;
+ int (*target_read_memory) PARAMS ((bfd_vma vma, char *myaddr, int len));
+{
+ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
+ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
+ Elf_External_Phdr *x_phdrs;
+ Elf_Internal_Phdr *i_phdrs, *last_phdr;
+ bfd *nbfd;
+ struct bfd_in_memory *bim;
+ int contents_size;
+ char *contents;
+ int err;
+ unsigned int i;
+ bfd_vma loadbase;
+
+ /* Read in the ELF header in external format. */
+ err = target_read_memory (ehdr_vma, (char *) &x_ehdr, sizeof x_ehdr);
+ if (err)
+ {
+ bfd_set_error (bfd_error_system_call);
+ errno = err;
+ return NULL;
+ }
+
+ /* Now check to see if we have a valid ELF file, and one that BFD can
+ make use of. The magic number must match, the address size ('class')
+ and byte-swapping must match our XVEC entry. */
+
+ if (! elf_file_p (&x_ehdr)
+ || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
+ || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Check that file's byte order matches xvec's */
+ switch (x_ehdr.e_ident[EI_DATA])
+ {
+ case ELFDATA2MSB: /* Big-endian */
+ if (! bfd_header_big_endian (templ))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ case ELFDATA2LSB: /* Little-endian */
+ if (! bfd_header_little_endian (templ))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ case ELFDATANONE: /* No data encoding specified */
+ default: /* Unknown data encoding specified */
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr);
+
+ /* The file header tells where to find the program headers.
+ These are what we use to actually choose what to read. */
+
+ if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ x_phdrs = (Elf_External_Phdr *)
+ bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
+ if (x_phdrs == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+ err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (char *) x_phdrs,
+ i_ehdr.e_phnum * sizeof x_phdrs[0]);
+ if (err)
+ {
+ free (x_phdrs);
+ bfd_set_error (bfd_error_system_call);
+ errno = err;
+ return NULL;
+ }
+ i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
+
+ contents_size = 0;
+ last_phdr = NULL;
+ loadbase = ehdr_vma;
+ for (i = 0; i < i_ehdr.e_phnum; ++i)
+ {
+ elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
+ if (i_phdrs[i].p_type == PT_LOAD)
+ {
+ bfd_vma segment_end;
+ segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
+ + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
+ if (segment_end > (bfd_vma) contents_size)
+ contents_size = segment_end;
+
+ if ((i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
+ loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
+
+ last_phdr = &i_phdrs[i];
+ }
+ }
+ if (last_phdr == NULL)
+ {
+ /* There were no PT_LOAD segments, so we don't have anything to read. */
+ free (x_phdrs);
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Trim the last segment so we don't bother with zeros in the last page
+ that are off the end of the file. However, if the extra bit in that
+ page includes the section headers, keep them. */
+ if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz
+ && (bfd_vma) contents_size >= (i_ehdr.e_shoff
+ + i_ehdr.e_shnum * i_ehdr.e_shentsize))
+ {
+ contents_size = last_phdr->p_offset + last_phdr->p_filesz;
+ if ((bfd_vma) contents_size < (i_ehdr.e_shoff
+ + i_ehdr.e_shnum * i_ehdr.e_shentsize))
+ contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
+ }
+ else
+ contents_size = last_phdr->p_offset + last_phdr->p_filesz;
+
+ /* Now we know the size of the whole image we want read in. */
+ contents = (char *) bfd_zmalloc ((bfd_size_type) contents_size);
+ if (contents == NULL)
+ {
+ free (x_phdrs);
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ for (i = 0; i < i_ehdr.e_phnum; ++i)
+ if (i_phdrs[i].p_type == PT_LOAD)
+ {
+ bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
+ bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
+ + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
+ if (end > (bfd_vma) contents_size)
+ end = contents_size;
+ err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
+ & -i_phdrs[i].p_align,
+ contents + start, end - start);
+ if (err)
+ {
+ free (x_phdrs);
+ free (contents);
+ bfd_set_error (bfd_error_system_call);
+ errno = err;
+ return NULL;
+ }
+ }
+ free (x_phdrs);
+
+ /* If the segments visible in memory didn't include the section headers,
+ then clear them from the file header. */
+ if ((bfd_vma) contents_size < (i_ehdr.e_shoff
+ + i_ehdr.e_shnum * i_ehdr.e_shentsize))
+ {
+ memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
+ memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
+ memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx);
+ }
+
+ /* This will normally have been in the first PT_LOAD segment. But it
+ conceivably could be missing, and we might have just changed it. */
+ memcpy (contents, &x_ehdr, sizeof x_ehdr);
+
+ /* Now we have a memory image of the ELF file contents. Make a BFD. */
+ bim = ((struct bfd_in_memory *)
+ bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
+ if (bim == NULL)
+ {
+ free (contents);
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ {
+ free (bim);
+ free (contents);
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+ nbfd->filename = "<in-memory>";
+ nbfd->xvec = templ->xvec;
+ bim->size = contents_size;
+ bim->buffer = contents;
+ nbfd->iostream = (PTR) bim;
+ nbfd->flags = BFD_IN_MEMORY;
+ nbfd->direction = read_direction;
+ nbfd->mtime = time (NULL);
+ nbfd->mtime_set = TRUE;
+
+ if (loadbasep)
+ *loadbasep = loadbase;
+ return nbfd;
+}
+\f
#include "elfcore.h"
#include "elflink.h"
\f
sizeof (Elf_External_Note),
4,
1,
- ARCH_SIZE, FILE_ALIGN,
+ ARCH_SIZE, LOG_FILE_ALIGN,
ELFCLASS, EV_CURRENT,
elf_write_out_phdrs,
elf_write_shdrs_and_ehdr,
elf_slurp_symbol_table,
elf_swap_dyn_in,
elf_swap_dyn_out,
- NULL,
- NULL,
- NULL,
- NULL
+ elf_swap_reloc_in,
+ elf_swap_reloc_out,
+ elf_swap_reloca_in,
+ elf_swap_reloca_out
};