aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJez Ng <me@jezng.com>2025-11-01 13:44:21 -0400
committerGitHub <noreply@github.com>2025-11-01 13:44:21 -0400
commitc3bc30bd282b84e5afdcebf72a9f9aa8ba1442ce (patch)
treee396e16cc5bc1aebc16e7ceed2925a8180cdad66
parent03d044971eccac47ed8518684ea18ba413cd5748 (diff)
downloadllvm-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.cpp3
-rw-r--r--lld/test/MachO/invalid/bad-offsets.s45
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 &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())) {
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