On August 23, I wrote:
[...]
Is there any example code that uses Jolt2? I also tried jolt2/main,
which prompts for code to compile/execute (I think) but I can't get that
to give me anything other than either syntax error or segv, in either 32
or 64-bit. Is this common, or is something wrong in my environment?
After some digging, it turned out that the reason that jolt2 was giving
me segv errors was because the generated code was being placed in a
malloced memory, which lacked the execute permission bit. Newer CPUs
(AMD64, Intel Core2, ...) have MMUs which are capable of enforcing
execute permission on memory regions, and recent Linux kernels (at least
x86_64 ones) are using this capability. So, whenever any generated code
tried to execute, a segv resulted.
There doesn't seem to be a way to malloc memory that's executable in
this kind of system, so I fixed it by using mmap/munmap instead of
malloc/free. The patch (relative to SVN 594) is below. This is probably
not the best possible fix (for instance, I'm not entirely happy with
adding a size instvar to Label) but it does get things working for me.
Regards,
-Martin
Index: function/jolt2/CodeGenerator-i386.st
===================================================================
--- function/jolt2/CodeGenerator-i386.st (revision 594)
+++ function/jolt2/CodeGenerator-i386.st (working copy)
@@ -26,6 +26,7 @@
{ import: CodeGenerator }
{ include "asm-i386.h" }
+{ include <sys/mman.h> }
Intel32CodeGenerator : CodeGenerator ( tempsSize eax ecx edx ebx esp
ebp esi edi cx cl )
@@ -468,7 +469,7 @@
tree generate: self.
CompilerOptions verboseExec ifTrue: [{ printf("code size %d
bytes\n", (int)asm_pc); }].
{ v__size= (oop)asm_pc; }.
- { asm_pc= (insn *)malloc((long)asm_pc); }.
+ { asm_pc= (insn *)mmap(NULL, (long)asm_pc, PROT_READ | PROT_WRITE |
PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); }.
{ asm_pass= 2; }.
{ v__entry= (oop)asm_pc; }.
self relocateLabels_: self _asmPC.
Index: function/jolt2/Compiler.st
===================================================================
--- function/jolt2/Compiler.st (revision 594)
+++ function/jolt2/Compiler.st (working copy)
@@ -954,7 +954,7 @@
Compiler compile: anObject for: codeGeneratorType
[
- | block entry tree gen |
+ | block entry tree gen stats |
self := self withGeneratorType: codeGeneratorType.
(block := Block new)
add: (entry := self newLabel);
@@ -973,7 +973,8 @@
gen lastLive ifTrue: [self error: 'compile: clobber ends with live
register: ', gen lastLive printString].
block allocateRegisters: gen registerAllocator.
CompilerOptions verboseTree ifTrue: [block printOn: StdOut indent:
2. StdOut cr].
- gen generate: block. "gen emit: block."
+ stats := gen generate: block. "gen emit: block."
+ entry length_: stats second.
self postProcess.
CompilerOptions verboseRegs ifTrue: [gen dumpResources].
^entry
@@ -1013,5 +1014,5 @@
Label free
[
CompilerOptions verboseExec ifTrue: [{ printf("free %p\n",
self->v__address); }].
- { free((void *)self->v__address); }.
+ { munmap((void *)self->v__address, self ->v__length); }.
]
Index: function/jolt2/Instruction.st
===================================================================
--- function/jolt2/Instruction.st (revision 594)
+++ function/jolt2/Instruction.st (working copy)
@@ -466,7 +466,7 @@
LabelCount := [ 0 ]
-Label : Statement ( ordinal _address ) Label name [ ^#label ]
+Label : Statement ( ordinal _address _length ) Label name [ ^#label ]
Label new
[
@@ -478,6 +478,7 @@
Label address_: _addr [ _address := _addr ]
Label _address [ ^_address ]
+Label length_: _len [ _length := _len ]
Label relocate_: _addr { self->v__address=
(oop)((long)self->v__address + (long)v__addr); }
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc