* Committed: more mmap cases for sim/cris
@ 2009-01-06 20:50 Hans-Peter Nilsson
2009-01-06 21:21 ` Hans-Peter Nilsson
0 siblings, 1 reply; 2+ messages in thread
From: Hans-Peter Nilsson @ 2009-01-06 20:50 UTC (permalink / raw)
To: gdb-patches
Unfortunately hello-world has a few different use-cases of mmap
when run through the interpreter, like the glibc testsuite does:
/objdir/ld.so.1 --library-path /objdir:/objdir... /objdir/prog
This fixes them, and adds separate tests for them, as well as
adding a test-case as above, adjusted to the test-suite.
(Looks like ld.so.1 is fine with being loaded at 0.)
While I was at it, I thought better improve on the abort calls
all over sim/cris/traps.c; why not emit a message before
exiting. Calling sim_io_error is the preferred means, rather
than sim_engine_abort, because it requires just one context
parameter (not three) that I'd have to compose out of thin air,
and if bad comes to worse, it'd support passing NULL as that
pointer.
This *does* introduce two warning regressions. Not that warnings
are particularly scarce for sim/*, specifically cgen sims, but
why make it worse:
x/src/sim/cris/traps.c: In function 'h_supr_get_handler':
x/src/sim/cris/traps.c:1124: warning: control reaches end of non-void function
x/src/sim/cris/traps.c: In function 'cris_bmod_handler':
x/src/sim/cris/traps.c:1105: warning: control reaches end of non-void function
They're handled with my next patch.
Committed.
sim:
* 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.
sim/testsuite:
* sim/cris/c/mmap5.c, sim/cris/c/mmap6.c, sim/cris/c/mmap7.c,
sim/cris/c/mmap8.c, sim/cris/c/hellodyn3.c: New tests.
Index: sim/cris/c/hellodyn3.c
===================================================================
RCS file: sim/cris/c/hellodyn3.c
diff -N sim/cris/c/hellodyn3.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/cris/c/hellodyn3.c 6 Jan 2009 20:46:57 -0000
@@ -0,0 +1,9 @@
+/* Check that invoking ld.so as a program, invoking the main program,
+ works. Jump through a few hoops to avoid reading the host
+ ld.so.cache (having no absolute path specified for the executable
+ falls back on loading through the same mechanisms as a DSO).
+#notarget: *-*-elf
+#dynamic:
+#sim: --sysroot=@exedir@ @exedir@/lib/ld.so.1 --library-path /
+ */
+#include "hello.c"
Index: sim/cris/c/mmap5.c
===================================================================
RCS file: sim/cris/c/mmap5.c
diff -N sim/cris/c/mmap5.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/cris/c/mmap5.c 6 Jan 2009 20:46:57 -0000
@@ -0,0 +1,91 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int main (int argc, char *argv[])
+{
+ int fd = open (argv[0], O_RDONLY);
+ struct stat sb;
+ int size;
+ void *a;
+ void *b;
+ const char *str = "a string you'll only find in the program";
+
+ if (fd == -1)
+ {
+ perror ("open");
+ abort ();
+ }
+
+ if (fstat (fd, &sb) < 0)
+ {
+ perror ("fstat");
+ abort ();
+ }
+
+ size = 8192;
+#ifdef MMAP_SIZE1
+ size = MMAP_SIZE1;
+#endif
+
+#ifndef MMAP_PROT1
+#define MMAP_PROT1 PROT_READ | PROT_WRITE | PROT_EXEC
+#endif
+
+#ifndef MMAP_FLAGS1
+#define MMAP_FLAGS1 MAP_PRIVATE | MAP_ANONYMOUS
+#endif
+
+ /* Get a page, any page. */
+ b = mmap (NULL, size, MMAP_PROT1, MMAP_FLAGS1, -1, 0);
+ if (b == MAP_FAILED)
+ abort ();
+
+ /* Remember it, unmap it. */
+#ifndef NO_MUNMAP
+ if (munmap (b, size) != 0)
+ abort ();
+#endif
+
+#ifdef MMAP_ADDR2
+ b = MMAP_ADDR2;
+#endif
+
+#ifndef MMAP_PROT2
+#define MMAP_PROT2 PROT_READ | PROT_EXEC
+#endif
+
+#ifndef MMAP_FLAGS2
+#define MMAP_FLAGS2 MAP_DENYWRITE | MAP_FIXED | MAP_PRIVATE
+#endif
+
+ size = sb.st_size;
+#ifdef MMAP_SIZE2
+ size = MMAP_SIZE2;
+#endif
+
+#define MMAP_TEST_BAD_ORIG \
+ (a == MAP_FAILED || memmem (a, size, str, strlen (str) + 1) == NULL)
+#ifndef MMAP_TEST_BAD
+#define MMAP_TEST_BAD MMAP_TEST_BAD_ORIG
+#endif
+
+ /* Try mapping the now non-mapped page fixed. */
+ a = mmap (b, size, MMAP_PROT2, MMAP_FLAGS2, fd, 0);
+
+ if (MMAP_TEST_BAD)
+ abort ();
+
+ printf ("pass\n");
+ exit (0);
+}
Index: sim/cris/c/mmap6.c
===================================================================
RCS file: sim/cris/c/mmap6.c
diff -N sim/cris/c/mmap6.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/cris/c/mmap6.c 6 Jan 2009 20:46:57 -0000
@@ -0,0 +1,8 @@
+/* Check that mmapping specifying a previously mmapped address without
+ MAP_FIXED works; that we just don't get the same address.
+#notarget: cris*-*-elf
+*/
+#define NO_MUNMAP
+#define MMAP_FLAGS2 MAP_PRIVATE
+#define MMAP_TEST_BAD (a == b || MMAP_TEST_BAD_ORIG)
+#include "mmap5.c"
Index: sim/cris/c/mmap7.c
===================================================================
RCS file: sim/cris/c/mmap7.c
diff -N sim/cris/c/mmap7.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/cris/c/mmap7.c 6 Jan 2009 20:46:57 -0000
@@ -0,0 +1,14 @@
+/* Check that mmapping a page-aligned size, larger than the file,
+ works.
+
+#notarget: cris*-*-elf
+*/
+
+/* Make sure we get an address where the size fits. */
+#define MMAP_SIZE1 ((sb.st_size + 8192) & ~8191)
+
+/* If this ever fails because the file is a page-multiple, we'll deal
+ with that then. We want it larger than the file-size anyway. */
+#define MMAP_SIZE2 ((size + 8192) & ~8191)
+#define MMAP_FLAGS2 MAP_DENYWRITE | MAP_PRIVATE | MAP_FIXED
+#include "mmap5.c"
Index: sim/cris/c/mmap8.c
===================================================================
RCS file: sim/cris/c/mmap8.c
diff -N sim/cris/c/mmap8.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/cris/c/mmap8.c 6 Jan 2009 20:46:57 -0000
@@ -0,0 +1,9 @@
+/* Check that mmapping 0 using MAP_FIXED works, both with/without
+ there being previously mmapped contents.
+#notarget: cris*-*-elf
+*/
+#define MMAP_FLAGS1 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED
+#define NO_MUNMAP
+#define MMAP_SIZE2 8192
+#define MMAP_TEST_BAD (a != b || a != 0)
+#include "mmap5.c"
brgds, H-P
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Committed: more mmap cases for sim/cris
2009-01-06 20:50 Committed: more mmap cases for sim/cris Hans-Peter Nilsson
@ 2009-01-06 21:21 ` Hans-Peter Nilsson
0 siblings, 0 replies; 2+ messages in thread
From: Hans-Peter Nilsson @ 2009-01-06 21:21 UTC (permalink / raw)
To: gdb-patches
> Date: Tue, 6 Jan 2009 21:50:37 +0100
> From: Hans-Peter Nilsson <hp@axis.com>
> sim:
> * 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.
ENOPATCH
Index: cris/traps.c
===================================================================
RCS file: /cvs/src/src/sim/cris/traps.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -p -u -r1.20 -r1.21
--- cris/traps.c 3 Jan 2009 21:00:48 -0000 1.20
+++ cris/traps.c 6 Jan 2009 20:49:00 -0000 1.21
@@ -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
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
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_si
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_si
/* 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
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
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
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, in
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_
&& 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_
&& 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_
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_
USI newlen = (len + 8191) & ~8191;
USI newaddr;
- if ((flags & TARGET_MAP_FIXED)
- && unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
- addr, newlen) != 0)
- abort ();
-
- newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page, addr,
- newlen);
+ 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 != 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_
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;
brgds, H-P
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-01-06 21:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-06 20:50 Committed: more mmap cases for sim/cris Hans-Peter Nilsson
2009-01-06 21:21 ` Hans-Peter Nilsson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox