devs! Could you help me? The project's goal is to translate byte code from a fictional architecture, generating an array of real machine code and make it run with jit, but I get a segmentation fault when I try to save a certain part of the output on a file. Part of the code responsible for this:
uint32_t length = sysconf(4096);
void * memory = mmap(0 , length , PROT_NONE , MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0);
//{machine array receives the translated machine code here...}
mprotect ( memory , length , PROT_WRITE ) ;
// copying the machine code array to the memory
memcpy ( memory , ( void *) ( machine ) , sizeof ( machine ) ) ;
mprotect ( memory , length , PROT_EXEC ) ;
uint32_t length = sysconf(4096);
const uint32_t (* jit ) (int32_t*, uint8_t*) = ( uint32_t (*) (int32_t*, uint8_t*) ) ( memory );
// running the machine code to produce de outputs
// &R is the array of registers to store the output and &mem contains the original byte
// code to receive inputs from a instruction that changes the original code
(*jit)((int *)&R, (unsigned char *)&mem);
munmap(memory,length);
// printf/fprintf that causes the segmentation fault if we try to print n and ic[n]
// n = 0; - does not work to print the correct starting value for n
// fflush(stdout); - works to print the correct starting value for n
for(n = 0; n < 16; n++) {
// fprintf(output,"%02x:\n",n);
// fprintf(output,":%d\n",ic[n]);
fprintf(output,"%02x:%d\n",n,ic[n]);
// printf("%02x:%d\n",n,ic[n]);
// fflush(stdout);
}
for (k = 0; k < 16; k++) {
fprintf(output,"R[%d]=0x%08x\n",k,R[k]);
}
The original byte code translated to instructions on this pseudo-assembly code. On this code, the R's represent and array of registers that is passed to the real assembly code R0 is %rdi, R1 = %rdi+0x4,..., R15 = %rdi+0x3C. Some of those pseudo-instructions translate to one or more actual assembly instructions, and [Rn] represents the memory location which contains the byte code for the original architecture. So when it access [Rn], it uses the current value for the register as the position to get the next 4 bytes (an instruction on the fantasy architecture is 4 bytes long).
mov R0, 0x006C
mov R1, 0x0001
mov R2, [R0]
cmp R15, R2
je 0x0030
mov R14, R2
jg 0x0000
jl 0x0000
add R13, R14
and R12, R13
or R11, R12
xor R10, R11
shl R10, 0x00
shr R10, 0x00
sub R2, R1
mov [R0], R2
jmp 0xFFC8
mov R1, 0x0004
add R0, R1
mov R2, [R0]
add R0, R1
mov R4, [R0]
add R0, R1
mov R8, [R0]
add R0, R1
mov R12, [R0]
jmp 0x0004
mov R3, R12
or R6, R13
add R10, R8
sub R15, R14
For the original architecture instructions (00 to 0F) and 16 registers (R[0] to R[15], the output should follow the model:
original instruction opcode: number of times executed
array of registers: value stored. Something like this:
00:2
01:1
...
0e:1
0f:1
R[0]=0x0000006c
R[1]=0x00000001
...
R[13]=0x03885533
R[14]=0x03885533
R[15]=0x00000000
The problem is that I keep getting a segmentation fault when I try to save the opcode: number of executions. If I try to print only the "opcode:" and register:value pairs, there's no segmentation fault, but instead of printing the first opcode value as "0:", it prints "6C:" which is the R[0] and the r12 (asm register) according to the gdb:
I have tried to insert the push rbp, mov rbp, rsp before the assembly code and the pop rbp, ret after the assembly, but nothing works. Any ideas that could help? Any more infos that I could provide?
Thanks for the help and have a good day.