I'm looking at some code which someone wrote back in cranelift = 0.66
-- and they used load_complex
and store_complex
instructions, which allowed you to pass a dynamic offset (a Value
instead of something which has Into<Offset32>
). What's the correct way to update this codegen now?
Second, I'm running into an issue with the binary format returned by lookup_by_name
let shared_builder = settings::builder();
let shared_flags = settings::Flags::new(shared_builder);
let codegen_flags: settings::Flags = settings::Flags::new(settings::builder());
let mut isa_builder = isa::lookup_by_name("x86_64").unwrap();
let isa = isa_builder.finish(shared_flags).unwrap();
let mut module: ObjectModule = ObjectModule::new(
ObjectBuilder::new(
isa,
[1, 2, 3, 4, 5, 6, 7, 8], // TODO: what is this?
default_libcall_names(),
)
.unwrap(),
);
In the compile, when I run it -- it panics
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Backend(binary format is unknown)', src/codegen.rs:38:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I honestly can't figure out why from looking at the cranelift
APIs.
To answer your second question: You should pass in a full triple to lookup_by_name
, not just the target arch. So for example x86_64-unknown-linux-gnu
. Otherwise cranelift_object doesn't know which OS to use the object file format for.
To answer the first question you can use zero or more iadd instructions before a load/store instruction to compute the address.
@bjorn3 do you know how to find a list of all targets?
See the target_lexicon crate. Basically whatever the latest stable rustc version supports I believe.
Re -- I performed some surgery. I changed instructions, and tested code generation on a Linux box. However, when I try to run the compiler on an Apple M1 -- I get linking warnings:
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _#cc_L from ack.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
and if I try to execute the binaries, I get bus errors. I don't fully understand why this occurs, but I know the parts of my language which are causing these issues for x86-64-apple-darwin
(?)
* thread #1, stop reason = EXC_BAD_ACCESS (code=2, address=0x100003da3)
frame #0: 0x00000002000249a8 dyld`invocation function for block in dyld4::Loader::applyFixupsGeneric(Diagnostics&, dyld4::RuntimeState&, dyld3::Array<void const*> const&, dyld3::Array<void const*> const&, bool, dyld3::Array<dyld4::Loader::MissingFlatLazySymbol> const&) const + 149
dyld`invocation function for block in dyld4::Loader::applyFixupsGeneric(Diagnostics&, dyld4::RuntimeState&, dyld3::Array<void const*> const&, dyld3::Array<void const*> const&, bool, dyld3::Array<dyld4::Loader::MissingFlatLazySymbol> const&) const:
-> 0x2000249a8 <+149>: movq %r15, (%r14)
0x2000249ab <+152>: cmpq 0x50(%r12), %r15
0x2000249b0 <+157>: je 0x2000249c1 ; <+174>
0x2000249b2 <+159>: addq $0x18, %rsp
here's the breaking point from lldb
-- it seems like this is actually a linker issue, but I'm not sure if it's also a cranelift codegen issue.
Is that when trying to build and run a project that uses cranelift or when trying to link and run a program compiled using cranelift?
Link and run a program compiled using cranelift.
I can send clang
flags, etc -- as well. I generate object code with cranelift
-- then run into bus errors, which turn out to be dynamic linking errors (like above).
Before this point, there's no indication that anything is "wrong" per say, except for the PIE warning.
Also, my data structures are aligned on word boundaries, as far as I can tell.
But even if they we're not -- put
to an address not on a word boundary shouldn't error if Rosetta emulation is faithful to x86_64.
I can tell this may be a pretty niche problem -- compiling to x86_64-apple-darwin
then running using Rosetta on an M1. I wasn't sure if this code path was fully supported yet.
Which flags are you setting when creating the TargetIsa
?
Maybe you need to set is_pic
? https://github.com/bjorn3/rustc_codegen_cranelift/blob/c431540544a03dc09577df4b97afd868deb167e5/src/lib.rs#L242
Edit: I'm pretty sure you need to set it.
@McCoy
I actually set is_pic
recently, had no effect.
That doesn't set is_pic
. It merely checks if it is already enabled. You need flags_builder.enable("is_pic").unwrap();
to enable it.
Also you shouldn't use use_colocated_libcalls
as you don't provide the libcalls yourself, but depend on libc which is unlikely to be within 128MiB of your executable on AArch64.
ah! thank you
@bjorn3 perhaps we should change the documentation: https://docs.rs/cranelift/latest/cranelift/prelude/settings/struct.Flags.html#method.is_pic
this says "Enable ..." which confused me.
Yeah. Maybe open an issue?
@bjorn3 do you mean builder.set("is_pic", "true")
(?)
builder.set("is_pic", "true")
and builder.enable("is_pic")
are equivalent.
Turned out that setting this flag enabled fixed code generation -- no more bus errors! Thank you @bjorn3
Re -- I am surprised that that just emits a linker warning...
Perhaps that means that there is a bug in Rosetta
I don't think it is too uncommon for linkers to emit just a warning when they created an executable that is not correct, rather than error.
Last updated: Dec 23 2024 at 12:05 UTC