On Mon, 2007-02-12 at 20:48 -0800, Nishanth Aravamudan wrote:
> On 13.02.2007 [15:24:26 +1100], David Gibson wrote:
> > 
> > Hrm.  The later functions that need the data from find_dynamic() take
> > the seg_info table.  The idea is that the seg_info table provides all
> > the necessary info for remapping the segments later, so we can avoid
> > passing ehdr around by moving the parsing of the extracopy information
> > to parse_phdrs() and storing it in the seg_info table.
> 
> That's probably a good idea. I can make that part of the "store
> extracopy information" patch stack, Steve, if you want to try and base
> such a patch off of those?

Sorry for the delay. Here's the requested patch.

elflink: Move ELF header pointer from a global into seg_info struct.

Signed-off-by: Steve Fox <[EMAIL PROTECTED]>

---

diff --git a/elflink.c b/elflink.c
index 9e4f6a0..0c8ec0c 100644
--- a/elflink.c
+++ b/elflink.c
@@ -191,6 +191,7 @@ struct seg_info {
        int prot;
        int fd;
        int phdr;
+       Elf_Ehdr *ehdr;
 };
 
 static struct seg_info htlb_seg_table[MAX_HTLB_SEGS];
@@ -198,7 +199,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 +232,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,7 +355,7 @@ 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_Ehdr *ehdr, Elf_Dyn **dyntab)
 {
        Elf_Phdr *phdr; /* program header table */
        int i = 1;
@@ -515,7 +464,7 @@ static void get_extracopy(struct seg_info *seg)
                goto bail2;
 
        /* Find dynamic program header */
-       ret = find_dynamic(&dyntab);
+       ret = find_dynamic(seg->ehdr, &dyntab);
        if (ret < 0)
                goto bail;
 
@@ -573,6 +522,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].ehdr = ehdr;
+               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++;
+       }
+}
+
+/*
  * 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.
@@ -939,7 +940,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) {

-- 

Steve Fox
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