* cris/traps.c (abort): Define to call sim_io_error.
authorHans-Peter Nilsson <hp@axis.com>
Tue, 6 Jan 2009 20:49:00 +0000 (20:49 +0000)
committerHans-Peter Nilsson <hp@axis.com>
Tue, 6 Jan 2009 20:49:00 +0000 (20:49 +0000)
(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.

sim/ChangeLog
sim/cris/traps.c

index d502ab62f17135d91dd5a3b70a11bc04caea3fb0..87cbc8c321f45343899760e77a879369f173ba8e 100644 (file)
@@ -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)
index aa3b90afefbce4fd922ea07eb73bff43e26197bc..5bd98bff2efbad3b4af7e4872b05df53e3b93003 100644 (file)
@@ -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;