Skip to content

Commit fbace9a

Browse files
committed
Merge branch 'fix/coredump_note_section_alignment' into 'master'
Fix/coredump note section headers and alignments Closes IDF-9948 See merge request espressif/esp-idf!36490
2 parents 9a0e097 + 287e55a commit fbace9a

File tree

3 files changed

+32
-22
lines changed

3 files changed

+32
-22
lines changed

components/espcoredump/src/core_dump_elf.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -196,23 +196,36 @@ static int elf_add_segment(core_dump_elf_t *self,
196196
return data_len;
197197
}
198198

199-
static int elf_write_note_header(core_dump_elf_t *self,
200-
const char* name, uint32_t name_len, uint32_t data_sz, uint32_t type)
199+
/*
200+
* Example Note Segment
201+
* +================================================================+
202+
* | Offset | +0 | +1 | +2 | +3 | Description |
203+
* +----------------------------------------------------------------+
204+
* | 0 | 0x05 | 0x00 | 0x00 | 0x00 | namesz = 5 |
205+
* | 4 | 0x06 | 0x00 | 0x00 | 0x00 | descsz = 6 |
206+
* | 8 | 0x01 | 0x00 | 0x00 | 0x00 | type = 1 |
207+
* | 12 | 'C' | 'O' | 'R' | 'E' | name ("CORE") |
208+
* | 16 | 0x00 | pad | pad | pad | NULL + padding |
209+
* | 20 | 0x1 | 0x2 | 0x3 | 0x4 | desc (6 bytes) |
210+
* | 24 | 0x5 | 0x6 | pad | pad | desc + padding |
211+
* +================================================================+
212+
*/
213+
static int elf_write_note_header(core_dump_elf_t *self, const char* name, uint32_t data_sz, uint32_t type)
201214
{
202215
// temporary aligned buffer for note name
203216
static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 };
204217
elf_note note_hdr = { 0 };
205218

206-
memcpy(name_buffer, name, name_len);
207-
note_hdr.n_namesz = ALIGN_UP(name_len + 1, 4);
219+
size_t name_len = strlcpy(name_buffer, name, sizeof(name_buffer));
220+
note_hdr.n_namesz = name_len + 1; /* name_buffer must be null terminated */
208221
note_hdr.n_descsz = data_sz;
209222
note_hdr.n_type = type;
210223
// write note header
211224
esp_err_t err = esp_core_dump_write_data(&self->write_data, &note_hdr, sizeof(note_hdr));
212225
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
213226
"Write ELF note header failure (%d)", err);
214227
// write note name
215-
err = esp_core_dump_write_data(&self->write_data, name_buffer, note_hdr.n_namesz);
228+
err = esp_core_dump_write_data(&self->write_data, name_buffer, ALIGN_UP(note_hdr.n_namesz, 4));
216229
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
217230
"Write ELF note name failure (%d)", err);
218231

@@ -226,18 +239,17 @@ static int elf_write_note(core_dump_elf_t *self,
226239
uint32_t data_sz)
227240
{
228241
esp_err_t err = ESP_FAIL;
229-
uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator
230-
uint32_t data_len = ALIGN_UP(data_sz, 4);
242+
uint32_t name_len = strlen(name) + 1; // get name length including terminator
231243

232244
ELF_CHECK_ERR((name_len <= ELF_NOTE_NAME_MAX_SIZE), 0,
233245
"Segment note name is too long %d.", name_len);
234246

235-
uint32_t note_size = ALIGN_UP(name_len + data_len + sizeof(elf_note), 4);
247+
uint32_t note_size = ALIGN_UP(name_len, 4) + ALIGN_UP(data_sz, 4) + sizeof(elf_note);
236248

237249
// write segment data during second pass
238250
if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
239251
ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, "Invalid data pointer %x.", (uint32_t)data);
240-
err = elf_write_note_header(self, name, strlen(name), data_sz, type);
252+
err = elf_write_note_header(self, name, data_sz, type);
241253
if (err != ESP_OK) {
242254
return err;
243255
}
@@ -246,8 +258,8 @@ static int elf_write_note(core_dump_elf_t *self,
246258
// which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary.
247259
err = esp_core_dump_write_data(&self->write_data, data, data_sz);
248260
if (err == ESP_OK) {
249-
int pad_size = data_len - data_sz;
250-
if (pad_size != 0) {
261+
const int pad_size = ALIGN_UP(data_sz, 4) - data_sz;
262+
if (pad_size > 0) {
251263
uint8_t pad_bytes[3] = {0};
252264
ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size);
253265
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)
621633

622634
static int elf_add_wdt_panic_details(core_dump_elf_t *self)
623635
{
624-
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME) - 1;
636+
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); /* len includes the null terminator */
625637
core_dump_elf_opaque_t param = {
626638
.self = self,
627639
.total_size = 0,
@@ -636,7 +648,6 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self)
636648
} else if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
637649
esp_err_t err = elf_write_note_header(self,
638650
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
639-
name_len,
640651
self->note_data_size,
641652
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
642653
if (err != ESP_OK) {
@@ -645,17 +656,16 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self)
645656

646657
esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, &param, NULL);
647658
ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err);
648-
const uint32_t mod = self->note_data_size & 3;
649-
if (mod != 0) {
659+
const int pad_size = ALIGN_UP(self->note_data_size, 4) - self->note_data_size;
660+
if (pad_size > 0) {
650661
uint8_t pad_bytes[3] = {0};
651-
uint32_t pad_size = 4 - mod;
652662
ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size);
653663
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
654664
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err);
655665
}
656666
}
657667

658-
return ALIGN_UP(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4);
668+
return ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note);
659669
}
660670
#endif //CONFIG_ESP_TASK_WDT_EN
661671

@@ -928,14 +938,14 @@ static void esp_core_dump_parse_note_section(uint8_t *coredump_data, elf_note_co
928938
for (size_t idx = 0; idx < size; ++idx) {
929939
if (target_notes[idx].n_type == note->n_type) {
930940
char *nm = (char *)&note[1];
931-
target_notes[idx].n_ptr = nm + note->n_namesz;
941+
target_notes[idx].n_ptr = nm + ALIGN_UP(note->n_namesz, 4);
932942
target_notes[idx].n_descsz = note->n_descsz;
933943
ESP_COREDUMP_LOGD("%d bytes target note (%X) found in the note section",
934944
note->n_descsz, note->n_type);
935945
break;
936946
}
937947
}
938-
consumed_note_sz += ALIGN_UP(note->n_namesz + note->n_descsz + sizeof(elf_note), 4);
948+
consumed_note_sz += ALIGN_UP(note->n_namesz, 4) + ALIGN_UP(note->n_descsz, 4) + sizeof(elf_note);
939949
}
940950
}
941951
}

components/espcoredump/src/core_dump_uart.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static esp_err_t esp_core_dump_uart_hw_init(void)
154154

155155
//Make sure txd/rxd are enabled
156156
// use direct reg access instead of gpio_pullup_dis which can cause exception when flash cache is disabled
157-
REG_CLR_BIT(GPIO_PIN_REG_1, FUN_PU); //TODO: IDF-9948
157+
gpio_hal_pullup_dis(&gpio_hal, U0TXD_GPIO_NUM);
158158
gpio_hal_func_sel(&gpio_hal, U0RXD_GPIO_NUM, U0RXD_MUX_FUNC);
159159
gpio_hal_func_sel(&gpio_hal, U0TXD_GPIO_NUM, U0TXD_MUX_FUNC);
160160
ESP_COREDUMP_LOGI("Press Enter to print core dump to UART...");

components/espcoredump/src/port/xtensa/core_dump_port.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static esp_err_t esp_core_dump_get_regs_from_stack(void* stack_addr,
241241
for (int i = 0; i < XT_SOL_AR_NUM; i++) {
242242
regs->ar[i] = stack_arr[XT_SOL_AR_START + i];
243243
}
244-
regs->pc = (regs->pc & 0x3fffffff);
244+
245245
if (regs->pc & 0x80000000) {
246246
regs->pc = (regs->pc & 0x3fffffff);
247247
}

0 commit comments

Comments
 (0)