[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