elf.c (ET_DYN): Undefine and define again.
* elf.c (ET_DYN): Undefine and define again. (elf_add): Add exe argument, if true and ehdr.e_type is ET_DYN, return early -1 without closing the descriptor. (struct phdr_data): Add exe_descriptor. (phdr_callback): If pd->exe_descriptor is not -1, for very first call if dlpi_name is NULL just call elf_add with the exe_descriptor, otherwise backtrace_close the exe_descriptor if not -1. Adjust call to elf_add. (backtrace_initialize): Adjust call to elf_add. If it returns -1, set pd.exe_descriptor to descriptor, otherwise set it to -1. From-SVN: r205748
This commit is contained in:
parent
26c096c3a3
commit
0284b52ec9
@ -1,3 +1,16 @@
|
|||||||
|
2013-12-06 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* elf.c (ET_DYN): Undefine and define again.
|
||||||
|
(elf_add): Add exe argument, if true and ehdr.e_type is ET_DYN,
|
||||||
|
return early -1 without closing the descriptor.
|
||||||
|
(struct phdr_data): Add exe_descriptor.
|
||||||
|
(phdr_callback): If pd->exe_descriptor is not -1, for very first
|
||||||
|
call if dlpi_name is NULL just call elf_add with the exe_descriptor,
|
||||||
|
otherwise backtrace_close the exe_descriptor if not -1. Adjust
|
||||||
|
call to elf_add.
|
||||||
|
(backtrace_initialize): Adjust call to elf_add. If it returns
|
||||||
|
-1, set pd.exe_descriptor to descriptor, otherwise set it to -1.
|
||||||
|
|
||||||
2013-12-05 Ian Lance Taylor <iant@google.com>
|
2013-12-05 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* alloc.c (backtrace_vector_finish): Add error_callback and data
|
* alloc.c (backtrace_vector_finish): Add error_callback and data
|
||||||
|
@ -96,6 +96,7 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
|
|||||||
#undef ELFDATA2LSB
|
#undef ELFDATA2LSB
|
||||||
#undef ELFDATA2MSB
|
#undef ELFDATA2MSB
|
||||||
#undef EV_CURRENT
|
#undef EV_CURRENT
|
||||||
|
#undef ET_DYN
|
||||||
#undef SHN_LORESERVE
|
#undef SHN_LORESERVE
|
||||||
#undef SHN_XINDEX
|
#undef SHN_XINDEX
|
||||||
#undef SHN_UNDEF
|
#undef SHN_UNDEF
|
||||||
@ -171,6 +172,8 @@ typedef struct {
|
|||||||
|
|
||||||
#define EV_CURRENT 1
|
#define EV_CURRENT 1
|
||||||
|
|
||||||
|
#define ET_DYN 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
b_elf_word sh_name; /* Section name, index in string tbl */
|
b_elf_word sh_name; /* Section name, index in string tbl */
|
||||||
b_elf_word sh_type; /* Type of section */
|
b_elf_word sh_type; /* Type of section */
|
||||||
@ -507,12 +510,16 @@ elf_syminfo (struct backtrace_state *state, uintptr_t addr,
|
|||||||
callback (data, addr, sym->name, sym->address, sym->size);
|
callback (data, addr, sym->name, sym->address, sym->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the backtrace data for one ELF file. */
|
/* Add the backtrace data for one ELF file. Returns 1 on success,
|
||||||
|
0 on failure (in both cases descriptor is closed) or -1 if exe
|
||||||
|
is non-zero and the ELF file is ET_DYN, which tells the caller that
|
||||||
|
elf_add will need to be called on the descriptor again after
|
||||||
|
base_address is determined. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
|
elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
fileline *fileline_fn, int *found_sym, int *found_dwarf)
|
fileline *fileline_fn, int *found_sym, int *found_dwarf, int exe)
|
||||||
{
|
{
|
||||||
struct backtrace_view ehdr_view;
|
struct backtrace_view ehdr_view;
|
||||||
b_elf_ehdr ehdr;
|
b_elf_ehdr ehdr;
|
||||||
@ -591,6 +598,12 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the executable is ET_DYN, it is either a PIE, or we are running
|
||||||
|
directly a shared library with .interp. We need to wait for
|
||||||
|
dl_iterate_phdr in that case to determine the actual base_address. */
|
||||||
|
if (exe && ehdr.e_type == ET_DYN)
|
||||||
|
return -1;
|
||||||
|
|
||||||
shoff = ehdr.e_shoff;
|
shoff = ehdr.e_shoff;
|
||||||
shnum = ehdr.e_shnum;
|
shnum = ehdr.e_shnum;
|
||||||
shstrndx = ehdr.e_shstrndx;
|
shstrndx = ehdr.e_shstrndx;
|
||||||
@ -847,6 +860,7 @@ struct phdr_data
|
|||||||
fileline *fileline_fn;
|
fileline *fileline_fn;
|
||||||
int *found_sym;
|
int *found_sym;
|
||||||
int *found_dwarf;
|
int *found_dwarf;
|
||||||
|
int exe_descriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callback passed to dl_iterate_phdr. Load debug info from shared
|
/* Callback passed to dl_iterate_phdr. Load debug info from shared
|
||||||
@ -862,17 +876,32 @@ phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
|
|||||||
fileline elf_fileline_fn;
|
fileline elf_fileline_fn;
|
||||||
int found_dwarf;
|
int found_dwarf;
|
||||||
|
|
||||||
/* There is not much we can do if we don't have the module name. */
|
/* There is not much we can do if we don't have the module name,
|
||||||
|
unless executable is ET_DYN, where we expect the very first
|
||||||
|
phdr_callback to be for the PIE. */
|
||||||
if (info->dlpi_name == NULL || info->dlpi_name[0] == '\0')
|
if (info->dlpi_name == NULL || info->dlpi_name[0] == '\0')
|
||||||
return 0;
|
{
|
||||||
|
if (pd->exe_descriptor == -1)
|
||||||
|
return 0;
|
||||||
|
descriptor = pd->exe_descriptor;
|
||||||
|
pd->exe_descriptor = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pd->exe_descriptor != -1)
|
||||||
|
{
|
||||||
|
backtrace_close (pd->exe_descriptor, pd->error_callback, pd->data);
|
||||||
|
pd->exe_descriptor = -1;
|
||||||
|
}
|
||||||
|
|
||||||
descriptor = backtrace_open (info->dlpi_name, pd->error_callback, pd->data,
|
descriptor = backtrace_open (info->dlpi_name, pd->error_callback,
|
||||||
&does_not_exist);
|
pd->data, &does_not_exist);
|
||||||
if (descriptor < 0)
|
if (descriptor < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (elf_add (pd->state, descriptor, info->dlpi_addr, pd->error_callback,
|
if (elf_add (pd->state, descriptor, info->dlpi_addr, pd->error_callback,
|
||||||
pd->data, &elf_fileline_fn, pd->found_sym, &found_dwarf))
|
pd->data, &elf_fileline_fn, pd->found_sym, &found_dwarf, 0))
|
||||||
{
|
{
|
||||||
if (found_dwarf)
|
if (found_dwarf)
|
||||||
{
|
{
|
||||||
@ -893,13 +922,15 @@ backtrace_initialize (struct backtrace_state *state, int descriptor,
|
|||||||
backtrace_error_callback error_callback,
|
backtrace_error_callback error_callback,
|
||||||
void *data, fileline *fileline_fn)
|
void *data, fileline *fileline_fn)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
int found_sym;
|
int found_sym;
|
||||||
int found_dwarf;
|
int found_dwarf;
|
||||||
fileline elf_fileline_fn;
|
fileline elf_fileline_fn;
|
||||||
struct phdr_data pd;
|
struct phdr_data pd;
|
||||||
|
|
||||||
if (!elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,
|
ret = elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,
|
||||||
&found_sym, &found_dwarf))
|
&found_sym, &found_dwarf, 1);
|
||||||
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pd.state = state;
|
pd.state = state;
|
||||||
@ -908,6 +939,7 @@ backtrace_initialize (struct backtrace_state *state, int descriptor,
|
|||||||
pd.fileline_fn = &elf_fileline_fn;
|
pd.fileline_fn = &elf_fileline_fn;
|
||||||
pd.found_sym = &found_sym;
|
pd.found_sym = &found_sym;
|
||||||
pd.found_dwarf = &found_dwarf;
|
pd.found_dwarf = &found_dwarf;
|
||||||
|
pd.exe_descriptor = ret < 0 ? descriptor : -1;
|
||||||
|
|
||||||
dl_iterate_phdr (phdr_callback, (void *) &pd);
|
dl_iterate_phdr (phdr_callback, (void *) &pd);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user