diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | config.make.in | 1 | ||||
-rw-r--r-- | elf/dl-load.c | 83 | ||||
-rw-r--r-- | elf/link.h | 6 | ||||
-rw-r--r-- | posix/unistd.h | 9 |
5 files changed, 75 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog index bd0651bf8f..2865f35eff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +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. + Tue Sep 26 16:50:17 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * locale/libintl.h: Rewritten by Ulrich Drepper for use with GNU diff --git a/config.make.in b/config.make.in index 652f10ec13..69d4fcbdea 100644 --- a/config.make.in +++ b/config.make.in @@ -29,6 +29,7 @@ build-omitfp = @omitfp@ CC = @CC@ AR = @AR@ RANLIB = @RANLIB@ +AS = $(CC) -c # Installation tools. INSTALL = @INSTALL@ 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); diff --git a/posix/unistd.h b/posix/unistd.h index eda44c96be..846653c75c 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -568,6 +568,15 @@ extern int vhangup __P ((void)); extern int revoke __P ((const char *__file)); +/* Enable statistical profiling, writing samples of the PC into at most + SIZE bytes of SAMPLE_BUFFER; every processor clock tick while profiling + is enabled, the system examines the user PC and increments + SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536]. If SCALE is zero, + disable profiling. Returns zero on success, -1 on error. */ +extern int profil __P ((unsigned short int *__sample_buffer, size_t __size, + size_t __offset, unsigned int __scale)); + + /* Turn accounting on if NAME is an existing file. The system will then write a record for each process as it terminates, to this file. If NAME is NULL, turn accounting off. This call is restricted to the super-user. */ |