base: Name segments after their index
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Mon, 21 Oct 2019 13:40:40 +0000 (14:40 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 30 Oct 2019 09:15:04 +0000 (09:15 +0000)
Current loader is performing a linear scan of the section table for
every segment in the elf since it is naming every segment after the
sections it contains. With this patch we are just naming segments
after their index.
This is in any case how they are referenced when a readelf --segments
command is issued on the elf file.

Change-Id: I599400fcdfc0b80ac64632aba36781bd876777f0
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21999
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/base/loader/elf_object.cc
src/base/loader/elf_object.hh

index 33aa2d8d148ee0b6e252da2ce8628b32f9f2c695..bbaa27b70ae10cff73c923a27a186ce7f2d6e5f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2013 ARM Limited
+ * Copyright (c) 2011-2013, 2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -116,7 +116,7 @@ ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
         }
 
         if (phdr.p_type == PT_LOAD)
-            handleLoadableSegment(phdr);
+            handleLoadableSegment(phdr, i);
         if (phdr.p_type == PT_INTERP) {
             // Make sure the interpreter is an valid ELF file.
             char *interp_path = (char *)imageData->data() + phdr.p_offset;
@@ -253,36 +253,9 @@ ElfObject::determineOpSys()
 }
 
 void
-ElfObject::handleLoadableSegment(GElf_Phdr phdr)
+ElfObject::handleLoadableSegment(GElf_Phdr phdr, int seg_num)
 {
-    Addr mem_start = phdr.p_vaddr;
-    Addr mem_end = mem_start + phdr.p_memsz;
-    Addr file_start = phdr.p_offset;
-    Addr file_end = file_start + phdr.p_filesz;
-
-    std::string name;
-
-    // Name segments after the sections they contain.
-    Elf_Scn *section = elf_getscn(elf, 1);
-    for (int sec_idx = 1; section; section = elf_getscn(elf, ++sec_idx)) {
-        GElf_Shdr shdr;
-        gelf_getshdr(section, &shdr);
-        char *sec_name = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
-
-        if (!sec_name) {
-            Elf_Error errorNum = (Elf_Error)elf_errno();
-            if (errorNum != ELF_E_NONE) {
-                const char *errorMessage = elf_errmsg(errorNum);
-                fatal("Error from libelf: %s.\n", errorMessage);
-            }
-        }
-
-        if (shdr.sh_addr >= mem_start && shdr.sh_addr < mem_end) {
-            if (name != "")
-                name += ",";
-            name += sec_name;
-        }
-    }
+    auto name = std::to_string(seg_num);
 
     image.addSegment({ name, phdr.p_paddr, imageData,
                        phdr.p_offset, phdr.p_filesz });
@@ -296,12 +269,15 @@ ElfObject::handleLoadableSegment(GElf_Phdr phdr)
                            phdr.p_paddr + phdr.p_filesz, uninitialized });
     }
 
+    const Addr file_start = phdr.p_offset;
+    const Addr file_end = file_start + phdr.p_filesz;
+
     // If there is a program header table, figure out the virtual
     // address of the header table in the final memory image. We use
     // the program headers themselves to translate from a file offset
     // to the address in the image.
     if (file_start <= ehdr.e_phoff && file_end > ehdr.e_phoff)
-        _programHeaderTable = mem_start + (ehdr.e_phoff - file_start);
+        _programHeaderTable = phdr.p_vaddr + (ehdr.e_phoff - file_start);
 }
 
 ElfObject::~ElfObject()
index 42edc7438c4df725dc8a19d9e5debc0e0f9ce2ad..2cc2016fd9474da0303d059d1732d94b422d05d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013, 2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -63,7 +63,7 @@ class ElfObject : public ObjectFile
 
     void determineArch();
     void determineOpSys();
-    void handleLoadableSegment(GElf_Phdr phdr);
+    void handleLoadableSegment(GElf_Phdr phdr, int seg_num);
 
     // These values are provided to a linux process by the kernel, so we
     // need to keep them around.