Firstly, apologies for accidentally starting new threads.
The patch allows this c program (macOS aarch64:
extern void * __stdoutp;
extern int fprintf(void *, const char *, ...);
static void * f;
static int (*p)(void *, const char *, ...);
int main() {
p = fprintf;
f = __stdoutp;
p(f, "hello\n");
}
To be compiled thus (with a new "extern” linkage keyword):
data $.Lstring.2 = align 1 { b "hello\012\000", }
export
function w $main() {
@start.1
@body.2
storel extern $fprintf, $p
%.1 =l loadl extern $__stdoutp
storel %.1, $f
%.2 =l loadl $f
%.3 =l loadl $p
%.4 =w call %.3(l %.2, l $.Lstring.2)
ret 0
}
data $f = align 8 { z 8 }
data $p = align 8 { z 8 }
Generating this assembler:
.data
.balign 1
_.Lstring.2:
.ascii "hello\012\000"
/* end data */
.text
.balign 4
.globl _main
_main:
stp x29, x30, [sp, -16]!
mov x29, sp
adrp x1, _p@page
add x1, x1, _p@pageoff
adrp x0, _fprintf@gotpage
ldr x0, [x0, _fprintf@gotpageoff]
str x0, [x1]
adrp x0, ___stdoutp@gotpage
ldr x0, [x0, ___stdoutp@gotpageoff]
ldr x0, [x0]
adrp x1, _f@page
add x1, x1, _f@pageoff
str x0, [x1]
adrp x1, _p@page
add x1, x1, _p@pageoff
ldr x2, [x1]
adrp x1, _.Lstring.2@page
add x1, x1, _.Lstring.2@pageoff
blr x2
mov w0, #0
ldp x29, x30, [sp], 16
ret
/* end function main */
.bss
.balign 8
_f:
.fill 8,1,0
/* end data */
.bss
.balign 8
_p:
.fill 8,1,0
/* end data */
Thus we can call pointers to building functions, in
this case fprintf, without linker errors.