char*
elf_core_file_failing_command (abfd)
bfd *abfd;
{
return elf_tdata (abfd)->core_command;
}
int
elf_core_file_failing_signal (abfd)
bfd *abfd;
{
return elf_tdata (abfd)->core_signal;
}
boolean
elf_core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd;
bfd *exec_bfd;
{
char* corename;
if (core_bfd->xvec != exec_bfd->xvec)
{
bfd_set_error (bfd_error_system_call);
return false;
}
corename = elf_tdata (core_bfd)->core_program;
if (corename != NULL)
{
const char* execname = strrchr (exec_bfd->filename, '/');
execname = execname ? execname + 1 : exec_bfd->filename;
if (strcmp(execname, corename) != 0)
return false;
}
return true;
}
const bfd_target *
elf_core_file_p (abfd)
bfd *abfd;
{
Elf_External_Ehdr x_ehdr;
Elf_Internal_Ehdr *i_ehdrp;
Elf_Internal_Phdr *i_phdrp;
unsigned int phindex;
struct elf_backend_data *ebd;
struct bfd_preserve preserve;
struct elf_obj_tdata *new_tdata = NULL;
bfd_size_type amt;
preserve.arch_info = abfd->arch_info;
if (bfd_bread ((PTR) &x_ehdr, (bfd_size_type) sizeof (x_ehdr), abfd)
!= sizeof (x_ehdr))
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
if (elf_file_p (&x_ehdr) == false)
goto wrong;
if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
goto wrong;
switch (x_ehdr.e_ident[EI_DATA])
{
case ELFDATA2MSB:
if (! bfd_big_endian (abfd))
goto wrong;
break;
case ELFDATA2LSB:
if (! bfd_little_endian (abfd))
goto wrong;
break;
default:
goto wrong;
}
amt = sizeof (struct elf_obj_tdata);
new_tdata = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt);
if (new_tdata == NULL)
return NULL;
preserve.tdata = elf_tdata (abfd);
elf_tdata (abfd) = new_tdata;
preserve.sections = abfd->sections;
preserve.section_tail = abfd->section_tail;
preserve.section_count = abfd->section_count;
preserve.section_htab = abfd->section_htab;
abfd->sections = NULL;
abfd->section_tail = &abfd->sections;
abfd->section_count = 0;
if (!bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))
goto fail;
i_ehdrp = elf_elfheader (abfd);
elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
#if DEBUG & 1
elf_debug_file (i_ehdrp);
#endif
ebd = get_elf_backend_data (abfd);
if (ebd->elf_machine_code != i_ehdrp->e_machine
&& (ebd->elf_machine_alt1 == 0
|| i_ehdrp->e_machine != ebd->elf_machine_alt1)
&& (ebd->elf_machine_alt2 == 0
|| i_ehdrp->e_machine != ebd->elf_machine_alt2))
{
const bfd_target * const *target_ptr;
if (ebd->elf_machine_code != EM_NONE)
goto wrong;
for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
{
struct elf_backend_data *back;
if ((*target_ptr)->flavour != bfd_target_elf_flavour)
continue;
back = (struct elf_backend_data *) (*target_ptr)->backend_data;
if (back->elf_machine_code == i_ehdrp->e_machine)
{
goto wrong;
}
}
}
if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
goto wrong;
if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
goto wrong;
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
goto wrong;
amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
if (!i_phdrp)
goto fail;
elf_tdata (abfd)->phdr = i_phdrp;
for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
{
Elf_External_Phdr x_phdr;
if (bfd_bread ((PTR) &x_phdr, (bfd_size_type) sizeof (x_phdr), abfd)
!= sizeof (x_phdr))
goto fail;
elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
}
for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
{
if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
goto fail;
}
if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
{
if (ebd->elf_machine_code != EM_NONE)
goto fail;
}
bfd_get_start_address (abfd) = i_ehdrp->e_entry;
if (ebd->elf_backend_object_p)
{
if ((*ebd->elf_backend_object_p) (abfd) == false)
goto wrong;
}
bfd_hash_table_free (&preserve.section_htab);
return abfd->xvec;
wrong:
bfd_set_error (bfd_error_wrong_format);
fail:
abfd->arch_info = preserve.arch_info;
if (new_tdata != NULL)
{
bfd_release (abfd, new_tdata);
elf_tdata (abfd) = preserve.tdata;
abfd->section_htab = preserve.section_htab;
abfd->sections = preserve.sections;
abfd->section_tail = preserve.section_tail;
abfd->section_count = preserve.section_count;
}
return NULL;
}