mirror of git://gcc.gnu.org/git/gcc.git
re PR other/82368 (with r253275 several new test cases in libbacktrace fail)
PR other/82368 * elf.c (EM_PPC64, EF_PPC64_ABI): Undefine and define. (struct elf_ppc64_opd_data): New type. (elf_initialize_syminfo): Add opd argument, handle symbols pointing into the PowerPC64 ELFv1 .opd section. (elf_add): Read .opd section on PowerPC64 ELFv1, pass pointer to structure with .opd data to elf_initialize_syminfo. From-SVN: r257658
This commit is contained in:
parent
316b2a2d84
commit
da07141fd7
|
|
@ -1,3 +1,13 @@
|
||||||
|
2018-02-14 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR other/82368
|
||||||
|
* elf.c (EM_PPC64, EF_PPC64_ABI): Undefine and define.
|
||||||
|
(struct elf_ppc64_opd_data): New type.
|
||||||
|
(elf_initialize_syminfo): Add opd argument, handle symbols
|
||||||
|
pointing into the PowerPC64 ELFv1 .opd section.
|
||||||
|
(elf_add): Read .opd section on PowerPC64 ELFv1, pass pointer
|
||||||
|
to structure with .opd data to elf_initialize_syminfo.
|
||||||
|
|
||||||
2018-01-31 Ian Lance Taylor <iant@golang.org>
|
2018-01-31 Ian Lance Taylor <iant@golang.org>
|
||||||
|
|
||||||
* elf.c (elf_add): Close descriptor if we use a debugfile.
|
* elf.c (elf_add): Close descriptor if we use a debugfile.
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,8 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
|
||||||
#undef ELFDATA2MSB
|
#undef ELFDATA2MSB
|
||||||
#undef EV_CURRENT
|
#undef EV_CURRENT
|
||||||
#undef ET_DYN
|
#undef ET_DYN
|
||||||
|
#undef EM_PPC64
|
||||||
|
#undef EF_PPC64_ABI
|
||||||
#undef SHN_LORESERVE
|
#undef SHN_LORESERVE
|
||||||
#undef SHN_XINDEX
|
#undef SHN_XINDEX
|
||||||
#undef SHN_UNDEF
|
#undef SHN_UNDEF
|
||||||
|
|
@ -245,6 +247,9 @@ typedef struct {
|
||||||
|
|
||||||
#define ET_DYN 3
|
#define ET_DYN 3
|
||||||
|
|
||||||
|
#define EM_PPC64 21
|
||||||
|
#define EF_PPC64_ABI 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 */
|
||||||
|
|
@ -405,6 +410,20 @@ struct elf_syminfo_data
|
||||||
size_t count;
|
size_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Information about PowerPC64 ELFv1 .opd section. */
|
||||||
|
|
||||||
|
struct elf_ppc64_opd_data
|
||||||
|
{
|
||||||
|
/* Address of the .opd section. */
|
||||||
|
b_elf_addr addr;
|
||||||
|
/* Section data. */
|
||||||
|
const char *data;
|
||||||
|
/* Size of the .opd section. */
|
||||||
|
size_t size;
|
||||||
|
/* Corresponding section view. */
|
||||||
|
struct backtrace_view view;
|
||||||
|
};
|
||||||
|
|
||||||
/* Compute the CRC-32 of BUF/LEN. This uses the CRC used for
|
/* Compute the CRC-32 of BUF/LEN. This uses the CRC used for
|
||||||
.gnu_debuglink files. */
|
.gnu_debuglink files. */
|
||||||
|
|
||||||
|
|
@ -569,7 +588,8 @@ elf_initialize_syminfo (struct backtrace_state *state,
|
||||||
const unsigned char *symtab_data, size_t symtab_size,
|
const unsigned char *symtab_data, size_t symtab_size,
|
||||||
const unsigned char *strtab, size_t strtab_size,
|
const unsigned char *strtab, size_t strtab_size,
|
||||||
backtrace_error_callback error_callback,
|
backtrace_error_callback error_callback,
|
||||||
void *data, struct elf_syminfo_data *sdata)
|
void *data, struct elf_syminfo_data *sdata,
|
||||||
|
struct elf_ppc64_opd_data *opd)
|
||||||
{
|
{
|
||||||
size_t sym_count;
|
size_t sym_count;
|
||||||
const b_elf_sym *sym;
|
const b_elf_sym *sym;
|
||||||
|
|
@ -620,7 +640,17 @@ elf_initialize_syminfo (struct backtrace_state *state,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
elf_symbols[j].name = (const char *) strtab + sym->st_name;
|
elf_symbols[j].name = (const char *) strtab + sym->st_name;
|
||||||
elf_symbols[j].address = sym->st_value + base_address;
|
/* Special case PowerPC64 ELFv1 symbols in .opd section, if the symbol
|
||||||
|
is a function descriptor, read the actual code address from the
|
||||||
|
descriptor. */
|
||||||
|
if (opd
|
||||||
|
&& sym->st_value >= opd->addr
|
||||||
|
&& sym->st_value < opd->addr + opd->size)
|
||||||
|
elf_symbols[j].address
|
||||||
|
= *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr));
|
||||||
|
else
|
||||||
|
elf_symbols[j].address = sym->st_value;
|
||||||
|
elf_symbols[j].address += base_address;
|
||||||
elf_symbols[j].size = sym->st_size;
|
elf_symbols[j].size = sym->st_size;
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
|
@ -2637,6 +2667,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||||
int debug_view_valid;
|
int debug_view_valid;
|
||||||
unsigned int using_debug_view;
|
unsigned int using_debug_view;
|
||||||
uint16_t *zdebug_table;
|
uint16_t *zdebug_table;
|
||||||
|
struct elf_ppc64_opd_data opd_data, *opd;
|
||||||
|
|
||||||
if (!debuginfo)
|
if (!debuginfo)
|
||||||
{
|
{
|
||||||
|
|
@ -2655,6 +2686,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||||
debuglink_name = NULL;
|
debuglink_name = NULL;
|
||||||
debuglink_crc = 0;
|
debuglink_crc = 0;
|
||||||
debug_view_valid = 0;
|
debug_view_valid = 0;
|
||||||
|
opd = NULL;
|
||||||
|
|
||||||
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
|
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
|
||||||
data, &ehdr_view))
|
data, &ehdr_view))
|
||||||
|
|
@ -2857,6 +2889,23 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||||
debuglink_crc = *(const uint32_t*)(debuglink_data + crc_offset);
|
debuglink_crc = *(const uint32_t*)(debuglink_data + crc_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read the .opd section on PowerPC64 ELFv1. */
|
||||||
|
if (ehdr.e_machine == EM_PPC64
|
||||||
|
&& (ehdr.e_flags & EF_PPC64_ABI) < 2
|
||||||
|
&& shdr->sh_type == SHT_PROGBITS
|
||||||
|
&& strcmp (name, ".opd") == 0)
|
||||||
|
{
|
||||||
|
if (!backtrace_get_view (state, descriptor, shdr->sh_offset,
|
||||||
|
shdr->sh_size, error_callback, data,
|
||||||
|
&opd_data.view))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
opd = &opd_data;
|
||||||
|
opd->addr = shdr->sh_addr;
|
||||||
|
opd->data = (const char *) opd_data.view.data;
|
||||||
|
opd->size = shdr->sh_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symtab_shndx == 0)
|
if (symtab_shndx == 0)
|
||||||
|
|
@ -2898,7 +2947,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||||
if (!elf_initialize_syminfo (state, base_address,
|
if (!elf_initialize_syminfo (state, base_address,
|
||||||
symtab_view.data, symtab_shdr->sh_size,
|
symtab_view.data, symtab_shdr->sh_size,
|
||||||
strtab_view.data, strtab_shdr->sh_size,
|
strtab_view.data, strtab_shdr->sh_size,
|
||||||
error_callback, data, sdata))
|
error_callback, data, sdata, opd))
|
||||||
{
|
{
|
||||||
backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
|
backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -2951,6 +3000,12 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||||
buildid_view_valid = 0;
|
buildid_view_valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opd)
|
||||||
|
{
|
||||||
|
backtrace_release_view (state, &opd->view, error_callback, data);
|
||||||
|
opd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (debuglink_name != NULL)
|
if (debuglink_name != NULL)
|
||||||
{
|
{
|
||||||
int d;
|
int d;
|
||||||
|
|
@ -3139,6 +3194,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||||
backtrace_release_view (state, &buildid_view, error_callback, data);
|
backtrace_release_view (state, &buildid_view, error_callback, data);
|
||||||
if (debug_view_valid)
|
if (debug_view_valid)
|
||||||
backtrace_release_view (state, &debug_view, error_callback, data);
|
backtrace_release_view (state, &debug_view, error_callback, data);
|
||||||
|
if (opd)
|
||||||
|
backtrace_release_view (state, &opd->view, error_callback, data);
|
||||||
if (descriptor != -1)
|
if (descriptor != -1)
|
||||||
backtrace_close (descriptor, error_callback, data);
|
backtrace_close (descriptor, error_callback, data);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue