Hi,
Trying to get pointers to functions working:
export function w $main() {
@body.1
%.1 =l loadl $fred # also tried storel $fred, $pfred
storel %.1, $pfred
call $fred()
call $pfred() # <<<< fails here
ret 0
}
function $fred() {
@body.1
call $printf(l $str_hello)
ret
}
data $pfred = {l 0}
data $str_hello = { b "hello\n", b 0 }
Compiles without linker error but I get a zsh: bus error ./tmp2
when I run it. When I try taking the address of printf or fprintf
I get linker errors.
Solutions would be welcome or pointers on stuff to read up on too.
Thx,
-- David
PS
Linker errors are along the lines of:
final section layout:
__TEXT/__text addr=0x100003EE8, size=0x000000D0, fileOffset=0x00003EE8, type=1
__TEXT/__unwind_info addr=0x100003FB8, size=0x00000048, fileOffset=0x00003FB8, type=22
__DATA/__data addr=0x100004000, size=0x0000001D, fileOffset=0x00004000, type=0
ld: ARM64 ADRP out of range (-4294979584 max is +/-4GB): from _main (0x100003EE8) to _printf@0x00000000 (0x00000000) in '_main' from /var/folders/_y/9km6chyj3mb5_ql1krwhcs4c0000gn/T/tmp-b3e919.o for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
But my Google and chatGPT foo are failing to help me diagnose at the moment.
On Tue May 9, 2023 at 2:46 PM CEST, dangermouseb wrote:
> export function w $main() {> @body.1> %.1 =l loadl $fred # also tried storel $fred, $pfred
%.1 =l copy $fred
call %.1()
something like this is what you need.
Your IL file is very wrong. Here is something that
has a chance to work:
export function w $main() {
@body.1
storel $fred, $pfred # stores the address of the fred function
# into the global pfred
%fn =l loadl $pfred # loads an address from the global pfred
call %fn() # calls this address
ret 0
}
function $fred() {
@body.1
call $printf(l $str_hello, ...)
ret
}
data $pfred = {l 0}
data $str_hello = { b "hello\n", b 0 }
> %.1 =l copy $fred> call %.1()> > something like this is what you need.
Brilliant - that worked nicely. Thank you.
My next question is how to get hold of stderr so I can use fprintf.
On Tue, May 9, 2023, at 14:51, Drew DeVault wrote:
> %.1 =l copy $fred> call %.1()
Note that qbe will hastily get rid of the copy and
just turn this code into:
call $fred()
On Tue May 9, 2023 at 3:02 PM CEST, Quentin Carbonneaux wrote:
> Note that qbe will hastily get rid of the copy and> just turn this code into:>> call $fred()
'course :)
Quoth dangermouseb <dangermouseb@forwarding.cc>:
> > > %.1 =l copy $fred> > call %.1()> > > > something like this is what you need.> > Brilliant - that worked nicely. Thank you.> > My next question is how to get hold of stderr so I can use fprintf.> > >
that depends very heavily on your libc; you'll have to
read the headers and see how it's defined. eg, on OpenBSD:
#define stdin (&__sF[0])
on other systems it will be different.
>> >> My next question is how to get hold of stderr so I can use fprintf.>> > > that depends very heavily on your libc; you'll have to> read the headers and see how it's defined. eg, on OpenBSD:> > #define stdin (&__sF[0])> > on other systems it will be different.>
So I lifted `extern FILE *__stderrp` from stdio.h, assumed it was
void * in QBE, but could figure out the link problem for macOS.
#define stderr __stderrp
where
extern FILE *__stderrp;
typedef struct __sFILE {
...
} FILE;
int fprintf(FILE * restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3)));
What seems odd is I can link printf okay.
On Tue, May 9, 2023, at 15:49, dangermouseb wrote:
> So I lifted `extern FILE *__stderrp` from stdio.h, assumed it was> void * in QBE, but could figure out the link problem for macOS.
See my answer to your other mail. qbe does not do well
with taking the address of dynamically-linked symbols.