Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions hal/aarch64/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,9 @@ void _hal_exceptionsInit(void)
exceptions.handler[i] = exceptions_trampoline;
}
}


cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return &ctx->cpuCtx;
}
7 changes: 6 additions & 1 deletion hal/armv7a/arch/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
#define EXC_UNDEFINED 1
#define EXC_PAGEFAULT 4

#define SIZE_CTXDUMP 512 /* Size of dumped context */
#define SIZE_CTXDUMP 512 /* Size of dumped context */
#define SIZE_COREDUMP_GREGSET 72
#define SIZE_COREDUMP_THREADAUX 280 /* vfp context note */
#define SIZE_COREDUMP_GENAUX 36 /* auxv HWCAP note */

#define HAL_ELF_MACHINE 40 /* ARM */


typedef struct _exc_context_t {
Expand Down
98 changes: 92 additions & 6 deletions hal/armv7a/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "hal/console.h"
#include "hal/string.h"
#include "include/mman.h"
#include "proc/elf.h"


#define EXC_ASYNC_EXTERNAL 0x16
Expand Down Expand Up @@ -49,18 +50,23 @@ struct {
enum { exc_reset = 0, exc_undef, exc_svc, exc_prefetch, exc_abort };


void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n)
const char *hal_exceptionMnemonic(int n)
{
static const char *const mnemonics[] = {
"0 #Reset", "1 #Undef", "2 #Syscall", "3 #Prefetch",
"4 #Abort", "5 #Reserved", "6 #FIRQ", "7 #IRQ"
"0 #Reset", "1 #Undef", "2 #Syscall", "3 #Prefetch",
"4 #Abort", "5 #Reserved", "6 #FIRQ", "7 #IRQ"
};
size_t i = 0;

n &= 0x7;
return mnemonics[n & 0x7];
}


void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n)
{
size_t i = 0;

hal_strcpy(buff, "\nException: ");
hal_strcpy(buff += hal_strlen(buff), mnemonics[n]);
hal_strcpy(buff += hal_strlen(buff), hal_exceptionMnemonic(n));
hal_strcpy(buff += hal_strlen(buff), "\n");
buff += hal_strlen(buff);

Expand Down Expand Up @@ -232,3 +238,83 @@ void _hal_exceptionsInit(void)
exceptions.abortHandler = exceptions_defaultHandler;
exceptions.defaultHandler = exceptions_defaultHandler;
}


cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return &ctx->cpuCtx;
}


void hal_coredumpGRegset(void *buff, cpu_context_t *ctx)
{
u32 *regs = (u32 *)buff;
*(regs++) = ctx->r0;
*(regs++) = ctx->r1;
*(regs++) = ctx->r2;
*(regs++) = ctx->r3;
*(regs++) = ctx->r4;
*(regs++) = ctx->r5;
*(regs++) = ctx->r6;
*(regs++) = ctx->r7;
*(regs++) = ctx->r8;
*(regs++) = ctx->r9;
*(regs++) = ctx->r10;
*(regs++) = ctx->fp;
*(regs++) = ctx->ip;
*(regs++) = ctx->sp;
*(regs++) = ctx->lr;
*(regs++) = ctx->pc;
*(regs++) = ctx->psr;
}
Comment on lines +249 to +269
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somewhat iffy in scope of C standard and MISRA - yes, we provide aligned buffer, but in pedantic view this is still unwanted method.

It is best to pass the desired type all the way down, in this case it depends on the architecture - perhaps per arch typedef?

On the other hand memcpy can be used instead, most likely less efficient approach.

Not really a merge blocker, I'll leave this for @Darchiv to decide

Copy link
Contributor Author

@etiaro etiaro Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the previous comment, would it be any better to define struct elf_prstatus including pr_regs in HAL which would just be filled here, and make a cast to this new type in caller?



void hal_coredumpThreadAux(void *buff, cpu_context_t *ctx)
{
static const char ARMVFP_NAME[] = "LINUX";
Elf32_Nhdr nhdr;
nhdr.n_namesz = sizeof(ARMVFP_NAME);
nhdr.n_descsz = sizeof(ctx->freg) + sizeof(ctx->fpsr);
nhdr.n_type = NT_ARM_VFP;
hal_memcpy(buff, &nhdr, sizeof(nhdr));
buff = (char *)buff + sizeof(nhdr);
hal_memcpy(buff, ARMVFP_NAME, sizeof(ARMVFP_NAME));
buff = (char *)buff + ((sizeof(ARMVFP_NAME) + 3) & ~3);
hal_memcpy(buff, ctx->freg, sizeof(ctx->freg));
buff = (char *)buff + sizeof(ctx->freg);
hal_memcpy(buff, &ctx->fpsr, sizeof(ctx->fpsr));
}


#define COMPAT_HWCAP_VFP (1 << 6)
#define COMPAT_HWCAP_NEON (1 << 12)
#define COMPAT_HWCAP_VFPv3 (1 << 13)
#define HWCAP_VFPv3 (COMPAT_HWCAP_VFP | COMPAT_HWCAP_NEON | COMPAT_HWCAP_VFPv3)

#define AT_HWCAP 16
#define AT_NULL 0


void hal_coredumpGeneralAux(void *buff)
{
static const char AUXV_NAME[] = "CORE";
Elf32_Nhdr nhdr;
struct {
u32 a_type;
u32 a_val;
} auxv[2];

nhdr.n_namesz = sizeof(AUXV_NAME);
nhdr.n_descsz = sizeof(auxv);
nhdr.n_type = NT_AUXV;
hal_memcpy(buff, &nhdr, sizeof(nhdr));
buff = (char *)buff + sizeof(nhdr);
hal_memcpy(buff, AUXV_NAME, sizeof(AUXV_NAME));
buff = (char *)buff + ((sizeof(AUXV_NAME) + 3) & ~3);

auxv[0].a_type = AT_HWCAP;
auxv[0].a_val = HWCAP_VFPv3;
auxv[1].a_type = AT_NULL;
auxv[1].a_val = 0;
hal_memcpy(buff, auxv, sizeof(auxv));
}
6 changes: 6 additions & 0 deletions hal/armv7m/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,9 @@ void _hal_exceptionsInit(void)
{
hal_exception_common.handler = NULL;
}


extern cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return NULL; /* unsupported */
}
6 changes: 6 additions & 0 deletions hal/armv7r/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,9 @@ void _hal_exceptionsInit(void)
exceptions.abortHandler = exceptions_defaultHandler;
exceptions.defaultHandler = exceptions_defaultHandler;
}


cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return &ctx->cpuCtx;
}
6 changes: 6 additions & 0 deletions hal/armv8m/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,9 @@ int hal_exceptionsSetHandler(unsigned int n, void (*handler)(unsigned int, exc_c
void _hal_exceptionsInit(void)
{
}


cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return NULL; /* unsupported */
}
6 changes: 6 additions & 0 deletions hal/armv8r/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,9 @@ void _hal_exceptionsInit(void)
exceptions.abortHandler = exceptions_defaultHandler;
exceptions.defaultHandler = exceptions_defaultHandler;
}


cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return &ctx->cpuCtx;
}
15 changes: 15 additions & 0 deletions hal/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ extern void *hal_exceptionsFaultAddr(unsigned int n, exc_context_t *ctx);
extern ptr_t hal_exceptionsPC(exc_context_t *ctx);


extern const char *hal_exceptionMnemonic(int n);


extern void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n);


Expand All @@ -36,4 +39,16 @@ extern int hal_exceptionsSetHandler(unsigned int n, void (*handler)(unsigned int

extern void _hal_exceptionsInit(void);


extern cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx);


extern void hal_coredumpGRegset(void *buff, cpu_context_t *ctx);


extern void hal_coredumpThreadAux(void *buff, cpu_context_t *ctx);


extern void hal_coredumpGeneralAux(void *buff);

#endif
7 changes: 6 additions & 1 deletion hal/ia32/arch/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
#define EXC_UNDEFINED 6
#define EXC_PAGEFAULT 14

#define SIZE_CTXDUMP 512 /* Size of dumped context */
#define SIZE_CTXDUMP 512 /* Size of dumped context */
#define SIZE_COREDUMP_GREGSET 68
#define SIZE_COREDUMP_THREADAUX 128 /* vfp context note */
#define SIZE_COREDUMP_GENAUX 0

#define HAL_ELF_MACHINE 3 /* IA32 */


#pragma pack(push, 1)
Expand Down
71 changes: 63 additions & 8 deletions hal/ia32/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "include/mman.h"
#include "include/errno.h"
#include "proc/elf.h"


/* Exception stubs */
Expand Down Expand Up @@ -112,19 +113,24 @@ ptr_t hal_exceptionsPC(exc_context_t *ctx)
}


void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n)
const char *hal_exceptionMnemonic(int n)
{
static const char *const mnemonics[] = {
"0 #DE", "1 #DB", "2 #NMI", "3 #BP", "4 #OF", "5 #BR", "6 #UD", "7 #NM",
"8 #BF", "9 #", "10 #TS", "11 #NP", "12 #SS", "13 #GP", "14 #PF", "15 #",
"16 #MF", "17 #AC", "18 #MC", "19 #XM/#XF", "20 #VE", "21 #", "22 #", "23 #",
"24 #", "25 #", "26 #", "27 #", "28 #", "29 #", "30 #SE", "31 #" };
"0 #DE", "1 #DB", "2 #NMI", "3 #BP", "4 #OF", "5 #BR", "6 #UD", "7 #NM",
"8 #BF", "9 #", "10 #TS", "11 #NP", "12 #SS", "13 #GP", "14 #PF", "15 #",
"16 #MF", "17 #AC", "18 #MC", "19 #XM/#XF", "20 #VE", "21 #", "22 #", "23 #",
"24 #", "25 #", "26 #", "27 #", "28 #", "29 #", "30 #SE", "31 #"
};

return mnemonics[n & 0x1f];
}


void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n)
{
size_t i = 0;
u32 ss;

n &= 0x1f;

/* clang-format off */
__asm__ volatile(
"xorl %0, %0\n\t"
Expand All @@ -135,7 +141,7 @@ void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n)
/* clang-format on */

hal_strcpy(buff, "\nException: ");
hal_strcpy(buff += hal_strlen(buff), mnemonics[n]);
hal_strcpy(buff += hal_strlen(buff), hal_exceptionMnemonic(n));
hal_strcpy(buff += hal_strlen(buff), "\n");
buff += hal_strlen(buff);

Expand Down Expand Up @@ -301,3 +307,52 @@ __attribute__ ((section (".init"))) void _hal_exceptionsInit(void)

return;
}


cpu_context_t *hal_excToCpuCtx(exc_context_t *ctx)
{
return &ctx->cpuCtx;
}


void hal_coredumpGRegset(void *buff, cpu_context_t *ctx)
{
u32 *regs = (u32 *)buff;
*(regs++) = ctx->ebx;
*(regs++) = ctx->ecx;
*(regs++) = ctx->edx;
*(regs++) = ctx->esi;
*(regs++) = ctx->edi;
*(regs++) = ctx->ebp;
*(regs++) = ctx->eax;
*(regs++) = ctx->ds;
*(regs++) = ctx->es;
*(regs++) = ctx->fs;
*(regs++) = ctx->gs;
*(regs++) = 0;
*(regs++) = ctx->eip;
*(regs++) = ctx->cs;
*(regs++) = ctx->eflags;
*(regs++) = ctx->esp;
*(regs++) = ctx->ss;
}


void hal_coredumpThreadAux(void *buff, cpu_context_t *ctx)
{
static const char FPREGSET_NAME[] = "CORE";
Elf32_Nhdr nhdr;
nhdr.n_namesz = sizeof(FPREGSET_NAME);
nhdr.n_descsz = sizeof(ctx->fpuContext);
nhdr.n_type = NT_FPREGSET;
hal_memcpy(buff, &nhdr, sizeof(nhdr));
buff = (char *)buff + sizeof(nhdr);
hal_memcpy(buff, FPREGSET_NAME, sizeof(FPREGSET_NAME));
buff = (char *)buff + ((sizeof(FPREGSET_NAME) + 3) & ~3);
hal_memcpy(buff, &ctx->fpuContext, sizeof(ctx->fpuContext));
}


void hal_coredumpGeneralAux(void *buff)
{
}
2 changes: 1 addition & 1 deletion hal/riscv64/arch/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ typedef struct {

/* CPU context saved by interrupt handlers on thread kernel stack */
typedef struct {
u64 pc;
u64 ra; /* x1 */
u64 gp; /* x3 */

u64 t0; /* x5 */
Expand Down
7 changes: 6 additions & 1 deletion hal/riscv64/arch/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
#define EXC_UNDEFINED 2
#define EXC_PAGEFAULT 127

#define SIZE_CTXDUMP 1024 /* Size of dumped context */
#define SIZE_CTXDUMP 1024 /* Size of dumped context */
#define SIZE_COREDUMP_GREGSET 256
#define SIZE_COREDUMP_THREADAUX 284 /* vfp context note */
#define SIZE_COREDUMP_GENAUX 0

#define HAL_ELF_MACHINE 243 /* RISC-V 64-bit */

typedef cpu_context_t exc_context_t;

Expand Down
2 changes: 1 addition & 1 deletion hal/riscv64/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t
__asm__ volatile("sd gp, %0" : "=m"(ctx->gp));
/* clang-format on */

ctx->pc = (u64)0;
ctx->ra = (u64)0;
ctx->sp = (u64)kstack + kstacksz;

ctx->t0 = 0;
Expand Down
Loading
Loading