+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)
{ -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;
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,
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)
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));
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? */
/* 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)
UINT srcreg ATTRIBUTE_UNUSED,
USI dstreg ATTRIBUTE_UNUSED)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
abort ();
}
USI page ATTRIBUTE_UNUSED,
USI newval ATTRIBUTE_UNUSED)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
abort ();
}
UINT index ATTRIBUTE_UNUSED,
USI page ATTRIBUTE_UNUSED)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
abort ();
}
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
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
&& 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,
&& 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)
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
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);
mapped_addr
= create_map (sd, ¤t_cpu->highest_mmapped_page,
- 0, new_len);
+ -1, new_len);
if (mapped_addr > (USI) -8192)
{
{
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;