Skip to content

ld64.lld: error: too many personalities (4) for compact unwind to encode #102754

Open
@glandium

Description

@glandium
Contributor

When mixing ObjC, C++ and Rust in the same binary on aarch64-apple-darwin targets (e.g. like in Firefox), lld from LLVM 15 complains about "too many personalities". This is a regression from #92845 and affects beta.

For some reason, since #92845, this code in lld is hit: https://github.com/llvm/llvm-project/blob/d30dccd21f2c3bc1ed6cd054c131436a1af548e1/lld/MachO/UnwindInfoSection.cpp#L300

Ultimately, this leads to https://github.com/llvm/llvm-project/blob/d30dccd21f2c3bc1ed6cd054c131436a1af548e1/lld/MachO/UnwindInfoSection.cpp#L378
where there are 4 personalities instead of 3:

  • ___objc_personality_v0,
  • ___gxx_personality_v0,
  • _rust_eh_personality
  • <internal>

With previous rust versions, only the first three ones would be there. It looks like the relocation that triggers the <internal> is related to the rust_eh_personality function in library/std/src/personality/gcc.rs itself.

STR:

  • Create a bar.cc file with content:
#include <stdexcept>

extern "C" void qux();

void bar() { qux(); throw std::runtime_error("foo"); }
  • Create a foo.m file with content:
void foo() { @try {} @finally {} }
  • Create a qux.rs file with content:
#![crate_type = "staticlib"]

extern "C" {
    fn foo();
}

#[no_mangle]
pub unsafe extern "C" fn qux() {
    println!("foo");
    foo();
}
  • Create a Makefile file with content:
TARGET = --target=aarch64-apple-darwin

lib.dylib: bar.o foo.o libqux.a
	clang++ -o $@ $^ -fuse-ld=lld -dynamiclib $(TARGET) -lobjc

bar.o: bar.cc
	clang++ -o $@ -c $^ $(TARGET)

foo.o: foo.m
	clang -o $@ -c $^ $(TARGET)

libqux.a: qux.rs
	rustc $^ $(TARGET)
  • Get clang 15 + lld and make sure it's in your $PATH.
  • Set SDKROOT to point to a macOS SDK
  • Run make

This does not happen on x86_64-apple-darwin, but interestingly the list of personalities there is:

  • ___objc_personality_v0,
  • ___gxx_personality_v0,
  • <internal>
    (no _rust_eh_personality).

With rust 1.64, the list of personalities was:

  • ___objc_personality_v0,
  • ___gxx_personality_v0,
  • _rust_eh_personality

Activity

nagisa

nagisa commented on Oct 9, 2022

@nagisa
Member

So, uh, wouldn’t this code basically mean that you cannot link a binary that consists of more than 3 languages with their own unwinding personalities? That seems like an unfortunate limitation, and I would argue that this is something ld.lld should be fixing, regardless.

As for why the <internal> gets constructed, I would imagine that with the move of the personality into libstd one of the codegen units now starts containing both the personality function and the functionality that depends on that personality (whereas before nothing in the standalone unwinding crate could unwind and thus did not reference the personality function.)

A workaround on our end could probably be to make sure these personality functions end up in a CU of their own.

nagisa

nagisa commented on Oct 9, 2022

@nagisa
Member

Does this happen with other linkers (e.g. ld that ships with Xcode, if it is something other than lld?)

added
A-linkageArea: linking into static, shared libraries and binaries
O-macosOperating system: macOS
O-iosOperating system: iOS
on Oct 9, 2022
glandium

glandium commented on Oct 10, 2022

@glandium
ContributorAuthor

It doesn't happen with ld64, but the resulting binary only lists 3 personalities as per llvm-object --unwind-info...

glandium

glandium commented on Oct 11, 2022

@glandium
ContributorAuthor

Should this be labeled regression-stable-to-beta or something?

added
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Oct 11, 2022
added this to the 1.65.0 milestone on Oct 11, 2022
apiraino

apiraino commented on Oct 11, 2022

@apiraino
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-critical

added and removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Oct 11, 2022

89 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.O-iosOperating system: iOSO-macosOperating system: macOSP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.relnotesMarks issues that should be documented in the release notes of the next release.

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @bridiver@pcwalton@pnkfelix@rillian@Amanieu

      Issue actions

        ld64.lld: error: too many personalities (4) for compact unwind to encode · Issue #102754 · rust-lang/rust