Currently the elf exectuable header pointer is global in elflink.c, but
passes as a parameter to parse_phdrs(). The only other user of ehdr is
the extracopy code. We run this code at prepare-time, but there is no
reason it couldn't be done at parse-time. This patch makes exactly this
change. This requires moving the parse_phdrs() function (the majority of
this patch) to avoid foward declarations. The only performance
implication of this, that I can see, is that we now will call
get_extracopy() unconditionally, whereas before we would not do prepare
(and thus not extracopy) for shared segments. Since get_extracopy() only
does parsing, though, I think this should be ok (extra work may be done
in DEBUG=yes mode, but that's not performance-critical).

Signed-off-by: Nishanth Aravamudan <[EMAIL PROTECTED]>
---
 elflink.c |  117 +++++++++++++++++++++++++++++-------------------------------
 1 files changed, 57 insertions(+), 60 deletions(-)

diff --git a/elflink.c b/elflink.c
index 9e4f6a0..6399b9f 100644
--- a/elflink.c
+++ b/elflink.c
@@ -198,7 +198,6 @@ static int htlb_num_segs;
 static int minimal_copy = 1;
 static int sharing; /* =0 */
 int __debug = 0;
-static Elf_Ehdr *ehdr;
 
 /**
  * assemble_path - handy wrapper around snprintf() for building paths
@@ -232,57 +231,6 @@ static void assemble_path(char *dst, const char *fmt, ...)
        }
 }
 
-/*
- * Parse an ELF header and record segment information for any segments
- * which contain hugetlb information.
- */
-
-static void parse_phdrs(Elf_Ehdr *ehdr)
-{
-       Elf_Phdr *phdr = (Elf_Phdr *)((char *)ehdr + ehdr->e_phoff);
-       int i;
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               unsigned long vaddr, filesz, memsz;
-               int prot = 0;
-
-               if (phdr[i].p_type != PT_LOAD)
-                       continue;
-
-               if (! (phdr[i].p_flags & PF_LINUX_HUGETLB))
-                       continue;
-
-               if (htlb_num_segs >= MAX_HTLB_SEGS) {
-                       ERROR("Executable has too many segments marked for "
-                             "hugepage (max %d)\n", MAX_HTLB_SEGS);
-                       htlb_num_segs = 0;
-                       return;
-               }
-
-               vaddr = phdr[i].p_vaddr;
-               filesz = phdr[i].p_filesz;
-               memsz = phdr[i].p_memsz;
-               if (phdr[i].p_flags & PF_R)
-                       prot |= PROT_READ;
-               if (phdr[i].p_flags & PF_W)
-                       prot |= PROT_WRITE;
-               if (phdr[i].p_flags & PF_X)
-                       prot |= PROT_EXEC;
-
-               DEBUG("Hugepage segment %d "
-                       "(phdr %d): %#0lx-%#0lx  (filesz=%#0lx) "
-                       "(prot = %#0x)\n",
-                       htlb_num_segs, i, vaddr, vaddr+memsz, filesz, prot);
-
-               htlb_seg_table[htlb_num_segs].vaddr = (void *)vaddr;
-               htlb_seg_table[htlb_num_segs].filesz = filesz;
-               htlb_seg_table[htlb_num_segs].memsz = memsz;
-               htlb_seg_table[htlb_num_segs].prot = prot;
-               htlb_seg_table[htlb_num_segs].phdr = i;
-               htlb_num_segs++;
-       }
-}
-
 /**
  * find_or_create_share_path - obtain a directory to store the shared
  * hugetlbfs files
@@ -406,13 +354,11 @@ static int get_shared_file_name(struct seg_info 
*htlb_seg_info, char *file_path)
 }
 
 /* Find the .dynamic program header */
-static int find_dynamic(Elf_Dyn **dyntab)
+static int find_dynamic(Elf_Dyn **dyntab, Elf_Phdr *phdr, int phnum)
 {
-       Elf_Phdr *phdr; /* program header table */
        int i = 1;
 
-       phdr = (Elf_Phdr *)((char *)ehdr + ehdr->e_phoff);
-       while ((phdr[i].p_type != PT_DYNAMIC) && (i < ehdr->e_phnum)) {
+       while ((phdr[i].p_type != PT_DYNAMIC) && (i < phnum)) {
                ++i;
        }
        if (phdr[i].p_type == PT_DYNAMIC) {
@@ -497,7 +443,7 @@ static inline int keep_symbol(Elf_Sym *s, void *start, void 
*end)
  * include these initialized variables in our copy.
  */
 
-static void get_extracopy(struct seg_info *seg)
+static void get_extracopy(struct seg_info *seg, Elf_Phdr *phdr, int phnum)
 {
        Elf_Dyn *dyntab;        /* dynamic segment table */
        Elf_Sym *symtab = NULL; /* dynamic symbol table */
@@ -515,7 +461,7 @@ static void get_extracopy(struct seg_info *seg)
                goto bail2;
 
        /* Find dynamic program header */
-       ret = find_dynamic(&dyntab);
+       ret = find_dynamic(&dyntab, phdr, phnum);
        if (ret < 0)
                goto bail;
 
@@ -573,6 +519,58 @@ bail2:
 }
 
 /*
+ * Parse an ELF header and record segment information for any segments
+ * which contain hugetlb information.
+ */
+static void parse_phdrs(Elf_Ehdr *ehdr)
+{
+       Elf_Phdr *phdr = (Elf_Phdr *)((char *)ehdr + ehdr->e_phoff);
+       int i;
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               unsigned long vaddr, filesz, memsz;
+               int prot = 0;
+
+               if (phdr[i].p_type != PT_LOAD)
+                       continue;
+
+               if (! (phdr[i].p_flags & PF_LINUX_HUGETLB))
+                       continue;
+
+               if (htlb_num_segs >= MAX_HTLB_SEGS) {
+                       ERROR("Executable has too many segments marked for "
+                             "hugepage (max %d)\n", MAX_HTLB_SEGS);
+                       htlb_num_segs = 0;
+                       return;
+               }
+
+               vaddr = phdr[i].p_vaddr;
+               filesz = phdr[i].p_filesz;
+               memsz = phdr[i].p_memsz;
+               if (phdr[i].p_flags & PF_R)
+                       prot |= PROT_READ;
+               if (phdr[i].p_flags & PF_W)
+                       prot |= PROT_WRITE;
+               if (phdr[i].p_flags & PF_X)
+                       prot |= PROT_EXEC;
+
+               DEBUG("Hugepage segment %d "
+                       "(phdr %d): %#0lx-%#0lx  (filesz=%#0lx) "
+                       "(prot = %#0x)\n",
+                       htlb_num_segs, i, vaddr, vaddr+memsz, filesz, prot);
+
+               htlb_seg_table[htlb_num_segs].vaddr = (void *)vaddr;
+               htlb_seg_table[htlb_num_segs].filesz = filesz;
+               htlb_seg_table[htlb_num_segs].memsz = memsz;
+               htlb_seg_table[htlb_num_segs].prot = prot;
+               htlb_seg_table[htlb_num_segs].phdr = i;
+               get_extracopy(&htlb_seg_table[htlb_num_segs], phdr,
+                                                       ehdr->e_phnum);
+               htlb_num_segs++;
+       }
+}
+
+/*
  * Copy a program segment into a huge page. If possible, try to copy the
  * smallest amount of data possible, unless the user disables this 
  * optimization via the HUGETLB_ELFMAP environment variable.
@@ -588,7 +586,6 @@ static int prepare_segment(struct seg_info *seg)
         * Calculate the BSS size that we must copy in order to minimize
         * the size of the shared mapping.
         */
-       get_extracopy(seg);
        if (seg->extra_vaddr) {
                size = ALIGN((unsigned long)seg->extra_vaddr +
                                seg->extrasz - (unsigned long)seg->vaddr,
@@ -939,7 +936,7 @@ static int check_env(void)
 static void __attribute__ ((constructor)) setup_elflink(void)
 {
        extern Elf_Ehdr __executable_start __attribute__((weak));
-       ehdr = &__executable_start;
+       Elf_Ehdr *ehdr = &__executable_start;
        int ret, i;
 
        if (! ehdr) {

-- 
Nishanth Aravamudan <[EMAIL PROTECTED]>
IBM Linux Technology Center

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libhugetlbfs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to