summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-09-27 06:49:48 +0000
committerRoland McGrath <roland@gnu.org>1995-09-27 06:49:48 +0000
commitea03559a9d4730f89105b6f5e674a0aaefc74b3b (patch)
tree103d2993e5d4eb971c2eec94c4c77a45abc8e2dc /elf
parentc709e372e8940b3f374b690d7eb7521e69ab4228 (diff)
Wed Sep 27 00:27:25 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* config.make.in (AS): New variable; set to `$(CC) -c'. * posix/unistd.h [__USE_BSD]: Declare profil. * elf/dl-load.c (_dl_map_object_from_fd): New function, broken out of _dl_map_object. (_dl_map_object): Call it. * elf/link.h (_dl_map_object_from_fd): Declare it.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-load.c83
-rw-r--r--elf/link.h6
2 files changed, 54 insertions, 35 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 6cacd3e3b6..7319602d81 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -108,40 +108,8 @@ _dl_map_object (struct link_map *loader, const char *name,
Elf32_Addr *entry_point)
{
int fd;
- struct link_map *l = NULL;
char *realname;
- const size_t pagesize = getpagesize ();
- void *file_mapping = NULL;
- size_t mapping_size = 0;
-
- void lose (int code, const char *msg)
- {
- (void) close (fd);
- if (file_mapping)
- munmap (file_mapping, mapping_size);
- _dl_signal_error (code, l ? l->l_name : name, msg);
- }
-
- /* 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 + pagesize - 1);
- mapping_size &= ~(pagesize - 1);
- result = mmap (file_mapping, mapping_size, PROT_READ,
- MAP_COPY|MAP_FILE, fd, 0);
- if (result == (void *) -1)
- lose (errno, "cannot map file data");
- file_mapping = result;
- }
- return file_mapping + location;
- }
-
- const Elf32_Ehdr *header;
+ struct link_map *l;
/* Look for this name among those already loaded. */
for (l = _dl_loaded; l; l = l->l_next)
@@ -182,7 +150,52 @@ _dl_map_object (struct link_map *loader, const char *name,
}
if (fd == -1)
- lose (errno, "cannot open shared object file");
+ _dl_signal_error (errno, name, "cannot open shared object file");
+
+ return _dl_map_object_from_fd (name, fd, realname, entry_point);
+}
+
+
+/* Map in the shared object NAME, actually located in REALNAME, and already
+ opened on FD. */
+
+struct link_map *
+_dl_map_object_from_fd (const char *name, int fd, char *realname,
+ Elf32_Addr *entry_point)
+{
+ struct link_map *l = NULL;
+ const size_t pagesize = getpagesize ();
+ void *file_mapping = NULL;
+ size_t mapping_size = 0;
+
+ void lose (int code, const char *msg)
+ {
+ (void) close (fd);
+ if (file_mapping)
+ munmap (file_mapping, mapping_size);
+ _dl_signal_error (code, l ? l->l_name : name, msg);
+ }
+
+ /* 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 + pagesize - 1);
+ mapping_size &= ~(pagesize - 1);
+ result = mmap (file_mapping, mapping_size, PROT_READ,
+ MAP_COPY|MAP_FILE, fd, 0);
+ if (result == (void *) -1)
+ lose (errno, "cannot map file data");
+ file_mapping = result;
+ }
+ return file_mapping + location;
+ }
+
+ const Elf32_Ehdr *header;
/* Look again to see if the real name matched another already loaded. */
for (l = _dl_loaded; l; l = l->l_next)
@@ -191,11 +204,11 @@ _dl_map_object (struct link_map *loader, const char *name,
/* The object is already loaded.
Just bump its reference count and return it. */
close (fd);
+ free (realname);
++l->l_opencount;
return l;
}
-
/* Map in the first page to read the header. */
header = map (0, sizeof *header);
diff --git a/elf/link.h b/elf/link.h
index 6f44a0cfdb..aacb3f1630 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -164,6 +164,12 @@ extern struct link_map *_dl_map_object (struct link_map *loader,
const char *name,
Elf32_Addr *entry_point);
+/* Similar, but file found at REALNAME and opened on FD.
+ REALNAME must malloc'd storage and is used in internal data structures. */
+extern struct link_map *_dl_map_object_from_fd (const char *name,
+ int fd, char *realname,
+ Elf32_Addr *entry_point);
+
/* Cache the locations of MAP's hash table. */
extern void _dl_setup_hash (struct link_map *map);