mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-18 12:16:13 +08:00
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.
This commit is contained in:
parent
91c7b85dc8
commit
1a3a58fd76
17
ChangeLog
17
ChangeLog
@ -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>
|
Mon Nov 20 16:19:15 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
||||||
|
|
||||||
* intl/Makefile [gettext-srcdir]: Rewrote copying rules to only
|
* intl/Makefile [gettext-srcdir]: Rewrote copying rules to only
|
||||||
|
57
elf/rtld.c
57
elf/rtld.c
@ -130,7 +130,6 @@ dl_main (const Elf32_Phdr *phdr,
|
|||||||
const char *interpreter_name;
|
const char *interpreter_name;
|
||||||
int lazy;
|
int lazy;
|
||||||
int list_only = 0;
|
int list_only = 0;
|
||||||
__typeof (_exit) *volatile exitfn;
|
|
||||||
|
|
||||||
if (*user_entry == (Elf32_Addr) &_start)
|
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;
|
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. */
|
||||||
|
|
||||||
/* Fetch this value now, before real relocation. For --list, it will
|
if (! _dl_loaded->l_info[DT_NEEDED])
|
||||||
be called below, and the finally-linked version is not the right
|
{
|
||||||
one. */
|
_dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n",
|
||||||
exitfn = &_exit;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
|
||||||
|
|
||||||
/* Do any necessary cleanups for the startup OS interface code.
|
/* Do any necessary cleanups for the startup OS interface code.
|
||||||
We do these now so that no calls are made after real relocation
|
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_map = _dl_loaded;
|
||||||
dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
|
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])
|
if (rtld_map.l_info[DT_INIT])
|
||||||
{
|
{
|
||||||
/* Call the initializer for the compatibility version of the
|
/* Call the initializer for the compatibility version of the
|
||||||
|
@ -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,
|
/* The lowest-numbered thread state flavor value is 1,
|
||||||
so we use bit 0 in machine_thread_all_state.set to
|
so we use bit 0 in machine_thread_all_state.set to
|
||||||
record whether we have done thread_abort. */
|
record whether we have done thread_abort. */
|
||||||
#define THREAD_ABORTED 1
|
#define THREAD_ABORTED 1
|
||||||
|
|
||||||
/* SS->thread is suspended. Abort the thread and get its basic state. If
|
/* SS->thread is suspended. Abort the thread and get its basic state. */
|
||||||
REPLY_PORT is not NULL, send a reply on *REPLY_PORT after aborting the
|
|
||||||
thread. */
|
|
||||||
static void
|
static void
|
||||||
abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
|
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,
|
void (*reply) (void))
|
||||||
int untraced)
|
|
||||||
{
|
{
|
||||||
if (!(state->set & THREAD_ABORTED))
|
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;
|
state->set = THREAD_ABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply_port)
|
if (reply)
|
||||||
post_reply (reply_port, reply_port_type, untraced, 0);
|
(*reply) ();
|
||||||
|
|
||||||
machine_get_basic_state (ss->thread, state);
|
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
|
mach_port_t
|
||||||
_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
|
_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
|
||||||
struct machine_thread_all_state *state, int *state_change,
|
struct machine_thread_all_state *state, int *state_change,
|
||||||
mach_port_t *reply_port,
|
void (*reply) (void))
|
||||||
mach_msg_type_name_t reply_port_type,
|
|
||||||
int untraced)
|
|
||||||
{
|
{
|
||||||
extern const void _hurd_intr_rpc_msg_in_trap;
|
extern const void _hurd_intr_rpc_msg_in_trap;
|
||||||
mach_port_t rcv_port = MACH_PORT_NULL;
|
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
|
/* Abort the thread's kernel context, so any pending message send or
|
||||||
receive completes immediately or aborts. */
|
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)
|
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. */
|
We will wait for all the replies below. */
|
||||||
reply_ports[nthreads++] = _hurdsig_abort_rpcs (ss, signo, 1,
|
reply_ports[nthreads++] = _hurdsig_abort_rpcs (ss, signo, 1,
|
||||||
state, &state_changed,
|
state, &state_changed,
|
||||||
NULL, 0, 0);
|
NULL);
|
||||||
if (state_changed && live)
|
if (state_changed && live)
|
||||||
/* Aborting the RPC needed to change this thread's state,
|
/* Aborting the RPC needed to change this thread's state,
|
||||||
and it might ever run again. So write back its 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;
|
int ss_suspended;
|
||||||
|
|
||||||
/* Reply to this sig_post message. */
|
/* 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. */
|
/* 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
|
RPC is in progress, abort_rpcs will do this. But we must always
|
||||||
do it before fetching the thread's state, because
|
do it before fetching the thread's state, because
|
||||||
thread_get_state is never kosher before thread_abort. */
|
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)
|
if (ss->context)
|
||||||
{
|
{
|
||||||
@ -793,7 +779,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
|
|||||||
wait_for_reply
|
wait_for_reply
|
||||||
= (_hurdsig_abort_rpcs (ss, signo, 1,
|
= (_hurdsig_abort_rpcs (ss, signo, 1,
|
||||||
&thread_state, &state_changed,
|
&thread_state, &state_changed,
|
||||||
&reply_port, reply_port_type, untraced)
|
&reply)
|
||||||
!= MACH_PORT_NULL);
|
!= MACH_PORT_NULL);
|
||||||
|
|
||||||
if (ss->critical_section)
|
if (ss->critical_section)
|
||||||
|
@ -66,16 +66,27 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
|
|||||||
{
|
{
|
||||||
case PROT_READ:
|
case PROT_READ:
|
||||||
memobj = robj;
|
memobj = robj;
|
||||||
__mach_port_deallocate (__mach_task_self (), wobj);
|
if (wobj != MACH_PORT_NULL)
|
||||||
|
__mach_port_deallocate (__mach_task_self (), wobj);
|
||||||
break;
|
break;
|
||||||
case PROT_WRITE:
|
case PROT_WRITE:
|
||||||
memobj = wobj;
|
memobj = wobj;
|
||||||
__mach_port_deallocate (__mach_task_self (), robj);
|
if (robj != MACH_PORT_NULL)
|
||||||
|
__mach_port_deallocate (__mach_task_self (), robj);
|
||||||
break;
|
break;
|
||||||
case PROT_READ|PROT_WRITE:
|
case PROT_READ|PROT_WRITE:
|
||||||
__mach_port_deallocate (__mach_task_self (), robj);
|
|
||||||
if (robj == wobj)
|
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
|
else
|
||||||
{
|
{
|
||||||
__mach_port_deallocate (__mach_task_self (), wobj);
|
__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,
|
memobj, (vm_offset_t) offset,
|
||||||
flags & (MAP_COPY|MAP_PRIVATE),
|
flags & (MAP_COPY|MAP_PRIVATE),
|
||||||
vmprot, VM_PROT_ALL,
|
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)
|
if (memobj != MACH_PORT_NULL)
|
||||||
__mach_port_deallocate (__mach_task_self (), memobj);
|
__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)
|
weak_alias (__mmap, mmap)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user