about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-05-21 15:30:48 +0000
committerUlrich Drepper <drepper@redhat.com>1998-05-21 15:30:48 +0000
commit32c85e43ed25cc954cb9ba62a6aad7c9338a2a08 (patch)
tree53559a6958b3f3ae625eb275a11334c9498d9436
parentc9a673763639234fc03360fa93a55b946abe6489 (diff)
downloadglibc-32c85e43ed25cc954cb9ba62a6aad7c9338a2a08.tar.gz
glibc-32c85e43ed25cc954cb9ba62a6aad7c9338a2a08.tar.xz
glibc-32c85e43ed25cc954cb9ba62a6aad7c9338a2a08.zip
(_dl_map_object_from_fd): Get file header with read instead of mmap.
-rw-r--r--elf/dl-load.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 5a70dec85c..e67ade2d59 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -107,6 +107,10 @@ static size_t ncapstr;
 static size_t max_capstrlen;
 
 
+/* This function has no public prototype.  */
+extern ssize_t __libc_read (int, void *, size_t);
+
+
 /* Local version of `strdup' function.  */
 static inline char *
 local_strdup (const char *s)
@@ -497,15 +501,11 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
 			struct link_map *loader, int l_type)
 {
   struct link_map *l = NULL;
-  void *file_mapping = NULL;
-  size_t mapping_size = 0;
 
 #define LOSE(s) lose (0, (s))
   void lose (int code, const char *msg)
     {
       (void) __close (fd);
-      if (file_mapping)
-	__munmap (file_mapping, mapping_size);
       if (l)
 	{
 	  /* Remove the stillborn object from the list and free it.  */
@@ -532,30 +532,13 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
       return mapat;
     }
 
-  /* Make sure LOCATION is mapped in.  */
-  void *map (off_t location, size_t size)
-    {
-      if ((off_t) mapping_size <= location + (off_t) size)
-	{
-	  void *result;
-	  if (file_mapping)
-	    __munmap (file_mapping, mapping_size);
-	  mapping_size = (location + size + 1 + _dl_pagesize - 1);
-	  mapping_size &= ~(_dl_pagesize - 1);
-	  result = __mmap (file_mapping, mapping_size, PROT_READ,
-			   MAP_COPY|MAP_FILE, fd, 0);
-	  if (result == MAP_FAILED)
-	    lose (errno, "cannot map file data");
-	  file_mapping = result;
-	}
-      return file_mapping + location;
-    }
-
   const ElfW(Ehdr) *header;
   const ElfW(Phdr) *phdr;
   const ElfW(Phdr) *ph;
   size_t maplength;
   int type;
+  char *readbuf;
+  ssize_t readlength;
 
   /* Look again to see if the real name matched another already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
@@ -577,8 +560,12 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
   if (_dl_debug_files)
     _dl_debug_message (1, "file=", name, ";  generating link map\n", NULL);
 
-  /* Map in the first page to read the header.  */
-  header = map (0, sizeof *header);
+  /* Read the header directly.  */
+  readbuf = alloca (_dl_pagesize);
+  readlength = __libc_read (fd, readbuf, _dl_pagesize);
+  if (readlength < sizeof(*header))
+    lose (errno, "cannot read file data");
+  header = (void *) readbuf;
 
   /* Check the header for basic validity.  */
   if (*(Elf32_Word *) &header->e_ident !=
@@ -631,11 +618,21 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
   l->l_loader = loader;
 
   /* Extract the remaining details we need from the ELF header
-     and then map in the program header table.  */
+     and then read in the program header table.  */
   l->l_entry = header->e_entry;
   type = header->e_type;
   l->l_phnum = header->e_phnum;
-  phdr = map (header->e_phoff, l->l_phnum * sizeof (ElfW(Phdr)));
+
+  maplength = header->e_phnum * sizeof (ElfW(Phdr));
+  if (header->e_phoff + maplength <= readlength)
+    phdr = (void *) (readbuf + header->e_phoff);
+  else
+    {
+      phdr = alloca (maplength);
+      __lseek (fd, SEEK_SET, header->e_phoff);
+      if (__libc_read (fd, (void *) phdr, maplength) != maplength)
+        lose (errno, "cannot read file data");
+    }
 
   {
     /* Scan the program header table, collecting its load commands.  */
@@ -689,9 +686,6 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
 	  }
 	}
 
-    /* We are done reading the file's headers now.  Unmap them.  */
-    __munmap (file_mapping, mapping_size);
-
     /* Now process the load commands and map segments into memory.  */
     c = loadcmds;