Skip to content

lld-macho: offset is outside the section in lld::macho::isCodeSection #139439

Open
@dianqk

Description

@dianqk

The following code fails to link on x86_64-apple-darwin:

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iostream>

// Helper to disable optimizations around a value.
static int black_box(int x) {
    volatile int temp = x;
    asm volatile("" ::: "memory");
    return temp;
}

__attribute__((noinline))
int slice_len_from_ptr_end(const char* ptr, const char* end) {
    return black_box(end - ptr);
}

static int slice_len(const char* ptr, int len) {
    const char* end = ptr + len;
    return slice_len_from_ptr_end(ptr, end);
}

__attribute__((noinline))
void non_trivial_destructor() {
    asm volatile("" ::: "memory");
}

struct NonTrivialDestructor {
    ~NonTrivialDestructor() {
        non_trivial_destructor();
    }
};

__attribute__((noinline))
int broken(int version) {
    NonTrivialDestructor _has_drop;

    switch (version) {
        case 1:
            return slice_len("aaaaaaa", 8);
        case 2:
            return slice_len("bbbbbbb", 8);
        case 3:
            return slice_len("bbbbbbb", 8);
        default:
            return 42;
    }
}

int main() {
    // Should return 8, unexpectedly returns 0 with old linker.
    return broken(2);
}

(from rust-lang/rust#140686 (comment) cc @madsmtm)

output:

$ clang++ main.cpp -O1 -target x86_64-apple-darwin -fuse-ld=lld
ld64.lld: warning: directory not found for option -L/usr/local/lib
ld64.lld: error: /var/folders/3_/gbxrlh2d7mq4gcvmny3pjzvc0000gn/T/main-2dec97.o:(__cstring): offset is outside the section
clang: error: linker command failed with exit code 1 (use -v to see invocation)

$ clang++ --version
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: arm64-apple-darwin23.2.0
Thread model: posix
InstalledDir: /Applications/Xcode-15.4.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ ld64.lld --version
LLD 20.1.4

Here is a simpler IR:

@L1 = private constant [1 x i8] zeroinitializer, align 1
@L2 = private unnamed_addr constant [8 x i8] c"\01\02\03\04\05\06\07\08", align 1
@L3 = private constant [1 x i8] c"\09", align 1
@reltable.broken = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @L1 to i64), i64 ptrtoint (ptr @reltable.broken to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @L2 to i64), i64 ptrtoint (ptr @reltable.broken to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @L3 to i64), i64 ptrtoint (ptr @reltable.broken to i64)) to i32)], align 4
@reltable.broken.1 = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds ([1 x i8], ptr @L1, i64 1, i64 0) to i64), i64 ptrtoint (ptr @reltable.broken.1 to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds ([8 x i8], ptr @L2, i64 1, i64 0) to i64), i64 ptrtoint (ptr @reltable.broken.1 to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds ([1 x i8], ptr @L3, i64 1, i64 0) to i64), i64 ptrtoint (ptr @reltable.broken.1 to i64)) to i32)], align 4

define i64 @broken(i64 noundef %0) {
  %reltable.shift = shl i64 %0, 2
  %2 = getelementptr i8, ptr @reltable.broken, i64 %reltable.shift
  %3 = load i32, ptr %2, align 4
  %4 = getelementptr i8, ptr @reltable.broken, i32 %3
  %5 = getelementptr i8, ptr @reltable.broken.1, i64 %reltable.shift
  %6 = load i32, ptr %5, align 4
  %7 = getelementptr i8, ptr @reltable.broken.1, i32 %6
  %8 = tail call i64 @slice_len_from_ptr_end(ptr noundef nonnull %4, ptr noundef nonnull %7)
  ret i64 %8
}

declare i64 @slice_len_from_ptr_end(ptr noundef, ptr noundef)

output:

clang foo.ll -shared -undefined dynamic_lookup -target x86_64-apple-darwin -fuse-ld=lld
warning: overriding the module target triple with x86_64-apple-macosx14.0.0 [-Woverride-module]
1 warning generated.
ld64.lld: warning: directory not found for option -L/usr/local/lib
out_of_range was thrown in -fno-exceptions mode with message "unordered_map::at: key not found"PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
 #0 0x000000010c3fb694 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0x16b694)
 #1 0x000000010c3f9608 llvm::sys::RunSignalHandlers() (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0x169608)
 #2 0x000000010c3fbde8 SignalHandler(int) (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0x16bde8)
 #3 0x00000001884c9a24 (/usr/lib/system/libsystem_platform.dylib+0x18046da24)
 #4 0x0000000188499cc0 (/usr/lib/system/libsystem_pthread.dylib+0x18043dcc0)
 #5 0x00000001883a5a40 (/usr/lib/system/libsystem_c.dylib+0x180349a40)
 #6 0x000000010366ecf0 std::__1::__cxx_atomic_notify_one(void const volatile*) (/nix/store/qh3kz2ywxgq1fl4ngkbav298nmgybnaq-libcxx-19.1.7/lib/libc++.1.0.dylib+0x2acf0)
 #7 0x0000000102afc0a4 std::__1::__function::__func<lld::coff::LinkerDriver::linkerMain(llvm::ArrayRef<char const*>)::$_5, std::__1::allocator<lld::coff::LinkerDriver::linkerMain(llvm::ArrayRef<char const*>)::$_5>, void (lld::coff::SymbolTable&)>::~__func() (/nix/store/caj11qkzv4rgl695lk39c3kjyjd85cfw-lld-20.1.4/bin/ld64.lld+0x10005c0a4)
 #8 0x0000000102dc037c lld::macho::isCodeSection(lld::macho::InputSection const*) (/nix/store/caj11qkzv4rgl695lk39c3kjyjd85cfw-lld-20.1.4/bin/ld64.lld+0x10032037c)
 #9 0x0000000102dc00c8 lld::macho::WordLiteralInputSection::getOffset(unsigned long long) const (/nix/store/caj11qkzv4rgl695lk39c3kjyjd85cfw-lld-20.1.4/bin/ld64.lld+0x1003200c8)
#10 0x0000000102dbeffc lld::macho::ConcatInputSection::writeTo(unsigned char*) (/nix/store/caj11qkzv4rgl695lk39c3kjyjd85cfw-lld-20.1.4/bin/ld64.lld+0x10031effc)
#11 0x0000000102d84308 lld::macho::TextOutputSection::writeTo(unsigned char*) const (/nix/store/caj11qkzv4rgl695lk39c3kjyjd85cfw-lld-20.1.4/bin/ld64.lld+0x1002e4308)
#12 0x000000010c36c1ec std::__1::__function::__func<llvm::parallelFor(unsigned long, unsigned long, llvm::function_ref<void (unsigned long)>)::$_0, std::__1::allocator<llvm::parallelFor(unsigned long, unsigned long, llvm::function_ref<void (unsigned long)>)::$_0>, void ()>::operator()() (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0xdc1ec)
#13 0x000000010c36c054 std::__1::__function::__func<llvm::parallel::TaskGroup::spawn(std::__1::function<void ()>)::$_0, std::__1::allocator<llvm::parallel::TaskGroup::spawn(std::__1::function<void ()>)::$_0>, void ()>::operator()() (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0xdc054)
#14 0x000000010c36ba8c llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::work(llvm::ThreadPoolStrategy, unsigned int) (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0xdba8c)
#15 0x000000010c36bb5c void* std::__1::__thread_proxy[abi:nn190107]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::ThreadPoolExecutor(llvm::ThreadPoolStrategy)::'lambda'()::operator()() const::'lambda'()>>(void*) (/nix/store/0r3i5hld2830wvjrpzmf9nww7vqljad6-llvm-20.1.4-lib/lib/libLLVM.dylib+0xdbb5c)
#16 0x000000018849a034 (/usr/lib/system/libsystem_pthread.dylib+0x18043e034)
#17 0x0000000188494e3c (/usr/lib/system/libsystem_pthread.dylib+0x180438e3c)
clang: error: unable to execute command: Abort trap: 6
clang: error: linker command failed due to signal (use -v to see invocation)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions