[mupen64plus-core] 91/310: Allocate exec memory using mmap

Sven Eckelmann ecsv-guest at moszumanska.debian.org
Thu Nov 26 05:57:23 UTC 2015


This is an automated email from the git hooks/post-receive script.

ecsv-guest pushed a commit to branch armhf_test
in repository mupen64plus-core.

commit f758d542386513617be28c36b014e2b86ef7f32d
Author: Sven Eckelmann <sven at narfation.org>
Date:   Sun Jul 24 12:54:54 2011 +0200

    Allocate exec memory using mmap
    
    mprotect has no defined behavior when it is used with memory regions not
    allocated by mmap. Therefore, it is easier to use mmap directly with the
    RWX flags instead of using mmap and then mprotect.
---
 debian/changelog                   |   1 +
 debian/patches/allocate_mmap.patch | 210 +++++++++++++++++++++++++++++++++++++
 debian/patches/series              |   1 +
 3 files changed, 212 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 8fbc186..db36599 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -22,6 +22,7 @@ mupen64plus-core (1.99.4-3) UNRELEASED; urgency=low
       file
     - Add osd_memory_corruption.patch, Prevent data corruption with caller
       managed OSD text
+    - Add allocate_mmap.patch, Allocate exec memory using mmap
 
  -- Sven Eckelmann <sven at narfation.org>  Wed, 13 Jul 2011 08:38:54 +0200
 
diff --git a/debian/patches/allocate_mmap.patch b/debian/patches/allocate_mmap.patch
new file mode 100644
index 0000000..67e8f78
--- /dev/null
+++ b/debian/patches/allocate_mmap.patch
@@ -0,0 +1,210 @@
+Description: Allocate exec memory using mmap
+ mprotect has no defined behavior when it is used with memory regions not
+ allocated by mmap. Therefore, it is easier to use mmap directly with the RWX
+ flags instead of using mmap and then mprotect.
+Origin: upstream, https://bitbucket.org/richard42/mupen64plus-core/changeset/bc034c4e3e07
+Author: Sven Eckelmann <sven at narfation.org>
+
+---
+diff --git a/src/r4300/interupt.c b/src/r4300/interupt.c
+index ac0f62095c54520575edeb5dcb6bd4f2e0b279b2..430adf871c08d107d7823bbc31a498e3404f2ea8 100644
+--- a/src/r4300/interupt.c
++++ b/src/r4300/interupt.c
+@@ -560,10 +560,7 @@ void gen_interupt()
+                 {
+                     if (blocks[i])
+                     {
+-                        if (blocks[i]->block) { free_exec(blocks[i]->block); blocks[i]->block = NULL; }
+-                        if (blocks[i]->code) { free_exec(blocks[i]->code); blocks[i]->code = NULL; }
+-                        if (blocks[i]->jumps_table) { free(blocks[i]->jumps_table); blocks[i]->jumps_table = NULL; }
+-                        if (blocks[i]->riprel_table) { free(blocks[i]->riprel_table); blocks[i]->riprel_table = NULL; }
++                        free_block(blocks[i]);
+                         free(blocks[i]);
+                         blocks[i] = NULL;
+                     }
+diff --git a/src/r4300/r4300.c b/src/r4300/r4300.c
+index f1d9ef9a06ca06713f1d3cd3044bcb3e7a64f6f5..a969dab7cc37fd1358d0e11fc605f66fa2cc6952 100644
+--- a/src/r4300/r4300.c
++++ b/src/r4300/r4300.c
+@@ -1892,6 +1892,11 @@ void r4300_execute(void)
+         DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler");
+         r4300emu = CORE_DYNAREC;
+         init_blocks();
++
++        /* Prevent segfault on failed init_blocks */
++        if (!actual->block || !actual->code)
++            return;
++
+         code = (void *)(actual->code+(actual->block[0x40/4].local_addr));
+         dyna_start(code);
+         PC++;
+@@ -1919,6 +1924,11 @@ void r4300_execute(void)
+         DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter");
+         r4300emu = CORE_INTERPRETER;
+         init_blocks();
++
++        /* Prevent segfault on failed init_blocks */
++        if (!actual->block || !actual->code)
++            return;
++
+         last_addr = PC->addr;
+         while (!stop)
+         {
+@@ -1940,10 +1950,7 @@ void r4300_execute(void)
+     {
+         if (blocks[i])
+         {
+-            if (blocks[i]->block) { free_exec(blocks[i]->block); blocks[i]->block = NULL; }
+-            if (blocks[i]->code) { free_exec(blocks[i]->code); blocks[i]->code = NULL; }
+-            if (blocks[i]->jumps_table) { free(blocks[i]->jumps_table); blocks[i]->jumps_table = NULL; }
+-            if (blocks[i]->riprel_table) { free(blocks[i]->riprel_table); blocks[i]->riprel_table = NULL; }
++            free_block(blocks[i]);
+             free(blocks[i]);
+             blocks[i] = NULL;
+         }
+diff --git a/src/r4300/recomp.c b/src/r4300/recomp.c
+index 0cc7cd43ee819bc3cb840a71ec7b758ca59fa55e..07261c7a8808bcf9fe004fad6a1eb91828739dcd 100644
+--- a/src/r4300/recomp.c
++++ b/src/r4300/recomp.c
+@@ -2159,6 +2159,17 @@ static void (*recomp_ops[64])(void) =
+    RSC     , RSWC1  , RSV  , RSV   , RSCD , RSDC1, RSV   , RSD
+ };
+ 
++static int get_block_length(const precomp_block *block)
++{
++  return (block->end-block->start)/4;
++}
++
++static size_t get_block_memsize(const precomp_block *block)
++{
++  int length = get_block_length(block);
++  return ((length+1)+(length>>2)) * sizeof(precomp_instr);
++}
++
+ /**********************************************************************
+  ******************** initialize an empty block ***********************
+  **********************************************************************/
+@@ -2171,12 +2182,16 @@ void init_block(int *source, precomp_block *block)
+   DebugMessage(M64MSG_INFO, "init block %x - %x", (int) block->start, (int) block->end);
+ #endif
+ 
+-  length = (block->end-block->start)/4;
++  length = get_block_length(block);
+    
+   if (!block->block)
+   {
+-    long memsize = ((length+1)+(length>>2)) * sizeof(precomp_instr);
++    size_t memsize = get_block_memsize(block);
+     block->block = (precomp_instr *) malloc_exec(memsize);
++    if (!block->block) {
++        DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate executable memory for dynamic recompiler/cached interpreter. Try to use the pure interpreter.");
++        return;
++    }
+     memset(block->block, 0, memsize);
+     already_exist = 0;
+   }
+@@ -2338,6 +2353,16 @@ void init_block(int *source, precomp_block *block)
+   end_section(COMPILER_SECTION);
+ }
+ 
++void free_block(precomp_block *block)
++{
++    size_t memsize = get_block_memsize(block);
++
++    if (block->block) { free_exec(block->block, memsize);; block->block = NULL; }
++    if (block->code) { free_exec(block->code, block->max_code_length); block->code = NULL; }
++    if (block->jumps_table) { free(block->jumps_table); block->jumps_table = NULL; }
++    if (block->riprel_table) { free(block->riprel_table); block->riprel_table = NULL; }
++}
++
+ /**********************************************************************
+  ********************* recompile a block of code **********************
+  **********************************************************************/
+@@ -2594,17 +2619,20 @@ void *malloc_exec(size_t size)
+ #if defined(WIN32)
+ 	return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ #elif defined(__GNUC__)
++
++#ifndef  MAP_ANONYMOUS
++   #ifdef MAP_ANON
++      #define MAP_ANONYMOUS MAP_ANON
++   #endif
++#endif
++
+    int pagesize = sysconf(_SC_PAGE_SIZE);
+    if (pagesize == -1)
+        { DebugMessage(M64MSG_ERROR, "Memory error: couldn't determine system memory page size."); return NULL; }
+ 
+-   /* Allocate a buffer aligned on a page boundary; initial protection is PROT_READ | PROT_WRITE */
+-   void *block = valloc(size);
+-   if (block == NULL)
+-       { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate %i byte block of %i-byte aligned memory.", (int) size, pagesize); return NULL; }
+-
+-   if (mprotect(block, size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+-       { DebugMessage(M64MSG_ERROR, "Memory error: couldn't set RWX permissions on %i byte block of memory.", (int) size); return NULL; }
++   void *block = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
++   if (block == MAP_FAILED)
++       { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate %i byte block of %zd-byte aligned RWX memory.", size, pagesize); return NULL; }
+ 
+    return block;
+ #else
+@@ -2615,30 +2643,30 @@ void *malloc_exec(size_t size)
+ /**********************************************************************
+  ************* reallocate memory with executable bit set **************
+  **********************************************************************/
+-void *realloc_exec(void *ptr, size_t size, size_t newsize)
++void *realloc_exec(void *ptr, size_t oldsize, size_t newsize)
+ {
+    void* block = malloc_exec(newsize);
+    if (block != NULL)
+    {
+       size_t copysize;
+-      if (size < newsize)
+-         copysize = size;
++      if (oldsize < newsize)
++         copysize = oldsize;
+       else
+          copysize = newsize;
+       memcpy(block, ptr, copysize);
+    }
+-   free_exec(ptr);
++   free_exec(ptr, oldsize);
+    return block;
+ }
+ 
+ /**********************************************************************
+  **************** frees memory with executable bit set ****************
+  **********************************************************************/
+-void free_exec(void *ptr)
++void free_exec(void *ptr, size_t length)
+ {
+ #if defined(WIN32)
+ 	VirtualFree(ptr, 0, MEM_RELEASE);
+-#else
+-	free(ptr);
++#else
++	munmap(ptr, length);
+ #endif
+ }
+diff --git a/src/r4300/recomp.h b/src/r4300/recomp.h
+index 210046eb64853a79c6d3f3352f4cec9377a40369..d0b07d8b85a6899ed8e19c27b4848d6aab81855d 100644
+--- a/src/r4300/recomp.h
++++ b/src/r4300/recomp.h
+@@ -88,14 +88,15 @@ typedef struct _precomp_block
+ 
+ void recompile_block(int *source, precomp_block *block, unsigned int func);
+ void init_block(int *source, precomp_block *block);
++void free_block(precomp_block *block);
+ void recompile_opcode(void);
+ void prefetch_opcode(unsigned int op);
+ void dyna_jump(void);
+ void dyna_start(void (*code)(void));
+ void dyna_stop(void);
+ void *malloc_exec(size_t size);
+-void *realloc_exec(void *ptr, size_t size, size_t newsize);
+-void free_exec(void *ptr);
++void *realloc_exec(void *ptr, size_t oldsize, size_t newsize);
++void free_exec(void *ptr, size_t length);
+ 
+ extern precomp_instr *dst; /* precomp_instr structure for instruction being recompiled */
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 44c395e..fabbea3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,4 @@ privilege_segfault.patch
 info_configuration_failure.patch
 conflicting_symbol.patch
 osd_memory_corruption.patch
+allocate_mmap.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus-core.git



More information about the Pkg-games-commits mailing list