aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/ChangeLog17
-rw-r--r--sim/cris/traps.c75
2 files changed, 68 insertions, 24 deletions
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 <hp@axis.com>
+
+ * 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) <case TARGET_SYS_mmap2>: 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 <hp@axis.com>
* 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, &current_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, &current_cpu->highest_mmapped_page,
- addr, newlen) != 0)
- abort ();
+ if (flags & TARGET_MAP_FIXED)
+ unmap_pages (sd, &current_cpu->highest_mmapped_page,
+ addr, newlen);
+ else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
+ addr, newlen))
+ addr = 0;
newaddr
- = create_map (sd, &current_cpu->highest_mmapped_page, addr,
+ = create_map (sd, &current_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, &current_cpu->highest_mmapped_page,
- addr, newlen) != 0)
- abort ();
+ if (flags & TARGET_MAP_FIXED)
+ unmap_pages (sd, &current_cpu->highest_mmapped_page,
+ addr, newlen);
+ else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
+ addr, newlen))
+ addr = 0;
- newaddr = create_map (sd, &current_cpu->highest_mmapped_page, addr,
- newlen);
+ newaddr = create_map (sd, &current_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, &current_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;