[lld] [lld][macho] Support order cstrings with -order_file (PR #140307)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 3 11:08:18 PDT 2025


https://github.com/SharonXSharon updated https://github.com/llvm/llvm-project/pull/140307

>From 4d0a7358771e3fe0009c7a2fcfb7e0a5c9bb86f4 Mon Sep 17 00:00:00 2001
From: Sharon Xu <sharonxu at fb.com>
Date: Thu, 15 May 2025 15:44:13 -0700
Subject: [PATCH 1/6] [lld] Support order cstrings with -order_file_cstring

---
 lld/MachO/Config.h                  |   1 +
 lld/MachO/Driver.cpp                |  21 +--
 lld/MachO/Options.td                |   4 +
 lld/MachO/SectionPriorities.cpp     |  71 +++++++++
 lld/MachO/SectionPriorities.h       |  20 +++
 lld/MachO/SyntheticSections.cpp     |  58 ++++----
 lld/test/MachO/ordre-file-cstring.s | 222 ++++++++++++++++++++++++++++
 7 files changed, 359 insertions(+), 38 deletions(-)
 create mode 100644 lld/test/MachO/ordre-file-cstring.s

diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index a01e60efbe761..d0217b38c3007 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -225,6 +225,7 @@ struct Configuration {
   bool callGraphProfileSort = false;
   llvm::StringRef printSymbolOrder;
 
+  llvm::StringRef cStringOrderFilePath;
   llvm::StringRef irpgoProfilePath;
   bool bpStartupFunctionSort = false;
   bool bpCompressionSortStartupFunctions = false;
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 5c32055166da6..0f2957295d136 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -337,15 +337,15 @@ static InputFile *addFile(StringRef path, LoadType loadType,
         for (const object::Archive::Child &c : file->getArchive().children(e)) {
           StringRef reason;
           switch (loadType) {
-            case LoadType::LCLinkerOption:
-              reason = "LC_LINKER_OPTION";
-              break;
-            case LoadType::CommandLineForce:
-              reason = "-force_load";
-              break;
-            case LoadType::CommandLine:
-              reason = "-all_load";
-              break;
+          case LoadType::LCLinkerOption:
+            reason = "LC_LINKER_OPTION";
+            break;
+          case LoadType::CommandLineForce:
+            reason = "-force_load";
+            break;
+          case LoadType::CommandLine:
+            reason = "-all_load";
+            break;
           }
           if (Error e = file->fetch(c, reason)) {
             if (config->warnThinArchiveMissingMembers)
@@ -2178,6 +2178,9 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
     StringRef orderFile = args.getLastArgValue(OPT_order_file);
     if (!orderFile.empty())
       priorityBuilder.parseOrderFile(orderFile);
+    config->cStringOrderFilePath = args.getLastArgValue(OPT_order_file_cstring);
+    if (!config->cStringOrderFilePath.empty())
+      priorityBuilder.parseOrderFileCString(config->cStringOrderFilePath);
 
     referenceStubBinder();
 
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 4f0602f59812b..34faa75103224 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -400,6 +400,10 @@ def order_file : Separate<["-"], "order_file">,
     MetaVarName<"<file>">,
     HelpText<"Layout functions and data according to specification in <file>">,
     Group<grp_opts>;
+def order_file_cstring : Separate<["-"], "order_file_cstring">,
+    MetaVarName<"<file>">,
+    HelpText<"Layout cstrings according to specification in <file>">,
+    Group<grp_opts>;
 def no_order_inits : Flag<["-"], "no_order_inits">,
     HelpText<"Disable default reordering of initializer and terminator functions">,
     Flags<[HelpHidden]>,
diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp
index 7a4a5d8465f64..e7372050b7601 100644
--- a/lld/MachO/SectionPriorities.cpp
+++ b/lld/MachO/SectionPriorities.cpp
@@ -388,3 +388,74 @@ macho::PriorityBuilder::buildInputSectionPriorities() {
 
   return sectionPriorities;
 }
+
+void macho::PriorityBuilder::parseOrderFileCString(StringRef path) {
+  std::optional<MemoryBufferRef> buffer = readFile(path);
+  if (!buffer) {
+    error("Could not read cstring order file at " + path);
+    return;
+  }
+  MemoryBufferRef mbref = *buffer;
+  int priority = std::numeric_limits<int>::min();
+  for (StringRef line : args::getLines(mbref)) {
+    if (line.empty())
+      continue;
+    uint32_t hash = 0;
+    if (!to_integer(line, hash))
+      continue;
+    auto it = cStringPriorities.find(hash);
+    if (it == cStringPriorities.end())
+      cStringPriorities[hash] = ++priority;
+    else
+      assert(it->second <= priority);
+  }
+}
+
+std::vector<StringPiecePair> macho::PriorityBuilder::buildCStringPriorities(
+    ArrayRef<CStringInputSection *> inputs) {
+  std::vector<StringPiecePair> orderedStringPieces;
+  if (config->cStringOrderFilePath.empty()) {
+    for (CStringInputSection *isec : inputs) {
+      for (const auto &[stringPieceIdx, piece] :
+           llvm::enumerate(isec->pieces)) {
+        if (!piece.live)
+          continue;
+        orderedStringPieces.emplace_back(isec, stringPieceIdx);
+      }
+    }
+    return orderedStringPieces;
+  }
+
+  // Split the input strings into hold and cold sets.
+  // Order hot set based on -order_file_cstring for performance improvement;
+  // TODO: Order cold set of cstrings for compression via BP.
+  std::vector<std::pair<int, StringPiecePair>>
+      hotStringPrioritiesAndStringPieces;
+  std::vector<StringPiecePair> coldStringPieces;
+
+  for (CStringInputSection *isec : inputs) {
+    for (const auto &[stringPieceIdx, piece] : llvm::enumerate(isec->pieces)) {
+      if (!piece.live)
+        continue;
+
+      auto it = cStringPriorities.find(piece.hash);
+      if (it != cStringPriorities.end())
+        hotStringPrioritiesAndStringPieces.emplace_back(
+            it->second, std::make_pair(isec, stringPieceIdx));
+      else
+        coldStringPieces.emplace_back(isec, stringPieceIdx);
+    }
+  }
+
+  // Order hot set for perf
+  llvm::stable_sort(hotStringPrioritiesAndStringPieces);
+  for (auto &[priority, stringPiecePair] : hotStringPrioritiesAndStringPieces)
+    orderedStringPieces.push_back(stringPiecePair);
+
+  // TODO: Order cold set for compression
+
+  orderedStringPieces.insert(orderedStringPieces.end(),
+                             coldStringPieces.begin(), coldStringPieces.end());
+
+  return orderedStringPieces;
+}
diff --git a/lld/MachO/SectionPriorities.h b/lld/MachO/SectionPriorities.h
index 44fb101990c51..5593494d8a274 100644
--- a/lld/MachO/SectionPriorities.h
+++ b/lld/MachO/SectionPriorities.h
@@ -16,6 +16,7 @@
 namespace lld::macho {
 
 using SectionPair = std::pair<const InputSection *, const InputSection *>;
+using StringPiecePair = std::pair<CStringInputSection *, size_t>;
 
 class PriorityBuilder {
 public:
@@ -55,6 +56,23 @@ class PriorityBuilder {
   // contains.
   llvm::DenseMap<const InputSection *, int> buildInputSectionPriorities();
 
+  // Reads the cstring order file at `path` into cStringPriorities.
+  // An cstring order file has one entry per line, in the following format:
+  //
+  // <hash of cstring literal content>
+  //
+  // Cstring literals are not symbolized, we can't identify them by name
+  // However, cstrings are deduplicated, hence unique, so we use the hash of
+  // the content of cstring literals to identify them and assign priority to it.
+  // We use the same hash as used in StringPiece, i.e. 31 bit:
+  // xxh3_64bits(string) & 0x7fffffff
+  //
+  // Additionally, given they are deduplicated and unique, we don't need to know
+  // which object file they are from.
+  void parseOrderFileCString(StringRef path);
+  std::vector<StringPiecePair>
+      buildCStringPriorities(ArrayRef<CStringInputSection *>);
+
 private:
   // The symbol with the smallest priority should be ordered first in the output
   // section (modulo input section contiguity constraints).
@@ -68,6 +86,8 @@ class PriorityBuilder {
 
   std::optional<int> getSymbolPriority(const Defined *sym);
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
+  /// A map from cstring literal hashes to priorities
+  llvm::DenseMap<uint32_t, int> cStringPriorities;
   llvm::MapVector<SectionPair, uint64_t> callGraphProfile;
 };
 
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index dfacaf2ef4e0d..beddcfa2174e0 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -15,6 +15,7 @@
 #include "MachOStructs.h"
 #include "ObjC.h"
 #include "OutputSegment.h"
+#include "SectionPriorities.h"
 #include "SymbolTable.h"
 #include "Symbols.h"
 
@@ -1766,26 +1767,25 @@ void DeduplicatedCStringSection::finalizeContents() {
     }
   }
 
-  // Assign an offset for each string and save it to the corresponding
+  // Sort the strings for performance and compression size win, and then
+  // assign an offset for each string and save it to the corresponding
   // StringPieces for easy access.
-  for (CStringInputSection *isec : inputs) {
-    for (const auto &[i, piece] : llvm::enumerate(isec->pieces)) {
-      if (!piece.live)
-        continue;
-      auto s = isec->getCachedHashStringRef(i);
-      auto it = stringOffsetMap.find(s);
-      assert(it != stringOffsetMap.end());
-      StringOffset &offsetInfo = it->second;
-      if (offsetInfo.outSecOff == UINT64_MAX) {
-        offsetInfo.outSecOff =
-            alignToPowerOf2(size, 1ULL << offsetInfo.trailingZeros);
-        size =
-            offsetInfo.outSecOff + s.size() + 1; // account for null terminator
-      }
-      piece.outSecOff = offsetInfo.outSecOff;
+  for (auto &[isec, i] : priorityBuilder.buildCStringPriorities(inputs)) {
+    auto &piece = isec->pieces[i];
+    auto s = isec->getCachedHashStringRef(i);
+    auto it = stringOffsetMap.find(s);
+    assert(it != stringOffsetMap.end());
+    lld::macho::DeduplicatedCStringSection::StringOffset &offsetInfo =
+        it->second;
+    if (offsetInfo.outSecOff == UINT64_MAX) {
+      offsetInfo.outSecOff =
+          alignToPowerOf2(size, 1ULL << offsetInfo.trailingZeros);
+      size = offsetInfo.outSecOff + s.size() + 1; // account for null terminator
     }
-    isec->isFinal = true;
+    piece.outSecOff = offsetInfo.outSecOff;
   }
+  for (CStringInputSection *isec : inputs)
+    isec->isFinal = true;
 }
 
 void DeduplicatedCStringSection::writeTo(uint8_t *buf) const {
@@ -1908,18 +1908,18 @@ ObjCImageInfoSection::parseImageInfo(const InputFile *file) {
 
 static std::string swiftVersionString(uint8_t version) {
   switch (version) {
-    case 1:
-      return "1.0";
-    case 2:
-      return "1.1";
-    case 3:
-      return "2.0";
-    case 4:
-      return "3.0";
-    case 5:
-      return "4.0";
-    default:
-      return ("0x" + Twine::utohexstr(version)).str();
+  case 1:
+    return "1.0";
+  case 2:
+    return "1.1";
+  case 3:
+    return "2.0";
+  case 4:
+    return "3.0";
+  case 5:
+    return "4.0";
+  default:
+    return ("0x" + Twine::utohexstr(version)).str();
   }
 }
 
diff --git a/lld/test/MachO/ordre-file-cstring.s b/lld/test/MachO/ordre-file-cstring.s
new file mode 100644
index 0000000000000..138f1685467ee
--- /dev/null
+++ b/lld/test/MachO/ordre-file-cstring.s
@@ -0,0 +1,222 @@
+# RUN: rm -rf %t; split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin  %t/test.s -o %t/test.o
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/more-cstrings.s -o %t/more-cstrings.o
+
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-0 %t/test.o %t/more-cstrings.o
+# RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-0 | FileCheck %s --check-prefix=ORIGIN_SYM
+# RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-0 | FileCheck %s --check-prefix=ORIGIN_SEC
+
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-1 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-1
+# RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-1 | FileCheck %s --check-prefix=ONE_SYM
+# RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-1 | FileCheck %s --check-prefix=ONE_SEC
+
+
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-2 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-2
+# RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-2 | FileCheck %s --check-prefix=TWO_SYM
+# RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-2 | FileCheck %s --check-prefix=TWO_SEC
+
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-3 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-3
+# RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-3 | FileCheck %s --check-prefix=THREE_SYM
+# RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-3 | FileCheck %s --check-prefix=THREE_SEC
+
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-4 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-4
+# RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-4 | FileCheck %s --check-prefix=FOUR_SYM
+# RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-4 | FileCheck %s --check-prefix=FOUR_SEC
+# RUN: llvm-readobj --string-dump=__cstring %t/test-4 | FileCheck %s --check-prefix=FOUR_SEC_ESCAPE
+
+
+# We expect:
+# 1) Covered cstring symbols are reordered
+# 2) the rest of the cstring symbols remain original relative order within the cstring section
+
+# ORIGIN_SYM: _local_foo1
+# ORIGIN_SYM: _globl_foo2
+# ORIGIN_SYM: _local_foo2
+# ORIGIN_SYM: _bar
+# ORIGIN_SYM: _baz
+# ORIGIN_SYM: _baz_dup
+# ORIGIN_SYM: _bar2
+# ORIGIN_SYM: _globl_foo3
+
+# ORIGIN_SEC: foo1
+# ORIGIN_SEC: foo2
+# ORIGIN_SEC: bar
+# ORIGIN_SEC: baz
+# ORIGIN_SEC: bar2
+# ORIGIN_SEC: foo3
+
+
+# ONE_SYM: _globl_foo2
+# ONE_SYM: _local_foo2
+# ONE_SYM: _bar
+# ONE_SYM: _bar2
+# ONE_SYM: _globl_foo3
+# ONE_SYM: _local_foo1
+# ONE_SYM: _baz
+# ONE_SYM: _baz_dup
+
+# ONE_SEC: foo2
+# ONE_SEC: bar
+# ONE_SEC: bar2
+# ONE_SEC: foo3
+# ONE_SEC: foo1
+# ONE_SEC: baz
+
+
+# TWO_SYM: _globl_foo2
+# TWO_SYM: _local_foo2
+# TWO_SYM: _local_foo1
+# TWO_SYM: _baz
+# TWO_SYM: _baz_dup
+# TWO_SYM: _bar
+# TWO_SYM: _bar2
+# TWO_SYM: _globl_foo3
+
+# TWO_SEC: foo2
+# TWO_SEC: foo1
+# TWO_SEC: baz
+# TWO_SEC: bar
+# TWO_SEC: bar2
+# TWO_SEC: foo3
+
+
+# THREE_SYM: _local_foo1
+# THREE_SYM: _baz
+# THREE_SYM: _baz_dup
+# THREE_SYM: _bar
+# THREE_SYM: _bar2
+# THREE_SYM: _globl_foo2
+# THREE_SYM: _local_foo2
+# THREE_SYM: _globl_foo3
+
+# THREE_SEC: foo1
+# THREE_SEC: baz
+# THREE_SEC: bar
+# THREE_SEC: bar2
+# THREE_SEC: foo2
+# THREE_SEC: foo3
+
+
+# FOUR_SYM: _local_escape_white_space
+# FOUR_SYM: _globl_foo2
+# FOUR_SYM: _local_foo2
+# FOUR_SYM: _local_escape
+# FOUR_SYM: _globl_foo3
+# FOUR_SYM: _bar
+# FOUR_SYM: _local_foo1
+# FOUR_SYM: _baz
+# FOUR_SYM: _baz_dup
+# FOUR_SYM: _bar2
+
+# FOUR_SEC: \t\n
+# FOUR_SEC: foo2
+# FOUR_SEC: @\"NSDictionary\"
+# FOUR_SEC: foo3
+# FOUR_SEC: bar
+# FOUR_SEC: foo1
+# FOUR_SEC: baz
+# FOUR_SEC: bar2
+
+# FOUR_SEC_ESCAPE: ..
+# FOUR_SEC_ESCAPE: foo2
+# FOUR_SEC_ESCAPE: @"NSDictionary"
+# FOUR_SEC_ESCAPE: foo3
+# FOUR_SEC_ESCAPE: bar
+# FOUR_SEC_ESCAPE: foo1
+# FOUR_SEC_ESCAPE: baz
+# FOUR_SEC_ESCAPE: bar2
+
+# original order, but only parital covered
+#--- ord-1
+#foo2
+0x55783A95
+#bar
+0x2032D362
+#bar2
+0x592F855B
+#foo3
+0x501BCC31
+
+# change order, parital covered
+#--- ord-2
+#foo2
+0x55783A95
+#foo1
+0x6326A039
+#baz
+0x336F8925
+#bar
+0x2032D362
+#bar2
+0x592F855B
+
+# change order, parital covered, with mismatches, duplicates
+#--- ord-3
+foo2222
+0x11111111
+#foo1
+0x6326A039
+#baz
+0x336F8925
+#bar
+0x2032D362
+#bar2
+0x592F855B
+#baz
+0x336F8925
+
+# test escape strings
+#--- ord-4
+#\t\n
+0x3DBEA0C9
+#foo2
+0x55783A95
+#@\"NSDictionary\"
+0x47AF4776
+#foo3
+0x501BCC31
+#bar
+0x2032D362
+
+
+#--- test.s
+.text
+.globl _main
+
+_main:
+  ret
+
+.cstring
+.p2align 2
+_local_foo1:
+  .asciz "foo1"
+_local_foo2:
+  .asciz "foo2"
+L_.foo1_dup:
+  .asciz "foo1"
+L_.foo2_dup:
+  .asciz "foo2"
+_local_escape:
+  .asciz "@\"NSDictionary\""
+_local_escape_white_space:
+  .asciz "\t\n"
+
+_bar:
+  .asciz "bar"
+_baz:
+  .asciz "baz"
+_bar2:
+  .asciz "bar2"
+_baz_dup:
+  .asciz "baz"
+
+.subsections_via_symbols
+
+#--- more-cstrings.s
+.globl _globl_foo1, _globl_foo3
+.cstring
+.p2align 4
+_globl_foo3:
+  .asciz "foo3"
+_globl_foo2:
+  .asciz "foo2"

>From 9d251c4e0d82eff273257d1e98a7b0eb3b56f5a7 Mon Sep 17 00:00:00 2001
From: Sharon Xu <sharonxu at fb.com>
Date: Mon, 19 May 2025 11:42:51 -0700
Subject: [PATCH 2/6] address comments

---
 lld/MachO/Driver.cpp            | 18 +++++++++---------
 lld/MachO/SectionPriorities.cpp | 22 ++++------------------
 lld/MachO/SyntheticSections.cpp | 24 ++++++++++++------------
 3 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 0f2957295d136..d071202bd1b46 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -337,15 +337,15 @@ static InputFile *addFile(StringRef path, LoadType loadType,
         for (const object::Archive::Child &c : file->getArchive().children(e)) {
           StringRef reason;
           switch (loadType) {
-          case LoadType::LCLinkerOption:
-            reason = "LC_LINKER_OPTION";
-            break;
-          case LoadType::CommandLineForce:
-            reason = "-force_load";
-            break;
-          case LoadType::CommandLine:
-            reason = "-all_load";
-            break;
+            case LoadType::LCLinkerOption:
+              reason = "LC_LINKER_OPTION";
+              break;
+            case LoadType::CommandLineForce:
+              reason = "-force_load";
+              break;
+            case LoadType::CommandLine:
+              reason = "-all_load";
+              break;
           }
           if (Error e = file->fetch(c, reason)) {
             if (config->warnThinArchiveMissingMembers)
diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp
index e7372050b7601..0f311739c862e 100644
--- a/lld/MachO/SectionPriorities.cpp
+++ b/lld/MachO/SectionPriorities.cpp
@@ -403,35 +403,21 @@ void macho::PriorityBuilder::parseOrderFileCString(StringRef path) {
     uint32_t hash = 0;
     if (!to_integer(line, hash))
       continue;
-    auto it = cStringPriorities.find(hash);
-    if (it == cStringPriorities.end())
-      cStringPriorities[hash] = ++priority;
-    else
-      assert(it->second <= priority);
+    auto [it, wasInserted] = cStringPriorities.try_emplace(hash, priority);
+    if (wasInserted)
+      ++priority;
   }
 }
 
 std::vector<StringPiecePair> macho::PriorityBuilder::buildCStringPriorities(
     ArrayRef<CStringInputSection *> inputs) {
-  std::vector<StringPiecePair> orderedStringPieces;
-  if (config->cStringOrderFilePath.empty()) {
-    for (CStringInputSection *isec : inputs) {
-      for (const auto &[stringPieceIdx, piece] :
-           llvm::enumerate(isec->pieces)) {
-        if (!piece.live)
-          continue;
-        orderedStringPieces.emplace_back(isec, stringPieceIdx);
-      }
-    }
-    return orderedStringPieces;
-  }
-
   // Split the input strings into hold and cold sets.
   // Order hot set based on -order_file_cstring for performance improvement;
   // TODO: Order cold set of cstrings for compression via BP.
   std::vector<std::pair<int, StringPiecePair>>
       hotStringPrioritiesAndStringPieces;
   std::vector<StringPiecePair> coldStringPieces;
+  std::vector<StringPiecePair> orderedStringPieces;
 
   for (CStringInputSection *isec : inputs) {
     for (const auto &[stringPieceIdx, piece] : llvm::enumerate(isec->pieces)) {
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index beddcfa2174e0..806858a961b99 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1908,18 +1908,18 @@ ObjCImageInfoSection::parseImageInfo(const InputFile *file) {
 
 static std::string swiftVersionString(uint8_t version) {
   switch (version) {
-  case 1:
-    return "1.0";
-  case 2:
-    return "1.1";
-  case 3:
-    return "2.0";
-  case 4:
-    return "3.0";
-  case 5:
-    return "4.0";
-  default:
-    return ("0x" + Twine::utohexstr(version)).str();
+    case 1:
+      return "1.0";
+    case 2:
+      return "1.1";
+    case 3:
+      return "2.0";
+    case 4:
+      return "3.0";
+    case 5:
+      return "4.0";
+    default:
+      return ("0x" + Twine::utohexstr(version)).str();
   }
 }
 

>From f39f9084ba6029f976a2e2012015c95af45d23ae Mon Sep 17 00:00:00 2001
From: Sharon Xu <sharonxu at fb.com>
Date: Thu, 22 May 2025 17:00:51 -0700
Subject: [PATCH 3/6] use -order_file for cstring hashes

---
 lld/MachO/Config.h                  |  1 -
 lld/MachO/Driver.cpp                | 21 ++++-----
 lld/MachO/Options.td                |  4 --
 lld/MachO/SectionPriorities.cpp     | 68 ++++++++++++++---------------
 lld/MachO/SectionPriorities.h       | 42 ++++++++----------
 lld/test/MachO/ordre-file-cstring.s | 64 ++++++++++++++-------------
 6 files changed, 95 insertions(+), 105 deletions(-)

diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index d0217b38c3007..a01e60efbe761 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -225,7 +225,6 @@ struct Configuration {
   bool callGraphProfileSort = false;
   llvm::StringRef printSymbolOrder;
 
-  llvm::StringRef cStringOrderFilePath;
   llvm::StringRef irpgoProfilePath;
   bool bpStartupFunctionSort = false;
   bool bpCompressionSortStartupFunctions = false;
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index d071202bd1b46..0b9c32f047f27 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -337,15 +337,15 @@ static InputFile *addFile(StringRef path, LoadType loadType,
         for (const object::Archive::Child &c : file->getArchive().children(e)) {
           StringRef reason;
           switch (loadType) {
-            case LoadType::LCLinkerOption:
-              reason = "LC_LINKER_OPTION";
-              break;
-            case LoadType::CommandLineForce:
-              reason = "-force_load";
-              break;
-            case LoadType::CommandLine:
-              reason = "-all_load";
-              break;
+          case LoadType::LCLinkerOption:
+            reason = "LC_LINKER_OPTION";
+            break;
+          case LoadType::CommandLineForce:
+            reason = "-force_load";
+            break;
+          case LoadType::CommandLine:
+            reason = "-all_load";
+            break;
           }
           if (Error e = file->fetch(c, reason)) {
             if (config->warnThinArchiveMissingMembers)
@@ -2178,9 +2178,6 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
     StringRef orderFile = args.getLastArgValue(OPT_order_file);
     if (!orderFile.empty())
       priorityBuilder.parseOrderFile(orderFile);
-    config->cStringOrderFilePath = args.getLastArgValue(OPT_order_file_cstring);
-    if (!config->cStringOrderFilePath.empty())
-      priorityBuilder.parseOrderFileCString(config->cStringOrderFilePath);
 
     referenceStubBinder();
 
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 34faa75103224..4f0602f59812b 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -400,10 +400,6 @@ def order_file : Separate<["-"], "order_file">,
     MetaVarName<"<file>">,
     HelpText<"Layout functions and data according to specification in <file>">,
     Group<grp_opts>;
-def order_file_cstring : Separate<["-"], "order_file_cstring">,
-    MetaVarName<"<file>">,
-    HelpText<"Layout cstrings according to specification in <file>">,
-    Group<grp_opts>;
 def no_order_inits : Flag<["-"], "no_order_inits">,
     HelpText<"Disable default reordering of initializer and terminator functions">,
     Flags<[HelpHidden]>,
diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp
index 0f311739c862e..1424b234d7153 100644
--- a/lld/MachO/SectionPriorities.cpp
+++ b/lld/MachO/SectionPriorities.cpp
@@ -246,15 +246,15 @@ DenseMap<const InputSection *, int> CallGraphSort::run() {
 }
 
 std::optional<int>
-macho::PriorityBuilder::getSymbolPriority(const Defined *sym) {
-  if (sym->isAbsolute())
-    return std::nullopt;
+macho::PriorityBuilder::getSymbolOrCStringPriority(const StringRef key,
+                                                   InputFile *f) {
 
-  auto it = priorities.find(sym->getName());
+  for (auto &[name, entry] : priorities)
+    llvm::errs() << name << ", " << entry.anyObjectFile << "\n";
+  auto it = priorities.find(key);
   if (it == priorities.end())
     return std::nullopt;
   const SymbolPriorityEntry &entry = it->second;
-  const InputFile *f = sym->isec()->getFile();
   if (!f)
     return entry.anyObjectFile;
   // We don't use toString(InputFile *) here because it returns the full path
@@ -268,6 +268,13 @@ macho::PriorityBuilder::getSymbolPriority(const Defined *sym) {
   return std::min(entry.objectFiles.lookup(filename), entry.anyObjectFile);
 }
 
+std::optional<int>
+macho::PriorityBuilder::getSymbolPriority(const Defined *sym) {
+  if (sym->isAbsolute())
+    return std::nullopt;
+  return getSymbolOrCStringPriority(sym->getName(), sym->isec()->getFile());
+}
+
 void macho::PriorityBuilder::extractCallGraphProfile() {
   TimeTraceScope timeScope("Extract call graph profile");
   bool hasOrderFile = !priorities.empty();
@@ -300,7 +307,7 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) {
   int prio = std::numeric_limits<int>::min();
   MemoryBufferRef mbref = *buffer;
   for (StringRef line : args::getLines(mbref)) {
-    StringRef objectFile, symbol;
+    StringRef objectFile, symbolOrCStrHash;
     line = line.take_until([](char c) { return c == '#'; }); // ignore comments
     line = line.ltrim();
 
@@ -315,7 +322,6 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) {
 
     if (cpuType != CPU_TYPE_ANY && cpuType != target->cpuType)
       continue;
-
     // Drop the CPU type as well as the colon
     if (cpuType != CPU_TYPE_ANY)
       line = line.drop_until([](char c) { return c == ':'; }).drop_front();
@@ -330,10 +336,20 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) {
         break;
       }
     }
-    symbol = line.trim();
 
-    if (!symbol.empty()) {
-      SymbolPriorityEntry &entry = priorities[symbol];
+    // The rest of the line is either <symbol name> or
+    // CStringEntryPrefix<cstring hash>
+    if (line.starts_with(CStringEntryPrefix)) {
+      StringRef possibleHash = line.drop_front(CStringEntryPrefix.size());
+      uint32_t hash = 0;
+      if (to_integer(possibleHash, hash))
+        line = possibleHash;
+    }
+    symbolOrCStrHash = line.trim();
+    llvm::errs() << symbolOrCStrHash << "\n";
+
+    if (!symbolOrCStrHash.empty()) {
+      SymbolPriorityEntry &entry = priorities[symbolOrCStrHash];
       if (!objectFile.empty())
         entry.objectFiles.insert(std::make_pair(objectFile, prio));
       else
@@ -389,26 +405,6 @@ macho::PriorityBuilder::buildInputSectionPriorities() {
   return sectionPriorities;
 }
 
-void macho::PriorityBuilder::parseOrderFileCString(StringRef path) {
-  std::optional<MemoryBufferRef> buffer = readFile(path);
-  if (!buffer) {
-    error("Could not read cstring order file at " + path);
-    return;
-  }
-  MemoryBufferRef mbref = *buffer;
-  int priority = std::numeric_limits<int>::min();
-  for (StringRef line : args::getLines(mbref)) {
-    if (line.empty())
-      continue;
-    uint32_t hash = 0;
-    if (!to_integer(line, hash))
-      continue;
-    auto [it, wasInserted] = cStringPriorities.try_emplace(hash, priority);
-    if (wasInserted)
-      ++priority;
-  }
-}
-
 std::vector<StringPiecePair> macho::PriorityBuilder::buildCStringPriorities(
     ArrayRef<CStringInputSection *> inputs) {
   // Split the input strings into hold and cold sets.
@@ -424,12 +420,14 @@ std::vector<StringPiecePair> macho::PriorityBuilder::buildCStringPriorities(
       if (!piece.live)
         continue;
 
-      auto it = cStringPriorities.find(piece.hash);
-      if (it != cStringPriorities.end())
-        hotStringPrioritiesAndStringPieces.emplace_back(
-            it->second, std::make_pair(isec, stringPieceIdx));
-      else
+      llvm::errs() << "buildCStringPriorities:" << piece.hash << "\n";
+      std::optional<int> priority = getSymbolOrCStringPriority(
+          std::to_string(piece.hash), isec->getFile());
+      if (!priority)
         coldStringPieces.emplace_back(isec, stringPieceIdx);
+      else
+        hotStringPrioritiesAndStringPieces.emplace_back(
+            *priority, std::make_pair(isec, stringPieceIdx));
     }
   }
 
diff --git a/lld/MachO/SectionPriorities.h b/lld/MachO/SectionPriorities.h
index 5593494d8a274..96c8f0b34bfc1 100644
--- a/lld/MachO/SectionPriorities.h
+++ b/lld/MachO/SectionPriorities.h
@@ -29,17 +29,28 @@ class PriorityBuilder {
   //
   // An order file has one entry per line, in the following format:
   //
-  //   <cpu>:<object file>:<symbol name>
+  //   <cpu>:<object file>:[<symbol name> | CStringEntryPrefix <cstring hash>]
   //
-  // <cpu> and <object file> are optional. If not specified, then that entry
-  // matches any symbol of that name. Parsing this format is not quite
-  // straightforward because the symbol name itself can contain colons, so when
-  // encountering a colon, we consider the preceding characters to decide if it
-  // can be a valid CPU type or file path.
+  // <cpu> and <object file> are optional.
+  // If not specified, then that entry tries to match either,
   //
+  // 1) any symbol of the <symbol name>;
+  // Parsing this format is not quite straightforward because the symbol name
+  // itself can contain colons, so when encountering a colon, we consider the
+  // preceding characters to decide if it can be a valid CPU type or file path.
   // If a symbol is matched by multiple entries, then it takes the
   // lowest-ordered entry (the one nearest to the front of the list.)
   //
+  // or 2) any cstring literal with the given hash, if the entry has the
+  // CStringEntryPrefix prefix defined below in the file. <cstring hash> is the
+  // hash of cstring literal content.
+  //
+  // Cstring literals are not symbolized, we can't identify them by name
+  // However, cstrings are deduplicated, hence unique, so we use the hash of
+  // the content of cstring literals to identify them and assign priority to it.
+  // We use the same hash as used in StringPiece, i.e. 31 bit:
+  // xxh3_64bits(string) & 0x7fffffff
+  //
   // The file can also have line comments that start with '#'.
   void parseOrderFile(StringRef path);
 
@@ -55,21 +66,6 @@ class PriorityBuilder {
   // Each section gets assigned the priority of the highest-priority symbol it
   // contains.
   llvm::DenseMap<const InputSection *, int> buildInputSectionPriorities();
-
-  // Reads the cstring order file at `path` into cStringPriorities.
-  // An cstring order file has one entry per line, in the following format:
-  //
-  // <hash of cstring literal content>
-  //
-  // Cstring literals are not symbolized, we can't identify them by name
-  // However, cstrings are deduplicated, hence unique, so we use the hash of
-  // the content of cstring literals to identify them and assign priority to it.
-  // We use the same hash as used in StringPiece, i.e. 31 bit:
-  // xxh3_64bits(string) & 0x7fffffff
-  //
-  // Additionally, given they are deduplicated and unique, we don't need to know
-  // which object file they are from.
-  void parseOrderFileCString(StringRef path);
   std::vector<StringPiecePair>
       buildCStringPriorities(ArrayRef<CStringInputSection *>);
 
@@ -83,11 +79,11 @@ class PriorityBuilder {
     // The priority given to a matching symbol from a particular object file.
     llvm::DenseMap<llvm::StringRef, int> objectFiles;
   };
+  const llvm::StringRef CStringEntryPrefix = "CSTR:";
 
   std::optional<int> getSymbolPriority(const Defined *sym);
+  std::optional<int> getSymbolOrCStringPriority(const StringRef key, InputFile *f);
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
-  /// A map from cstring literal hashes to priorities
-  llvm::DenseMap<uint32_t, int> cStringPriorities;
   llvm::MapVector<SectionPair, uint64_t> callGraphProfile;
 };
 
diff --git a/lld/test/MachO/ordre-file-cstring.s b/lld/test/MachO/ordre-file-cstring.s
index 138f1685467ee..fac2758dcc804 100644
--- a/lld/test/MachO/ordre-file-cstring.s
+++ b/lld/test/MachO/ordre-file-cstring.s
@@ -6,20 +6,20 @@
 # RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-0 | FileCheck %s --check-prefix=ORIGIN_SYM
 # RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-0 | FileCheck %s --check-prefix=ORIGIN_SEC
 
-# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-1 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-1
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-1 %t/test.o %t/more-cstrings.o -order_file %t/ord-1
 # RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-1 | FileCheck %s --check-prefix=ONE_SYM
 # RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-1 | FileCheck %s --check-prefix=ONE_SEC
 
 
-# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-2 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-2
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-2 %t/test.o %t/more-cstrings.o -order_file %t/ord-2
 # RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-2 | FileCheck %s --check-prefix=TWO_SYM
 # RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-2 | FileCheck %s --check-prefix=TWO_SEC
 
-# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-3 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-3
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-3 %t/test.o %t/more-cstrings.o -order_file %t/ord-3
 # RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-3 | FileCheck %s --check-prefix=THREE_SYM
 # RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-3 | FileCheck %s --check-prefix=THREE_SEC
 
-# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-4 %t/test.o %t/more-cstrings.o -order_file_cstring %t/ord-4
+# RUN: %lld --deduplicate-strings -arch arm64 -lSystem -e _main -o %t/test-4 %t/test.o %t/more-cstrings.o -order_file %t/ord-4
 # RUN: llvm-nm --numeric-sort --format=just-symbols %t/test-4 | FileCheck %s --check-prefix=FOUR_SYM
 # RUN: llvm-objdump --macho --section="__TEXT,__cstring" %t/test-4 | FileCheck %s --check-prefix=FOUR_SEC
 # RUN: llvm-readobj --string-dump=__cstring %t/test-4 | FileCheck %s --check-prefix=FOUR_SEC_ESCAPE
@@ -45,6 +45,16 @@
 # ORIGIN_SEC: bar2
 # ORIGIN_SEC: foo3
 
+# original order, but only parital covered
+#--- ord-1
+#foo2
+CSTR:1433942677
+#bar
+CSTR:540201826
+#bar2
+CSTR:1496286555
+#foo3
+CSTR:1343999025
 
 # ONE_SYM: _globl_foo2
 # ONE_SYM: _local_foo2
@@ -126,57 +136,51 @@
 # FOUR_SEC_ESCAPE: baz
 # FOUR_SEC_ESCAPE: bar2
 
-# original order, but only parital covered
-#--- ord-1
-#foo2
-0x55783A95
-#bar
-0x2032D362
-#bar2
-0x592F855B
-#foo3
-0x501BCC31
 
 # change order, parital covered
 #--- ord-2
 #foo2
-0x55783A95
+CSTR:1433942677
 #foo1
-0x6326A039
+CSTR:1663475769
 #baz
-0x336F8925
+CSTR:862947621
 #bar
-0x2032D362
+CSTR:540201826
 #bar2
-0x592F855B
+CSTR:1496286555
 
 # change order, parital covered, with mismatches, duplicates
 #--- ord-3
 foo2222
-0x11111111
+CSTR:0x11111111
+#bar (mismatched cpu and file name)
+fakeCPU:fake-file-name.o:CSTR:540201826
+#not a hash
+CSTR:xxx
 #foo1
-0x6326A039
+CSTR:1663475769
 #baz
-0x336F8925
+CSTR:862947621
 #bar
-0x2032D362
+CSTR:540201826
 #bar2
-0x592F855B
+CSTR:1496286555
 #baz
-0x336F8925
+CSTR:862947621
 
 # test escape strings
 #--- ord-4
 #\t\n
-0x3DBEA0C9
+CSTR:1035903177
 #foo2
-0x55783A95
+CSTR:1433942677
 #@\"NSDictionary\"
-0x47AF4776
+CSTR:1202669430
 #foo3
-0x501BCC31
+CSTR:1343999025
 #bar
-0x2032D362
+CSTR:540201826
 
 
 #--- test.s

>From 7c089997a32c70843377fe934abb0c3c729b37b1 Mon Sep 17 00:00:00 2001
From: Sharon Xu <sharonxu at fb.com>
Date: Tue, 27 May 2025 18:37:43 -0700
Subject: [PATCH 4/6] fix typo

---
 lld/MachO/Driver.cpp            | 18 +++++++++---------
 lld/MachO/SectionPriorities.cpp |  4 ----
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 0b9c32f047f27..5c32055166da6 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -337,15 +337,15 @@ static InputFile *addFile(StringRef path, LoadType loadType,
         for (const object::Archive::Child &c : file->getArchive().children(e)) {
           StringRef reason;
           switch (loadType) {
-          case LoadType::LCLinkerOption:
-            reason = "LC_LINKER_OPTION";
-            break;
-          case LoadType::CommandLineForce:
-            reason = "-force_load";
-            break;
-          case LoadType::CommandLine:
-            reason = "-all_load";
-            break;
+            case LoadType::LCLinkerOption:
+              reason = "LC_LINKER_OPTION";
+              break;
+            case LoadType::CommandLineForce:
+              reason = "-force_load";
+              break;
+            case LoadType::CommandLine:
+              reason = "-all_load";
+              break;
           }
           if (Error e = file->fetch(c, reason)) {
             if (config->warnThinArchiveMissingMembers)
diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp
index 1424b234d7153..9c968eb01cfce 100644
--- a/lld/MachO/SectionPriorities.cpp
+++ b/lld/MachO/SectionPriorities.cpp
@@ -249,8 +249,6 @@ std::optional<int>
 macho::PriorityBuilder::getSymbolOrCStringPriority(const StringRef key,
                                                    InputFile *f) {
 
-  for (auto &[name, entry] : priorities)
-    llvm::errs() << name << ", " << entry.anyObjectFile << "\n";
   auto it = priorities.find(key);
   if (it == priorities.end())
     return std::nullopt;
@@ -346,7 +344,6 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) {
         line = possibleHash;
     }
     symbolOrCStrHash = line.trim();
-    llvm::errs() << symbolOrCStrHash << "\n";
 
     if (!symbolOrCStrHash.empty()) {
       SymbolPriorityEntry &entry = priorities[symbolOrCStrHash];
@@ -420,7 +417,6 @@ std::vector<StringPiecePair> macho::PriorityBuilder::buildCStringPriorities(
       if (!piece.live)
         continue;
 
-      llvm::errs() << "buildCStringPriorities:" << piece.hash << "\n";
       std::optional<int> priority = getSymbolOrCStringPriority(
           std::to_string(piece.hash), isec->getFile());
       if (!priority)

>From b2c4acb510796771d8224d15744b933f63fd0571 Mon Sep 17 00:00:00 2001
From: Sharon Xu <sharonxu at fb.com>
Date: Tue, 27 May 2025 18:39:34 -0700
Subject: [PATCH 5/6] fix typo2

---
 lld/MachO/SectionPriorities.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lld/MachO/SectionPriorities.h b/lld/MachO/SectionPriorities.h
index 96c8f0b34bfc1..85faa4aaf1fc3 100644
--- a/lld/MachO/SectionPriorities.h
+++ b/lld/MachO/SectionPriorities.h
@@ -82,7 +82,8 @@ class PriorityBuilder {
   const llvm::StringRef CStringEntryPrefix = "CSTR:";
 
   std::optional<int> getSymbolPriority(const Defined *sym);
-  std::optional<int> getSymbolOrCStringPriority(const StringRef key, InputFile *f);
+  std::optional<int> getSymbolOrCStringPriority(const StringRef key,
+                                                InputFile *f);
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
   llvm::MapVector<SectionPair, uint64_t> callGraphProfile;
 };

>From af0f01985bdd780c48d6f20bc4fcc4c90a194e08 Mon Sep 17 00:00:00 2001
From: Sharon Xu <sharonxu at fb.com>
Date: Tue, 3 Jun 2025 09:51:02 -0700
Subject: [PATCH 6/6] fix the cstr prefix from CSTR: to CSTR;

---
 lld/MachO/SectionPriorities.h       |  2 +-
 lld/test/MachO/ordre-file-cstring.s | 44 ++++++++++++++---------------
 2 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/lld/MachO/SectionPriorities.h b/lld/MachO/SectionPriorities.h
index 85faa4aaf1fc3..cc4e30fffc600 100644
--- a/lld/MachO/SectionPriorities.h
+++ b/lld/MachO/SectionPriorities.h
@@ -79,7 +79,7 @@ class PriorityBuilder {
     // The priority given to a matching symbol from a particular object file.
     llvm::DenseMap<llvm::StringRef, int> objectFiles;
   };
-  const llvm::StringRef CStringEntryPrefix = "CSTR:";
+  const llvm::StringRef CStringEntryPrefix = "CSTR;";
 
   std::optional<int> getSymbolPriority(const Defined *sym);
   std::optional<int> getSymbolOrCStringPriority(const StringRef key,
diff --git a/lld/test/MachO/ordre-file-cstring.s b/lld/test/MachO/ordre-file-cstring.s
index fac2758dcc804..b5e3b01ce043a 100644
--- a/lld/test/MachO/ordre-file-cstring.s
+++ b/lld/test/MachO/ordre-file-cstring.s
@@ -48,13 +48,13 @@
 # original order, but only parital covered
 #--- ord-1
 #foo2
-CSTR:1433942677
+CSTR;1433942677
 #bar
-CSTR:540201826
+CSTR;540201826
 #bar2
-CSTR:1496286555
+CSTR;1496286555
 #foo3
-CSTR:1343999025
+CSTR;1343999025
 
 # ONE_SYM: _globl_foo2
 # ONE_SYM: _local_foo2
@@ -140,47 +140,47 @@ CSTR:1343999025
 # change order, parital covered
 #--- ord-2
 #foo2
-CSTR:1433942677
+CSTR;1433942677
 #foo1
-CSTR:1663475769
+CSTR;1663475769
 #baz
-CSTR:862947621
+CSTR;862947621
 #bar
-CSTR:540201826
+CSTR;540201826
 #bar2
-CSTR:1496286555
+CSTR;1496286555
 
 # change order, parital covered, with mismatches, duplicates
 #--- ord-3
 foo2222
-CSTR:0x11111111
+CSTR;0x11111111
 #bar (mismatched cpu and file name)
-fakeCPU:fake-file-name.o:CSTR:540201826
+fakeCPU:fake-file-name.o:CSTR;540201826
 #not a hash
-CSTR:xxx
+CSTR;xxx
 #foo1
-CSTR:1663475769
+CSTR;1663475769
 #baz
-CSTR:862947621
+CSTR;862947621
 #bar
-CSTR:540201826
+CSTR;540201826
 #bar2
-CSTR:1496286555
+CSTR;1496286555
 #baz
-CSTR:862947621
+CSTR;862947621
 
 # test escape strings
 #--- ord-4
 #\t\n
-CSTR:1035903177
+CSTR;1035903177
 #foo2
-CSTR:1433942677
+CSTR;1433942677
 #@\"NSDictionary\"
-CSTR:1202669430
+CSTR;1202669430
 #foo3
-CSTR:1343999025
+CSTR;1343999025
 #bar
-CSTR:540201826
+CSTR;540201826
 
 
 #--- test.s



More information about the llvm-commits mailing list