[llvm] [dsymutil] Add new argument allow_invalid_macho (PR #173503)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 24 10:15:39 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Ch1p (Ch111p)
<details>
<summary>Changes</summary>
Similar to the issue discussed in [#<!-- -->165940](https://github.com/llvm/llvm-project/pull/165940) and in some apps I’ve seen at work, we’ve observed dSYM files being generated where a section’s offset exceeds 4GB.
This seems to happen because many DWARF sections produced for DWARF4 end up with an alignment of 0. Before [PR #<!-- -->168925](https://github.com/llvm/llvm-project/pull/168925) (which added validation for sections with a zero alignment attribute), this could go unnoticed and result in an invalid MachO.
However, such a dSYM is effectively an invalid Mach-O file today. Unless/until Mach-O explicitly defines standards like:
["32-bit section offsets can exceed 4G but must be ordered for 64-bit offset reconstruction"](https://github.com/llvm/llvm-project/pull/165940#issuecomment-3483238444), I think the proper approach is to add a new argument to support this.
---
Full diff: https://github.com/llvm/llvm-project/pull/173503.diff
6 Files Affected:
- (modified) llvm/tools/dsymutil/DwarfLinkerForBinary.cpp (+1-1)
- (modified) llvm/tools/dsymutil/LinkUtils.h (+4)
- (modified) llvm/tools/dsymutil/MachOUtils.cpp (+4-4)
- (modified) llvm/tools/dsymutil/MachOUtils.h (+1-1)
- (modified) llvm/tools/dsymutil/Options.td (+6)
- (modified) llvm/tools/dsymutil/dsymutil.cpp (+2)
``````````diff
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index 1fc5bba602d8b..68756a891d90d 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -883,7 +883,7 @@ bool DwarfLinkerForBinary::linkImpl(
ObjectType == Linker::OutputFileType::Object)
return MachOUtils::generateDsymCompanion(
Options.VFS, Map, *Streamer->getAsmPrinter().OutStreamer, OutFile,
- RelocationsToApply);
+ RelocationsToApply, Options.AllowInvalidMachO);
Streamer->finish();
return true;
diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h
index c333a3d4afee0..d950f5f19474c 100644
--- a/llvm/tools/dsymutil/LinkUtils.h
+++ b/llvm/tools/dsymutil/LinkUtils.h
@@ -123,6 +123,10 @@ struct LinkOptions {
bool IncludeSwiftModulesFromInterface = false;
/// @}
+ /// Whether to allow generating Mach-O files that exceed certain format
+ /// limitations, such as sections with file offsets greater than 4GB.
+ bool AllowInvalidMachO = false;
+
LinkOptions() = default;
};
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index fba698896618b..deb2225dc22c6 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -324,7 +324,7 @@ static void transferSegmentAndSections(
// Write the __DWARF segment load command to the output file.
static bool createDwarfSegment(const MCAssembler& Asm,uint64_t VMAddr, uint64_t FileOffset,
uint64_t FileSize, unsigned NumSections,
- MachObjectWriter &Writer) {
+ MachObjectWriter &Writer, bool AllowInvalidMachO) {
Writer.writeSegmentLoadCommand("__DWARF", NumSections, VMAddr,
alignTo(FileSize, 0x1000), FileOffset,
FileSize, /* MaxProt */ 7,
@@ -340,7 +340,7 @@ static bool createDwarfSegment(const MCAssembler& Asm,uint64_t VMAddr, uint64_t
VMAddr = alignTo(VMAddr, Alignment);
FileOffset = alignTo(FileOffset, Alignment);
}
- if (FileOffset > UINT32_MAX)
+ if (FileOffset > UINT32_MAX && !AllowInvalidMachO)
return error("section " + Sec->getName() +
"'s file offset exceeds 4GB."
" Refusing to produce an invalid Mach-O file.");
@@ -374,7 +374,7 @@ bool generateDsymCompanion(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM,
MCStreamer &MS, raw_fd_ostream &OutFile,
const std::vector<MachOUtils::DwarfRelocationApplicationInfo>
- &RelocationsToApply) {
+ &RelocationsToApply, bool AllowInvalidMachO) {
auto &ObjectStreamer = static_cast<MCObjectStreamer &>(MS);
MCAssembler &MCAsm = ObjectStreamer.getAssembler();
auto &Writer = static_cast<MachObjectWriter &>(MCAsm.getWriter());
@@ -586,7 +586,7 @@ bool generateDsymCompanion(
// Write the load command for the __DWARF segment.
if (!createDwarfSegment(MCAsm, DwarfVMAddr, DwarfSegmentStart, DwarfSegmentSize,
- NumDwarfSections, Writer))
+ NumDwarfSections, Writer, AllowInvalidMachO))
return false;
assert(OutFile.tell() == LoadCommandSize + HeaderSize);
diff --git a/llvm/tools/dsymutil/MachOUtils.h b/llvm/tools/dsymutil/MachOUtils.h
index 0229647b00f85..d276a21b6de72 100644
--- a/llvm/tools/dsymutil/MachOUtils.h
+++ b/llvm/tools/dsymutil/MachOUtils.h
@@ -59,7 +59,7 @@ bool generateDsymCompanion(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM,
MCStreamer &MS, raw_fd_ostream &OutFile,
const std::vector<MachOUtils::DwarfRelocationApplicationInfo>
- &RelocationsToApply);
+ &RelocationsToApply, bool AllowInvalidMachO);
std::string getArchName(StringRef Arch);
} // namespace MachOUtils
diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td
index 571f90c1e46f5..036094f5eeca5 100644
--- a/llvm/tools/dsymutil/Options.td
+++ b/llvm/tools/dsymutil/Options.td
@@ -108,6 +108,12 @@ def fat64: F<"fat64">,
def update: F<"update">,
HelpText<"Updates existing dSYM files to contain the latest accelerator tables and other DWARF optimizations.">,
Group<grp_general>;
+
+def allow_invalid_macho: F<"allow-invalid-macho">,
+ HelpText<"Allow generating Mach-O files that exceed certain format limitations, such as sections with file offsets greater than 4GB."
+ "Use with caution, as such files may not be compatible with all tools.">,
+ Group<grp_general>;
+
def: Flag<["-"], "u">,
Alias<update>,
HelpText<"Alias for --update">,
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index a71c57c60593c..0a3af1bdb0cec 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -315,6 +315,8 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
Options.LinkOpts.Fat64 = Args.hasArg(OPT_fat64);
Options.LinkOpts.KeepFunctionForStatic =
Args.hasArg(OPT_keep_func_for_static);
+ Options.LinkOpts.AllowInvalidMachO =
+ Args.hasArg(OPT_allow_invalid_macho);
if (opt::Arg *ReproducerPath = Args.getLastArg(OPT_use_reproducer)) {
Options.ReproMode = ReproducerMode::Use;
``````````
</details>
https://github.com/llvm/llvm-project/pull/173503
More information about the llvm-commits
mailing list