I'm trying to make JonesForth run on a recent MacBook out of the box, just using Mac tools.
I started to convert everything 64 bits and attend to the Mac assembler syntax.
I got things to assemble, but I immediately run into a curious segmentation fault:
/* NEXT macro. */ .macro NEXT lodsq jmpq *(%rax) .endm ... /* Assembler entry point. */ .text .globl start .balign 16 start: cld mov %rsp,var_SZ(%rip) // Save the initial data stack pointer in FORTH variable S0. mov return_stack_top(%rip),%rbp // Initialise the return stack. //call set_up_data_segment mov cold_start(%rip),%rsi // Initialise interpreter. NEXT // Run interpreter! .const cold_start: // High-level code without a codeword. .quad QUIT
QUIT is defined like this via macro defword:
.macro defword .const_data .balign 8 .globl name_$3 name_$3 : .quad $4 // Link .byte $2+$1 // Flags + length byte .ascii $0 // The name .balign 8 // Padding to next four-byte boundary .globl $3 $3 : .quad DOCOL // Codeword - the interpreter // list of word pointers follow .endm // QUIT must not return (ie. must not call EXIT). defword "QUIT",4,,QUIT,name_TELL .quad RZ,RSPSTORE // R0 RSP!, clear the return stack .quad INTERPRET // Interpret the next word .quad BRANCH,-16 // And loop (indefinitely) ...more code
When I run this, I get a segmentation fault the first time in the NEXT macro:
(lldb) run There is a running process, kill it and restart?: [Y/n] y Process 83000 exited with status = 9 (0x00000009) Process 83042 launched: '/Users/klapauciusisgreat/jonesforth64/jonesforth' (x86_64) Process 83042 stopped * thread #1, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x0000000100000698 jonesforth`start + 24 jonesforth`start: -> 0x100000698 <+24>: jmpq *(%rax) 0x10000069a <+26>: nopw (%rax,%rax) jonesforth`code_DROP: 0x1000006a0 <+0>: popq %rax 0x1000006a1 <+1>: lodsq (%rsi), %rax Target 0: (jonesforth) stopped.
rax does point to what I think is the dereferenced address, DOCOL:
(lldb) register read General Purpose Registers: rax = 0x0000000100000660 jonesforth`DOCOL
So one mystery is:
I commented out the original segment setup code in the original that called brk to set up a data segment. Another [implementation] also did not call it at all, so I thought I could as well ignore this. Is there any magic on how to set up segment permissions with syscalls in a 64-bit binary on Catalina? The make command is pretty much the standard JonesForth one:
jonesforth: jonesforth.S gcc -nostdlib -g -static $(BUILD_ID_NONE) -o $@ $<
P.S.: Yes, I can get JonesForth to work perfectly in Docker images, but that's besides the point. I really want it to work in 64 bit on Catalina, out of the box.
The original code had something like
And the Apple assembler complains about not being able to use 32 immediate addressing in 64-bit binaries.
So I tried
but that also doesn't work.
So I tried
which assembles, but of course it dereferences
cold start, which is not something I need.
The correct way of doing this is apparently
This seems to work as intended.
User contributions licensed under CC BY-SA 3.0