From fc887f09c5e2aa53ef9c345773ffe70c4b5fb609 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Tue, 6 Jan 2009 20:49:00 +0000 Subject: * cris/traps.c (abort): Define to call sim_io_error. (create_map): Make -1 imply a non-fixed address, not 0. All callers changed. Only prefer the next higher unmapped address if the last mapped address is no less than 0x40000000. Check that the address to be mapped is not already mapped. Update head comment. (unmap_pages): Don't call abort when recursive call fails, just note and return an error if a page in the range couldn't be unmapped. (cris_bmod_handler, h_supr_set_handler, h_supr_get_handler) (schedule, make_first_thread, cris_pipe_empty): New local variable sd. (cris_break_13_handler) : Handle non-MAP_FIXED argument overlapping existing map. For MAP_FIXED, don't abort on page not being mapped. Handle non-anon filemap with length padded to pagesize. --- sim/ChangeLog | 17 +++++++++++++ sim/cris/traps.c | 75 ++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 68 insertions(+), 24 deletions(-) (limited to 'sim') diff --git a/sim/ChangeLog b/sim/ChangeLog index d502ab6..87cbc8c 100644 --- a/sim/ChangeLog +++ b/sim/ChangeLog @@ -1,3 +1,20 @@ +2009-01-06 Hans-Peter Nilsson + + * cris/traps.c (abort): Define to call sim_io_error. + (create_map): Make -1 imply a non-fixed address, not 0. All + callers changed. Only prefer the next higher unmapped address if + the last mapped address is no less than 0x40000000. Check that + the address to be mapped is not already mapped. Update head + comment. + (unmap_pages): Don't call abort when recursive call fails, just + note and return an error if a page in the range couldn't be unmapped. + (cris_bmod_handler, h_supr_set_handler, h_supr_get_handler) + (schedule, make_first_thread, cris_pipe_empty): New local variable sd. + (cris_break_13_handler) : Handle + non-MAP_FIXED argument overlapping existing map. For MAP_FIXED, + don't abort on page not being mapped. Handle non-anon filemap + with length padded to pagesize. + 2009-01-03 Hans-Peter Nilsson * cris/sim-if.c (TARGET_AT_NULL, TARGET_AT_PHDR, TARGET_AT_PHENT) diff --git a/sim/cris/traps.c b/sim/cris/traps.c index aa3b90a..5bd98bf 100644 --- a/sim/cris/traps.c +++ b/sim/cris/traps.c @@ -755,6 +755,11 @@ static const CB_TARGET_DEFS_MAP open_map[] = { { -1, -1 } }; +/* Let's be less drastic and more traceable. FIXME: mark as noreturn. */ +#define abort() \ + sim_io_error (sd, "simulator unhandled condition at %s:%d", \ + __FUNCTION__, __LINE__) + /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */ static SIM_CPU *current_cpu_for_cb_callback; @@ -975,7 +980,8 @@ cris_dump_map (SIM_CPU *current_cpu) sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end); } -/* Create mmapped memory. */ +/* Create mmapped memory. ADDR is -1 if any address will do. Caller + must make sure that the address isn't already mapped. */ static USI create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, @@ -985,9 +991,9 @@ create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, struct cris_sim_mmapped_page **higher_prevp = rootp; USI new_addr = 0x40000000; - if (addr != 0) + if (addr != (USI) -1) new_addr = addr; - else if (*rootp) + else if (*rootp && rootp[0]->addr >= new_addr) new_addr = rootp[0]->addr + 8192; if (len != 8192) @@ -1011,6 +1017,10 @@ create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, mapp = mapp->prev) higher_prevp = &mapp->prev; + /* Assert for consistency that we don't create duplicate maps. */ + if (is_mapped (sd, rootp, new_addr, len)) + abort (); + /* Allocate the new page, on the next higher page from the last one allocated, and link in the new descriptor before previous ones. */ mapp = malloc (sizeof (*mapp)); @@ -1041,6 +1051,7 @@ unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, if (len != 8192) { USI page_addr; + int ret = 0; if (len & 8191) /* Which is better: return an error for this, or just round it up? */ @@ -1049,12 +1060,15 @@ unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr, /* Loop backwards to make each call is O(1) over the number of pages allocated, if we're unmapping from the high end of the pages. */ for (page_addr = addr + len - 8192; - page_addr >= addr; + page_addr > addr; page_addr -= 8192) - if (unmap_pages (sd, rootp, page_addr, 8192) != 0) - abort (); + if (unmap_pages (sd, rootp, page_addr, 8192)) + ret = EINVAL; - return 0; + if (unmap_pages (sd, rootp, addr, 8192)) + ret = EINVAL; + + return ret; } for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev) @@ -1087,6 +1101,7 @@ cris_bmod_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED, UINT srcreg ATTRIBUTE_UNUSED, USI dstreg ATTRIBUTE_UNUSED) { + SIM_DESC sd = CPU_STATE (current_cpu); abort (); } @@ -1096,6 +1111,7 @@ h_supr_set_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED, USI page ATTRIBUTE_UNUSED, USI newval ATTRIBUTE_UNUSED) { + SIM_DESC sd = CPU_STATE (current_cpu); abort (); } @@ -1104,6 +1120,7 @@ h_supr_get_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED, UINT index ATTRIBUTE_UNUSED, USI page ATTRIBUTE_UNUSED) { + SIM_DESC sd = CPU_STATE (current_cpu); abort (); } @@ -1260,6 +1277,7 @@ schedule (SIM_CPU *current_cpu, int next) static void reschedule (SIM_CPU *current_cpu) { + SIM_DESC sd = CPU_STATE (current_cpu); int i; /* Iterate over all thread slots, because after a few thread creations @@ -1397,6 +1415,7 @@ deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid) static void make_first_thread (SIM_CPU *current_cpu) { + SIM_DESC sd = CPU_STATE (current_cpu); current_cpu->thread_data = xcalloc (1, SIM_TARGET_MAX_THREADS @@ -1706,10 +1725,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1, && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC) && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)) || (fd == (USI) -1 && pgoff != 0) - || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS)) - || ((flags & TARGET_MAP_FIXED) == 0 - && is_mapped (sd, ¤t_cpu->highest_mmapped_page, - addr, (len + 8191) & ~8191))) + || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS))) { retval = cris_unknown_syscall (current_cpu, pc, @@ -1742,13 +1758,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1, && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)) abort (); - if ((flags & TARGET_MAP_FIXED) - && unmap_pages (sd, ¤t_cpu->highest_mmapped_page, - addr, newlen) != 0) - abort (); + if (flags & TARGET_MAP_FIXED) + unmap_pages (sd, ¤t_cpu->highest_mmapped_page, + addr, newlen); + else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page, + addr, newlen)) + addr = 0; newaddr - = create_map (sd, ¤t_cpu->highest_mmapped_page, addr, + = create_map (sd, ¤t_cpu->highest_mmapped_page, + addr != 0 || (flags & TARGET_MAP_FIXED) + ? addr : -1, newlen); if (newaddr >= (USI) -8191) @@ -1800,7 +1820,9 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1, if (cb_syscall (cb, &s) != CB_RC_OK) abort (); - if ((USI) s.result != len) + /* If the result is a page or more lesser than what + was requested, something went wrong. */ + if (len >= 8192 && (USI) s.result <= len - 8192) abort (); /* After reading, we need to go back to the previous @@ -1821,13 +1843,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1, USI newlen = (len + 8191) & ~8191; USI newaddr; - if ((flags & TARGET_MAP_FIXED) - && unmap_pages (sd, ¤t_cpu->highest_mmapped_page, - addr, newlen) != 0) - abort (); + if (flags & TARGET_MAP_FIXED) + unmap_pages (sd, ¤t_cpu->highest_mmapped_page, + addr, newlen); + else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page, + addr, newlen)) + addr = 0; - newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page, addr, - newlen); + newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page, + addr != 0 || (flags & TARGET_MAP_FIXED) + ? addr : -1, + newlen); if (newaddr >= (USI) -8191) retval = -cb_host_to_target_errno (cb, -(SI) newaddr); @@ -2114,7 +2140,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1, mapped_addr = create_map (sd, ¤t_cpu->highest_mmapped_page, - 0, new_len); + -1, new_len); if (mapped_addr > (USI) -8192) { @@ -3263,6 +3289,7 @@ cris_pipe_empty (host_callback *cb, { int i; SIM_CPU *cpu = current_cpu_for_cb_callback; + SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback); bfd_byte r10_buf[4]; int remaining = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size; -- cgit v1.1