diff --git a/include/patchelfcrc/elfpatch.h b/include/patchelfcrc/elfpatch.h
index 5d525ed..4d5b778 100644
--- a/include/patchelfcrc/elfpatch.h
+++ b/include/patchelfcrc/elfpatch.h
@@ -63,13 +63,14 @@ int elf_patch_get_bits(elfpatch_handle_t *ep);
* @param ep Elfpatch handle
* @param[in] section section name
* @param[out] vma Virtual Memory Address. May be NULL.
+ * @param[out] lma Load memory address. May be NULL.
* @param[out] len Size of section in bytes. May be NULL.
* @return 0 if successful
* @return -1 if section is not found
* @return -1000 and below: Parameter error.
*/
int elf_patch_get_section_address(elfpatch_handle_t *ep, const char *section,
- uint64_t *vma, uint64_t *len);
+ uint64_t *vma, uint64_t *lma, uint64_t *len);
/**
* @brief Compute CRC over a section in an ELF file
diff --git a/resources/schema.xsd b/resources/schema.xsd
index 874ddbb..89c2d3f 100644
--- a/resources/schema.xsd
+++ b/resources/schema.xsd
@@ -51,6 +51,7 @@
+
diff --git a/src/elfpatch.c b/src/elfpatch.c
index 1ab0e1d..100f60f 100644
--- a/src/elfpatch.c
+++ b/src/elfpatch.c
@@ -35,6 +35,7 @@ struct elf_section {
GElf_Shdr section_header;
Elf_Scn *scn;
char *name;
+ uint64_t lma; /**< @Resolved load memory address of a section. May be equivalent to VMA */
};
struct elfpatch {
@@ -161,17 +162,18 @@ static void print_sections(elfpatch_handle_t *ep)
/* Write header */
ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
- ft_write_ln(table, "Section", "Type", "Size", "Address", "File Offset");
+ ft_write_ln(table, "Section", "Type", "Size", "VMA", "LMA", "File Offset");
for (iter = ep->sections; iter; iter = sl_list_next(iter)) {
section = (const struct elf_section *)iter->data;
if (!section)
continue;
- ft_printf_ln(table, "%s|%s|%lu|0x%p|0x%p",
+ ft_printf_ln(table, "%s|%s|%lu|%p|%p|%p",
section->name,
section_type_to_str(section->section_header.sh_type),
section->section_header.sh_size,
(void *)section->section_header.sh_addr,
+ (void *)section->lma,
(void *)section->section_header.sh_offset
);
}
@@ -211,6 +213,10 @@ static SlList *elf_patch_get_sections(elfpatch_handle_t *ep)
free(sec);
continue;
}
+
+ /* Default setting of LMA if not modified by segment */
+ sec->lma = (uint64_t)sec->section_header.sh_addr;
+
name = elf_strptr(ep->elf, shstrndx, sec->section_header.sh_name);
if (name) {
sec->name = strdup(name);
@@ -220,8 +226,6 @@ static SlList *elf_patch_get_sections(elfpatch_handle_t *ep)
ep->sections = ret;
- print_sections(ep);
-
return ret;
ret_free_section_list:
@@ -284,6 +288,17 @@ ret_free_err:
return -1;
}
+static void resolve_section_lmas(elfpatch_handle_t *ep)
+{
+ SlList *sec_iter;
+
+ ret_if_ep_err(ep);
+
+ for (sec_iter = ep->sections; sec_iter; sec_iter = sl_list_next(sec_iter)) {
+
+ }
+}
+
static int elf_patch_update_info(elfpatch_handle_t *ep)
{
Elf_Kind ek;
@@ -334,6 +349,12 @@ static int elf_patch_update_info(elfpatch_handle_t *ep)
return -1;
}
+ /* Resolve section to segment mapping to calculate the LMA of eachs section */
+ resolve_section_lmas(ep);
+
+ /* Print the debug section table */
+ print_sections(ep);
+
return 0;
}
@@ -572,6 +593,15 @@ static void get_section_addr_and_length(const struct elf_section *sec, uint64_t
*len = sec->section_header.sh_size;
}
+static void get_section_load_addr(const struct elf_section *sec, uint64_t *lma)
+{
+ if (!sec || !lma)
+ return;
+
+ *lma = sec->lma;
+}
+
+
int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section, const SlList *section_name_list,
const uint32_t *crcs, uint8_t crc_size_bits, uint32_t start_magic, uint32_t end_magic,
bool check_start_magic, bool check_end_magic, enum crc_format format, bool little_endian)
@@ -776,7 +806,7 @@ void elf_patch_close_and_free(elfpatch_handle_t *ep)
}
int elf_patch_get_section_address(elfpatch_handle_t *ep, const char *section,
- uint64_t *vma, uint64_t *len)
+ uint64_t *vma, uint64_t *lma, uint64_t *len)
{
const struct elf_section *sec;
@@ -789,6 +819,7 @@ int elf_patch_get_section_address(elfpatch_handle_t *ep, const char *section,
return -1;
get_section_addr_and_length(sec, vma, len);
+ get_section_load_addr(sec, lma);
return 0;
}
diff --git a/src/xml.c b/src/xml.c
index 3896a34..4ed7af6 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -31,7 +31,7 @@ int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *secti
SlList *name_iter;
const char *section_name;
size_t index;
- uint64_t vma, len;
+ uint64_t vma, len, lma;
if (!path || !crcs || !section_name_list || !crc_params || !ep) {
return -1000;
@@ -76,12 +76,13 @@ int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *secti
xmlTextWriterStartElement(writer, BAD_CAST "crc");
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "name", "%s", section_name);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "index", "%zu", index);
- if (elf_patch_get_section_address(ep, section_name, &vma, &len)) {
- print_err("Could not retrieve section address / length of section '%s'. XML output will be faulty.\n",
+ if (elf_patch_get_section_address(ep, section_name, &vma, &lma, &len)) {
+ print_err("Could not retrieve section addresses / length of section '%s'. XML output will be faulty.\n",
section_name);
ret |= -1;
}
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "vma", "0x%" PRIx64, vma);
+ xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "lma", "0x%" PRIx64, lma);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "size", "0x%" PRIx64, len);
xmlTextWriterWriteFormatRaw(writer, "0x%" PRIx32, crcs[index]);
xmlTextWriterEndElement(writer); /* End crc */