mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
fix(coredump): fix note section alignments
This commit is contained in:
parent
eaefd0bd25
commit
21161b2fb3
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -196,15 +196,28 @@ static int elf_add_segment(core_dump_elf_t *self,
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static int elf_write_note_header(core_dump_elf_t *self,
|
||||
const char* name, uint32_t name_len, uint32_t data_sz, uint32_t type)
|
||||
/*
|
||||
* Example Note Segment
|
||||
* +================================================================+
|
||||
* | Offset | +0 | +1 | +2 | +3 | Description |
|
||||
* +----------------------------------------------------------------+
|
||||
* | 0 | 0x05 | 0x00 | 0x00 | 0x00 | namesz = 5 |
|
||||
* | 4 | 0x06 | 0x00 | 0x00 | 0x00 | descsz = 6 |
|
||||
* | 8 | 0x01 | 0x00 | 0x00 | 0x00 | type = 1 |
|
||||
* | 12 | 'C' | 'O' | 'R' | 'E' | name ("CORE") |
|
||||
* | 16 | 0x00 | pad | pad | pad | NULL + padding |
|
||||
* | 20 | 0x1 | 0x2 | 0x3 | 0x4 | desc (6 bytes) |
|
||||
* | 24 | 0x5 | 0x6 | pad | pad | desc + padding |
|
||||
* +================================================================+
|
||||
*/
|
||||
static int elf_write_note_header(core_dump_elf_t *self, const char* name, uint32_t data_sz, uint32_t type)
|
||||
{
|
||||
// temporary aligned buffer for note name
|
||||
static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 };
|
||||
elf_note note_hdr = { 0 };
|
||||
|
||||
memcpy(name_buffer, name, name_len);
|
||||
note_hdr.n_namesz = ALIGN_UP(name_len + 1, 4);
|
||||
size_t name_len = strlcpy(name_buffer, name, sizeof(name_buffer));
|
||||
note_hdr.n_namesz = name_len + 1; /* name_buffer must be null terminated */
|
||||
note_hdr.n_descsz = data_sz;
|
||||
note_hdr.n_type = type;
|
||||
// write note header
|
||||
@ -212,7 +225,7 @@ static int elf_write_note_header(core_dump_elf_t *self,
|
||||
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
|
||||
"Write ELF note header failure (%d)", err);
|
||||
// write note name
|
||||
err = esp_core_dump_write_data(&self->write_data, name_buffer, note_hdr.n_namesz);
|
||||
err = esp_core_dump_write_data(&self->write_data, name_buffer, ALIGN_UP(note_hdr.n_namesz, 4));
|
||||
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
|
||||
"Write ELF note name failure (%d)", err);
|
||||
|
||||
@ -226,18 +239,17 @@ static int elf_write_note(core_dump_elf_t *self,
|
||||
uint32_t data_sz)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator
|
||||
uint32_t data_len = ALIGN_UP(data_sz, 4);
|
||||
uint32_t name_len = strlen(name) + 1; // get name length including terminator
|
||||
|
||||
ELF_CHECK_ERR((name_len <= ELF_NOTE_NAME_MAX_SIZE), 0,
|
||||
"Segment note name is too long %d.", name_len);
|
||||
|
||||
uint32_t note_size = ALIGN_UP(name_len + data_len + sizeof(elf_note), 4);
|
||||
uint32_t note_size = ALIGN_UP(name_len, 4) + ALIGN_UP(data_sz, 4) + sizeof(elf_note);
|
||||
|
||||
// write segment data during second pass
|
||||
if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
|
||||
ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, "Invalid data pointer %x.", (uint32_t)data);
|
||||
err = elf_write_note_header(self, name, strlen(name), data_sz, type);
|
||||
err = elf_write_note_header(self, name, data_sz, type);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@ -246,8 +258,8 @@ static int elf_write_note(core_dump_elf_t *self,
|
||||
// which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary.
|
||||
err = esp_core_dump_write_data(&self->write_data, data, data_sz);
|
||||
if (err == ESP_OK) {
|
||||
int pad_size = data_len - data_sz;
|
||||
if (pad_size != 0) {
|
||||
const int pad_size = ALIGN_UP(data_sz, 4) - data_sz;
|
||||
if (pad_size > 0) {
|
||||
uint8_t pad_bytes[3] = {0};
|
||||
ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size);
|
||||
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
|
||||
@ -621,7 +633,7 @@ static void elf_write_core_dump_note_cb(void *opaque, const char *data)
|
||||
|
||||
static int elf_add_wdt_panic_details(core_dump_elf_t *self)
|
||||
{
|
||||
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME) - 1;
|
||||
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); /* len includes the null terminator */
|
||||
core_dump_elf_opaque_t param = {
|
||||
.self = self,
|
||||
.total_size = 0,
|
||||
@ -636,7 +648,6 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self)
|
||||
} else if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
|
||||
esp_err_t err = elf_write_note_header(self,
|
||||
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
|
||||
name_len,
|
||||
self->note_data_size,
|
||||
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
|
||||
if (err != ESP_OK) {
|
||||
@ -645,17 +656,16 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self)
|
||||
|
||||
esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, ¶m, NULL);
|
||||
ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err);
|
||||
const uint32_t mod = self->note_data_size & 3;
|
||||
if (mod != 0) {
|
||||
const int pad_size = ALIGN_UP(self->note_data_size, 4) - self->note_data_size;
|
||||
if (pad_size > 0) {
|
||||
uint8_t pad_bytes[3] = {0};
|
||||
uint32_t pad_size = 4 - mod;
|
||||
ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size);
|
||||
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
|
||||
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err);
|
||||
}
|
||||
}
|
||||
|
||||
return ALIGN_UP(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4);
|
||||
return ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note);
|
||||
}
|
||||
#endif //CONFIG_ESP_TASK_WDT_EN
|
||||
|
||||
@ -928,14 +938,14 @@ static void esp_core_dump_parse_note_section(uint8_t *coredump_data, elf_note_co
|
||||
for (size_t idx = 0; idx < size; ++idx) {
|
||||
if (target_notes[idx].n_type == note->n_type) {
|
||||
char *nm = (char *)¬e[1];
|
||||
target_notes[idx].n_ptr = nm + note->n_namesz;
|
||||
target_notes[idx].n_ptr = nm + ALIGN_UP(note->n_namesz, 4);
|
||||
target_notes[idx].n_descsz = note->n_descsz;
|
||||
ESP_COREDUMP_LOGD("%d bytes target note (%X) found in the note section",
|
||||
note->n_descsz, note->n_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
consumed_note_sz += ALIGN_UP(note->n_namesz + note->n_descsz + sizeof(elf_note), 4);
|
||||
consumed_note_sz += ALIGN_UP(note->n_namesz, 4) + ALIGN_UP(note->n_descsz, 4) + sizeof(elf_note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user