Line 1... |
Line 1... |
/* ELF executable support for BFD.
|
/* ELF executable support for BFD.
|
|
|
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
Line 7402... |
Line 7402... |
low_func = 0;
|
low_func = 0;
|
state = nothing_seen;
|
state = nothing_seen;
|
|
|
for (p = symbols; *p != NULL; p++)
|
for (p = symbols; *p != NULL; p++)
|
{
|
{
|
elf_symbol_type *q;
|
asymbol *sym = *p;
|
unsigned int type;
|
asection *code_sec;
|
|
bfd_vma code_off;
|
|
|
q = (elf_symbol_type *) *p;
|
if ((sym->flags & BSF_FILE) != 0)
|
|
|
type = ELF_ST_TYPE (q->internal_elf_sym.st_info);
|
|
switch (type)
|
|
{
|
{
|
case STT_FILE:
|
file = sym;
|
file = &q->symbol;
|
|
if (state == symbol_seen)
|
if (state == symbol_seen)
|
state = file_after_symbol_seen;
|
state = file_after_symbol_seen;
|
continue;
|
continue;
|
default:
|
}
|
if (!bed->is_function_type (type))
|
|
break;
|
if (bed->maybe_function_sym (sym, &code_sec, &code_off)
|
case STT_NOTYPE:
|
&& code_sec == section
|
if (bfd_get_section (&q->symbol) == section
|
&& code_off >= low_func
|
&& q->symbol.value >= low_func
|
&& code_off <= offset)
|
&& q->symbol.value <= offset)
|
|
{
|
{
|
func = (asymbol *) q;
|
func = sym;
|
low_func = q->symbol.value;
|
low_func = code_off;
|
filename = NULL;
|
filename = NULL;
|
if (file != NULL
|
if (file != NULL
|
&& (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL
|
&& ((sym->flags & BSF_LOCAL) != 0
|
|| state != file_after_symbol_seen))
|
|| state != file_after_symbol_seen))
|
filename = bfd_asymbol_name (file);
|
filename = bfd_asymbol_name (file);
|
}
|
}
|
break;
|
|
}
|
|
if (state == nothing_seen)
|
if (state == nothing_seen)
|
state = symbol_seen;
|
state = symbol_seen;
|
}
|
}
|
|
|
if (func == NULL)
|
if (func == NULL)
|
Line 7696... |
Line 7690... |
}
|
}
|
|
|
bfd_boolean
|
bfd_boolean
|
_bfd_elf_close_and_cleanup (bfd *abfd)
|
_bfd_elf_close_and_cleanup (bfd *abfd)
|
{
|
{
|
if (bfd_get_format (abfd) == bfd_object)
|
struct elf_obj_tdata *tdata = elf_tdata (abfd);
|
|
if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
|
{
|
{
|
if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL)
|
if (elf_shstrtab (abfd) != NULL)
|
_bfd_elf_strtab_free (elf_shstrtab (abfd));
|
_bfd_elf_strtab_free (elf_shstrtab (abfd));
|
_bfd_dwarf2_cleanup_debug_info (abfd);
|
_bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
|
}
|
}
|
|
|
return _bfd_generic_close_and_cleanup (abfd);
|
return _bfd_generic_close_and_cleanup (abfd);
|
}
|
}
|
|
|
Line 7981... |
Line 7976... |
{
|
{
|
return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
|
return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
|
}
|
}
|
|
|
static bfd_boolean
|
static bfd_boolean
|
|
elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
|
|
{
|
|
return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
|
|
}
|
|
|
|
static bfd_boolean
|
|
elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
|
|
{
|
|
return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
|
|
}
|
|
|
|
static bfd_boolean
|
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
|
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
|
{
|
{
|
return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
|
return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
|
}
|
}
|
|
|
Line 8405... |
Line 8412... |
&& strcmp (note->namedata, "LINUX") == 0)
|
&& strcmp (note->namedata, "LINUX") == 0)
|
return elfcore_grok_s390_prefix (abfd, note);
|
return elfcore_grok_s390_prefix (abfd, note);
|
else
|
else
|
return TRUE;
|
return TRUE;
|
|
|
|
case NT_S390_LAST_BREAK:
|
|
if (note->namesz == 6
|
|
&& strcmp (note->namedata, "LINUX") == 0)
|
|
return elfcore_grok_s390_last_break (abfd, note);
|
|
else
|
|
return TRUE;
|
|
|
|
case NT_S390_SYSTEM_CALL:
|
|
if (note->namesz == 6
|
|
&& strcmp (note->namedata, "LINUX") == 0)
|
|
return elfcore_grok_s390_system_call (abfd, note);
|
|
else
|
|
return TRUE;
|
|
|
case NT_ARM_VFP:
|
case NT_ARM_VFP:
|
if (note->namesz == 6
|
if (note->namesz == 6
|
&& strcmp (note->namedata, "LINUX") == 0)
|
&& strcmp (note->namedata, "LINUX") == 0)
|
return elfcore_grok_arm_vfp (abfd, note);
|
return elfcore_grok_arm_vfp (abfd, note);
|
else
|
else
|
Line 8861... |
Line 8882... |
++size;
|
++size;
|
}
|
}
|
return buf;
|
return buf;
|
}
|
}
|
|
|
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
|
|
char *
|
char *
|
elfcore_write_prpsinfo (bfd *abfd,
|
elfcore_write_prpsinfo (bfd *abfd,
|
char *buf,
|
char *buf,
|
int *bufsiz,
|
int *bufsiz,
|
const char *fname,
|
const char *fname,
|
const char *psargs)
|
const char *psargs)
|
{
|
{
|
const char *note_name = "CORE";
|
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
|
|
if (bed->elf_backend_write_core_note != NULL)
|
if (bed->elf_backend_write_core_note != NULL)
|
{
|
{
|
char *ret;
|
char *ret;
|
Line 8881... |
Line 8900... |
NT_PRPSINFO, fname, psargs);
|
NT_PRPSINFO, fname, psargs);
|
if (ret != NULL)
|
if (ret != NULL)
|
return ret;
|
return ret;
|
}
|
}
|
|
|
|
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
|
#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
|
#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
|
if (bed->s->elfclass == ELFCLASS32)
|
if (bed->s->elfclass == ELFCLASS32)
|
{
|
{
|
#if defined (HAVE_PSINFO32_T)
|
#if defined (HAVE_PSINFO32_T)
|
psinfo32_t data;
|
psinfo32_t data;
|
Line 8896... |
Line 8916... |
|
|
memset (&data, 0, sizeof (data));
|
memset (&data, 0, sizeof (data));
|
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
return elfcore_write_note (abfd, buf, bufsiz,
|
return elfcore_write_note (abfd, buf, bufsiz,
|
note_name, note_type, &data, sizeof (data));
|
"CORE", note_type, &data, sizeof (data));
|
}
|
}
|
else
|
else
|
#endif
|
#endif
|
{
|
{
|
#if defined (HAVE_PSINFO_T)
|
#if defined (HAVE_PSINFO_T)
|
Line 8913... |
Line 8933... |
|
|
memset (&data, 0, sizeof (data));
|
memset (&data, 0, sizeof (data));
|
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
return elfcore_write_note (abfd, buf, bufsiz,
|
return elfcore_write_note (abfd, buf, bufsiz,
|
note_name, note_type, &data, sizeof (data));
|
"CORE", note_type, &data, sizeof (data));
|
}
|
|
}
|
}
|
#endif /* PSINFO_T or PRPSINFO_T */
|
#endif /* PSINFO_T or PRPSINFO_T */
|
|
|
#if defined (HAVE_PRSTATUS_T)
|
free (buf);
|
|
return NULL;
|
|
}
|
|
|
char *
|
char *
|
elfcore_write_prstatus (bfd *abfd,
|
elfcore_write_prstatus (bfd *abfd,
|
char *buf,
|
char *buf,
|
int *bufsiz,
|
int *bufsiz,
|
long pid,
|
long pid,
|
int cursig,
|
int cursig,
|
const void *gregs)
|
const void *gregs)
|
{
|
{
|
const char *note_name = "CORE";
|
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
|
|
if (bed->elf_backend_write_core_note != NULL)
|
if (bed->elf_backend_write_core_note != NULL)
|
{
|
{
|
char *ret;
|
char *ret;
|
Line 8940... |
Line 8961... |
pid, cursig, gregs);
|
pid, cursig, gregs);
|
if (ret != NULL)
|
if (ret != NULL)
|
return ret;
|
return ret;
|
}
|
}
|
|
|
|
#if defined (HAVE_PRSTATUS_T)
|
#if defined (HAVE_PRSTATUS32_T)
|
#if defined (HAVE_PRSTATUS32_T)
|
if (bed->s->elfclass == ELFCLASS32)
|
if (bed->s->elfclass == ELFCLASS32)
|
{
|
{
|
prstatus32_t prstat;
|
prstatus32_t prstat;
|
|
|
memset (&prstat, 0, sizeof (prstat));
|
memset (&prstat, 0, sizeof (prstat));
|
prstat.pr_pid = pid;
|
prstat.pr_pid = pid;
|
prstat.pr_cursig = cursig;
|
prstat.pr_cursig = cursig;
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
return elfcore_write_note (abfd, buf, bufsiz, note_name,
|
return elfcore_write_note (abfd, buf, bufsiz, "CORE",
|
NT_PRSTATUS, &prstat, sizeof (prstat));
|
NT_PRSTATUS, &prstat, sizeof (prstat));
|
}
|
}
|
else
|
else
|
#endif
|
#endif
|
{
|
{
|
Line 8961... |
Line 8983... |
|
|
memset (&prstat, 0, sizeof (prstat));
|
memset (&prstat, 0, sizeof (prstat));
|
prstat.pr_pid = pid;
|
prstat.pr_pid = pid;
|
prstat.pr_cursig = cursig;
|
prstat.pr_cursig = cursig;
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
return elfcore_write_note (abfd, buf, bufsiz, note_name,
|
return elfcore_write_note (abfd, buf, bufsiz, "CORE",
|
NT_PRSTATUS, &prstat, sizeof (prstat));
|
NT_PRSTATUS, &prstat, sizeof (prstat));
|
}
|
}
|
}
|
|
#endif /* HAVE_PRSTATUS_T */
|
#endif /* HAVE_PRSTATUS_T */
|
|
|
|
free (buf);
|
|
return NULL;
|
|
}
|
|
|
#if defined (HAVE_LWPSTATUS_T)
|
#if defined (HAVE_LWPSTATUS_T)
|
char *
|
char *
|
elfcore_write_lwpstatus (bfd *abfd,
|
elfcore_write_lwpstatus (bfd *abfd,
|
char *buf,
|
char *buf,
|
int *bufsiz,
|
int *bufsiz,
|
Line 9166... |
Line 9191... |
return elfcore_write_note (abfd, buf, bufsiz,
|
return elfcore_write_note (abfd, buf, bufsiz,
|
note_name, NT_S390_PREFIX, s390_prefix, size);
|
note_name, NT_S390_PREFIX, s390_prefix, size);
|
}
|
}
|
|
|
char *
|
char *
|
|
elfcore_write_s390_last_break (bfd *abfd,
|
|
char *buf,
|
|
int *bufsiz,
|
|
const void *s390_last_break,
|
|
int size)
|
|
{
|
|
char *note_name = "LINUX";
|
|
return elfcore_write_note (abfd, buf, bufsiz,
|
|
note_name, NT_S390_LAST_BREAK,
|
|
s390_last_break, size);
|
|
}
|
|
|
|
char *
|
|
elfcore_write_s390_system_call (bfd *abfd,
|
|
char *buf,
|
|
int *bufsiz,
|
|
const void *s390_system_call,
|
|
int size)
|
|
{
|
|
char *note_name = "LINUX";
|
|
return elfcore_write_note (abfd, buf, bufsiz,
|
|
note_name, NT_S390_SYSTEM_CALL,
|
|
s390_system_call, size);
|
|
}
|
|
|
|
char *
|
elfcore_write_arm_vfp (bfd *abfd,
|
elfcore_write_arm_vfp (bfd *abfd,
|
char *buf,
|
char *buf,
|
int *bufsiz,
|
int *bufsiz,
|
const void *arm_vfp,
|
const void *arm_vfp,
|
int size)
|
int size)
|
Line 9207... |
Line 9258... |
return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
|
return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
|
if (strcmp (section, ".reg-s390-ctrs") == 0)
|
if (strcmp (section, ".reg-s390-ctrs") == 0)
|
return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
|
return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
|
if (strcmp (section, ".reg-s390-prefix") == 0)
|
if (strcmp (section, ".reg-s390-prefix") == 0)
|
return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
|
return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
|
|
if (strcmp (section, ".reg-s390-last-break") == 0)
|
|
return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
|
|
if (strcmp (section, ".reg-s390-system-call") == 0)
|
|
return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
|
if (strcmp (section, ".reg-arm-vfp") == 0)
|
if (strcmp (section, ".reg-arm-vfp") == 0)
|
return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
|
return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
Line 9628... |
Line 9683... |
{
|
{
|
return (type == STT_FUNC
|
return (type == STT_FUNC
|
|| type == STT_GNU_IFUNC);
|
|| type == STT_GNU_IFUNC);
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|
|
/* Return TRUE iff the ELF symbol SYM might be a function. Set *CODE_SEC
|
|
and *CODE_OFF to the function's entry point. */
|
|
|
|
bfd_boolean
|
|
_bfd_elf_maybe_function_sym (const asymbol *sym,
|
|
asection **code_sec, bfd_vma *code_off)
|
|
{
|
|
if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
|
|
| BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0)
|
|
return FALSE;
|
|
|
|
*code_sec = sym->section;
|
|
*code_off = sym->value;
|
|
return TRUE;
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|