From b1f75f03f47856862c421bb1e5b1f4fc1d3fa997 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Thu, 30 Jul 2026 08:34:02 +0000
Subject: [PATCH 1/3] [tapi] Infer macOS platform for load-command-less
 ppc/ppc64 dylibs

PowerPC dylibs from macOS 10.5 and earlier predate the
LC_VERSION_MIN_MACOSX and LC_BUILD_VERSION load commands, so they carry
no platform information. Both Mach-O readers fall back to an "unknown" OS
triple in that case, which the reader then rejects outright via
mapToPlatformType() == PLATFORM_UNKNOWN ("unknown/unsupported platform").
The result is that a perfectly valid ppc/ppc64 dylib cannot be read at
all.

PowerPC only ever targeted macOS, so when no platform load command is
present infer a macOS target for ppc/ppc64 instead of an unknown one. A
version-less "macos" triple defaults to the 10.4 deployment floor, the
correct minimum to assume when the binary records none. Behavior for all
other architectures is unchanged.

Applied to both the TAPI Core reader (MachOReader.cpp, used by
MachODylibReader / stubify / libtapi) and the LLVM TextAPI binary reader
(DylibReader.cpp, used by tapi-binary-reader) so the whole toolchain is
consistent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PrKAYGVW1tzwQAAoTGXVfM
---
 .../lib/TextAPI/BinaryReader/DylibReader.cpp   | 18 ++++++++++++++----
 src/tapi/lib/Core/MachOReader.cpp              | 18 ++++++++++++++----
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp b/src/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
index 40b57b5..435356d 100644
--- a/src/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
+++ b/src/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
@@ -132,10 +132,20 @@ static TripleVec constructTriples(MachOObjectFile *Obj,
     }
   }
 
-  // Record unknown platform for older binaries that don't enforce platform
-  // load commands.
-  if (Triples.empty())
-    emplace(Triples, {Arch, "apple", "unknown"});
+  // Handle older binaries that don't carry a platform load command.
+  if (Triples.empty()) {
+    // PowerPC only ever targeted macOS, and ppc/ppc64 dylibs predate the
+    // LC_VERSION_MIN_MACOSX / LC_BUILD_VERSION load commands (macOS 10.5 and
+    // earlier). Infer a macOS target instead of an unknown platform, which the
+    // reader would otherwise reject. A version-less "macos" triple defaults to
+    // the 10.4 deployment floor, the correct minimum when none is recorded.
+    if (ArchT == AK_ppc || ArchT == AK_ppc64)
+      emplace(Triples, {Arch, "apple", "macos"});
+    else
+      // Record unknown platform for older binaries that don't enforce platform
+      // load commands.
+      emplace(Triples, {Arch, "apple", "unknown"});
+  }
 
   return Triples;
 }
diff --git a/src/tapi/lib/Core/MachOReader.cpp b/src/tapi/lib/Core/MachOReader.cpp
index 323a21a..ba4849d 100644
--- a/src/tapi/lib/Core/MachOReader.cpp
+++ b/src/tapi/lib/Core/MachOReader.cpp
@@ -820,10 +820,20 @@ std::vector<Triple> constructTripleFromMachO(MachOObjectFile *object) {
     }
   }
 
-  // record unknown platform for older binary that does not enforece platform
-  // load commands.
-  if (triples.empty())
-    triples.emplace_back(arch, "apple", "unknown");
+  // Handle older binaries that do not carry a platform load command.
+  if (triples.empty()) {
+    // PowerPC only ever targeted macOS, and ppc/ppc64 dylibs predate the
+    // LC_VERSION_MIN_MACOSX / LC_BUILD_VERSION load commands (macOS 10.5 and
+    // earlier). Infer a macOS target instead of an unknown platform, which the
+    // reader would otherwise reject. A version-less "macos" triple defaults to
+    // the 10.4 deployment floor, the correct minimum when none is recorded.
+    if (archType == AK_ppc || archType == AK_ppc64)
+      triples.emplace_back(arch, "apple", "macos");
+    else
+      // record unknown platform for older binary that does not enforce platform
+      // load commands.
+      triples.emplace_back(arch, "apple", "unknown");
+  }
 
   // Remove duplicates.
   sort(triples, [](const Triple &lhs, const Triple &rhs) {
-- 
2.43.0

