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