:: commit 223a47b8e81e6c1513acb74974ca064c2b5eee7c

mintsuki <mintsuki@protonmail.com> — 2024-06-11 15:13

parents: 86a3dcd33b

lib/elf: Minor rework of dynamic segment parsing

diff --git a/common/lib/elf.c b/common/lib/elf.c
index 5811c3f9..a765c78e 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -345,6 +345,9 @@ static bool elf64_apply_relocations(uint8_t *elf, struct elf64_hdr *hdr, void *b
                     break;
                 case DT_SYMENT:
                     symtab_ent = dyn->d_un;
+                    if (symtab_ent < sizeof(struct elf64_sym)) {
+                        panic(true, "elf: symtab_ent < sizeof(struct elf64_sym)");
+                    }
                     break;
                 case DT_PLTREL:
                     dt_pltrel = dyn->d_un;
@@ -367,10 +370,6 @@ static bool elf64_apply_relocations(uint8_t *elf, struct elf64_hdr *hdr, void *b
 end_of_pt_segment:
 
     if (rela_offset != 0) {
-        if (rela_ent < sizeof(struct elf64_rela)) {
-            panic(true, "elf: rela_ent < sizeof(struct elf64_rela)");
-        }
-
         for (uint16_t i = 0; i < hdr->ph_num; i++) {
             struct elf64_phdr *_phdr = (void *)elf + (hdr->phoff + i * hdr->phdr_size);
 
@@ -383,10 +382,6 @@ end_of_pt_segment:
     }
 
     if (relr_offset != 0) {
-        if (relr_ent != 8) {
-            panic(true, "elf: relr_ent != 8");
-        }
-
         for (uint16_t i = 0; i < hdr->ph_num; i++) {
             struct elf64_phdr *_phdr = (void *)elf + (hdr->phoff + i * hdr->phdr_size);
 
@@ -399,10 +394,6 @@ end_of_pt_segment:
     }
 
     if (symtab_offset != 0) {
-        if (symtab_ent < sizeof(struct elf64_sym)) {
-            panic(true, "elf: symtab_ent < sizeof(struct elf64_sym)");
-        }
-
         for (uint16_t i = 0; i < hdr->ph_num; i++) {
             struct elf64_phdr *_phdr = (void *)elf + (hdr->phoff + i * hdr->phdr_size);
 
@@ -415,10 +406,6 @@ end_of_pt_segment:
     }
 
     if (dt_jmprel != 0) {
-        if (dt_pltrel != DT_RELA) {
-            panic(true, "elf: dt_pltrel != DT_RELA");
-        }
-
         for (uint16_t i = 0; i < hdr->ph_num; i++) {
             struct elf64_phdr *_phdr = (void *)elf + (hdr->phoff + i * hdr->phdr_size);
 
@@ -431,7 +418,10 @@ end_of_pt_segment:
     }
 
     size_t relocs_i = 0;
-    if (relr_offset != 0) {
+    if (relr_size != 0) {
+        if (relr_ent != 8) {
+            panic(true, "elf: relr_ent != 8");
+        }
         for (size_t i = 0; i < relr_size / relr_ent; i++) {
             uint64_t entry = *((uint64_t *)(elf + relr_offset + i * relr_ent));
 
@@ -443,15 +433,21 @@ end_of_pt_segment:
         }
     }
     size_t relr_count = relocs_i;
-    if (rela_offset != 0) {
+    if (rela_size != 0) {
+        if (rela_ent < sizeof(struct elf64_rela)) {
+            panic(true, "elf: rela_ent < sizeof(struct elf64_rela)");
+        }
         relocs_i += rela_size / rela_ent;
     }
-    if (dt_jmprel != 0) {
+    if (dt_pltrelsz != 0) {
+        if (dt_pltrel != DT_RELA) {
+            panic(true, "elf: dt_pltrel != DT_RELA");
+        }
         relocs_i += dt_pltrelsz / rela_ent;
     }
     struct elf64_rela **relocs = ext_mem_alloc(relocs_i * sizeof(struct elf64_rela *));
 
-    if (relr_offset != 0) {
+    if (relr_size != 0) {
         size_t relr_i;
         for (relr_i = 0; relr_i < relr_count; relr_i++) {
             relocs[relr_i] = ext_mem_alloc(sizeof(struct elf64_rela));
@@ -479,13 +475,13 @@ end_of_pt_segment:
         }
     }
 
-    if (rela_offset != 0) {
+    if (rela_size != 0) {
         for (uint64_t i = relr_count, offset = 0; offset < rela_size; offset += rela_ent) {
             relocs[i++] = (void *)elf + (rela_offset + offset);
         }
     }
 
-    if (dt_jmprel != 0) {
+    if (dt_pltrelsz != 0) {
         for (uint64_t i = relr_count + rela_size / rela_ent, offset = 0; offset < dt_pltrelsz; offset += rela_ent) {
             relocs[i++] = (void *)elf + (dt_jmprel + offset);
         }
tab: 248 wrap: offon