From 89d8fe9d08c395875cf1201feaf9d213cadeea7a Mon Sep 17 00:00:00 2001 From: wanglei Date: Fri, 20 Mar 2026 10:03:09 +0800 Subject: [PATCH] [LoongArch] Ensure .dwo sections do not contain relocations (#187429) When linker relaxation is enabled, LoongArchAsmBackend may emit relocations for same-section symbol differences, even when the fixup is in a .dwo section. This leads to errors such as: error: A dwo section may not contain relocations Split DWARF (.dwo) sections must not contain relocations. Fix this by resolving such fixups immediately when they are emitted into .dwo sections, even if the referenced symbols are in relaxable sections. This avoids generating invalid relocations in .debug_*.dwo sections when compiling with -gsplit-dwarf and -mrelax. Fixes #187428 --- .../MCTargetDesc/LoongArchAsmBackend.cpp | 13 +++--- .../DebugInfo/LoongArch/dwo-no-relocations.ll | 45 +++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 llvm/test/DebugInfo/LoongArch/dwo-no-relocations.ll diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp index 6a8869c5d708..2eb95c2512d5 100644 --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp @@ -427,11 +427,14 @@ bool LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup, isPCRelFixupResolved(Target.getSubSym(), F)) return Fallback(); - // In SecA == SecB case. If the section is not linker-relaxable, the - // FixedValue has already been calculated out in evaluateFixup, - // return true and avoid record relocations. - if (&SecA == &SecB && !SecA.isLinkerRelaxable()) - return true; + if (&SecA == &SecB) { + // If the section is not linker-relaxable, or if the fixup is in a .dwo + // section (where relocations are forbidden), we must resolve the + // difference directly. The computed Value in evaluateFixup is correct + // based on the current layout. + if (!SecA.isLinkerRelaxable() || SecCur.getName().ends_with(".dwo")) + return true; + } } switch (Fixup.getKind()) { diff --git a/llvm/test/DebugInfo/LoongArch/dwo-no-relocations.ll b/llvm/test/DebugInfo/LoongArch/dwo-no-relocations.ll new file mode 100644 index 000000000000..cf2b7cf1626b --- /dev/null +++ b/llvm/test/DebugInfo/LoongArch/dwo-no-relocations.ll @@ -0,0 +1,45 @@ +;; Ensure no relocations are emitted into .debug_*.dwo sections. +;; This used to fail when relaxation was enabled. + +; RUN: llc --mtriple=loongarch64-unknown-linux-gnu --dwarf-version=5 \ +; RUN: --split-dwarf-file=foo.dwo --split-dwarf-output=%t.dwo --mattr=+relax --filetype=obj %s -o %t.o +; RUN: llvm-readobj -r %t.dwo | FileCheck %s --check-prefix=DWO-RELOC + +; DWO-RELOC: Relocations [ +; DWO-RELOC-NEXT: ] + +@.str = external constant [3 x i8] + +define i64 @_ZN15partition_alloc8internal4base7strings8internal12SafeSNPrintfEPcmPKcPKNS3_3ArgEm(i1 %cmp14.i622) !dbg !3 { +entry: + %0 = load i8, ptr @.str, align 1 + br i1 %cmp14.i622, label %while.body.i.preheader, label %for.inc.preheader.i, !dbg !6 + +while.body.i.preheader: ; preds = %entry + store i8 %0, ptr null, align 1 + ret i64 0 + +for.inc.preheader.i: ; preds = %entry + %strlen.i = load volatile i64, ptr @.str, align 8 + br label %do.body61.i + +do.body61.i: ; preds = %do.body61.i, %for.inc.preheader.i + %reverse_prefix.2.i = phi ptr [ null, %for.inc.preheader.i ], [ %incdec.ptr98.i, %do.body61.i ] + %cmp96.i = icmp ugt ptr %reverse_prefix.2.i, null + %incdec.ptr98.i = getelementptr i8, ptr %reverse_prefix.2.i, i64 -1, !dbg !9 + br label %do.body61.i +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 22.1.2 (https://github.com/llvm/llvm-project.git 6121df77a781d2e6f9a8e569aa45ccfffd6c7e0e)", isOptimized: true, runtimeVersion: 0, splitDebugFilename: "safe_sprintf.dwo", emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: GNU) +!1 = !DIFile(filename: "../../third_party/partition_alloc/src/partition_alloc/partition_alloc_base/strings/safe_sprintf.cc", directory: "/home/wanglei") +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = distinct !DISubprogram(name: "SafeSNPrintf", scope: !1, file: !1, line: 437, type: !4, scopeLine: 441, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true) +!4 = !DISubroutineType(types: !5) +!5 = !{} +!6 = !DILocation(line: 326, column: 13, scope: !7, inlinedAt: !8, atomGroup: 23, atomRank: 1) +!7 = distinct !DISubprogram(name: "IToASCII", scope: !1, file: !1, line: 276, type: !4, scopeLine: 282, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true) +!8 = distinct !DILocation(line: 597, column: 18, scope: !3) +!9 = !DILocation(line: 385, column: 15, scope: !7, inlinedAt: !8, atomGroup: 57, atomRank: 2)