recent ARM-Linux merge.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10992
}
DiCfSI;
#elif defined(VGA_ppc32) || defined(VGA_ppc64)
-typedef void DiCfSI;
+/* Just have a struct with the common fields in, so that code that
+ processes the common fields doesn't have to be ifdef'd against
+ VGP_/VGA_ symbols. These are not used in any way on ppc32/64-linux
+ at the moment. */
+typedef
+ struct {
+ Addr base;
+ UInt len;
+ UChar cfa_how; /* a CFIC_ value */
+ UChar ra_how; /* a CFIR_ value */
+ Int cfa_off;
+ Int ra_off;
+ }
+ DiCfSI;
#else
# error "Unknown arch"
#endif
: /* reads none */ \
: "r0" /* trashed */ \
); \
- srP->r_pc = (ULong)cia; \
- srP->r_sp = (ULong)r1; \
- srP->misc.PPC32.lr = lr; \
+ (srP)->r_pc = (ULong)cia; \
+ (srP)->r_sp = (ULong)r1; \
+ (srP)->misc.PPC32.r_lr = lr; \
}
#elif defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
# define GET_STARTREGS(srP) \
: /* reads none */ \
: "r0" /* trashed */ \
); \
- srP->r_pc = cia; \
- srP->r_sp = r1; \
- srP->misc.PPC64.lr = lr; \
+ (srP)->r_pc = cia; \
+ (srP)->r_sp = r1; \
+ (srP)->misc.PPC64.r_lr = lr; \
}
#elif defined(VGP_arm_linux)
# define GET_STARTREGS(srP) \
= VG_(threads)[tid].arch.vex.guest_RBP;
# elif defined(VGA_ppc32)
regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_CIA;
- regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_R1;
+ regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_GPR1;
regs->misc.PPC32.r_lr
= VG_(threads)[tid].arch.vex.guest_LR;
# elif defined(VGA_ppc64)
regs->r_pc = VG_(threads)[tid].arch.vex.guest_CIA;
- regs->r_sp = VG_(threads)[tid].arch.vex.guest_R1;
+ regs->r_sp = VG_(threads)[tid].arch.vex.guest_GPR1;
regs->misc.PPC64.r_lr
= VG_(threads)[tid].arch.vex.guest_LR;
# elif defined(VGA_arm)
meaningless, so the caller of VG_UCONTEXT_SYSCALL_SYSRES has to be
very careful to pay attention to the results only when it is sure
that the said constraint on the program counter is indeed valid. */
+
#if defined(VGP_x86_linux)
# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
uc->uc_regs->mc_gregs[PT_MSR], otherwise it clears it. That bit
will always be clear under 2.4.20. So you can use that bit to tell
whether uc->uc_regs->mc_vregs is valid. */
-# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
-# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
-# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
+# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
+# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
/* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
VG_(mk_SysRes_ppc32_linux)( \
(uc)->uc_regs->mc_gregs[VKI_PT_R3], \
(((uc)->uc_regs->mc_gregs[VKI_PT_CCR] >> 28) & 1) \
)
-# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_LNK])
+# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
+ { (srP)->r_pc = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_NIP]); \
+ (srP)->r_sp = (ULong)((uc)->uc_regs->mc_gregs[VKI_PT_R1]); \
+ (srP)->misc.PPC32.r_lr = (uc)->uc_regs->mc_gregs[VKI_PT_LNK]; \
+ }
#elif defined(VGP_ppc64_linux)
-# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
-# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
-# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
+# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
+# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
/* Dubious hack: if there is an error, only consider the lowest 8
bits of r3. memcheck/tests/post-syscall shows a case where an
interrupted syscall should have produced a ucontext with 0x4
if (err) r3 &= 0xFF;
return VG_(mk_SysRes_ppc64_linux)( r3, err );
}
-# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK])
+# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
+ { (srP)->r_pc = (uc)->uc_mcontext.gp_regs[VKI_PT_NIP]; \
+ (srP)->r_sp = (uc)->uc_mcontext.gp_regs[VKI_PT_R1]; \
+ (srP)->misc.PPC64.r_lr = (uc)->uc_mcontext.gp_regs[VKI_PT_LNK]; \
+ }
#elif defined(VGP_arm_linux)
# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc)
UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
/*OUT*/Addr* ips, UInt max_n_ips,
/*OUT*/Addr* sps, /*OUT*/Addr* fps,
- Addr ip, Addr sp, Addr fp, Addr lr,
- Addr fp_min, Addr fp_max_orig )
+ UnwindStartRegs* startRegs,
+ Addr fp_max_orig )
{
Bool lr_is_first_RA = False;
# if defined(VG_PLAT_USES_PPCTOC)
vg_assert(sizeof(Addr) == sizeof(UWord));
vg_assert(sizeof(Addr) == sizeof(void*));
+ Addr ip = (Addr)startRegs->r_pc;
+ Addr sp = (Addr)startRegs->r_sp;
+ Addr fp = sp;
+# if defined(VGP_ppc32_linux) || defined(VGP_ppc32_aix5)
+ Addr lr = startRegs->misc.PPC32.r_lr;
+# elif defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
+ Addr lr = startRegs->misc.PPC64.r_lr;
+# endif
+ Addr fp_min = sp;
+
/* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
stopping when the trail goes cold, which we guess to be
when FP is not a reasonable stack location. */
// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
// (unknown).
-const SyscallTableEntry ML_(syscall_table)[] = {
+static SyscallTableEntry syscall_table[] = {
//.. (restart_syscall) // 0
GENX_(__NR_exit, sys_exit), // 1
GENX_(__NR_fork, sys_fork), // 2
LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
};
-const UInt ML_(syscall_table_size) =
- sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
+SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
+{
+ const UInt syscall_table_size
+ = sizeof(syscall_table) / sizeof(syscall_table[0]);
+
+ /* Is it in the contiguous initial section of the table? */
+ if (sysno < syscall_table_size) {
+ SyscallTableEntry* sys = &syscall_table[sysno];
+ if (sys->before == NULL)
+ return NULL; /* no entry */
+ else
+ return sys;
+ }
+
+ /* Can't find a wrapper */
+ return NULL;
+}
#endif // defined(VGP_ppc32_linux)
// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
// (unknown).
-const SyscallTableEntry ML_(syscall_table)[] = {
+static SyscallTableEntry syscall_table[] = {
// _____(__NR_restart_syscall, sys_restart_syscall), // 0
GENX_(__NR_exit, sys_exit), // 1
GENX_(__NR_fork, sys_fork), // 2
LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
};
-const UInt ML_(syscall_table_size) =
- sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
+SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
+{
+ const UInt syscall_table_size
+ = sizeof(syscall_table) / sizeof(syscall_table[0]);
+
+ /* Is it in the contiguous initial section of the table? */
+ if (sysno < syscall_table_size) {
+ SyscallTableEntry* sys = &syscall_table[sysno];
+ if (sys->before == NULL)
+ return NULL; /* no entry */
+ else
+ return sys;
+ }
+
+ /* Can't find a wrapper */
+ return NULL;
+}
#endif // defined(VGP_ppc64_linux)
D3UnwindRegs;
#elif defined(VGA_ppc32) || defined(VGA_ppc64)
typedef
- void
+ UChar /* should be void, but gcc complains at use points */
D3UnwindRegs;
#else
# error "Unsupported arch"