diff options
| author | Roland McGrath <roland@gnu.org> | 1995-05-08 09:11:25 +0000 |
|---|---|---|
| committer | Roland McGrath <roland@gnu.org> | 1995-05-08 09:11:25 +0000 |
| commit | 421f82e5cc8f81ab003247d771bcecbad799be85 (patch) | |
| tree | 6d2e888aa32ba05854b1bd793b903cd0eb755bc4 | |
| parent | 0fb807c1dbb08de4408c440c2db490b52bd16f57 (diff) | |
| download | glibc-421f82e5cc8f81ab003247d771bcecbad799be85.tar.xz glibc-421f82e5cc8f81ab003247d771bcecbad799be85.zip | |
Sat May 6 11:06:47 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* Makeconfig (+gccwarn): Add -Winline.
* hurd/hurdsig.c (_hurd_internal_post_signal): If SS->context is
set, avoid abort_rpcs, and use reply and intr ports saved in
SS->context.
* sysdeps/mach/hurd/i386/trampoline.c: Don't set SS->intr_port
from SS->context. Don't clear SS->context.
* sysdeps/mach/hurd/i386/sigreturn.c: Don't set SS->intr_port when
setting SS->context. If msg_sig_post returns, re-lock and clear
SS->context.
Fri May 5 10:37:09 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* mach/Makefile (errsystems.c): Comment out generation rule.
* sysdeps/mach/_strerror.c: Consider a system unknown if its
bad_sub member is null.
* mach/mig-alloc.c: Add weak alias to non-__ name.
| -rw-r--r-- | ChangeLog | 22 | ||||
| -rw-r--r-- | Makeconfig | 2 | ||||
| -rw-r--r-- | elf/dl-error.c | 13 | ||||
| -rw-r--r-- | elf/dl-load.c | 38 | ||||
| -rw-r--r-- | elf/dl-lookup.c | 5 | ||||
| -rw-r--r-- | elf/dl-object.c | 3 | ||||
| -rw-r--r-- | elf/dl-reloc.c | 9 | ||||
| -rw-r--r-- | elf/dlclose.c | 2 | ||||
| -rw-r--r-- | elf/dlerror.c | 57 | ||||
| -rw-r--r-- | elf/dlsym.c | 2 | ||||
| -rw-r--r-- | elf/do-rel.h | 68 | ||||
| -rw-r--r-- | elf/dynamic-link.h | 105 | ||||
| -rw-r--r-- | elf/link.h | 26 | ||||
| -rw-r--r-- | elf/rtld.c | 268 | ||||
| -rw-r--r-- | hurd/hurdsig.c | 113 | ||||
| -rw-r--r-- | mach/Makefile | 4 | ||||
| -rw-r--r-- | sysdeps/i386/dl-machine.h | 37 | ||||
| -rw-r--r-- | sysdeps/i386/dl-runtime.c | 9 | ||||
| -rw-r--r-- | sysdeps/mach/_strerror.c | 6 | ||||
| -rw-r--r-- | sysdeps/mach/hurd/getdtsz.c | 7 | ||||
| -rw-r--r-- | sysdeps/mach/hurd/i386/sigreturn.c | 10 | ||||
| -rw-r--r-- | sysdeps/mach/hurd/i386/trampoline.c | 18 |
22 files changed, 470 insertions, 354 deletions
@@ -1,3 +1,25 @@ +Sat May 6 11:06:47 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Makeconfig (+gccwarn): Add -Winline. + + * hurd/hurdsig.c (_hurd_internal_post_signal): If SS->context is + set, avoid abort_rpcs, and use reply and intr ports saved in + SS->context. + * sysdeps/mach/hurd/i386/trampoline.c: Don't set SS->intr_port + from SS->context. Don't clear SS->context. + * sysdeps/mach/hurd/i386/sigreturn.c: Don't set SS->intr_port when + setting SS->context. If msg_sig_post returns, re-lock and clear + SS->context. + +Fri May 5 10:37:09 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * mach/Makefile (errsystems.c): Comment out generation rule. + + * sysdeps/mach/_strerror.c: Consider a system unknown if its + bad_sub member is null. + + * mach/mig-alloc.c: Add weak alias to non-__ name. + Wed May 3 11:56:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * sysdeps/mach/hurd/dup2.c: Fixed broken test in last change. diff --git a/Makeconfig b/Makeconfig index 823b7f44f1..cb3c065ddc 100644 --- a/Makeconfig +++ b/Makeconfig @@ -272,7 +272,7 @@ RANLIB = ranlib endif # Extra flags to pass to GCC. -+gccwarn := -Wall -Wwrite-strings -Wno-parentheses ++gccwarn := -Wall -Wwrite-strings -Wno-parentheses -Winline # This is the program that generates makefile # dependencies from C source files. diff --git a/elf/dl-error.c b/elf/dl-error.c index b9ee3516b5..5f8e4e4088 100644 --- a/elf/dl-error.c +++ b/elf/dl-error.c @@ -22,23 +22,28 @@ Cambridge, MA 02139, USA. */ #include <setjmp.h> static jmp_buf catch_env; -static const char *signalled_errstring; +static const char *signalled_errstring, *signalled_objname; void -_dl_signal_error (int errcode, const char *errstring) +_dl_signal_error (int errcode, + const char *objname, + const char *errstring) { signalled_errstring = errstring ?: "DYNAMIC LINKER BUG!!!"; longjmp (catch_env, errcode ?: -1); } int -_dl_catch_error (const char **errstring, void (*operate) (void)) +_dl_catch_error (const char **errstring, + const char **objname, + void (*operate) (void)) { int errcode; - signalled_errstring = NULL; + signalled_errstring = signalled_objname = NULL; errcode = setjmp (catch_env); (*operate) (); *errstring = signalled_errstring; + *objname = signalled_objname; return *errstring ? errcode : 0; } diff --git a/elf/dl-load.c b/elf/dl-load.c index 0de7404a80..f8b37ba346 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -107,10 +107,20 @@ _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) { @@ -124,14 +134,13 @@ _dl_map_object (struct link_map *loader, const char *name, result = mmap (file_mapping, mapping_size, PROT_READ, MAP_COPY|MAP_FILE, fd, 0); if (result == (void *) -1) - return NULL; + 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) @@ -170,7 +179,7 @@ _dl_map_object (struct link_map *loader, const char *name, } if (fd == -1) - return NULL; + lose (errno, "cannot open shared object file"); /* Look again to see if the real name matched another already loaded. */ for (l = _dl_loaded; l; l = l->l_next) @@ -186,17 +195,9 @@ _dl_map_object (struct link_map *loader, const char *name, /* Map in the first page to read the header. */ header = map (0, sizeof *header); - if (! header) - { - lose: - (void) close (fd); - if (file_mapping) - munmap (file_mapping, mapping_size); - return NULL; - } #undef LOSE -#define LOSE(s) _dl_signal_error (0, s) +#define LOSE(s) lose (0, (s)) /* Check the header for basic validity. */ if (*(Elf32_Word *) &header->e_ident != ((ELFMAG0 << (EI_MAG0 * 8)) | (ELFMAG1 << (EI_MAG1 * 8)) | @@ -224,7 +225,7 @@ _dl_map_object (struct link_map *loader, const char *name, { _dl_zerofd = _dl_sysdep_open_zero_fill (); if (_dl_zerofd == -1) - _dl_signal_error (errno, "cannot open zero fill device"); + _dl_signal_error (errno, NULL, "cannot open zero fill device"); } { @@ -235,8 +236,6 @@ _dl_map_object (struct link_map *loader, const char *name, int anywhere; ph = map (header->e_phoff, header->e_phnum * sizeof (Elf32_Phdr)); - if (! ph) - goto lose; memcpy (phdr, ph, sizeof phdr); l->l_phnum = header->e_phnum; @@ -288,7 +287,8 @@ _dl_map_object (struct link_map *loader, const char *name, { /* XXX this loses if the first segment mmap call puts it someplace where the later segments cannot fit. */ - mapat = mmap ((caddr_t) l->l_addr + mapstart, mapend - mapstart, + mapat = mmap ((caddr_t) (l->l_addr + mapstart), + mapend - mapstart, prot, MAP_COPY|MAP_FILE|MAP_INHERIT | /* Let the system choose any convenient location if this is the first segment. @@ -312,8 +312,7 @@ _dl_map_object (struct link_map *loader, const char *name, l->l_addr = 0; } if (mapat == (caddr_t) -1) - _dl_signal_error (errno, - "failed to map region from shared object"); + lose (errno, "failed to map segment from shared object"); if (ph->p_memsz > ph->p_filesz) { @@ -341,8 +340,7 @@ _dl_map_object (struct link_map *loader, const char *name, & ~(pagesize - 1)), pagesize, prot|PROT_WRITE) < 0) - _dl_signal_error (errno, - "cannot change protections"); + lose (errno, "cannot change memory protections"); } memset (zero, 0, zeroend - zero); if ((prot & PROT_WRITE) == 0) diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index b4600b1970..a7afcc79bb 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -27,7 +27,8 @@ Cambridge, MA 02139, USA. */ Elf32_Addr _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, - struct link_map *symbol_scope) + struct link_map *symbol_scope, + const char *reference_name) { unsigned long int hash = elf_hash (undef_name); struct link_map *map; @@ -106,7 +107,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, char buf[sizeof msg + strlen (undef_name)]; memcpy (buf, msg, sizeof msg - 1); memcpy (&buf[sizeof msg - 1], undef_name, sizeof buf - sizeof msg); - _dl_signal_error (0, msg); + _dl_signal_error (0, reference_name, msg); } *ref = weak_value.s; diff --git a/elf/dl-object.c b/elf/dl-object.c index e7b1ce3f45..ca4e785be3 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -37,7 +37,8 @@ _dl_new_object (char *realname, const char *libname, int type) { struct link_map *new = malloc (sizeof *new); if (! new) - _dl_signal_error (ENOMEM, "can't open new object"); + _dl_signal_error (ENOMEM, libname, + "cannot allocate shared object descriptor"); memset (new, 0, sizeof *new); new->l_name = realname; diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 8efb3f04a6..94ffb71759 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -48,7 +48,7 @@ _dl_relocate_object (struct link_map *l, int lazy) & ~(pagesize - 1))); if (mprotect (mapstart, mapend - mapstart, PROT_READ|PROT_WRITE) < 0) - _dl_signal_error (errno, + _dl_signal_error (errno, l->l_name, "cannot make segment writable for relocation"); } } @@ -62,7 +62,8 @@ _dl_relocate_object (struct link_map *l, int lazy) Elf32_Addr resolve (const Elf32_Sym **ref) { - return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope); + return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, + l->l_name); } real_next = l->l_next; @@ -75,7 +76,7 @@ _dl_relocate_object (struct link_map *l, int lazy) else scope = _dl_loaded; - elf_dynamic_relocate (l->l_info, l->l_addr, lazy, resolve); + ELF_DYNAMIC_RELOCATE (l, lazy, resolve); /* Restore list frobnication done above for DT_SYMBOLIC. */ l->l_next = real_next; @@ -107,7 +108,7 @@ _dl_relocate_object (struct link_map *l, int lazy) if (ph->p_flags & PF_X) prot |= PROT_EXEC; if (mprotect (mapstart, mapend - mapstart, prot) < 0) - _dl_signal_error (errno, + _dl_signal_error (errno, l->l_name, "can't restore segment prot after reloc"); } } diff --git a/elf/dlclose.c b/elf/dlclose.c index 4aa4085f66..06b2d1bdcd 100644 --- a/elf/dlclose.c +++ b/elf/dlclose.c @@ -24,7 +24,7 @@ Cambridge, MA 02139, USA. */ #include <sys/mman.h> -#define LOSE(s) _dl_signal_error (0, s) +#define LOSE(s) _dl_signal_error (0, map->l_name, s) int dlclose (void *handle) diff --git a/elf/dlerror.c b/elf/dlerror.c index 0eed60a45d..4ec5037de4 100644 --- a/elf/dlerror.c +++ b/elf/dlerror.c @@ -23,42 +23,49 @@ Cambridge, MA 02139, USA. */ #include <string.h> #include <stdlib.h> -static int _dl_last_errcode; -static const char *_dl_last_errstring; +static int last_errcode; +static const char *last_errstring; +static const char *last_object_name; char * dlerror (void) { - char *ret; + static char *buf; + char *ret; - if (! _dl_last_errstring) - return NULL; - - if (_dl_last_errcode) + if (buf) { - static char *buf; - if (buf) - { - free (buf); - buf = NULL; - } - if (asprintf (&buf, "%s: %s", - _dl_last_errstring, strerror (_dl_last_errcode)) == -1) - return NULL; - else - ret = buf; + free (buf); + buf = NULL; } - else - ret = (char *) _dl_last_errstring; - /* Reset the error indicator. */ - _dl_last_errstring = NULL; - return ret; + if (! last_errstring) + return NULL; + + if (last_errcode == 0 && ! last_object_name) + ret = (char *) last_errstring; + else if (last_errcode == 0) + ret = (asprintf (&buf, "%s: %s", last_object_name, last_errstring) == -1 + ? NULL : buf); + else if (! last_object_name) + ret = (asprintf (&buf, "%s: %s", + last_errstring, strerror (last_errcode)) == -1 + ? NULL : buf); + else + ret = (asprintf (&buf, "%s: %s: %s", + last_object_name, last_errstring, + strerror (last_errcode)) == -1 + ? NULL : buf); + + /* Reset the error indicator. */ + last_errstring = NULL; + return ret; } int _dlerror_run (void (*operate) (void)) { - _dl_last_errcode = _dl_catch_error (&_dl_last_errstring, operate); - return _dl_last_errstring != NULL; + last_errcode = _dl_catch_error (&last_errstring, &last_object_name, + operate); + return last_errstring != NULL; } diff --git a/elf/dlsym.c b/elf/dlsym.c index 6d8781053b..3e10812da8 100644 --- a/elf/dlsym.c +++ b/elf/dlsym.c @@ -33,7 +33,7 @@ dlsym (void *handle, const char *name) void doit (void) { const Elf32_Sym *ref = NULL; - value = _dl_lookup_symbol (name, &ref, map); + value = _dl_lookup_symbol (name, map->l_name, &ref, map); } /* Confine the symbol scope to just this map. */ diff --git a/elf/do-rel.h b/elf/do-rel.h new file mode 100644 index 0000000000..04643e8fac --- /dev/null +++ b/elf/do-rel.h @@ -0,0 +1,68 @@ +/* Do relocations for ELF dynamic linking. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file may be included twice, to define both + `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ + +#ifdef DO_RELA +#define elf_dynamic_do_rel elf_dynamic_do_rela +#define Elf32_Rel Elf32_Rela +#define elf_machine_rel elf_machine_rela +#endif + + +/* Perform the relocations in MAP on the running program image as specified + by RELTAG, SZTAG. *RESOLVE is called to resolve symbol values; it + modifies its argument pointer to point to the defining symbol, and + returns the base load address of the defining object. */ + +static inline void +elf_dynamic_do_rel (struct link_map *map, + int reltag, int sztag, + Elf32_Addr (*resolve) (const Elf32_Sym **)) +{ + const Elf32_Sym *const symtab + = (const Elf32_Sym *) map->l_info[DT_SYMTAB]->d_un.d_ptr; + const Elf32_Rel *r = (const Elf32_Rel *) map->l_info[reltag]->d_un.d_ptr; + const Elf32_Rel *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r]; + + for (; r < end; ++r) + { + const Elf32_Sym *definer = &symtab[ELF32_R_SYM (r->r_info)]; + Elf32_Addr loadbase; + + if (ELF32_R_SYM (r->r_info) == STN_UNDEF) + loadbase = 0; /* This value will not be consulted. */ + else + { + if (resolve) + loadbase = (*resolve) (&definer); + else + { + assert (definer->st_shndx != SHN_UNDEF); + loadbase = map->l_addr; + } + } + elf_machine_rel (map, r, loadbase, definer); + } +} + +#undef elf_dynamic_do_rel +#undef Elf32_Rel +#undef elf_machine_rel diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 1c3af29d6a..fc5c585356 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -18,23 +18,10 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <elf.h> - -/* This machine-dependent file defines these inline functions. */ - -static void elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM], - const Elf32_Rel *reloc, - Elf32_Addr sym_loadaddr, const Elf32_Sym *sym); -static void elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM], - const Elf32_Rela *reloc, - Elf32_Addr sym_loadaddr, const Elf32_Sym *sym); -static Elf32_Addr *elf_machine_got (void); -static Elf32_Addr elf_machine_load_address (void); - #include <dl-machine.h> - - #include <assert.h> + /* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ static inline void @@ -60,60 +47,36 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM]) info[DT_PLTREL]->d_un.d_val == DT_RELA); } -/* Perform the relocations specified by DYNAMIC on the running program - image. If LAZY is nonzero, don't relocate PLT entries. *RESOLVE is - called to resolve symbol values; it modifies its argument pointer to - point to the defining symbol, and returns the base load address of the - defining object. */ - -static inline void -elf_dynamic_relocate (Elf32_Dyn *dynamic[DT_NUM], Elf32_Addr loadaddr, - int lazy, Elf32_Addr (*resolve) (const Elf32_Sym **)) -{ - const Elf32_Sym *const symtab - = (const Elf32_Sym *) dynamic[DT_SYMTAB]->d_un.d_ptr; - - inline Elf32_Addr symvalue (Elf32_Word info, const Elf32_Sym **definer) - { - if (ELF32_R_SYM (info) == STN_UNDEF) - return 0; /* This value will not be consulted. */ - *definer = &symtab[ELF32_R_SYM (info)]; - return (*resolve) (definer); - } - - /* Perform Elf32_Rel relocations in the section found by RELTAG, SZTAG. */ - inline void do_rel (Elf32_Word reltag, Elf32_Word sztag) - { - const Elf32_Rel *r = (const Elf32_Rel *) dynamic[reltag]->d_un.d_ptr; - const Elf32_Rel *end = &r[dynamic[sztag]->d_un.d_val / sizeof *r]; - while (r < end) - { - const Elf32_Sym *definer; - Elf32_Addr loadbase = symvalue (r->r_info, &definer); - elf_machine_rel (loadaddr, dynamic, r, loadbase, definer); - ++r; - } - } - /* Perform Elf32_Rela relocations in the section found by RELTAG, SZTAG. */ - inline void do_rela (Elf32_Word reltag, Elf32_Word sztag) - { - const Elf32_Rela *r = (const Elf32_Rela *) dynamic[reltag]->d_un.d_ptr; - const Elf32_Rela *end = &r[dynamic[sztag]->d_un.d_val / sizeof *r]; - while (r < end) - { - const Elf32_Sym *definer; - Elf32_Addr loadbase = symvalue (r->r_info, &definer); - elf_machine_rela (loadaddr, dynamic, r, loadbase, definer); |
