[lld] 6f9dd84 - [lld-macho] Implement options -rename_section -rename_segment

Greg McGary via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 27 11:55:03 PST 2021


Author: Greg McGary
Date: 2021-02-27T11:44:12-08:00
New Revision: 6f9dd843db4096cb3a63ce55e3f144e52dcaa98e

URL: https://github.com/llvm/llvm-project/commit/6f9dd843db4096cb3a63ce55e3f144e52dcaa98e
DIFF: https://github.com/llvm/llvm-project/commit/6f9dd843db4096cb3a63ce55e3f144e52dcaa98e.diff

LOG: [lld-macho] Implement options -rename_section -rename_segment

Implement command-line options to rename output sections & segments.

Differential Revision: https://reviews.llvm.org/D97600

Added: 
    lld/test/MachO/rename.s

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/Options.td
    lld/MachO/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 8ac07a198071..df5d1f867e2d 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -24,6 +24,10 @@ namespace macho {
 class Symbol;
 struct SymbolPriorityEntry;
 
+using NamePair = std::pair<llvm::StringRef, llvm::StringRef>;
+using SectionRenameMap = llvm::DenseMap<NamePair, NamePair>;
+using SegmentRenameMap = llvm::DenseMap<llvm::StringRef, llvm::StringRef>;
+
 struct PlatformInfo {
   llvm::MachO::PlatformKind kind;
   llvm::VersionTuple minimum;
@@ -76,6 +80,8 @@ struct Configuration {
   std::vector<llvm::StringRef> runtimePaths;
   std::vector<Symbol *> explicitUndefineds;
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
+  SectionRenameMap sectionRenameMap;
+  SegmentRenameMap segmentRenameMap;
 };
 
 // The symbol with the highest priority should be ordered first in the output

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index df0eaac21e0c..ca6378aa5560 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -815,6 +815,24 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
       parseDylibVersion(args, OPT_compatibility_version);
   config->dylibCurrentVersion = parseDylibVersion(args, OPT_current_version);
 
+  // Reject every special character except '.' and '$'
+  // TODO(gkm): verify that this is the proper set of invalid chars
+  StringRef invalidNameChars("!\"#%&'()*+,-/:;<=>?@[\\]^`{|}~");
+  auto validName = [invalidNameChars](StringRef s) {
+    if (s.find_first_of(invalidNameChars) != StringRef::npos)
+      error("invalid name for segment or section: " + s);
+    return s;
+  };
+  for (opt::Arg *arg : args.filtered(OPT_rename_section)) {
+    config->sectionRenameMap[{validName(arg->getValue(0)),
+                              validName(arg->getValue(1))}] = {
+        validName(arg->getValue(2)), validName(arg->getValue(3))};
+  }
+  for (opt::Arg *arg : args.filtered(OPT_rename_segment)) {
+    config->segmentRenameMap[validName(arg->getValue(0))] =
+        validName(arg->getValue(1));
+  }
+
   config->saveTemps = args.hasArg(OPT_save_temps);
 
   if (args.hasArg(OPT_v)) {

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 743b9cb08e0b..81fcdad30ffb 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -629,12 +629,10 @@ def move_to_ro_segment : MultiArg<["-"], "move_to_ro_segment", 2>,
 def rename_section : MultiArg<["-"], "rename_section", 4>,
      MetaVarName<"<from_segment> <from_section> <to_segment> <to_section>">,
      HelpText<"Rename <from_segment>/<from_section> as <to_segment>/<to_section>">,
-     Flags<[HelpHidden]>,
      Group<grp_rare>;
 def rename_segment : MultiArg<["-"], "rename_segment", 2>,
      MetaVarName<"<from_segment> <to_segment>">,
      HelpText<"Rename <from_segment> as <to_segment>">,
-     Flags<[HelpHidden]>,
      Group<grp_rare>;
 def trace_symbol_layout : Flag<["-"], "trace_symbol_layout">,
      HelpText<"Show where and why symbols move, as specified by -move_to_ro_segment, -move_to_rw_segment, -rename_section, and -rename_segment">,

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 56da22c1a19d..932bfebe0677 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -704,6 +704,16 @@ static void sortSegmentsAndSections() {
   }
 }
 
+static NamePair maybeRenameSection(NamePair key) {
+  auto newNames = config->sectionRenameMap.find(key);
+  if (newNames != config->sectionRenameMap.end())
+    return newNames->second;
+  auto newName = config->segmentRenameMap.find(key.first);
+  if (newName != config->segmentRenameMap.end())
+    return std::make_pair(newName->second, key.second);
+  return key;
+}
+
 void Writer::createOutputSections() {
   // First, create hidden sections
   stringTableSection = make<StringTableSection>();
@@ -726,13 +736,12 @@ void Writer::createOutputSections() {
   }
 
   // Then merge input sections into output sections.
-  MapVector<std::pair<StringRef, StringRef>, MergedOutputSection *>
-      mergedOutputSections;
+  MapVector<NamePair, MergedOutputSection *> mergedOutputSections;
   for (InputSection *isec : inputSections) {
-    MergedOutputSection *&osec =
-        mergedOutputSections[{isec->segname, isec->name}];
+    NamePair names = maybeRenameSection({isec->segname, isec->name});
+    MergedOutputSection *&osec = mergedOutputSections[names];
     if (osec == nullptr)
-      osec = make<MergedOutputSection>(isec->name);
+      osec = make<MergedOutputSection>(names.second);
     osec->mergeInput(isec);
   }
 

diff  --git a/lld/test/MachO/rename.s b/lld/test/MachO/rename.s
new file mode 100644
index 000000000000..77885b19fdef
--- /dev/null
+++ b/lld/test/MachO/rename.s
@@ -0,0 +1,62 @@
+# REQUIRES: x86
+# RUN: rm -fr %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
+# RUN: %lld -o %t %t.o
+
+## Check option format
+# RUN: not %lld \
+# RUN:     -rename_section B at GUS_SEG b at gus_sect S/ASHY_SEG st*rry_sect \
+# RUN:     -rename_section __FROM_SECT __from_sect __TO_SECT \
+# RUN:   -o /dev/null %t.o 2>&1 | FileCheck %s --check-prefix=BAD1
+
+# BAD1-DAG: error: invalid name for segment or section: B at GUS_SEG
+# BAD1-DAG: error: invalid name for segment or section: b at gus_sect
+# BAD1-DAG: error: invalid name for segment or section: S/ASHY_SEG
+# BAD1-DAG: error: invalid name for segment or section: st*rry_sect
+# BAD1-DAG: error: invalid name for segment or section: -o
+# BAD1-DAG: error: /dev/null: unhandled file type
+
+# RUN: not %lld \
+# RUN:     -rename_segment H#SHY_SEG PL+SSY_SEG \
+# RUN:     -rename_segment __FROM_SEG \
+# RUN:   -o /dev/null %t.o 2>&1 | FileCheck %s --check-prefix=BAD2
+
+# BAD2-DAG: error: invalid name for segment or section: H#SHY_SEG
+# BAD2-DAG: error: invalid name for segment or section: PL+SSY_SEG
+# BAD2-DAG: error: invalid name for segment or section: -o
+# BAD2-DAG: error: /dev/null: unhandled file type
+
+## Check that section and segment renames happen
+# RUN: %lld \
+# RUN:     -rename_section __FROM_SECT __from_sect __TO_SECT __to_sect \
+# RUN:     -rename_segment __FROM_SEG __TO_SEG \
+# RUN:   -o %t %t.o
+# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s
+
+# CHECK:      {{^}}Section{{$}}
+# CHECK-NEXT: sectname __text
+# CHECK-NEXT: segname __TEXT
+# CHECK:      {{^}}Section{{$}}
+# CHECK-NOT:  sectname __from_sect
+# CHECK-NEXT: sectname __to_sect
+# CHECK-NOT:  segname __FROM_SECT
+# CHECK-NEXT: segname __TO_SECT
+# CHECK:      {{^}}Section{{$}}
+# CHECK-NEXT: sectname __from_seg
+# CHECK-NOT:  segname __FROM_SEG
+# CHECK-NEXT: segname __TO_SEG
+
+.section __FROM_SECT,__from_sect
+.global _from_sect
+_from_sect:
+  .space 8
+
+.section __FROM_SEG,__from_seg
+.global _from_seg
+_from_seg:
+  .space 8
+
+.text
+.global _main
+_main:
+  ret


        


More information about the llvm-commits mailing list