aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-load.c')
-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;