]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
elf-from-memory: Refactor to get rid of nested function
authorTimm Bäder <tbaeder@redhat.com>
Fri, 8 Jan 2021 08:09:56 +0000 (09:09 +0100)
committerMark Wielaard <mark@klomp.org>
Thu, 28 Jan 2021 22:57:06 +0000 (23:57 +0100)
Try to unify the 32/64 bit code paths and get rid of the nested
handle_segment() this way.

Signed-off-by: Timm Bäder <tbaeder@redhat.com>
libdwfl/ChangeLog
libdwfl/elf-from-memory.c

index f17eafe78aca60c0cc0ad6e348b03d035083d917..5058f5f8c8ac7472fb209579ffa0273f3c133b2e 100644 (file)
@@ -1,3 +1,9 @@
+2021-01-08  Timm Bäder  <tbaeder@redhat.com>
+
+       * elf-from-memory.c (elf_from_remote_memory): Add for loop over
+       switch. inline handle_segment call, set vaddr, offset and filesz
+       directly based on class.
+
 2021-01-08  Timm Bäder  <tbaeder@redhat.com>
 
        * elf-from-memory.c (elf_from_remote_memory): Use if instead of
index 933ab8642290acf8d601eb88a8791b22097b905c..a0ef00146c0eb21296a4c3a40561dbd01cfcc045 100644 (file)
@@ -292,80 +292,65 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
       goto no_memory;
     }
 
-  switch (ehdr.e32.e_ident[EI_CLASS])
+  for (uint_fast16_t i = 0; i < phnum; ++i)
     {
-      /* Reads the given segment.  Returns true if reading fails,
-        false otherwise.  */
-      inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
-                                 GElf_Xword filesz)
-       {
-         GElf_Off start = offset & -pagesize;
-         GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
-         if (end > (GElf_Off) contents_size)
-           end = contents_size;
-         nread = (*read_memory) (arg, buffer + start,
-                                 (loadbase + vaddr) & -pagesize,
-                                 end - start, end - start);
-         return nread <= 0;
-       }
+      GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type;
 
-    case ELFCLASS32:
-      for (uint_fast16_t i = 0; i < phnum; ++i)
-       if ((*p32)[i].p_type == PT_LOAD)
-         if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
-                             (*p32)[i].p_filesz))
-           goto read_error;
-
-      /* If the segments visible in memory didn't include the section
-        headers, then clear them from the file header.  */
-      if (contents_size < shdrs_end)
-       {
-         ehdr.e32.e_shoff = 0;
-         ehdr.e32.e_shnum = 0;
-         ehdr.e32.e_shstrndx = 0;
-       }
+      if (type != PT_LOAD)
+        continue;
+
+      GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr;
+      GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset;
+      GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz;
+
+      GElf_Off start = offset & -pagesize;
+      GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
+      if (end > (GElf_Off) contents_size)
+        end = contents_size;
+      nread = (*read_memory) (arg, buffer + start,
+                              (loadbase + vaddr) & -pagesize,
+                              end - start, end - start);
+      if (nread <= 0)
+        goto read_error;
+    }
+
+  /* If the segments visible in memory didn't include the section
+     headers, then clear them from the file header.  */
+  if (contents_size < shdrs_end)
+    {
+      if (class32)
+        {
+          ehdr.e32.e_shoff = 0;
+          ehdr.e32.e_shnum = 0;
+          ehdr.e32.e_shstrndx = 0;
+        }
+      else
+        {
+          ehdr.e64.e_shoff = 0;
+          ehdr.e64.e_shnum = 0;
+          ehdr.e64.e_shstrndx = 0;
+        }
+    }
 
-      /* This will normally have been in the first PT_LOAD segment.  But it
-        conceivably could be missing, and we might have just changed it.  */
-      xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+  /* This will normally have been in the first PT_LOAD segment.  But it
+     conceivably could be missing, and we might have just changed it.  */
+  xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+  xlateto.d_buf = buffer;
+  if (class32)
+    {
       xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
       xlatefrom.d_buf = &ehdr.e32;
-      xlateto.d_buf = buffer;
       if (elf32_xlatetof (&xlateto, &xlatefrom,
-                         ehdr.e32.e_ident[EI_DATA]) == NULL)
-       goto libelf_error;
-      break;
-
-    case ELFCLASS64:
-      for (uint_fast16_t i = 0; i < phnum; ++i)
-       if ((*p64)[i].p_type == PT_LOAD)
-         if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
-                             (*p64)[i].p_filesz))
-           goto read_error;
-
-      /* If the segments visible in memory didn't include the section
-        headers, then clear them from the file header.  */
-      if (contents_size < shdrs_end)
-       {
-         ehdr.e64.e_shoff = 0;
-         ehdr.e64.e_shnum = 0;
-         ehdr.e64.e_shstrndx = 0;
-       }
-
-      /* This will normally have been in the first PT_LOAD segment.  But it
-        conceivably could be missing, and we might have just changed it.  */
-      xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+                          ehdr.e32.e_ident[EI_DATA]) == NULL)
+        goto libelf_error;
+    }
+  else
+    {
       xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
       xlatefrom.d_buf = &ehdr.e64;
-      xlateto.d_buf = buffer;
       if (elf64_xlatetof (&xlateto, &xlatefrom,
-                         ehdr.e64.e_ident[EI_DATA]) == NULL)
-       goto libelf_error;
-      break;
-
-    default:
-      abort ();
-      break;
+                          ehdr.e64.e_ident[EI_DATA]) == NULL)
+        goto libelf_error;
     }
 
   free (phdrsp);