Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling to Apple's arm64e got linking error! #138481

Open
Wyvern opened this issue Mar 14, 2025 · 3 comments
Open

Compiling to Apple's arm64e got linking error! #138481

Wyvern opened this issue Mar 14, 2025 · 3 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. O-macos Operating system: macOS

Comments

@Wyvern
Copy link

Wyvern commented Mar 14, 2025

When compiling to Apple's arm64e targets arm64e-apple-ios arm64e-apple-tvos arm64e-apple-darwin using -Zbuild-stdgot linking error:

linking with `cc` failed: exit status: 1
          rust-lld: error: INVALID relocation has width 8 bytes, but must be 0 bytes at offset 128 of __DATA,__data in /var/folders/r4/ph658m2d3vs0vj00g75q0zyr0000gn/T/rustcj3lmdR/symbols.o
          rust-lld: error: INVALID relocation has width 8 bytes, but must be 0 bytes at offset 0 of __DATA,__data in /var/folders/r4/ph658m2d3vs0vj00g75q0zyr0000gn/T/rustcj3lmdR/symbols.o
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

Rust: 1.87.0-nightly (cbfdf0b 2025-03-13)

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 14, 2025
@saethlin saethlin added the S-needs-repro Status: This issue has no reproduction and needs a reproduction to make progress. label Mar 14, 2025
@bjorn3
Copy link
Member

bjorn3 commented Mar 14, 2025

Probably something wrong in

/// Add relocation and section data needed for a symbol to be considered
/// undefined by ld64.
///
/// The relocation must be valid, and hence must point to a valid piece of
/// machine code, and hence this is unfortunately very architecture-specific.
///
///
/// # New architectures
///
/// The values here are basically the same as emitted by the following program:
///
/// ```c
/// // clang -c foo.c -target $CLANG_TARGET
/// void foo(void);
///
/// extern int bar;
///
/// void* foobar[2] = {
/// (void*)foo,
/// (void*)&bar,
/// // ...
/// };
/// ```
///
/// Can be inspected with:
/// ```console
/// objdump --macho --reloc foo.o
/// objdump --macho --full-contents foo.o
/// ```
pub(super) fn add_data_and_relocation(
file: &mut object::write::Object<'_>,
section: object::write::SectionId,
symbol: object::write::SymbolId,
target: &Target,
kind: SymbolExportKind,
) -> object::write::Result<()> {
let authenticated_pointer =
kind == SymbolExportKind::Text && target.llvm_target.starts_with("arm64e");
let data: &[u8] = match target.pointer_width {
_ if authenticated_pointer => &[0, 0, 0, 0, 0, 0, 0, 0x80],
32 => &[0; 4],
64 => &[0; 8],
pointer_width => unimplemented!("unsupported Apple pointer width {pointer_width:?}"),
};
if target.arch == "x86_64" {
// Force alignment for the entire section to be 16 on x86_64.
file.section_mut(section).append_data(&[], 16);
} else {
// Elsewhere, the section alignment is the same as the pointer width.
file.section_mut(section).append_data(&[], target.pointer_width as u64);
}
let offset = file.section_mut(section).append_data(data, data.len() as u64);
let flags = if authenticated_pointer {
object::write::RelocationFlags::MachO {
r_type: object::macho::ARM64_RELOC_AUTHENTICATED_POINTER,
r_pcrel: false,
r_length: 3,
}
} else if target.arch == "arm" {
// FIXME(madsmtm): Remove once `object` supports 32-bit ARM relocations:
// https://github.com/gimli-rs/object/pull/757
object::write::RelocationFlags::MachO {
r_type: object::macho::ARM_RELOC_VANILLA,
r_pcrel: false,
r_length: 2,
}
} else {
object::write::RelocationFlags::Generic {
kind: object::RelocationKind::Absolute,
encoding: object::RelocationEncoding::Generic,
size: target.pointer_width as u8,
}
};
file.add_relocation(section, object::write::Relocation { offset, addend: 0, symbol, flags })?;
Ok(())
}

@bjorn3 bjorn3 added the O-macos Operating system: macOS label Mar 14, 2025
@madsmtm
Copy link
Contributor

madsmtm commented Mar 19, 2025

It seems to be a bug in lld. E.g. the following:

void foo(void);

extern int bar;

void* foobar[2] = {
    (void*)foo,
    (void*)&bar,
};

int main() {
    return 0;
}

Fails when linking with rust-lld too:

$ clang -target arm64e-apple-macosx -fuse-ld=$HOME/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/bin/gcc-ld/ld64.lld foo.c
rust-lld: warning: directory not found for option -L/usr/local/lib
rust-lld: error: INVALID relocation has width 8 bytes, but must be 0 bytes at offset 0 of __DATA,__data in /var/folders/0j/tk3sfgz540712zgqd1hrry0m0000gn/T/foo-e172f0.o
rust-lld: error: undefined symbol: bar
>>> referenced by /var/folders/0j/tk3sfgz540712zgqd1hrry0m0000gn/T/foo-e172f0.o:(symbol foobar+0x8)
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@madsmtm
Copy link
Contributor

madsmtm commented Mar 19, 2025

Fundamentally because lld doesn't support arm64e at all: llvm/llvm-project#79543.

We could "fix" this in rustc by not doing the relocation stuff on arm64e, but I'm inclined to not do so, linking with lld is horribly broken here and doesn't actually get you an arm64e binary. The upstream issue should be resolved instead.

@rustbot label +A-llvm +A-linkage -S-needs-repro -needs-triage

@rustbot rustbot added A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. and removed S-needs-repro Status: This issue has no reproduction and needs a reproduction to make progress. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. O-macos Operating system: macOS
Projects
None yet
Development

No branches or pull requests

5 participants