diff options
Diffstat (limited to 'lld')
| -rw-r--r-- | lld/ELF/Arch/ARM.cpp | 2 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 18 | ||||
| -rw-r--r-- | lld/ELF/ScriptParser.cpp | 7 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 7 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.h | 4 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 7 | ||||
| -rw-r--r-- | lld/MachO/Arch/X86_64.cpp | 2 | ||||
| -rw-r--r-- | lld/MachO/BPSectionOrderer.cpp | 4 | ||||
| -rw-r--r-- | lld/MachO/Driver.cpp | 28 | ||||
| -rw-r--r-- | lld/MachO/InputSection.cpp | 3 | ||||
| -rw-r--r-- | lld/MachO/Sections.cpp | 2 | ||||
| -rw-r--r-- | lld/test/ELF/aarch64-build-attributes.s | 10 | ||||
| -rw-r--r-- | lld/test/ELF/arm-wraparound-veneer.s | 102 | ||||
| -rw-r--r-- | lld/test/MachO/bp-section-orderer.s | 5 | ||||
| -rw-r--r-- | lld/test/MachO/invalid/bad-offsets.s | 45 |
15 files changed, 202 insertions, 44 deletions
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index 91a673f..6c4290f 100644 --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -472,7 +472,7 @@ bool ARM::inBranchRange(RelType type, uint64_t src, uint64_t dst) const { // Bit 0 == 1 denotes Thumb state, it is not part of the range. dst &= ~0x1; - int64_t offset = dst - src; + int64_t offset = llvm::SignExtend64<32>(dst - src); switch (type) { case R_ARM_PC24: case R_ARM_PLT32: diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index e52d3a0..8647752 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -156,23 +156,23 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(Ctx &ctx, std::pair<ELFKind, uint16_t> ret = StringSwitch<std::pair<ELFKind, uint16_t>>(s) - .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64}) - .Cases("aarch64elfb", "aarch64linuxb", {ELF64BEKind, EM_AARCH64}) - .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM}) - .Cases("armelfb", "armelfb_linux_eabi", {ELF32BEKind, EM_ARM}) + .Cases({"aarch64elf", "aarch64linux"}, {ELF64LEKind, EM_AARCH64}) + .Cases({"aarch64elfb", "aarch64linuxb"}, {ELF64BEKind, EM_AARCH64}) + .Cases({"armelf", "armelf_linux_eabi"}, {ELF32LEKind, EM_ARM}) + .Cases({"armelfb", "armelfb_linux_eabi"}, {ELF32BEKind, EM_ARM}) .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64}) - .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS}) - .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS}) + .Cases({"elf32btsmip", "elf32btsmipn32"}, {ELF32BEKind, EM_MIPS}) + .Cases({"elf32ltsmip", "elf32ltsmipn32"}, {ELF32LEKind, EM_MIPS}) .Case("elf32lriscv", {ELF32LEKind, EM_RISCV}) - .Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC}) - .Cases("elf32lppc", "elf32lppclinux", {ELF32LEKind, EM_PPC}) + .Cases({"elf32ppc", "elf32ppclinux"}, {ELF32BEKind, EM_PPC}) + .Cases({"elf32lppc", "elf32lppclinux"}, {ELF32LEKind, EM_PPC}) .Case("elf32loongarch", {ELF32LEKind, EM_LOONGARCH}) .Case("elf64btsmip", {ELF64BEKind, EM_MIPS}) .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS}) .Case("elf64lriscv", {ELF64LEKind, EM_RISCV}) .Case("elf64ppc", {ELF64BEKind, EM_PPC64}) .Case("elf64lppc", {ELF64LEKind, EM_PPC64}) - .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64}) + .Cases({"elf_amd64", "elf_x86_64"}, {ELF64LEKind, EM_X86_64}) .Case("elf_i386", {ELF32LEKind, EM_386}) .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU}) .Case("elf64_sparc", {ELF64BEKind, EM_SPARCV9}) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 4b9c941..b61dc647 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -450,7 +450,7 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) { .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) - .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS}) + .Cases({"elf32-tradbigmips", "elf32-bigmips"}, {ELF32BEKind, EM_MIPS}) .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) @@ -463,7 +463,8 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) { .Case("elf32-loongarch", {ELF32LEKind, EM_LOONGARCH}) .Case("elf64-loongarch", {ELF64LEKind, EM_LOONGARCH}) .Case("elf64-s390", {ELF64BEKind, EM_S390}) - .Cases("elf32-hexagon", "elf32-littlehexagon", {ELF32LEKind, EM_HEXAGON}) + .Cases({"elf32-hexagon", "elf32-littlehexagon"}, + {ELF32LEKind, EM_HEXAGON}) .Default({ELFNoneKind, EM_NONE}); } @@ -745,7 +746,7 @@ StringMatcher ScriptParser::readFilePatterns() { SortSectionPolicy ScriptParser::peekSortKind() { return StringSwitch<SortSectionPolicy>(peek()) .Case("REVERSE", SortSectionPolicy::Reverse) - .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name) + .Cases({"SORT", "SORT_BY_NAME"}, SortSectionPolicy::Name) .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment) .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority) .Case("SORT_NONE", SortSectionPolicy::None) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index bbf4b29..a4150eb 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2749,14 +2749,13 @@ RelroPaddingSection::RelroPaddingSection(Ctx &ctx) : SyntheticSection(ctx, ".relro_padding", SHT_NOBITS, SHF_ALLOC | SHF_WRITE, 1) {} -RandomizePaddingSection::RandomizePaddingSection(Ctx &ctx, uint64_t size, - OutputSection *parent) - : SyntheticSection(ctx, ".randomize_padding", SHT_PROGBITS, SHF_ALLOC, 1), +PaddingSection::PaddingSection(Ctx &ctx, uint64_t size, OutputSection *parent) + : SyntheticSection(ctx, ".padding", SHT_PROGBITS, SHF_ALLOC, 1), size(size) { this->parent = parent; } -void RandomizePaddingSection::writeTo(uint8_t *buf) { +void PaddingSection::writeTo(uint8_t *buf) { std::array<uint8_t, 4> filler = getParent()->getFiller(ctx); uint8_t *end = buf + size; for (; buf + 4 <= end; buf += 4) diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index ac3ec63..38e6811 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -779,11 +779,11 @@ public: void writeTo(uint8_t *buf) override {} }; -class RandomizePaddingSection final : public SyntheticSection { +class PaddingSection final : public SyntheticSection { uint64_t size; public: - RandomizePaddingSection(Ctx &ctx, uint64_t size, OutputSection *parent); + PaddingSection(Ctx &ctx, uint64_t size, OutputSection *parent); size_t getSize() const override { return size; } void writeTo(uint8_t *buf) override; }; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 4fa8039..083b4fb 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1495,15 +1495,14 @@ static void randomizeSectionPadding(Ctx &ctx) { if (auto *isd = dyn_cast<InputSectionDescription>(bc)) { SmallVector<InputSection *, 0> tmp; if (os->ptLoad != curPtLoad) { - tmp.push_back(make<RandomizePaddingSection>( - ctx, g() % ctx.arg.maxPageSize, os)); + tmp.push_back( + make<PaddingSection>(ctx, g() % ctx.arg.maxPageSize, os)); curPtLoad = os->ptLoad; } for (InputSection *isec : isd->sections) { // Probability of inserting padding is 1 in 16. if (g() % 16 == 0) - tmp.push_back( - make<RandomizePaddingSection>(ctx, isec->addralign, os)); + tmp.push_back(make<PaddingSection>(ctx, isec->addralign, os)); tmp.push_back(isec); } isd->sections = std::move(tmp); diff --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp index a7c4b45..111c4d9 100644 --- a/lld/MachO/Arch/X86_64.cpp +++ b/lld/MachO/Arch/X86_64.cpp @@ -104,7 +104,7 @@ int64_t X86_64::getEmbeddedAddend(MemoryBufferRef mb, uint64_t offset, void X86_64::relocateOne(uint8_t *loc, const Reloc &r, uint64_t value, uint64_t relocVA) const { if (r.pcrel) { - uint64_t pc = relocVA + (1 << r.length) + pcrelOffset(r.type); + uint64_t pc = relocVA + (1ull << r.length) + pcrelOffset(r.type); value -= pc; } diff --git a/lld/MachO/BPSectionOrderer.cpp b/lld/MachO/BPSectionOrderer.cpp index d50abc2..328c33e 100644 --- a/lld/MachO/BPSectionOrderer.cpp +++ b/lld/MachO/BPSectionOrderer.cpp @@ -118,6 +118,10 @@ DenseMap<const InputSection *, int> lld::macho::runBalancedPartitioning( auto *isec = subsec.isec; if (!isec || isec->data.empty() || !isec->data.data()) continue; + // CString section order is handled by + // {Deduplicated}CStringSection::finalizeContents() + if (isa<CStringInputSection>(isec) || isec->isFinal) + continue; // ConcatInputSections are entirely live or dead, so the offset is // irrelevant. if (isa<ConcatInputSection>(isec) && !isec->isLive(0)) diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 9b67db9..32b2099 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -841,18 +841,18 @@ static PlatformVersion parsePlatformVersion(const Arg *arg) { // TODO(compnerd) see if we can generate this case list via XMACROS platformVersion.platform = StringSwitch<PlatformType>(lowerDash(platformStr)) - .Cases("macos", "1", PLATFORM_MACOS) - .Cases("ios", "2", PLATFORM_IOS) - .Cases("tvos", "3", PLATFORM_TVOS) - .Cases("watchos", "4", PLATFORM_WATCHOS) - .Cases("bridgeos", "5", PLATFORM_BRIDGEOS) - .Cases("mac-catalyst", "6", PLATFORM_MACCATALYST) - .Cases("ios-simulator", "7", PLATFORM_IOSSIMULATOR) - .Cases("tvos-simulator", "8", PLATFORM_TVOSSIMULATOR) - .Cases("watchos-simulator", "9", PLATFORM_WATCHOSSIMULATOR) - .Cases("driverkit", "10", PLATFORM_DRIVERKIT) - .Cases("xros", "11", PLATFORM_XROS) - .Cases("xros-simulator", "12", PLATFORM_XROS_SIMULATOR) + .Cases({"macos", "1"}, PLATFORM_MACOS) + .Cases({"ios", "2"}, PLATFORM_IOS) + .Cases({"tvos", "3"}, PLATFORM_TVOS) + .Cases({"watchos", "4"}, PLATFORM_WATCHOS) + .Cases({"bridgeos", "5"}, PLATFORM_BRIDGEOS) + .Cases({"mac-catalyst", "6"}, PLATFORM_MACCATALYST) + .Cases({"ios-simulator", "7"}, PLATFORM_IOSSIMULATOR) + .Cases({"tvos-simulator", "8"}, PLATFORM_TVOSSIMULATOR) + .Cases({"watchos-simulator", "9"}, PLATFORM_WATCHOSSIMULATOR) + .Cases({"driverkit", "10"}, PLATFORM_DRIVERKIT) + .Cases({"xros", "11"}, PLATFORM_XROS) + .Cases({"xros-simulator", "12"}, PLATFORM_XROS_SIMULATOR) .Default(PLATFORM_UNKNOWN); if (platformVersion.platform == PLATFORM_UNKNOWN) error(Twine("malformed platform: ") + platformStr); @@ -948,7 +948,7 @@ getUndefinedSymbolTreatment(const ArgList &args) { StringRef treatmentStr = args.getLastArgValue(OPT_undefined); auto treatment = StringSwitch<UndefinedSymbolTreatment>(treatmentStr) - .Cases("error", "", UndefinedSymbolTreatment::error) + .Cases({"error", ""}, UndefinedSymbolTreatment::error) .Case("warning", UndefinedSymbolTreatment::warning) .Case("suppress", UndefinedSymbolTreatment::suppress) .Case("dynamic_lookup", UndefinedSymbolTreatment::dynamic_lookup) @@ -972,7 +972,7 @@ getUndefinedSymbolTreatment(const ArgList &args) { static ICFLevel getICFLevel(const ArgList &args) { StringRef icfLevelStr = args.getLastArgValue(OPT_icf_eq); auto icfLevel = StringSwitch<ICFLevel>(icfLevelStr) - .Cases("none", "", ICFLevel::none) + .Cases({"none", ""}, ICFLevel::none) .Case("safe", ICFLevel::safe) .Case("safe_thunks", ICFLevel::safe_thunks) .Case("all", ICFLevel::all) 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/MachO/Sections.cpp b/lld/MachO/Sections.cpp index a27d902..47169c7 100644 --- a/lld/MachO/Sections.cpp +++ b/lld/MachO/Sections.cpp @@ -27,7 +27,7 @@ bool isCodeSection(StringRef name, StringRef segName, uint32_t flags) { if (segName == segment_names::text) return StringSwitch<bool>(name) - .Cases(section_names::textCoalNt, section_names::staticInit, true) + .Cases({section_names::textCoalNt, section_names::staticInit}, true) .Default(false); return false; diff --git a/lld/test/ELF/aarch64-build-attributes.s b/lld/test/ELF/aarch64-build-attributes.s index f2d5421..3d333bf 100644 --- a/lld/test/ELF/aarch64-build-attributes.s +++ b/lld/test/ELF/aarch64-build-attributes.s @@ -1,11 +1,11 @@ // REQUIRES: aarch64 // RUN: rm -rf %t && split-file %s %t && cd %t -// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t1.o -// RUN: llvm-mc -triple=aarch64 -filetype=obj pauth-bti-gcs.s -o %t2.o -// RUN: llvm-mc -triple=aarch64 -filetype=obj pauth-bti-pac.s -o %t3.o -// RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t.merged.o -// RUN: llvm-readelf -n %t.merged.o | FileCheck %s --check-prefix=NOTE +// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o 1.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj pauth-bti-gcs.s -o 2.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj pauth-bti-pac.s -o 3.o +// RUN: ld.lld -r 1.o 2.o 3.o -o merged.o +// RUN: llvm-readelf -n merged.o | FileCheck %s --check-prefix=NOTE /// This test merges three object files with AArch64 build attributes. /// All contain identical PAuth ABI info (platform/version), which must be preserved. diff --git a/lld/test/ELF/arm-wraparound-veneer.s b/lld/test/ELF/arm-wraparound-veneer.s new file mode 100644 index 0000000..74dd6f2 --- /dev/null +++ b/lld/test/ELF/arm-wraparound-veneer.s @@ -0,0 +1,102 @@ +// REQUIRES: arm +// RUN: rm -rf %t && split-file %s %t && cd %t +// RUN: llvm-mc -filetype=obj -triple=armv7-none-eabi code.s -o code.o +// RUN: ld.lld -T unsigned1.ld code.o -o unsigned1.elf +// RUN: llvm-objdump --triple=armv7 --no-show-raw-insn -d unsigned1.elf | FileCheck %s --check-prefix=UNSIGNED1 +// RUN: ld.lld -T unsigned2.ld code.o -o unsigned2.elf +// RUN: llvm-objdump --triple=armv7 --no-show-raw-insn -d unsigned2.elf | FileCheck %s --check-prefix=UNSIGNED2 +// RUN: ld.lld -T signed1.ld code.o -o signed1.elf +// RUN: llvm-objdump --triple=armv7 --no-show-raw-insn -d signed1.elf | FileCheck %s --check-prefix=SIGNED1 +// RUN: ld.lld -T signed2.ld code.o -o signed2.elf +// RUN: llvm-objdump --triple=armv7 --no-show-raw-insn -d signed2.elf | FileCheck %s --check-prefix=SIGNED2 + +/// The aim of this test is to ensure that a BL instruction near one end of the +/// address space can reach a function at the extreme other end, directly, +/// using a branch offset that makes the address wrap round. We check this at +/// both the unsigned wraparound point (one address near 0 and the other near +/// 0xFFFFFFFF) and the signed wraparound point (addresses either side of +/// 0x80000000), crossing the boundary in both directions. In all four cases we +/// expect a direct branch with no veneer. + +// UNSIGNED1: Disassembly of section .text.lowaddr: +// UNSIGNED1: <func>: +// UNSIGNED1: 10000: bx lr +// +// UNSIGNED1: Disassembly of section .text.highaddr: +// UNSIGNED1: <_start>: +// UNSIGNED1: ffff0000: bl 0x10000 +// UNSIGNED1-NEXT: bx lr + +// UNSIGNED2: Disassembly of section .text.lowaddr: +// UNSIGNED2: <_start>: +// UNSIGNED2: 10000: bl 0xffff0000 +// UNSIGNED2-NEXT: bx lr +// +// UNSIGNED2: Disassembly of section .text.highaddr: +// UNSIGNED2: <func>: +// UNSIGNED2: ffff0000: bx lr + +// SIGNED1: Disassembly of section .text.posaddr: +// SIGNED1: <_start>: +// SIGNED1: 7fff0000: bl 0x80010000 +// SIGNED1-NEXT: bx lr +// +// SIGNED1: Disassembly of section .text.negaddr: +// SIGNED1: <func>: +// SIGNED1: 80010000: bx lr + +// SIGNED2: Disassembly of section .text.posaddr: +// SIGNED2: <func>: +// SIGNED2: 7fff0000: bx lr +// +// SIGNED2: Disassembly of section .text.negaddr: +// SIGNED2: <_start>: +// SIGNED2: 80010000: bl 0x7fff0000 +// SIGNED2-NEXT: bx lr + +//--- code.s + + .section .text.callee, "ax", %progbits + .global func + .type func, %function +func: + bx lr + + .section .text.caller, "ax", %progbits + .global _start + .type _start, %function +_start: + bl func + bx lr + +//--- unsigned1.ld + +ENTRY(_start) +SECTIONS { + .text.lowaddr 0x00010000 : AT(0x00010000) { *(.text.callee) } + .text.highaddr 0xffff0000 : AT(0xffff0000) { *(.text.caller) } +} + +//--- unsigned2.ld + +ENTRY(_start) +SECTIONS { + .text.lowaddr 0x00010000 : AT(0x00010000) { *(.text.caller) } + .text.highaddr 0xffff0000 : AT(0xffff0000) { *(.text.callee) } +} + +//--- signed1.ld + +ENTRY(_start) +SECTIONS { + .text.posaddr 0x7fff0000 : AT(0x7fff0000) { *(.text.caller) } + .text.negaddr 0x80010000 : AT(0x80010000) { *(.text.callee) } +} + +//--- signed2.ld + +ENTRY(_start) +SECTIONS { + .text.posaddr 0x7fff0000 : AT(0x7fff0000) { *(.text.callee) } + .text.negaddr 0x80010000 : AT(0x80010000) { *(.text.caller) } +} diff --git a/lld/test/MachO/bp-section-orderer.s b/lld/test/MachO/bp-section-orderer.s index 90924e5..d7de90d 100644 --- a/lld/test/MachO/bp-section-orderer.s +++ b/lld/test/MachO/bp-section-orderer.s @@ -106,6 +106,11 @@ r3: r4: .quad s2 +# cstrings are ignored by runBalancedPartitioning() +.cstring +cstr: + .asciz "this is cstr" + .bss bss0: .zero 10 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 |
