Changeset View
Changeset View
Standalone View
Standalone View
head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
Show First 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | for (i = 0; i < dof->dofh_secnum; i++) { | ||||
/*LINTED*/ | /*LINTED*/ | ||||
dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); | dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); | ||||
nrel = s->dofs_size / s->dofs_entsize; | nrel = s->dofs_size / s->dofs_entsize; | ||||
s = &dofs[dofrh->dofr_tgtsec]; | s = &dofs[dofrh->dofr_tgtsec]; | ||||
for (j = 0; j < nrel; j++) { | for (j = 0; j < nrel; j++) { | ||||
#if defined(__aarch64__) | #if defined(__aarch64__) | ||||
/* XXX */ | rel->r_offset = s->dofs_offset + | ||||
printf("%s:%s(%d): aarch64 not implemented\n", | dofr[j].dofr_offset; | ||||
__FUNCTION__, __FILE__, __LINE__); | rel->r_info = ELF32_R_INFO(count + dep->de_global, | ||||
R_ARM_REL32); | |||||
#elif defined(__arm__) | #elif defined(__arm__) | ||||
/* XXX */ | /* XXX */ | ||||
printf("%s:%s(%d): arm not implemented\n", | printf("%s:%s(%d): arm not implemented\n", | ||||
__FUNCTION__, __FILE__, __LINE__); | __FUNCTION__, __FILE__, __LINE__); | ||||
#elif defined(__i386) || defined(__amd64) | #elif defined(__i386) || defined(__amd64) | ||||
rel->r_offset = s->dofs_offset + | rel->r_offset = s->dofs_offset + | ||||
dofr[j].dofr_offset; | dofr[j].dofr_offset; | ||||
rel->r_info = ELF32_R_INFO(count + dep->de_global, | rel->r_info = ELF32_R_INFO(count + dep->de_global, | ||||
▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | for (i = 0; i < dof->dofh_secnum; i++) { | ||||
/*LINTED*/ | /*LINTED*/ | ||||
dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); | dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); | ||||
nrel = s->dofs_size / s->dofs_entsize; | nrel = s->dofs_size / s->dofs_entsize; | ||||
s = &dofs[dofrh->dofr_tgtsec]; | s = &dofs[dofrh->dofr_tgtsec]; | ||||
for (j = 0; j < nrel; j++) { | for (j = 0; j < nrel; j++) { | ||||
#if defined(__aarch64__) | #if defined(__aarch64__) | ||||
/* XXX */ | rel->r_offset = s->dofs_offset + | ||||
dofr[j].dofr_offset; | |||||
rel->r_info = ELF64_R_INFO(count + dep->de_global, | |||||
R_AARCH64_PREL64); | |||||
#elif defined(__arm__) | #elif defined(__arm__) | ||||
/* XXX */ | /* XXX */ | ||||
#elif defined(__mips__) | #elif defined(__mips__) | ||||
/* XXX */ | /* XXX */ | ||||
#elif defined(__powerpc__) | #elif defined(__powerpc__) | ||||
rel->r_offset = s->dofs_offset + | rel->r_offset = s->dofs_offset + | ||||
dofr[j].dofr_offset; | dofr[j].dofr_offset; | ||||
rel->r_info = ELF64_R_INFO(count + dep->de_global, | rel->r_info = ELF64_R_INFO(count + dep->de_global, | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
#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(__powerpc__) | ||||
elf_file.ehdr.e_machine = EM_PPC; | elf_file.ehdr.e_machine = EM_PPC; | ||||
#elif defined(__sparc) | #elif defined(__sparc) | ||||
elf_file.ehdr.e_machine = EM_SPARC; | elf_file.ehdr.e_machine = EM_SPARC; | ||||
#elif defined(__i386) || defined(__amd64) | #elif defined(__i386) || defined(__amd64) | ||||
elf_file.ehdr.e_machine = EM_386; | elf_file.ehdr.e_machine = EM_386; | ||||
#elif defined(__aarch64__) | |||||
elf_file.ehdr.e_machine = EM_AARCH64; | |||||
#endif | #endif | ||||
elf_file.ehdr.e_version = EV_CURRENT; | elf_file.ehdr.e_version = EV_CURRENT; | ||||
elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr); | elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr); | ||||
elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr); | elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr); | ||||
elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr); | elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr); | ||||
elf_file.ehdr.e_shentsize = sizeof (Elf32_Shdr); | elf_file.ehdr.e_shentsize = sizeof (Elf32_Shdr); | ||||
elf_file.ehdr.e_shnum = nshdr; | elf_file.ehdr.e_shnum = nshdr; | ||||
elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; | elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | |||||
#elif defined(__mips__) | #elif defined(__mips__) | ||||
elf_file.ehdr.e_machine = EM_MIPS; | elf_file.ehdr.e_machine = EM_MIPS; | ||||
#elif defined(__powerpc64__) | #elif defined(__powerpc64__) | ||||
elf_file.ehdr.e_machine = EM_PPC64; | 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) | ||||
elf_file.ehdr.e_machine = EM_AMD64; | elf_file.ehdr.e_machine = EM_AMD64; | ||||
#elif defined(__aarch64__) | |||||
elf_file.ehdr.e_machine = EM_AARCH64; | |||||
#endif | #endif | ||||
elf_file.ehdr.e_version = EV_CURRENT; | elf_file.ehdr.e_version = EV_CURRENT; | ||||
elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr); | elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr); | ||||
elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr); | elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr); | ||||
elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr); | elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr); | ||||
elf_file.ehdr.e_shentsize = sizeof (Elf64_Shdr); | elf_file.ehdr.e_shentsize = sizeof (Elf64_Shdr); | ||||
elf_file.ehdr.e_shnum = nshdr; | elf_file.ehdr.e_shnum = nshdr; | ||||
elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; | elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) { | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
return (-1); | return (-1); | ||||
} | } | ||||
#if defined(__aarch64__) | #if defined(__aarch64__) | ||||
/* XXX */ | #define DT_OP_NOP 0xd503201f | ||||
#define DT_OP_RET 0xd65f03c0 | |||||
#define DT_OP_CALL26 0x94000000 | |||||
#define DT_OP_JUMP26 0x14000000 | |||||
static int | static int | ||||
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, | dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, | ||||
uint32_t *off) | uint32_t *off) | ||||
{ | { | ||||
printf("%s:%s(%d): aarch64 not implemented\n", __FUNCTION__, __FILE__, | uint32_t *ip; | ||||
__LINE__); | |||||
/* | |||||
* Ensure that the offset is aligned on an instruction boundary. | |||||
*/ | |||||
if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0) | |||||
return (-1); | return (-1); | ||||
/* | |||||
* We only know about some specific relocation types. | |||||
* We also recognize relocation type NONE, since that gets used for | |||||
* relocations of USDT probes, and we might be re-processing a file. | |||||
*/ | |||||
if (GELF_R_TYPE(rela->r_info) != R_AARCH64_CALL26 && | |||||
GELF_R_TYPE(rela->r_info) != R_AARCH64_JUMP26 && | |||||
GELF_R_TYPE(rela->r_info) != R_AARCH64_NONE) | |||||
return (-1); | |||||
ip = (uint32_t *)(p + rela->r_offset); | |||||
/* | |||||
* We may have already processed this object file in an earlier linker | |||||
* invocation. Check to see if the present instruction sequence matches | |||||
* the one we would install below. | |||||
*/ | |||||
if (ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) | |||||
return (0); | |||||
/* | |||||
* We only expect call instructions with a displacement of 0, or a jump | |||||
* instruction acting as a tail call. | |||||
*/ | |||||
if (ip[0] != DT_OP_CALL26 && ip[0] != DT_OP_JUMP26) { | |||||
dt_dprintf("found %x instead of a call or jmp instruction at " | |||||
"%llx\n", ip[0], (u_longlong_t)rela->r_offset); | |||||
return (-1); | |||||
} | } | ||||
/* | |||||
* On arm64, we do not have to differentiate between regular probes and | |||||
* is-enabled probes. Both cases are encoded as a regular branch for | |||||
* non-tail call locations, and a jump for tail call locations. Calls | |||||
* are to be converted into a no-op whereas jumps should become a | |||||
* return. | |||||
*/ | |||||
if (ip[0] == DT_OP_CALL26) | |||||
ip[0] = DT_OP_NOP; | |||||
else | |||||
ip[0] = DT_OP_RET; | |||||
return (0); | |||||
} | |||||
#elif defined(__arm__) | #elif defined(__arm__) | ||||
/* XXX */ | /* XXX */ | ||||
static int | static int | ||||
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, | dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, | ||||
uint32_t *off) | uint32_t *off) | ||||
{ | { | ||||
printf("%s:%s(%d): arm not implemented\n", __FUNCTION__, __FILE__, | printf("%s:%s(%d): arm not implemented\n", __FUNCTION__, __FILE__, | ||||
__LINE__); | __LINE__); | ||||
▲ Show 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | |||||
#if defined(__mips__) | #if defined(__mips__) | ||||
emachine1 = emachine2 = EM_MIPS; | emachine1 = emachine2 = EM_MIPS; | ||||
#elif defined(__powerpc__) | #elif defined(__powerpc__) | ||||
emachine1 = emachine2 = EM_PPC64; | emachine1 = emachine2 = EM_PPC64; | ||||
#elif defined(__sparc) | #elif defined(__sparc) | ||||
emachine1 = emachine2 = EM_SPARCV9; | emachine1 = emachine2 = EM_SPARCV9; | ||||
#elif defined(__i386) || defined(__amd64) | #elif defined(__i386) || defined(__amd64) | ||||
emachine1 = emachine2 = EM_AMD64; | emachine1 = emachine2 = EM_AMD64; | ||||
#elif defined(__aarch64__) | |||||
emachine1 = emachine2 = EM_AARCH64; | |||||
#endif | #endif | ||||
symsize = sizeof (Elf64_Sym); | symsize = sizeof (Elf64_Sym); | ||||
} else { | } else { | ||||
eclass = ELFCLASS32; | eclass = ELFCLASS32; | ||||
#if defined(__arm__) | #if defined(__arm__) | ||||
emachine1 = emachine2 = EM_ARM; | emachine1 = emachine2 = EM_ARM; | ||||
#elif defined(__mips__) | #elif defined(__mips__) | ||||
emachine1 = emachine2 = EM_MIPS; | emachine1 = emachine2 = EM_MIPS; | ||||
▲ Show 20 Lines • Show All 700 Lines • Show Last 20 Lines |