mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-14 20:37:06 +00:00
arm,arm64: Add a NT_ARM_TLS read-only register set.
This register set exposes the per-thread TLS register. It matches the layout used by Linux on arm64. Linux does not implement this note for 32-bit arm. Reviewed by: andrew, markj Sponsored by: University of Cambridge, Google, Inc. Differential Revision: https://reviews.freebsd.org/D34595
This commit is contained in:
parent
add00c381e
commit
b2cb74c22c
|
@ -1197,6 +1197,7 @@ note_type_freebsd_core(unsigned int nt)
|
|||
case 0x102: return "NT_PPC_VSX (ppc VSX registers)";
|
||||
case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)";
|
||||
case 0x400: return "NT_ARM_VFP (arm VFP registers)";
|
||||
case 0x401: return "NT_ARM_TLS (arm TLS register)";
|
||||
case 0x406: return "NT_ARM_ADDR_MASK (arm address mask)";
|
||||
default: return (note_type_unknown(nt));
|
||||
}
|
||||
|
|
|
@ -67,6 +67,28 @@ static struct regset regset_arm_vfp = {
|
|||
ELF_REGSET(regset_arm_vfp);
|
||||
#endif
|
||||
|
||||
static bool
|
||||
get_arm_tls(struct regset *rs, struct thread *td, void *buf,
|
||||
size_t *sizep)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
KASSERT(*sizep == sizeof(td->td_pcb->pcb_regs.sf_tpidrurw),
|
||||
("%s: invalid size", __func__));
|
||||
memcpy(buf, &td->td_pcb->pcb_regs.sf_tpidrurw,
|
||||
sizeof(td->td_pcb->pcb_regs.sf_tpidrurw));
|
||||
}
|
||||
*sizep = sizeof(td->td_pcb->pcb_regs.sf_tpidrurw);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static struct regset regset_arm_tls = {
|
||||
.note = NT_ARM_TLS,
|
||||
.size = sizeof(uint32_t),
|
||||
.get = get_arm_tls,
|
||||
};
|
||||
ELF_REGSET(regset_arm_tls);
|
||||
|
||||
int
|
||||
cpu_ptrace(struct thread *td, int req, void *addr, int data)
|
||||
{
|
||||
|
|
|
@ -81,6 +81,54 @@ static struct regset regset_arm_vfp = {
|
|||
ELF32_REGSET(regset_arm_vfp);
|
||||
#endif
|
||||
|
||||
static bool
|
||||
get_arm64_tls(struct regset *rs, struct thread *td, void *buf,
|
||||
size_t *sizep)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
KASSERT(*sizep == sizeof(td->td_pcb->pcb_tpidr_el0),
|
||||
("%s: invalid size", __func__));
|
||||
memcpy(buf, &td->td_pcb->pcb_tpidr_el0,
|
||||
sizeof(td->td_pcb->pcb_tpidr_el0));
|
||||
}
|
||||
*sizep = sizeof(td->td_pcb->pcb_tpidr_el0);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static struct regset regset_arm64_tls = {
|
||||
.note = NT_ARM_TLS,
|
||||
.size = sizeof(uint64_t),
|
||||
.get = get_arm64_tls,
|
||||
};
|
||||
ELF_REGSET(regset_arm64_tls);
|
||||
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
static bool
|
||||
get_arm_tls(struct regset *rs, struct thread *td, void *buf,
|
||||
size_t *sizep)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
uint32_t tp;
|
||||
|
||||
KASSERT(*sizep == sizeof(uint32_t),
|
||||
("%s: invalid size", __func__));
|
||||
tp = (uint32_t)td->td_pcb->pcb_tpidr_el0;
|
||||
memcpy(buf, &tp, sizeof(tp));
|
||||
}
|
||||
*sizep = sizeof(uint32_t);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static struct regset regset_arm_tls = {
|
||||
.note = NT_ARM_TLS,
|
||||
.size = sizeof(uint32_t),
|
||||
.get = get_arm_tls,
|
||||
};
|
||||
ELF32_REGSET(regset_arm_tls);
|
||||
#endif
|
||||
|
||||
int
|
||||
ptrace_set_pc(struct thread *td, u_long addr)
|
||||
{
|
||||
|
|
|
@ -825,6 +825,7 @@ typedef struct {
|
|||
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
|
||||
#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
|
||||
#define NT_ARM_VFP 0x400 /* ARM VFP registers */
|
||||
#define NT_ARM_TLS 0x401 /* ARM TLS register */
|
||||
#define NT_ARM_ADDR_MASK 0x406 /* arm64 address mask (e.g. for TBI) */
|
||||
|
||||
/* GNU note types. */
|
||||
|
|
|
@ -372,6 +372,9 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep)
|
|||
elf_putregnote(NT_FPREGSET, tids[i], sb);
|
||||
elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb);
|
||||
elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb);
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
elf_putregnote(NT_ARM_TLS, tids[i], sb);
|
||||
#endif
|
||||
#if (defined(ELFCORE_COMPAT_32) && defined(__aarch64__)) || defined(__arm__)
|
||||
elf_putregnote(NT_ARM_VFP, tids[i], sb);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue