#ifndef _ELFCORE_H
#define _ELFCORE_H
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
defined(__mips__)) && defined(__linux)
#include <stdarg.h>
#include <stdint.h>
#include <sys/types.h>
#include <config.h>
#define DUMPER "ELF"
#if defined(__i386__) || defined(__x86_64__)
typedef struct i386_regs {
#ifdef __x86_64__
#define BP rbp
#define SP rsp
#define IP rip
uint64_t r15,r14,r13,r12,rbp,rbx,r11,r10;
uint64_t r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
uint64_t rip,cs,eflags;
uint64_t rsp,ss;
uint64_t fs_base, gs_base;
uint64_t ds,es,fs,gs;
#else
#define BP ebp
#define SP esp
#define IP eip
uint32_t ebx, ecx, edx, esi, edi, ebp, eax;
uint16_t ds, __ds, es, __es;
uint16_t fs, __fs, gs, __gs;
uint32_t orig_eax, eip;
uint16_t cs, __cs;
uint32_t eflags, esp;
uint16_t ss, __ss;
#endif
} i386_regs;
#elif defined(__ARM_ARCH_3__)
typedef struct arm_regs {
#define BP uregs[11]
#define SP uregs[13]
#define IP uregs[15]
#define LR uregs[14]
long uregs[18];
} arm_regs;
#elif defined(__mips__)
typedef struct mips_regs {
unsigned long pad[6];
unsigned long uregs[32];
unsigned long hi;
unsigned long lo;
unsigned long cp0_epc;
unsigned long cp0_badvaddr;
unsigned long cp0_status;
unsigned long cp0_cause;
unsigned long unused;
} mips_regs;
#endif
#if defined(__i386__) && defined(__GNUC__)
typedef struct Frame {
struct i386_regs uregs;
int errno_;
pid_t tid;
} Frame;
#define FRAME(f) Frame f; \
do { \
f.errno_ = errno; \
f.tid = sys_gettid(); \
__asm__ volatile ( \
"push %%ebp\n" \
"push %%ebx\n" \
"mov %%ebx,0(%%eax)\n" \
"mov %%ecx,4(%%eax)\n" \
"mov %%edx,8(%%eax)\n" \
"mov %%esi,12(%%eax)\n" \
"mov %%edi,16(%%eax)\n" \
"mov %%ebp,20(%%eax)\n" \
"mov %%eax,24(%%eax)\n" \
"mov %%ds,%%ebx\n" \
"mov %%ebx,28(%%eax)\n" \
"mov %%es,%%ebx\n" \
"mov %%ebx,32(%%eax)\n" \
"mov %%fs,%%ebx\n" \
"mov %%ebx,36(%%eax)\n" \
"mov %%gs,%%ebx\n" \
"mov %%ebx, 40(%%eax)\n" \
"call 0f\n" \
"0:pop %%ebx\n" \
"add $1f-0b,%%ebx\n" \
"mov %%ebx,48(%%eax)\n" \
"mov %%cs,%%ebx\n" \
"mov %%ebx,52(%%eax)\n" \
"pushf\n" \
"pop %%ebx\n" \
"mov %%ebx,56(%%eax)\n" \
"mov %%esp,%%ebx\n" \
"add $8,%%ebx\n" \
"mov %%ebx,60(%%eax)\n" \
"mov %%ss,%%ebx\n" \
"mov %%ebx,64(%%eax)\n" \
"pop %%ebx\n" \
"pop %%ebp\n" \
"1:" \
: : "a" (&f) : "memory"); \
} while (0)
#define SET_FRAME(f,r) \
do { \
errno = (f).errno_; \
(r) = (f).uregs; \
} while (0)
#elif defined(__x86_64__) && defined(__GNUC__)
typedef struct Frame {
struct i386_regs uregs;
int errno_;
pid_t tid;
} Frame;
#define FRAME(f) Frame f; \
do { \
f.errno_ = errno; \
f.tid = sys_gettid(); \
__asm__ volatile ( \
"push %%rbp\n" \
"push %%rbx\n" \
"mov %%r15,0(%%rax)\n" \
"mov %%r14,8(%%rax)\n" \
"mov %%r13,16(%%rax)\n" \
"mov %%r12,24(%%rax)\n" \
"mov %%rbp,32(%%rax)\n" \
"mov %%rbx,40(%%rax)\n" \
"mov %%r11,48(%%rax)\n" \
"mov %%r10,56(%%rax)\n" \
"mov %%r9,64(%%rax)\n" \
"mov %%r8,72(%%rax)\n" \
"mov %%rax,80(%%rax)\n" \
"mov %%rcx,88(%%rax)\n" \
"mov %%rdx,96(%%rax)\n" \
"mov %%rsi,104(%%rax)\n" \
"mov %%rdi,112(%%rax)\n" \
"mov %%ds,%%rbx\n" \
"mov %%rbx,184(%%rax)\n" \
"mov %%es,%%rbx\n" \
"mov %%rbx,192(%%rax)\n" \
"mov %%fs,%%rbx\n" \
"mov %%rbx,200(%%rax)\n" \
"mov %%gs,%%rbx\n" \
"mov %%rbx,208(%%rax)\n" \
"call 0f\n" \
"0:pop %%rbx\n" \
"add $1f-0b,%%rbx\n" \
"mov %%rbx,128(%%rax)\n" \
"mov %%cs,%%rbx\n" \
"mov %%rbx,136(%%rax)\n" \
"pushf\n" \
"pop %%rbx\n" \
"mov %%rbx,144(%%rax)\n" \
"mov %%rsp,%%rbx\n" \
"add $16,%%ebx\n" \
"mov %%rbx,152(%%rax)\n" \
"mov %%ss,%%rbx\n" \
"mov %%rbx,160(%%rax)\n" \
"pop %%rbx\n" \
"pop %%rbp\n" \
"1:" \
: : "a" (&f) : "memory"); \
} while (0)
#define SET_FRAME(f,r) \
do { \
errno = (f).errno_; \
(f).uregs.fs_base = (r).fs_base; \
(f).uregs.gs_base = (r).gs_base; \
(r) = (f).uregs; \
} while (0)
#elif defined(__ARM_ARCH_3__) && defined(__GNUC__)
typedef struct Frame {
struct arm_regs arm;
int errno_;
pid_t tid;
} Frame;
#define FRAME(f) Frame f; \
do { \
long cpsr; \
f.errno_ = errno; \
f.tid = sys_gettid(); \
__asm__ volatile( \
"stmia %0, {r0-r15}\n" \
: : "r"(&f.arm) : "memory"); \
f.arm.uregs[16] = 0; \
__asm__ volatile( \
"mrs %0, cpsr\n" \
: "=r"(cpsr)); \
f.arm.uregs[17] = cpsr; \
} while (0)
#define SET_FRAME(f,r) \
do { \
\
\
\
\
long fps = (f).arm.uregs[16]; \
errno = (f).errno_; \
(r) = (f).arm; \
(r).uregs[16] = fps; \
} while (0)
#elif defined(__mips__) && defined(__GNUC__)
typedef struct Frame {
struct mips_regs mips_regs;
int errno_;
pid_t tid;
} Frame;
#define MIPSREG(n) ({ register unsigned long r __asm__("$"#n); r; })
#define FRAME(f) Frame f = { 0 }; \
do { \
unsigned long hi, lo; \
register unsigned long pc __asm__("$31"); \
f.mips_regs.uregs[ 0] = MIPSREG( 0); \
f.mips_regs.uregs[ 1] = MIPSREG( 1); \
f.mips_regs.uregs[ 2] = MIPSREG( 2); \
f.mips_regs.uregs[ 3] = MIPSREG( 3); \
f.mips_regs.uregs[ 4] = MIPSREG( 4); \
f.mips_regs.uregs[ 5] = MIPSREG( 5); \
f.mips_regs.uregs[ 6] = MIPSREG( 6); \
f.mips_regs.uregs[ 7] = MIPSREG( 7); \
f.mips_regs.uregs[ 8] = MIPSREG( 8); \
f.mips_regs.uregs[ 9] = MIPSREG( 9); \
f.mips_regs.uregs[10] = MIPSREG(10); \
f.mips_regs.uregs[11] = MIPSREG(11); \
f.mips_regs.uregs[12] = MIPSREG(12); \
f.mips_regs.uregs[13] = MIPSREG(13); \
f.mips_regs.uregs[14] = MIPSREG(14); \
f.mips_regs.uregs[15] = MIPSREG(15); \
f.mips_regs.uregs[16] = MIPSREG(16); \
f.mips_regs.uregs[17] = MIPSREG(17); \
f.mips_regs.uregs[18] = MIPSREG(18); \
f.mips_regs.uregs[19] = MIPSREG(19); \
f.mips_regs.uregs[20] = MIPSREG(20); \
f.mips_regs.uregs[21] = MIPSREG(21); \
f.mips_regs.uregs[22] = MIPSREG(22); \
f.mips_regs.uregs[23] = MIPSREG(23); \
f.mips_regs.uregs[24] = MIPSREG(24); \
f.mips_regs.uregs[25] = MIPSREG(25); \
f.mips_regs.uregs[26] = MIPSREG(26); \
f.mips_regs.uregs[27] = MIPSREG(27); \
f.mips_regs.uregs[28] = MIPSREG(28); \
f.mips_regs.uregs[29] = MIPSREG(29); \
f.mips_regs.uregs[30] = MIPSREG(30); \
f.mips_regs.uregs[31] = MIPSREG(31); \
__asm__ volatile ("mfhi %0" : "=r"(hi)); \
__asm__ volatile ("mflo %0" : "=r"(lo)); \
__asm__ volatile ("jal 1f; 1:nop" : "=r"(pc)); \
f.mips_regs.hi = hi; \
f.mips_regs.lo = lo; \
f.mips_regs.cp0_epc = pc; \
f.errno_ = errno; \
f.tid = sys_gettid(); \
} while (0)
#define SET_FRAME(f,r) \
do { \
errno = (f).errno_; \
memcpy((r).uregs, (f).mips_regs.uregs, \
32*sizeof(unsigned long)); \
(r).hi = (f).mips_regs.hi; \
(r).lo = (f).mips_regs.lo; \
(r).cp0_epc = (f).mips_regs.cp0_epc; \
} while (0)
#else
typedef struct Frame {
pid_t tid;
} Frame;
#define FRAME(f) Frame f; do { f.tid = sys_gettid(); } while (0)
#define SET_FRAME(f,r) do { } while (0)
#endif
int InternalGetCoreDump(void *frame, int num_threads, pid_t *thread_pids,
va_list ap
);
#endif
#ifdef __cplusplus
}
#endif
#endif