-
Notifications
You must be signed in to change notification settings - Fork 45
Coredump: implementation on MMU targets #649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
417ccec
9a702dc
e09fe69
257dd26
cbace95
63f1506
cb0b2ce
9c3c753
18d4587
d8fa2c2
1f2790a
0dd4218
4c626a9
afe2296
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -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); | ||
|
|
||
|
|
@@ -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; | ||
| } | ||
etiaro marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+249
to
+269
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Not really a merge blocker, I'll leave this for @Darchiv to decide
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding the previous comment, would it be any better to define |
||
|
|
||
|
|
||
| void hal_coredumpThreadAux(void *buff, cpu_context_t *ctx) | ||
| { | ||
| static const char ARMVFP_NAME[] = "LINUX"; | ||
| Elf32_Nhdr nhdr; | ||
| nhdr.n_namesz = sizeof(ARMVFP_NAME); | ||
etiaro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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)); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.