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