[RFC,07/15] Fix mmap usage of MAP_FIXED for multiple pages.

Message ID 64c9969c224e555335979b9168cfacb839727596.1444820235.git.henrik.wallin@windriver.com
State New, archived
Headers

Commit Message

henrik.wallin@windriver.com Oct. 14, 2015, 11:14 a.m. UTC
  From: Henrik Wallin <henrik.wallin@windriver.com>

mmap using MAP_FIXED will overwrite mapped pages if multiple pages
are requested.
E.g. On ARM it will result in overwriting the main code pages.

Fix by not using MAP_FIXED and use mmunmap in case we
don't get the start address we asked for.

gdb/gdbserver/ChangeLog:

	* tracepoint.c : Include stdint.h and sys/mman.h.
	(initialize_tracepoint): Fix problem with
	MAP_FIXED usage in mmap.

Signed-off-by: Henrik Wallin <henrik.wallin@windriver.com>
---
 gdb/gdbserver/tracepoint.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
  

Comments

Andreas Schwab Oct. 14, 2015, 3:26 p.m. UTC | #1
henrik.wallin@windriver.com writes:

> mmap using MAP_FIXED will overwrite mapped pages if multiple pages
> are requested.

It's also true if you request a single page.

Andreas.
  
henrik.wallin@windriver.com Oct. 29, 2015, 5:48 p.m. UTC | #2
2015-10-14 17:26 GMT+02:00 Andreas Schwab <schwab@suse.de>:
> henrik.wallin@windriver.com writes:
>
>> mmap using MAP_FIXED will overwrite mapped pages if multiple pages
>> are requested.
>
> It's also true if you request a single page.

True, I will adjust the commit message.

thanks,
/ Henrik
  

Patch

diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index d2ad197e58ab..35a125c951d5 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -27,6 +27,9 @@ 
 #include <unistd.h>
 #include "gdb_sys_time.h"
 #include <inttypes.h>
+#include <stdint.h>
+#include <sys/mman.h>
+
 #include "ax.h"
 #include "tdesc.h"
 
@@ -7392,10 +7395,12 @@  initialize_tracepoint (void)
 	  = (char *) mmap ((void *) addr,
 			   pagesize * SCRATCH_BUFFER_NPAGES,
 			   PROT_READ | PROT_WRITE | PROT_EXEC,
-			   MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+			   MAP_PRIVATE | MAP_ANONYMOUS,
 			   -1, 0);
-	if (gdb_jump_pad_buffer != MAP_FAILED)
+	if (gdb_jump_pad_buffer == (void *)addr)
 	  break;
+	if (gdb_jump_pad_buffer != MAP_FAILED)
+	  munmap(gdb_jump_pad_buffer, pagesize * SCRATCH_BUFFER_NPAGES);
       }
 
     if (addr == 0)