summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-05-07 00:00:48 +0000
committerUlrich Drepper <drepper@redhat.com>1999-05-07 00:00:48 +0000
commit7bcaca4384ad7234926730e9e2d90dae67d521bb (patch)
tree10781234adb41508ed57adb9956b5c6f9e0ac4a3 /elf
parent607c351a149e23617e14c8fd583fcb4f4e9d2aeb (diff)
downloadglibc-7bcaca4384ad7234926730e9e2d90dae67d521bb.tar.gz
glibc-7bcaca4384ad7234926730e9e2d90dae67d521bb.tar.xz
glibc-7bcaca4384ad7234926730e9e2d90dae67d521bb.zip
Update.
	* elf/link.h (struct link_map): New field l_phdr_allocated.
	* elf/dl-load.c (_dl_map_object_from_fd): Don't depend on having
	the program header being part of any loaded segment.  If it is not
	allocate memory and set l_phdr_allocated flag.
	* elf/dl-close.c (_dl_close): Free l_phdr if necessary.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c3
-rw-r--r--elf/dl-load.c34
-rw-r--r--elf/link.h3
3 files changed, 25 insertions, 15 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index d7a61c4535..6846f83a8d 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -165,6 +165,9 @@ _dl_close (struct link_map *map)
 	  if (imap != map && imap->l_searchlist.r_list != NULL)
 	    free (imap->l_searchlist.r_list);
 
+	  if (imap->l_phdr_allocated)
+	    free (imap->l_phdr);
+
 	  free (imap);
 	}
     }
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 6e8b977195..5ed5128ef5 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -917,6 +917,13 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 		       c->prot, MAP_FIXED, c->mapoff);
 
       postmap:
+	if (l->l_phdr == 0
+	    && c->mapoff <= header->e_phoff
+	    && (c->mapend - c->mapstart + c->mapoff
+		>= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr))))
+	  /* Found the program header in this segment.  */
+	  l->l_phdr = (void *) (c->mapstart + header->e_phoff - c->mapoff);
+
 	if (c->allocend > c->dataend)
 	  {
 	    /* Extra zero pages should appear at the end of this segment,
@@ -963,22 +970,19 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 	++c;
       }
 
-    if (l->l_phdr == 0)
+    if (l->l_phdr == NULL)
       {
-	/* There was no PT_PHDR specified.  We need to find the phdr in the
-           load image ourselves.  We assume it is in fact in the load image
-           somewhere.  */
-	for (c = loadcmds; c < &loadcmds[nloadcmds]; c++)
-	  if (c->mapoff <= header->e_phoff
-	      && (c->mapend - c->mapstart + c->mapoff
-		  >= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr))))
-	    {
-	      ElfW(Addr) bof = l->l_addr + c->mapstart;
-	      l->l_phdr = (void *) (bof + header->e_phoff - c->mapoff);
-	      break;
-	    }
-	if (l->l_phdr == 0)
-	  LOSE (0, "program headers not contained in any loaded segment");
+	/* The program header is not contained in any of the segmenst.
+	   We have to allocate memory ourself and copy it over from
+	   out temporary place.  */
+	ElfW(Phdr) *newp = (ElfW(Phdr) *) malloc (header->e_phnum
+						  * sizeof (ElfW(Phdr)));
+	if (newp == NULL)
+	  LOSE (ENOMEM, "cannot allocate memory for program header");
+
+	l->l_phdr = memcpy (newp, phdr,
+			    (header->e_phnum * sizeof (ElfW(Phdr))));
+	l->l_phdr_allocated = 1;
       }
     else
       /* Adjust the PT_PHDR value by the runtime load address.  */
diff --git a/elf/link.h b/elf/link.h
index 4abcb49070..5e9d7a8868 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -199,6 +199,9 @@ struct link_map
        object is the same as one already loaded.  */
     dev_t l_dev;
     ino_t l_ino;
+
+    /* Nonzero if the data structure pointed to by `l_phdr' is allocated.  */
+    int l_phdr_allocated;
   };
 
 #endif /* link.h */