diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | elf/rtld.c | 57 | ||||
-rw-r--r-- | hurd/hurdsig.c | 52 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mmap.c | 25 |
4 files changed, 83 insertions, 68 deletions
@@ -1,3 +1,20 @@ +Tue Nov 21 14:12:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * malloc/malloc.c (align): Don't check contiguity and call abort. + + * hurd/hurdsig.c (post_reply): Function removed. + (abort_thread, abort_all_rpcs, _hurdsig_abort_rpcs): Don't call it. + Take single callback fn arg instead of reply port and type. + (_hurd_internal_post_signal): Callers changed. + Cache reply stub fn ptr in local var before UNTRACED might be changed. + + * sysdeps/mach/hurd/mmap.c: Cope with a null write memobj for + PROT_READ|PROT_WRITE copy mapping. Pass a proper vm_inherit_t to + vm_map. + + * elf/rtld.c (_dl_start): For --list, do output and exit before + relocating. + Mon Nov 20 16:19:15 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * intl/Makefile [gettext-srcdir]: Rewrote copying rules to only @@ -130,7 +130,6 @@ dl_main (const Elf32_Phdr *phdr, const char *interpreter_name; int lazy; int list_only = 0; - __typeof (_exit) *volatile exitfn; if (*user_entry == (Elf32_Addr) &_start) { @@ -294,12 +293,35 @@ of this helper program; chances are you did not intend to run this program.\n", rtld_map.l_next->l_prev = &rtld_map; } - lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0'; + if (list_only) + { + /* We were run just to list the shared libraries. It is + important that we do this before real relocation, because the + functions we call below for output may no longer work properly + after relocation. */ + + if (! _dl_loaded->l_info[DT_NEEDED]) + { + _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n", + NULL); + _exit (1); + } + + for (l = _dl_loaded->l_next; l; l = l->l_next) + { + char buf[20], *bp; + buf[sizeof buf - 1] = '\0'; + bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0); + while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2) + *--bp = '0'; + _dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name, + " (0x", bp, ")\n", NULL); + } + + _exit (0); + } - /* Fetch this value now, before real relocation. For --list, it will - be called below, and the finally-linked version is not the right - one. */ - exitfn = &_exit; + lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0'; /* Do any necessary cleanups for the startup OS interface code. We do these now so that no calls are made after real relocation @@ -324,29 +346,6 @@ of this helper program; chances are you did not intend to run this program.\n", dl_r_debug.r_map = _dl_loaded; dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state; - if (list_only) - { - if (! _dl_loaded->l_info[DT_NEEDED]) - { - _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n", - NULL); - (*exitfn) (1); - } - - for (l = _dl_loaded->l_next; l; l = l->l_next) - { - char buf[20], *bp; - buf[sizeof buf - 1] = '\0'; - bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0); - while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2) - *--bp = '0'; - _dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name, - " (0x", bp, ")\n", NULL); - } - - (*exitfn) (0); - } - if (rtld_map.l_info[DT_INIT]) { /* Call the initializer for the compatibility version of the diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index 13ffb71..537ea56 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -179,35 +179,15 @@ write_corefile (int signo, long int sigcode, int sigerror) } -/* Send a sig_post reply message if it hasn't already been sent. */ -static inline void -post_reply (mach_port_t *reply_port, mach_msg_type_name_t reply_port_type, - int untraced, - error_t result) -{ - error_t err; - if (reply_port == NULL || *reply_port == MACH_PORT_NULL) - return; - err = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply) - (*reply_port, reply_port_type, result); - *reply_port = MACH_PORT_NULL; - if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */ - assert_perror (err); -} - - /* The lowest-numbered thread state flavor value is 1, so we use bit 0 in machine_thread_all_state.set to record whether we have done thread_abort. */ #define THREAD_ABORTED 1 -/* SS->thread is suspended. Abort the thread and get its basic state. If - REPLY_PORT is not NULL, send a reply on *REPLY_PORT after aborting the - thread. */ +/* SS->thread is suspended. Abort the thread and get its basic state. */ static void abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state, - mach_port_t *reply_port, mach_msg_type_name_t reply_port_type, - int untraced) + void (*reply) (void)) { if (!(state->set & THREAD_ABORTED)) { @@ -218,8 +198,8 @@ abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state, state->set = THREAD_ABORTED; } - if (reply_port) - post_reply (reply_port, reply_port_type, untraced, 0); + if (reply) + (*reply) (); machine_get_basic_state (ss->thread, state); } @@ -274,9 +254,7 @@ interrupted_reply_port_location (struct machine_thread_all_state *thread_state, mach_port_t _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread, struct machine_thread_all_state *state, int *state_change, - mach_port_t *reply_port, - mach_msg_type_name_t reply_port_type, - int untraced) + void (*reply) (void)) { extern const void _hurd_intr_rpc_msg_in_trap; mach_port_t rcv_port = MACH_PORT_NULL; @@ -291,7 +269,7 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread, /* Abort the thread's kernel context, so any pending message send or receive completes immediately or aborts. */ - abort_thread (ss, state, reply_port, reply_port_type, untraced); + abort_thread (ss, state, reply); if (state->basic.PC < (natural_t) &_hurd_intr_rpc_msg_in_trap) { @@ -396,7 +374,7 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live) We will wait for all the replies below. */ reply_ports[nthreads++] = _hurdsig_abort_rpcs (ss, signo, 1, state, &state_changed, - NULL, 0, 0); + NULL); if (state_changed && live) /* Aborting the RPC needed to change this thread's state, and it might ever run again. So write back its state. */ @@ -452,9 +430,17 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, int ss_suspended; /* Reply to this sig_post message. */ - inline void reply (void) + __typeof (__msg_sig_post_reply) *reply_rpc + = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply); + void reply (void) { - post_reply (&reply_port, reply_port_type, untraced, 0); + error_t err; + if (reply_port == MACH_PORT_NULL) + return; + err = (*reply_rpc) (reply_port, reply_port_type, 0); + reply_port = MACH_PORT_NULL; + if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */ + assert_perror (err); } /* Mark the signal as pending. */ @@ -746,7 +732,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, RPC is in progress, abort_rpcs will do this. But we must always do it before fetching the thread's state, because thread_get_state is never kosher before thread_abort. */ - abort_thread (ss, &thread_state, NULL, 0, 0); + abort_thread (ss, &thread_state, NULL); if (ss->context) { @@ -793,7 +779,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, wait_for_reply = (_hurdsig_abort_rpcs (ss, signo, 1, &thread_state, &state_changed, - &reply_port, reply_port_type, untraced) + &reply) != MACH_PORT_NULL); if (ss->critical_section) diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c index 9793077..4f9304f 100644 --- a/sysdeps/mach/hurd/mmap.c +++ b/sysdeps/mach/hurd/mmap.c @@ -66,16 +66,27 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) { case PROT_READ: memobj = robj; - __mach_port_deallocate (__mach_task_self (), wobj); + if (wobj != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), wobj); break; case PROT_WRITE: memobj = wobj; - __mach_port_deallocate (__mach_task_self (), robj); + if (robj != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), robj); break; case PROT_READ|PROT_WRITE: - __mach_port_deallocate (__mach_task_self (), robj); if (robj == wobj) - memobj = wobj; + { + memobj = wobj; + /* Remove extra reference. */ + __mach_port_deallocate (__mach_task_self (), memobj); + } + else if (wobj == MACH_PORT_NULL && /* Not writable by mapping. */ + (flags & (MAP_COPY|MAP_PRIVATE))) + /* The file can only be mapped for reading. Since we are + making a private mapping, we will never try to write the + object anyway, so we don't care. */ + memobj = robj; else { __mach_port_deallocate (__mach_task_self (), wobj); @@ -96,7 +107,9 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) memobj, (vm_offset_t) offset, flags & (MAP_COPY|MAP_PRIVATE), vmprot, VM_PROT_ALL, - flags & MAP_INHERIT); + (flags & MAP_INHERIT) == 0 ? VM_INHERIT_NONE : + (flags & (MAP_COPY|MAP_PRIVATE)) ? VM_INHERIT_COPY : + VM_INHERIT_SHARE); if (memobj != MACH_PORT_NULL) __mach_port_deallocate (__mach_task_self (), memobj); @@ -105,4 +118,4 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) } weak_alias (__mmap, mmap) - + |