[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.
This commit is contained in:
Jez Ng 2025-11-01 13:44:21 -04:00 committed by GitHub
parent 03d044971e
commit c3bc30bd28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 0 deletions

View File

@ -348,6 +348,9 @@ WordLiteralInputSection::WordLiteralInputSection(const Section &section,
}
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())) {

View File

@ -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