I'm trying to use Cranelift to call malloc
, with the following IR:
function u0:0() -> i64 system_v {
sig0 = (i64) -> i64 system_v
sig1 = (i64) -> i64 system_v
fn0 = u0:1 sig0
fn1 = u0:2 sig1
block0:
v0 = iconst.i64 20
v1 = iconst.i64 8
v2 = imul v0, v1
v3 = call fn0(v2)
v4 = call fn1(v3)
v5 = iconst.i64 0
return v5
}
fn0 is (should be?) malloc
and fn1 is (should be?) free
.
This compiles fine on x86_64 MacOS, however, when I emit an object file (using cranelift-module
), link with cc
and run it, I obtain the following error:
dyld: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB has segment 1 which is not writable in /<redacted>/examples/./a.out
zsh: abort ./a.out
I'm not sure if I'm doing something wrong (most likely) or this is a bug in Cranelift – any help would be much appreciated.
@Teymour Aldridge Can you run otool -hltdr ./a.out
?
Yes:
./a.out:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777223 3 0x00 2 14 744 0x00000085
Load command 0
cmd LC_SEGMENT_64
cmdsize 72
segname __PAGEZERO
vmaddr 0x0000000000000000
vmsize 0x0000000100000000
fileoff 0
filesize 0
maxprot 0x00000000
initprot 0x00000000
nsects 0
flags 0x0
Load command 1
cmd LC_SEGMENT_64
cmdsize 232
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x0000000000004000
fileoff 0
filesize 16384
maxprot 0x00000005
initprot 0x00000005
nsects 2
flags 0x0
Section
sectname __text
segname __TEXT
addr 0x0000000100003f88
size 0x0000000000000030
offset 16264
align 2^0 (1)
reloff 0
nreloc 0
flags 0x80000600
reserved1 0
reserved2 0
Section
sectname __unwind_info
segname __TEXT
addr 0x0000000100003fb8
size 0x0000000000000048
offset 16312
align 2^2 (4)
reloff 0
nreloc 0
flags 0x00000000
reserved1 0
reserved2 0
Load command 2
cmd LC_SEGMENT_64
cmdsize 72
segname __LINKEDIT
vmaddr 0x0000000100004000
vmsize 0x0000000000004000
fileoff 16384
filesize 240
maxprot 0x00000001
initprot 0x00000001
nsects 0
flags 0x0
Load command 3
cmd LC_DYLD_INFO_ONLY
cmdsize 48
rebase_off 0
rebase_size 0
bind_off 16384
bind_size 40
weak_bind_off 0
weak_bind_size 0
lazy_bind_off 0
lazy_bind_size 0
export_off 16424
export_size 48
Load command 4
cmd LC_SYMTAB
cmdsize 24
symoff 16480
nsyms 5
stroff 16560
strsize 64
Load command 5
cmd LC_DYSYMTAB
cmdsize 80
ilocalsym 0
nlocalsym 0
iextdefsym 0
nextdefsym 2
iundefsym 2
nundefsym 3
tocoff 0
ntoc 0
modtaboff 0
nmodtab 0
extrefsymoff 0
nextrefsyms 0
indirectsymoff 0
nindirectsyms 0
extreloff 0
nextrel 0
locreloff 0
nlocrel 0
Load command 6
cmd LC_LOAD_DYLINKER
cmdsize 32
name /usr/lib/dyld (offset 12)
Load command 7
cmd LC_UUID
cmdsize 24
uuid 9D372077-63F5-3F81-9AEC-969682BFFD4B
Load command 8
cmd LC_BUILD_VERSION
cmdsize 32
platform 1
minos 10.15
sdk 10.15.6
ntools 1
tool 3
version 609.8
Load command 9
cmd LC_SOURCE_VERSION
cmdsize 16
version 0.0
Load command 10
cmd LC_MAIN
cmdsize 24
entryoff 16264
stacksize 0
Load command 11
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1281.100.1
compatibility version 1.0.0
Load command 12
cmd LC_FUNCTION_STARTS
cmdsize 16
dataoff 16472
datasize 8
Load command 13
cmd LC_DATA_IN_CODE
cmdsize 16
dataoff 16480
datasize 0
(__TEXT,__text) section
0000000100003f88 55 48 89 e5 bf 08 00 00 00 48 6b ff 14 48 be 00
0000000100003f98 00 00 00 00 00 00 00 ff d6 48 89 c7 48 be 00 00
0000000100003fa8 00 00 00 00 00 00 ff d6 48 31 c0 48 89 ec 5d c3
Just to confirm you are on x86_64, right?
Also can you run the same command on the original object file before linking?
Does it still error if you omit one or both of the calls?
I'm on MacOS Catalina, x86_64.
I don't the see the error if I emit both calls.
When I run the command on the object file I get this output:
program.o:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777223 3 0x00 1 2 176 0x00000000
Load command 0
cmd LC_SEGMENT_64
cmdsize 152
segname
vmaddr 0x0000000000000000
vmsize 0x0000000000000030
fileoff 208
filesize 48
maxprot 0x00000007
initprot 0x00000007
nsects 1
flags 0x0
Section
sectname __text
segname __TEXT
addr 0x0000000000000000
size 0x0000000000000030
offset 208
align 2^0 (1)
reloff 328
nreloc 2
flags 0x80000400
reserved1 0
reserved2 0
Load command 1
cmd LC_SYMTAB
cmdsize 24
symoff 256
nsyms 3
stroff 304
strsize 21
Relocation information (__TEXT,__text) 2 entries
address pcrel length extern type scattered symbolnum/value
0000000f 0 3 1 0 0 1
0000001e 0 3 1 0 0 2
(__TEXT,__text) section
0000000000000000 55 48 89 e5 bf 08 00 00 00 48 6b ff 14 48 be 00
0000000000000010 00 00 00 00 00 00 00 ff d6 48 89 c7 48 be 00 00
0000000000000020 00 00 00 00 00 00 ff d6 48 31 c0 48 89 ec 5d c3
The error doesn't appear if I omit both calls.
function u0:0() -> i64 system_v {
block0:
v0 = iconst.i64 0
return v0
}
It does appear if I just omit the call to free
:
function u0:0() -> i64 system_v {
sig0 = (i64) -> i64 system_v
fn0 = u0:1 sig0
block0:
v0 = iconst.i64 20
v1 = iconst.i64 8
v2 = imul v0, v1
v3 = call fn0(v2)
v4 = iconst.i64 0
return v4
}
Weirdly enough, I compiled the same program (instantiating the module for Linux) on Linux (Fedora) and it worked fine.
Strange. I don't have a clue what could be going wrong.
Me too! I searched the internet quite a bit and couldn't find anything, so I thought it might be worth asking here.
Do you know of any examples (source-viewable code ideally) using Cranelift and malloc on MacOS?
I _think_ there has been a related bug in LLVM: https://lists.llvm.org/pipermail/llvm-dev/2017-July/115222.html
I managed to fix it!
details: https://github.com/bailion/compiler/commit/909f733af57e33f939940bdfbad4ed36a6bc9b72
Turns out PIC is needed on MacOS (I think at least).
Thank you for your help!
Nice! That explains why cg_clif doesn't hit this issue.
Last updated: Dec 23 2024 at 12:05 UTC