Skip to content

Commit ca878a8

Browse files
committed
simx86: add support for dlmalloc memory spaces
Pre-map 128Mb pool and use as a memory space.
1 parent 4b28f14 commit ca878a8

File tree

13 files changed

+161
-32
lines changed

13 files changed

+161
-32
lines changed

src/base/emu-i386/simx86/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ JITFILES = codegen-x86.c fp87-x86.c sigsegv.c cpatch.c
1515
endif
1616
CFILES = interp.c cpu-emu.c modrm-gen.c $(JITFILES) \
1717
codegen-sim.c fp87-sim.c protmode.c tables.c \
18-
codegen.c trees.c memory.c
18+
codegen.c trees.c memory.c codebuf.c
1919
ALL_CPPFLAGS +=-I$(EM86DIR) $(EM86FLG)
2020

2121
SFILES=

src/base/emu-i386/simx86/codebuf.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation; either version 2 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program; if not, write to the Free Software
14+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15+
*/
16+
17+
/*
18+
* Purpose: dlmalloc's memory spaces support
19+
* and circumvent W^X restrictions.
20+
*
21+
* Author: @stsp
22+
*
23+
*/
24+
#include <stddef.h>
25+
#include <assert.h>
26+
#include <sys/mman.h>
27+
#include "emu86.h"
28+
#include "misc/dlmalloc.h"
29+
30+
#ifndef MAP_JIT
31+
#define MAP_JIT 0
32+
#endif
33+
#define CODEBUF_SZ (128 * 1024 * 1024)
34+
static mspace cspace;
35+
static unsigned char *wbase;
36+
static unsigned char *xbase;
37+
38+
void InitGenCodeBuf(void)
39+
{
40+
void *addr;
41+
42+
#if HAVE_DECL_MREMAP_MAYMOVE && 0
43+
int err;
44+
45+
addr = mmap(NULL, CODEBUF_SZ, PROT_NONE,
46+
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
47+
assert(addr != MAP_FAILED);
48+
xbase = mremap(addr, 0, CODEBUF_SZ, MREMAP_MAYMOVE);
49+
assert(xbase != MAP_FAILED && xbase != addr);
50+
err = mprotect(addr, CODEBUF_SZ, PROT_READ | PROT_WRITE);
51+
assert(!err);
52+
err = mprotect(xbase, CODEBUF_SZ, PROT_EXEC);
53+
assert(!err);
54+
#else
55+
addr = mmap(NULL, CODEBUF_SZ, PROT_READ | PROT_WRITE | PROT_EXEC,
56+
MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT, -1, 0);
57+
assert(addr != MAP_FAILED);
58+
xbase = addr;
59+
#endif
60+
wbase = addr;
61+
cspace = create_mspace_with_base(addr, CODEBUF_SZ, 0);
62+
assert(cspace);
63+
}
64+
65+
void EndGenCodeBuf(void)
66+
{
67+
destroy_mspace(cspace);
68+
if (xbase != wbase)
69+
munmap(xbase, CODEBUF_SZ);
70+
munmap(wbase, CODEBUF_SZ);
71+
}
72+
73+
struct cbptr AllocGenCodeBuf(size_t size)
74+
{
75+
struct cbptr ret;
76+
77+
ret.ptr = mspace_malloc(cspace, size);
78+
assert(ret.ptr);
79+
ret.xptr = xbase + (ret.ptr - wbase);
80+
return ret;
81+
}
82+
83+
void ShrinkGenCodeBuf(struct cbptr ptr, size_t size)
84+
{
85+
void *ptr2 = mspace_realloc(cspace, ptr.ptr, size);
86+
assert(ptr2 == ptr.ptr);
87+
}
88+
89+
void FreeGenCodeBuf(void *ptr)
90+
{
91+
if (!ptr)
92+
return;
93+
mspace_free(cspace, ptr);
94+
}
95+
96+
unsigned char *GetGenCodeBuf(const unsigned char *eip)
97+
{
98+
assert(eip >= xbase && eip < xbase + CODEBUF_SZ);
99+
return wbase + (eip - xbase);
100+
}
101+
102+
unsigned char *GetExecCodeBuf(const unsigned char *ptr)
103+
{
104+
assert(ptr >= wbase && ptr < wbase + CODEBUF_SZ);
105+
return xbase + (ptr - wbase);
106+
}

src/base/emu-i386/simx86/codegen-x86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2436,7 +2436,7 @@ static unsigned Exec_x86_asm(unsigned *mem_ref, unsigned long *flg,
24362436
#endif
24372437
"pop "RE_REG(bp)"\n"
24382438
: "=d"(*flg),"=a"(ePC),"=D"(*mem_ref),"=c"(*seqbase)
2439-
: "b"(ecpu),"d"(*flg),"a"(SeqStart),
2439+
: "b"(ecpu),"d"(*flg),"a"(GetExecCodeBuf(SeqStart)),
24402440
[mb]"D"(jb) // don't use "r" or can assign to %rbp
24412441
/* Note: we need to clobber "class-less" regs (like %rbp) even
24422442
* if we save/restore them, to avoid gcc from allocating

src/base/emu-i386/simx86/codegen.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@
5555
#include <string.h>
5656
#include "utilities.h"
5757
#include "emu86.h"
58-
#include "misc/dlmalloc.h"
59-
#include "mapping/mapping.h"
6058
#include "codegen-arch.h"
6159

6260
unsigned char * (*CodeGen)(unsigned char *CodePtr, unsigned char *BaseGenBuf, const IGen *IG);
@@ -393,11 +391,12 @@ void Gen(int op, int mode, ...)
393391
/////////////////////////////////////////////////////////////////////////////
394392

395393

396-
static unsigned char *ProduceCode(unsigned int PC, IMeta *I0)
394+
static struct cbptr ProduceCode(unsigned int PC, IMeta *I0)
397395
{
398396
int i,j,mall_req;
399397
unsigned char *cp, *cp1, *BaseGenBuf, *CodePtr;
400398
size_t GenBufSize;
399+
struct cbptr cbp;
401400

402401
if (debug_level('e')>1) {
403402
e_printf("---------------------------------------------\n");
@@ -415,7 +414,8 @@ static unsigned char *ProduceCode(unsigned int PC, IMeta *I0)
415414
for (i=0; i<=CurrIMeta; i++)
416415
GenBufSize += I0[i].ngen * MAX_GEND_BYTES_PER_OP;
417416
mall_req = GenBufSize + 32;// 32 for tail
418-
BaseGenBuf = dlmalloc(mall_req);
417+
cbp = AllocGenCodeBuf(mall_req);
418+
BaseGenBuf = cbp.ptr;
419419
/* actual code buffer starts from here */
420420
CodePtr = BaseGenBuf;
421421
I0->daddr = 0;
@@ -467,11 +467,11 @@ static unsigned char *ProduceCode(unsigned int PC, IMeta *I0)
467467

468468
/* shrink buffer to what is actually needed */
469469
mall_req = I0->totlen;
470-
BaseGenBuf = dlrealloc(BaseGenBuf, mall_req);
470+
ShrinkGenCodeBuf(cbp, mall_req);
471471
if (debug_level('e')>3)
472472
e_printf("Seq len %#x:%#x\n",I0->seqlen,I0->totlen);
473473

474-
return BaseGenBuf;
474+
return cbp;
475475
}
476476

477477

@@ -503,7 +503,7 @@ TNode *Close(unsigned int PC, unsigned int Interp_LONG_CS, int mode,
503503
{
504504
IMeta *I0;
505505
TNode *G;
506-
unsigned char *GenCodeBuf;
506+
struct cbptr GenCodeBuf;
507507

508508
assert (CurrIMeta >= 0);
509509

src/base/emu-i386/simx86/cpatch.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void m_munprotect(unsigned int addr, unsigned int len, unsigned char *eip)
7070
return;
7171
// no need to invalidate the whole page here,
7272
// as the page does not need to be unprotected
73-
InvalidateNodeRange(addr, len, eip);
73+
InvalidateNodeRange_X(addr, len, eip);
7474
#if PROFILE
7575
CpatchInvalidates++;
7676
#endif
@@ -260,7 +260,7 @@ void stk_32(dosaddr_t addr, Bit32u value)
260260
static void wri8_slow(dosaddr_t addr, Bit8u value, unsigned char *eip)
261261
{
262262
if (e_querymark(addr, 1)) {
263-
InvalidateNodeRange(addr, 1, eip);
263+
InvalidateNodeRange_X(addr, 1, eip);
264264
#if PROFILE
265265
CpatchInvalidates++;
266266
#endif
@@ -271,7 +271,7 @@ static void wri8_slow(dosaddr_t addr, Bit8u value, unsigned char *eip)
271271
static void wri16_slow(dosaddr_t addr, Bit16u value, unsigned char *eip)
272272
{
273273
if (e_querymark(addr, 2)) {
274-
InvalidateNodeRange(addr, 2, eip);
274+
InvalidateNodeRange_X(addr, 2, eip);
275275
#if PROFILE
276276
CpatchInvalidates++;
277277
#endif
@@ -282,7 +282,7 @@ static void wri16_slow(dosaddr_t addr, Bit16u value, unsigned char *eip)
282282
static void wri32_slow(dosaddr_t addr, Bit32u value, unsigned char *eip)
283283
{
284284
if (e_querymark(addr, 4)) {
285-
InvalidateNodeRange(addr, 4, eip);
285+
InvalidateNodeRange_X(addr, 4, eip);
286286
#if PROFILE
287287
CpatchInvalidates++;
288288
#endif

src/base/emu-i386/simx86/cpu-emu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ void init_emu_cpu(int cpu_type)
775775
}
776776
e_printf("EMU86: tss mask=%08lx\n", eTSSMASK);
777777
mprot_init();
778+
InitGenCodeBuf();
778779
InitGen();
779780
InitTrees();
780781
sem_init(&prejit_sem, 0, 0);
@@ -910,6 +911,7 @@ void leave_cpu_emu(void)
910911
IOFF(0x10)=INT10_WATCHER_OFF;
911912
#endif
912913
EndGen();
914+
EndGenCodeBuf();
913915
#ifdef DEBUG_TREE
914916
fclose(tLog); tLog = NULL;
915917
#endif

src/base/emu-i386/simx86/emu86.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,9 +749,18 @@ int e_querymprotrange_full(unsigned int addr, size_t len);
749749
int e_markpage(unsigned int addr, size_t len);
750750
int e_unmarkpage(unsigned int addr, size_t len);
751751
void m_munprotect(unsigned int addr, unsigned int len, unsigned char *eip);
752+
753+
struct cbptr {
754+
unsigned char *ptr;
755+
unsigned char *xptr;
756+
};
752757
void InitGenCodeBuf(void);
753-
void *AllocGenCodeBuf(size_t size);
758+
void EndGenCodeBuf(void);
759+
struct cbptr AllocGenCodeBuf(size_t size);
760+
void ShrinkGenCodeBuf(struct cbptr ptr, size_t size);
754761
void FreeGenCodeBuf(void *ptr);
762+
unsigned char *GetGenCodeBuf(const unsigned char *eip);
763+
unsigned char *GetExecCodeBuf(const unsigned char *ptr);
755764
//
756765
void CollectStat(void);
757766
//

src/base/emu-i386/simx86/memory.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#include "mapping/mapping.h"
4343
#include "dosemu_debug.h"
4444
#include "utilities.h"
45-
#include "misc/dlmalloc.h"
4645
#include "emu86.h"
4746
#include "trees.h"
4847
#include "codegen.h"

src/base/emu-i386/simx86/sigsegv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ static int e_vgaemu_fault(sigcontext_t *scp, dosaddr_t cr2)
248248
/* save eip, eflags, and do a "ret" out of compiled code */
249249
static int e_return_from_jit(sigcontext_t *scp, int pop_flags)
250250
{
251-
_scp_eax = FindPC((unsigned char *)_scp_rip);
251+
_scp_eax = FindPC_X((unsigned char *)_scp_rip);
252252
e_printf("FindPC: found %x\n",_scp_eax);
253253
if (pop_flags) {
254254
_scp_edx = *(long *)_scp_rsp; // flags
@@ -397,7 +397,7 @@ int e_handle_pagefault(dosaddr_t addr, unsigned err, sigcontext_t *scp)
397397
/* We HAVE to invalidate all the code in the page
398398
* if the page is going to be unprotected */
399399
addr &= _PAGE_MASK;
400-
return InvalidateNodeRange(addr, PAGE_SIZE, p);
400+
return InvalidateNodeRange_X(addr, PAGE_SIZE, p);
401401
}
402402

403403
int e_handle_fault(sigcontext_t *scp)

src/base/emu-i386/simx86/trees.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#include <errno.h>
4848
#include <sys/mman.h>
4949
#include "emu86.h"
50-
#include "misc/dlmalloc.h"
5150
#include "codegen.h"
5251

5352
IMeta InstrMeta[MAXINODES];
@@ -446,7 +445,7 @@ void avltr_delete(const int key)
446445
pthread_mutex_unlock(&trees_mtx);
447446
leavedos_main(0x8130);
448447
}
449-
if (G->addr) dlfree(G->addr);
448+
FreeGenCodeBuf(G->addr);
450449
__atomic_store_n(&findtree_cache[G->key&FINDTREE_CACHE_HASH_MASK],
451450
NULL, __ATOMIC_RELAXED);
452451
free(G);
@@ -636,7 +635,7 @@ void avltr_destroy(void)
636635
B = B->next;
637636
free(B2);
638637
}
639-
if (p->data->addr) dlfree(p->data->addr);
638+
FreeGenCodeBuf(p->data->addr);
640639
free(p->data);
641640
p->data = NULL;
642641
}
@@ -1148,7 +1147,7 @@ static int TraverseAndClean(void)
11481147
* code addresses. At the end, we reset both CodeBuf and InstrMeta to prepare
11491148
* for a new sequence.
11501149
*/
1151-
TNode *Move2Tree(IMeta *I0, unsigned char *GenCodeBuf)
1150+
TNode *Move2Tree(IMeta *I0, struct cbptr GenCodeBuf)
11521151
{
11531152
TNode *nG = NULL;
11541153
#if PROFILE >= 2
@@ -1184,7 +1183,7 @@ TNode *Move2Tree(IMeta *I0, unsigned char *GenCodeBuf)
11841183
/* ->REPLACE the code of the node found with the latest
11851184
compiled version */
11861185
NodeUnlinker(nG);
1187-
if (nG->addr) dlfree(nG->addr);
1186+
FreeGenCodeBuf(nG->addr);
11881187
free(nG);
11891188
}
11901189
else {
@@ -1213,7 +1212,7 @@ TNode *Move2Tree(IMeta *I0, unsigned char *GenCodeBuf)
12131212
__atomic_store_n(&findtree_cache[key&FINDTREE_CACHE_HASH_MASK], nG,
12141213
__ATOMIC_RELAXED);
12151214

1216-
nG->addr = GenCodeBuf;
1215+
nG->addr = GenCodeBuf.ptr;
12171216

12181217
/* setup structures for inter-node linking */
12191218
nG->unlinked_jmp_targets = 0;
@@ -1530,7 +1529,7 @@ static void do_invalidate(unsigned data, int cnt)
15301529
{
15311530
cnt = PAGE_ALIGN(data + cnt) - (data & _PAGE_MASK);
15321531
data &= _PAGE_MASK;
1533-
InvalidateNodeRange(data, cnt, 0);
1532+
InvalidateNodeRange(data, cnt, NULL);
15341533
}
15351534

15361535
static void _e_invalidate(unsigned data, int cnt)
@@ -1542,7 +1541,7 @@ static void _e_invalidate(unsigned data, int cnt)
15421541
return;
15431542
// no need to invalidate the whole page here,
15441543
// as the page does not need to be unprotected
1545-
InvalidateNodeRange(data, cnt, 0);
1544+
InvalidateNodeRange(data, cnt, NULL);
15461545
}
15471546

15481547
void e_invalidate(unsigned data, int cnt)

0 commit comments

Comments
 (0)