/* address must be aligned to 4 and size must be multiple of 4 */ static NOINSTR void emit_core_dump_section(const char *name, uint32_t addr, uint32_t size) { struct section_ctx ctx = {.col_counter = 0, .crc32 = 0}; cs_base64_init(&ctx.b64_ctx, core_dump_emit_char, &ctx); esp_exc_printf(",\r\n\"%s\": {\"addr\": %u, \"data\": \"\r\n", name, addr); uint32_t end = addr + size; while (addr < end) { uint32_t tmp; tmp = *((uint32_t *) addr); addr += sizeof(tmp); ctx.crc32 = cs_crc32(ctx.crc32, &tmp, sizeof(tmp)); cs_base64_update(&ctx.b64_ctx, (char *) &tmp, sizeof(tmp)); } cs_base64_finish(&ctx.b64_ctx); esp_exc_printf("\", \"crc32\": %u}", ctx.crc32); } NOINSTR void esp_dump_core(uint32_t cause, struct regfile *regs) { (void) cause; esp_exc_puts("\r\n--- BEGIN CORE DUMP ---\r\n{\"arch\": \"ESP8266\""); emit_core_dump_section("REGS", (uintptr_t) regs, sizeof(*regs)); emit_core_dump_section("DRAM", 0x3FFE8000, 0x18000); emit_core_dump_section("IRAM", 0x40100000, 0x8000); /* * IRAM and IROM can be obtained from the firmware/ dir. * We need the ELF binary anyway to do symbolic debugging anyway * so we can avoid sending here huge amount of data that's available * on the host where we run GDB. */ esp_exc_puts("}\r\n---- END CORE DUMP ----\r\n"); }
NOINSTR void esp_dump_core(int fd, struct regfile *regs) { if (fd == -1) { fd = ESP_COREDUMP_FILENO; } uart_puts(fd, "--- BEGIN CORE DUMP ---\n"); uart_puts(fd, "{\"arch\": \"ESP8266\""); emit_core_dump_section(fd, "REGS", (uintptr_t) regs, sizeof(*regs)); emit_core_dump_section(fd, "DRAM", 0x3FFE8000, 0x18000); /* rtos relocates vectors here */ emit_core_dump_section(fd, "VEC", 0x40100000, 0x1000); emit_core_dump_section(fd, "ROM", 0x40000000, 0x10000); uart_puts(fd, "}\n"); /* * IRAM and IROM can be obtained from the firmware/ dir. * We need the ELF binary anyway to do symbolic debugging anyway * so we can avoid sending here huge amount of data that's available * on the host where we run GDB. */ uart_puts(fd, "---- END CORE DUMP ----\n"); }