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:
Jakub Jelinek 2013-12-06 15:48:17 +01:00 committed by Jakub Jelinek
parent 26c096c3a3
commit 0284b52ec9
2 changed files with 56 additions and 11 deletions

View File

@ -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

View File

@ -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);