[PATCH 01/10] util_lib: add paddr_to_offset function and expose raw vmcoreinfo data
Pnina Feder
pnina.feder at mobileye.com
Mon Jun 22 13:54:39 PDT 2026
Add paddr_to_offset() to translate physical addresses to file offsets,
complementing the existing vaddr_to_offset() for virtual addresses.
Store raw vmcoreinfo note data when parsing ELF notes and provide
elf_get_raw_vmcoreinfo() accessor to retrieve it. This allows callers
to access the unparsed vmcoreinfo content for external processing.
and fix compilation warnings.
Change-Id: Icc75c22d6b2d95b6c951ccf647819d7e9cc4e7de
Signed-off-by: Pnina Feder <pnina.feder at mobileye.com>
---
util_lib/elf_info.c | 53 ++++++++++++++++++++++++++++++++-----
util_lib/include/elf_info.h | 11 ++++----
2 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 589bc1ad..fd7d1d5b 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -16,7 +16,8 @@
*/
#include <inttypes.h>
-#include <elf_info.h>
+
+#include "elf_info.h"
/* The 32bit and 64bit note headers make it clear we don't care */
typedef Elf32_Nhdr Elf_Nhdr;
@@ -27,6 +28,9 @@ static Elf64_Phdr *phdr;
static int num_pt_loads;
static char osrelease[4096];
+/* Raw vmcoreinfo storage */
+static char *raw_vmcoreinfo = NULL;
+static size_t raw_vmcoreinfo_len = 0;
/* VMCOREINFO symbols for lockless printk ringbuffer */
static loff_t prb_vaddr;
@@ -140,6 +144,21 @@ static uint64_t vaddr_to_offset(uint64_t vaddr)
exit(30);
}
+uint64_t paddr_to_offset(uint64_t paddr){
+ ssize_t i;
+
+ for (i = 0; i < ehdr.e_phnum; i++) {
+ if (phdr[i].p_paddr > paddr)
+ continue;
+ if ((phdr[i].p_paddr + phdr[i].p_memsz) <= paddr)
+ continue;
+ return phdr[i].p_offset + (paddr - phdr[i].p_paddr);
+ }
+ fprintf(stderr, "No program header covering paddr 0x%llx found kexec bug?\n",
+ (unsigned long long)paddr);
+ return (uint64_t)-1;
+}
+
static unsigned machine_pointer_bits(void)
{
uint8_t bits = 0;
@@ -646,6 +665,16 @@ static int scan_notes(int fd, loff_t start, loff_t lsize)
if ((memcmp(n_name, "VMCOREINFO", 11) != 0) || (n_type != 0))
continue;
+
+ /* Save raw vmcoreinfo for later use */
+ if (raw_vmcoreinfo)
+ free(raw_vmcoreinfo);
+ raw_vmcoreinfo = malloc(n_descsz);
+ if (raw_vmcoreinfo) {
+ memcpy(raw_vmcoreinfo, n_desc, n_descsz);
+ raw_vmcoreinfo_len = n_descsz;
+ }
+
scan_vmcoreinfo(n_desc, n_descsz);
}
@@ -776,7 +805,7 @@ static void dump_dmesg_legacy(int fd, void (*handler)(char*, unsigned int))
* To collect full dmesg including the part before `dmesg -c` is useful
* for later debugging. Use same logic as what crash utility is using.
*/
- logged_chars = log_end < log_buf_len ? log_end : log_buf_len;
+ logged_chars = log_end < (unsigned int)log_buf_len ? log_end : (unsigned int)log_buf_len;
if (handler)
handler(buf + (log_buf_len - logged_chars), logged_chars);
@@ -873,7 +902,7 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
uint16_t loglen;
ret = pread(fd, buf, log_sz, log_buf_offset + current_idx);
- if (ret != log_sz) {
+ if (ret != (ssize_t)log_sz) {
fprintf(stderr, "Failed to read log of size %" PRId64 " bytes:"
" %s\n", log_sz, strerror(errno));
exit(65);
@@ -1165,7 +1194,7 @@ static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
exit(64);
}
ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr));
- if (ret != printk_ringbuffer_sz) {
+ if (ret != (ssize_t)printk_ringbuffer_sz) {
fprintf(stderr, "Failed to read prb of size %zu bytes: %s\n",
printk_ringbuffer_sz, strerror(errno));
exit(65);
@@ -1184,7 +1213,7 @@ static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
}
ret = pread(fd, m.descs, prb_desc_sz * m.desc_ring_count,
vaddr_to_offset(kaddr));
- if (ret != prb_desc_sz * m.desc_ring_count) {
+ if (ret != (ssize_t)(prb_desc_sz * m.desc_ring_count)) {
fprintf(stderr,
"Failed to read descs of size %lu bytes: %s\n",
prb_desc_sz * m.desc_ring_count, strerror(errno));
@@ -1201,7 +1230,7 @@ static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
}
ret = pread(fd, m.infos, printk_info_sz * m.desc_ring_count,
vaddr_to_offset(kaddr));
- if (ret != printk_info_sz * m.desc_ring_count) {
+ if (ret != (ssize_t)(printk_info_sz * m.desc_ring_count)) {
fprintf(stderr,
"Failed to read infos of size %lu bytes: %s\n",
printk_info_sz * m.desc_ring_count, strerror(errno));
@@ -1222,7 +1251,7 @@ static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
}
ret = pread(fd, m.text_data, m.text_data_ring_size,
vaddr_to_offset(kaddr));
- if (ret != m.text_data_ring_size) {
+ if (ret != (ssize_t)(m.text_data_ring_size)) {
fprintf(stderr,
"Failed to read text_data of size %lu bytes: %s\n",
m.text_data_ring_size, strerror(errno));
@@ -1321,3 +1350,13 @@ int read_phys_offset_elf_kcore(int fd, long *phys_off)
return 2;
}
+
+int elf_get_raw_vmcoreinfo(const char **data, size_t *size)
+{
+ if (!raw_vmcoreinfo || raw_vmcoreinfo_len == 0)
+ return -1;
+
+ *data = raw_vmcoreinfo;
+ *size = raw_vmcoreinfo_len;
+ return 0;
+}
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
index fdf4c3d0..c2873365 100644
--- a/util_lib/include/elf_info.h
+++ b/util_lib/include/elf_info.h
@@ -24,13 +24,14 @@
#include <ctype.h>
int get_pt_load(int idx,
- unsigned long long *phys_start,
- unsigned long long *phys_end,
- unsigned long long *virt_start,
- unsigned long long *virt_end);
+ unsigned long long *phys_start,
+ unsigned long long *phys_end,
+ unsigned long long *virt_start,
+ unsigned long long *virt_end);
int read_phys_offset_elf_kcore(int fd, long *phys_off);
int read_elf(int fd);
void dump_dmesg(int fd, void (*handler)(char*, unsigned int));
extern void (*arch_scan_vmcoreinfo)(char *pos);
-
+uint64_t paddr_to_offset(uint64_t paddr);
+int elf_get_raw_vmcoreinfo(const char **data, size_t *size);
#endif /* ELF_INFO_H */
--
2.43.0
More information about the kexec
mailing list