diff options
| author | Jez Ng <me@jezng.com> | 2025-11-01 13:44:21 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-01 13:44:21 -0400 |
| commit | c3bc30bd282b84e5afdcebf72a9f9aa8ba1442ce (patch) | |
| tree | e396e16cc5bc1aebc16e7ceed2925a8180cdad66 | |
| parent | 03d044971eccac47ed8518684ea18ba413cd5748 (diff) | |
| download | llvm-c3bc30bd282b84e5afdcebf72a9f9aa8ba1442ce.zip llvm-c3bc30bd282b84e5afdcebf72a9f9aa8ba1442ce.tar.gz llvm-c3bc30bd282b84e5afdcebf72a9f9aa8ba1442ce.tar.bz2 | |
[lld][macho] Error out gracefully when offset is outside literal section (#164660)
We typically shouldn't get this, but when we do (e.g. in #139439) we
should error out gracefully instead of crashing.
Note that we are stricter than ld64 here; ld64 appears to be able to
handle section offsets that point outside literal sections if the end
result is a valid pointer to another section in the input object file.
Supporting this would probably be a pain given our current design, and
it seems like enough of an edge case that it's onot worth it.
| -rw-r--r-- | lld/MachO/InputSection.cpp | 3 | ||||
| -rw-r--r-- | lld/test/MachO/invalid/bad-offsets.s | 45 |
2 files changed, 48 insertions, 0 deletions
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp index b173e14..2b2d28e 100644 --- a/lld/MachO/InputSection.cpp +++ b/lld/MachO/InputSection.cpp @@ -348,6 +348,9 @@ WordLiteralInputSection::WordLiteralInputSection(const Section §ion, } uint64_t WordLiteralInputSection::getOffset(uint64_t off) const { + if (off >= data.size()) + fatal(toString(this) + ": offset is outside the section"); + auto *osec = cast<WordLiteralSection>(parent); const uintptr_t buf = reinterpret_cast<uintptr_t>(data.data()); switch (sectionType(getFlags())) { diff --git a/lld/test/MachO/invalid/bad-offsets.s b/lld/test/MachO/invalid/bad-offsets.s new file mode 100644 index 0000000..e1244ee --- /dev/null +++ b/lld/test/MachO/invalid/bad-offsets.s @@ -0,0 +1,45 @@ +## Test that we properly detect and report out-of-bounds offsets in literal sections. +## We're intentionally testing fatal errors (for malformed input files), and +## fatal errors aren't supported for testing when main is run twice. +# XFAIL: main-run-twice + +# REQUIRES: x86 +# RUN: rm -rf %t; split-file %s %t + +## Test WordLiteralInputSection bounds checking +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/word-literal.s -o %t/word-literal.o +# RUN: not %lld -dylib %t/word-literal.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=WORD + +## Test CStringInputSection bounds checking +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/cstring.s -o %t/cstring.o +# RUN: not %lld -dylib %t/cstring.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CSTRING + +# WORD: error: {{.*}}word-literal.o:(__literal4): offset is outside the section +# CSTRING: error: {{.*}}cstring.o:(__cstring): offset is outside the section + +#--- word-literal.s +.section __TEXT,__literal4,4byte_literals +L_literal: + .long 0x01020304 + +.text +.globl _main +_main: + # We use a subtractor expression to force a section relocation. Symbol relocations + # don't trigger the error. + .long L_literal - _main + 4 + +.subsections_via_symbols + +#--- cstring.s +## Create a cstring section with a reference that points past the end +.cstring +L_str: + .asciz "foo" + +.text +.globl _main +_main: + .long L_str - _main + 4 + +.subsections_via_symbols
\ No newline at end of file |
