Add PowerPC64 function descriptor support for dt_link.c
Summary: PowerPC64 uses function descriptors in a section .opd, exporting the descriptors to the symbol table. This adds support for these into dt_link.c so that dtrace USDT probes can be compiled. Test Plan: Tested only on powerpc64. No regression testing has been performed, so I want someone with x86 hardware to regression test this. Tested on amd64 by markj Reviewers: #dtrace, markj Reviewed By: #dtrace, markj Subscribers: markj Differential Revision: https://reviews.freebsd.org/D1267 MFC after: 3 weeks
This commit is contained in:
parent
1a5934ef8e
commit
b08e2b04fe
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276326
@ -685,8 +685,8 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
|
|||||||
elf_file.ehdr.e_machine = EM_ARM;
|
elf_file.ehdr.e_machine = EM_ARM;
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
elf_file.ehdr.e_machine = EM_MIPS;
|
elf_file.ehdr.e_machine = EM_MIPS;
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc64__)
|
||||||
elf_file.ehdr.e_machine = EM_PPC;
|
elf_file.ehdr.e_machine = EM_PPC64;
|
||||||
#elif defined(__sparc)
|
#elif defined(__sparc)
|
||||||
elf_file.ehdr.e_machine = EM_SPARCV9;
|
elf_file.ehdr.e_machine = EM_SPARCV9;
|
||||||
#elif defined(__i386) || defined(__amd64)
|
#elif defined(__i386) || defined(__amd64)
|
||||||
@ -784,21 +784,32 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
|
dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
|
||||||
GElf_Sym *sym)
|
GElf_Sym *sym, int uses_funcdesc, Elf *elf)
|
||||||
{
|
{
|
||||||
int i, ret = -1;
|
int i, ret = -1;
|
||||||
|
Elf64_Addr symval;
|
||||||
|
Elf_Scn *opd_scn;
|
||||||
|
Elf_Data *opd_desc;
|
||||||
GElf_Sym s;
|
GElf_Sym s;
|
||||||
|
|
||||||
for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
|
for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
|
||||||
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC &&
|
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) {
|
||||||
shn == sym->st_shndx &&
|
symval = sym->st_value;
|
||||||
sym->st_value <= addr &&
|
if (uses_funcdesc) {
|
||||||
addr < sym->st_value + sym->st_size) {
|
opd_scn = elf_getscn(elf, sym->st_shndx);
|
||||||
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
|
opd_desc = elf_rawdata(opd_scn, NULL);
|
||||||
return (0);
|
symval =
|
||||||
|
*(uint64_t*)((char *)opd_desc->d_buf + symval);
|
||||||
|
}
|
||||||
|
if ((uses_funcdesc || shn == sym->st_shndx) &&
|
||||||
|
symval <= addr &&
|
||||||
|
addr < symval + sym->st_size) {
|
||||||
|
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
s = *sym;
|
s = *sym;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1375,7 +1386,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
|
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
|
||||||
shdr_rel.sh_info, &fsym) != 0) {
|
shdr_rel.sh_info, &fsym,
|
||||||
|
(emachine1 == EM_PPC64), elf) != 0) {
|
||||||
dt_strtab_destroy(strtab);
|
dt_strtab_destroy(strtab);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -1536,7 +1548,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
|
|||||||
p = strhyphenate(p + 3); /* strlen("___") */
|
p = strhyphenate(p + 3); /* strlen("___") */
|
||||||
|
|
||||||
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
|
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
|
||||||
shdr_rel.sh_info, &fsym) != 0)
|
shdr_rel.sh_info, &fsym,
|
||||||
|
(emachine1 == EM_PPC64), elf) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (fsym.st_name > data_str->d_size)
|
if (fsym.st_name > data_str->d_size)
|
||||||
|
Loading…
Reference in New Issue
Block a user