diff options
author | Ulrich Drepper <drepper@redhat.com> | 1999-05-07 00:00:48 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1999-05-07 00:00:48 +0000 |
commit | 7bcaca4384ad7234926730e9e2d90dae67d521bb (patch) | |
tree | 10781234adb41508ed57adb9956b5c6f9e0ac4a3 /elf | |
parent | 607c351a149e23617e14c8fd583fcb4f4e9d2aeb (diff) | |
download | glibc-7bcaca4384ad7234926730e9e2d90dae67d521bb.zip glibc-7bcaca4384ad7234926730e9e2d90dae67d521bb.tar.gz glibc-7bcaca4384ad7234926730e9e2d90dae67d521bb.tar.bz2 |
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.c | 3 | ||||
-rw-r--r-- | elf/dl-load.c | 34 | ||||
-rw-r--r-- | elf/link.h | 3 |
3 files changed, 25 insertions, 15 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c index d7a61c4..6846f83 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 6e8b977..5ed5128 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. */ @@ -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 */ |