[PowerPC] [DTrace] Add ELFv2 support in libdtrace

PPC64 ELFv2 acts like a "normal" platform in that it no longer needs
function descriptors. So, ensure we are only enabling them on ELFv1.

Additionally, ELFv2 requires that the ELF header have a nonzero e_flags,
so ensure that the synthesized ELF header in dt_link.c is setting it.

Reviewed by:	jhibbits, markj
Approved by:	gnn
Differential Revision:	https://reviews.freebsd.org/D22403
This commit is contained in:
Brandon Bergren 2020-02-05 19:39:48 +00:00
parent 42ee7a9a9b
commit 7283901ae9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357590

View File

@ -687,6 +687,9 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
#elif defined(__mips__)
elf_file.ehdr.e_machine = EM_MIPS;
#elif defined(__powerpc64__)
#if defined(_CALL_ELF) && _CALL_ELF == 2
elf_file.ehdr.e_flags = 2;
#endif
elf_file.ehdr.e_machine = EM_PPC64;
#elif defined(__sparc)
elf_file.ehdr.e_machine = EM_SPARCV9;
@ -1276,7 +1279,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
static const char dt_symfmt[] = "%s%u.%s";
static const char dt_weaksymfmt[] = "%s.%s";
char probename[DTRACE_NAMELEN];
int fd, i, ndx, eprobe, mod = 0;
int fd, i, ndx, eprobe, uses_funcdesc = 0, mod = 0;
Elf *elf = NULL;
GElf_Ehdr ehdr;
Elf_Scn *scn_rel, *scn_sym, *scn_str, *scn_tgt;
@ -1328,6 +1331,9 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
emachine1 = emachine2 = EM_MIPS;
#elif defined(__powerpc__)
emachine1 = emachine2 = EM_PPC64;
#if !defined(_CALL_ELF) || _CALL_ELF == 1
uses_funcdesc = 1;
#endif
#elif defined(__sparc)
emachine1 = emachine2 = EM_SPARCV9;
#elif defined(__i386) || defined(__amd64)
@ -1473,7 +1479,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
continue;
if (dt_symtab_lookup(data_sym, 0, isym, rela.r_offset,
shdr_rel.sh_info, &fsym, (emachine1 == EM_PPC64),
shdr_rel.sh_info, &fsym, uses_funcdesc,
elf) != 0) {
dt_strtab_destroy(strtab);
goto err;
@ -1644,7 +1650,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
if (dt_symtab_lookup(data_sym, osym, isym,
rela.r_offset, shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) == 0) {
uses_funcdesc, elf) == 0) {
if (fsym.st_name > data_str->d_size)
goto err;
@ -1653,7 +1659,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
s = strchr(s, '.') + 1;
} else if (dt_symtab_lookup(data_sym, 0, osym,
rela.r_offset, shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) == 0) {
uses_funcdesc, elf) == 0) {
u_int bind;
bind = GELF_ST_BIND(fsym.st_info) == STB_WEAK ?