[llvm] r338582 - [llvm-objcopy] Add support for --rename-section flags from gnu objcopy

Jordan Rupprecht via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 1 09:23:22 PDT 2018


Author: rupprecht
Date: Wed Aug  1 09:23:22 2018
New Revision: 338582

URL: http://llvm.org/viewvc/llvm-project?rev=338582&view=rev
Log:
[llvm-objcopy] Add support for --rename-section flags from gnu objcopy

Summary:
Add support for --rename-section flags from gnu objcopy.

Not all flags appear to have an effect for ELF objects, but allowing them would allow easier drop-in replacement. Other unrecognized flags are rejected.

This was only tested by comparing flags printed by "readelf -e <.o>" against the output of gnu vs llvm objcopy, it hasn't been tested to be valid beyond that.

Reviewers: jakehehrlich, alexshap

Subscribers: llvm-commits, paulsemel, alexshap

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

Added:
    llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-osproc-mask.test
    llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-preserved.test
    llvm/trunk/test/tools/llvm-objcopy/rename-section-flag.test
Modified:
    llvm/trunk/test/tools/llvm-objcopy/rename-section.test
    llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp

Added: llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-osproc-mask.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-osproc-mask.test?rev=338582&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-osproc-mask.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-osproc-mask.test Wed Aug  1 09:23:22 2018
@@ -0,0 +1,115 @@
+# Test that cpu/processor-specific SHF_* flags are preserved.
+
+# ===== x86_64 =====
+
+# RUN: yaml2obj -docnum 1 %s > %t-x86_64.o
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc %t-x86_64.o
+# RUN: llvm-readobj -sections %t-x86_64.o | FileCheck %s --check-prefix=X86_64
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:          .foo
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_X86_64_LARGE ]
+
+# X86_64:        Name: .bar
+# X86_64-NEXT:   Type: SHT_PROGBITS
+# X86_64-NEXT:   Flags [
+# X86_64-NEXT:     SHF_ALLOC (0x2)
+# X86_64-NEXT:     SHF_WRITE (0x1)
+# X86_64-NEXT:     SHF_X86_64_LARGE (0x10000000)
+# X86_64-NEXT:   ]
+
+# ===== hex =====
+
+# RUN: yaml2obj -docnum 2 %s > %t-hex.o
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc %t-hex.o
+# RUN: llvm-readobj -sections %t-hex.o | FileCheck %s --check-prefix=HEX
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_HEXAGON
+Sections:
+  - Name:          .foo
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_HEX_GPREL ]
+
+# HEX:        Name: .bar
+# HEX-NEXT:   Type: SHT_PROGBITS
+# HEX-NEXT:   Flags [
+# HEX-NEXT:     SHF_ALLOC (0x2)
+# HEX-NEXT:     SHF_HEX_GPREL (0x10000000)
+# HEX-NEXT:     SHF_WRITE (0x1)
+# HEX-NEXT:   ]
+
+# ===== mips =====
+
+# RUN: yaml2obj -docnum 3 %s > %t-mips.o
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc %t-mips.o
+# RUN: llvm-readobj -sections %t-mips.o | FileCheck %s --check-prefix=MIPS
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+Sections:
+  - Name:          .foo
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_MIPS_NODUPES, SHF_MIPS_NAMES, SHF_MIPS_LOCAL,
+                     SHF_MIPS_NOSTRIP, SHF_MIPS_GPREL, SHF_MIPS_MERGE,
+		     SHF_MIPS_ADDR, SHF_MIPS_STRING ]
+
+# Note: llvm-readobj prints SHF_EXCLUDE/SHF_MASKPROC since specifying all
+# SHF_MIPS_* flags covers the same bitset.
+
+# MIPS:        Name: .bar
+# MIPS-NEXT:   Type: SHT_PROGBITS
+# MIPS-NEXT:   Flags [
+# MIPS-NEXT:     SHF_ALLOC (0x2)
+# MIPS-NEXT:     SHF_EXCLUDE (0x80000000)
+# MIPS-NEXT:     SHF_MASKPROC (0xF0000000)
+# MIPS-NEXT:     SHF_MIPS_ADDR (0x40000000)
+# MIPS-NEXT:     SHF_MIPS_GPREL (0x10000000)
+# MIPS-NEXT:     SHF_MIPS_LOCAL (0x4000000)
+# MIPS-NEXT:     SHF_MIPS_MERGE (0x20000000)
+# MIPS-NEXT:     SHF_MIPS_NAMES (0x2000000)
+# MIPS-NEXT:     SHF_MIPS_NODUPES (0x1000000)
+# MIPS-NEXT:     SHF_MIPS_NOSTRIP (0x8000000)
+# MIPS-NEXT:     SHF_MIPS_STRING (0x80000000)
+# MIPS-NEXT:     SHF_WRITE (0x1)
+# MIPS-NEXT:   ]
+
+# ===== arm =====
+
+# RUN: yaml2obj -docnum 4 %s > %t-arm.o
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc %t-arm.o
+# RUN: llvm-readobj -sections %t-arm.o | FileCheck %s --check-prefix=ARM
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+Sections:
+  - Name:          .foo
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ARM_PURECODE ]
+
+# ARM:        Name: .bar
+# ARM-NEXT:   Type: SHT_PROGBITS
+# ARM-NEXT:   Flags [
+# ARM-NEXT:     SHF_ALLOC (0x2)
+# ARM-NEXT:     SHF_ARM_PURECODE (0x20000000)
+# ARM-NEXT:     SHF_WRITE (0x1)
+# ARM-NEXT:   ]

Added: llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-preserved.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-preserved.test?rev=338582&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-preserved.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/rename-section-flag-preserved.test Wed Aug  1 09:23:22 2018
@@ -0,0 +1,74 @@
+# RUN: yaml2obj %s > %t
+
+# Single flags on a section with all flags:
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc %t %t.alloc
+# RUN: llvm-readobj -sections %t.alloc | FileCheck %s --check-prefixes=CHECK,ALLOC,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,load %t %t.load
+# RUN: llvm-readobj -sections %t.load | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,noload %t %t.noload
+# RUN: llvm-readobj -sections %t.noload | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,readonly %t %t.readonly
+# RUN: llvm-readobj -sections %t.readonly | FileCheck %s --check-prefixes=CHECK
+# RUN: llvm-objcopy --rename-section=.foo=.bar,debug %t %t.debug
+# RUN: llvm-readobj -sections %t.debug | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,code %t %t.code
+# RUN: llvm-readobj -sections %t.code | FileCheck %s --check-prefixes=CHECK,EXEC,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,data %t %t.data
+# RUN: llvm-readobj -sections %t.data | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,rom %t %t.rom
+# RUN: llvm-readobj -sections %t.rom | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,contents %t %t.contents
+# RUN: llvm-readobj -sections %t.contents | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,merge %t %t.merge
+# RUN: llvm-readobj -sections %t.merge | FileCheck %s --check-prefixes=CHECK,MERGE,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,strings %t %t.strings
+# RUN: llvm-readobj -sections %t.strings | FileCheck %s --check-prefixes=CHECK,STRINGS,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,share %t %t.share
+# RUN: llvm-readobj -sections %t.share | FileCheck %s --check-prefixes=CHECK,WRITE
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .infolink
+    Type:            SHT_NOBITS
+  - Name:            .group
+    Type:            SHT_GROUP
+    Link:            .symtab
+    Flags:           [ ]
+    Info:            dummy
+    Members:
+      - SectionOrType: GRP_COMDAT
+      - SectionOrType: .foo
+  - Name:            .foo
+    Type:            SHT_PROGBITS
+    Link:            .infolink
+    Flags:           [ SHF_ALLOC, SHF_COMPRESSED, SHF_EXCLUDE, SHF_EXECINSTR,
+                       SHF_GROUP, SHF_INFO_LINK, SHF_LINK_ORDER, SHF_MERGE,
+                       SHF_OS_NONCONFORMING, SHF_STRINGS, SHF_TLS, SHF_WRITE ]
+    Content:        "a4a4a4a4"
+Symbols:
+  Local:
+  - Name:            dummy
+    Section:         .group
+
+# CHECK:        Name: .bar
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# ALLOC-NEXT:     SHF_ALLOC (0x2)
+# CHECK-NEXT:     SHF_COMPRESSED (0x800)
+# CHECK-NEXT:     SHF_EXCLUDE (0x80000000)
+# EXEC-NEXT:      SHF_EXECINSTR (0x4)
+# CHECK-NEXT:     SHF_GROUP (0x200)
+# CHECK-NEXT:     SHF_INFO_LINK (0x40)
+# CHECK-NEXT:     SHF_LINK_ORDER (0x80)
+# MERGE-NEXT:     SHF_MERGE (0x10)
+# STRINGS-NEXT:   SHF_STRINGS (0x20)
+# CHECK-NEXT:     SHF_TLS (0x400)
+# WRITE-NEXT:     SHF_WRITE (0x1)
+# CHECK-NEXT:   ]
+
+# BAD-FLAG: unrecognized section flag 'xyzzy'

Added: llvm/trunk/test/tools/llvm-objcopy/rename-section-flag.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/rename-section-flag.test?rev=338582&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/rename-section-flag.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/rename-section-flag.test Wed Aug  1 09:23:22 2018
@@ -0,0 +1,60 @@
+# RUN: yaml2obj %s > %t
+
+# Single flags on a section with no flags:
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc %t %t.alloc
+# RUN: llvm-readobj -sections %t.alloc | FileCheck %s --check-prefixes=CHECK,ALLOC,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,load %t %t.load
+# RUN: llvm-readobj -sections %t.load | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,noload %t %t.noload
+# RUN: llvm-readobj -sections %t.noload | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,readonly %t %t.readonly
+# RUN: llvm-readobj -sections %t.readonly | FileCheck %s --check-prefixes=CHECK
+# RUN: llvm-objcopy --rename-section=.foo=.bar,debug %t %t.debug
+# RUN: llvm-readobj -sections %t.debug | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,code %t %t.code
+# RUN: llvm-readobj -sections %t.code | FileCheck %s --check-prefixes=CHECK,EXEC,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,data %t %t.data
+# RUN: llvm-readobj -sections %t.data | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,rom %t %t.rom
+# RUN: llvm-readobj -sections %t.rom | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,contents %t %t.contents
+# RUN: llvm-readobj -sections %t.contents | FileCheck %s --check-prefixes=CHECK,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,merge %t %t.merge
+# RUN: llvm-readobj -sections %t.merge | FileCheck %s --check-prefixes=CHECK,MERGE,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,strings %t %t.strings
+# RUN: llvm-readobj -sections %t.strings | FileCheck %s --check-prefixes=CHECK,STRINGS,WRITE
+# RUN: llvm-objcopy --rename-section=.foo=.bar,share %t %t.share
+# RUN: llvm-readobj -sections %t.share | FileCheck %s --check-prefixes=CHECK,WRITE
+
+# Multiple flags:
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc,readonly,strings %t %t.alloc_ro_strings
+# RUN: llvm-readobj -sections %t.alloc_ro_strings | FileCheck %s --check-prefixes=CHECK,ALLOC,STRINGS
+# RUN: llvm-objcopy --rename-section=.foo=.bar,alloc,code %t %t.alloc_code
+# RUN: llvm-readobj -sections %t.alloc_code | FileCheck %s --check-prefixes=CHECK,ALLOC,EXEC,WRITE
+
+# Invalid flags:
+# RUN: not llvm-objcopy --rename-section=.foo=.bar,xyzzy %t %t.xyzzy 2>&1 | FileCheck %s --check-prefix=BAD-FLAG
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .foo
+    Type:            SHT_PROGBITS
+    Flags:           [ ]
+    Content:        "c3c3c3c3"
+
+# CHECK:        Name: .bar
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# ALLOC-NEXT:     SHF_ALLOC (0x2)
+# EXEC-NEXT:      SHF_EXECINSTR (0x4)
+# MERGE-NEXT:     SHF_MERGE (0x10)
+# STRINGS-NEXT:   SHF_STRINGS (0x20)
+# WRITE-NEXT:     SHF_WRITE (0x1)
+# CHECK-NEXT:   ]
+
+# BAD-FLAG: Unrecognized section flag 'xyzzy'. Flags supported for GNU compatibility: alloc, load, noload, readonly, debug, code, data, rom, share, contents, merge, strings.

Modified: llvm/trunk/test/tools/llvm-objcopy/rename-section.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/rename-section.test?rev=338582&r1=338581&r2=338582&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/rename-section.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/rename-section.test Wed Aug  1 09:23:22 2018
@@ -26,5 +26,5 @@ Sections:
 # CHECK: Name: .strtab
 # CHECK: Name: .shstrtab
 
-#BAD-FORMAT: Bad format for --rename-section
-#MULTIPLE-RENAMES: Already have a section rename for .foo
+#BAD-FORMAT: Bad format for --rename-section: missing '='
+#MULTIPLE-RENAMES: Multiple renames of section .foo

Modified: llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=338582&r1=338581&r2=338582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td Wed Aug  1 09:23:22 2018
@@ -27,9 +27,13 @@ defm add_gnu_debuglink : Eq<"add-gnu-deb
 defm remove_section : Eq<"remove-section">,
                       MetaVarName<"section">,
                       HelpText<"Remove <section>">;
-defm rename_section : Eq<"rename-section">,
-                      MetaVarName<"old=new">,
-                      HelpText<"Renames a section from old to new">;
+defm rename_section
+    : Eq<"rename-section">,
+      MetaVarName<"old=new[,flag1,...]">,
+      HelpText<
+          "Renames a section from old to new, optionally with specified flags. "
+          "Flags supported for GNU compatibility: alloc, load, noload, "
+          "readonly, debug, code, data, rom, share, contents, merge, strings.">;
 defm redefine_symbol : Eq<"redefine-sym">,
                        MetaVarName<"old=new">,
                        HelpText<"Change the name of a symbol old to new">;

Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=338582&r1=338581&r2=338582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Wed Aug  1 09:23:22 2018
@@ -9,7 +9,10 @@
 
 #include "llvm-objcopy.h"
 #include "Object.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/ELF.h"
@@ -115,6 +118,12 @@ public:
   StripOptTable() : OptTable(StripInfoTable, true) {}
 };
 
+struct SectionRename {
+  StringRef OriginalName;
+  StringRef NewName;
+  Optional<uint64_t> NewFlags;
+};
+
 struct CopyConfig {
   StringRef OutputFilename;
   StringRef InputFilename;
@@ -133,7 +142,7 @@ struct CopyConfig {
   std::vector<StringRef> SymbolsToWeaken;
   std::vector<StringRef> SymbolsToRemove;
   std::vector<StringRef> SymbolsToKeep;
-  StringMap<StringRef> SectionsToRename;
+  StringMap<SectionRename> SectionsToRename;
   StringMap<StringRef> SymbolsToRename;
   bool StripAll = false;
   bool StripAllGNU = false;
@@ -152,6 +161,23 @@ struct CopyConfig {
 
 using SectionPred = std::function<bool(const SectionBase &Sec)>;
 
+enum SectionFlag {
+  SecNone = 0,
+  SecAlloc = 1 << 0,
+  SecLoad = 1 << 1,
+  SecNoload = 1 << 2,
+  SecReadonly = 1 << 3,
+  SecDebug = 1 << 4,
+  SecCode = 1 << 5,
+  SecData = 1 << 6,
+  SecRom = 1 << 7,
+  SecMerge = 1 << 8,
+  SecStrings = 1 << 9,
+  SecContents = 1 << 10,
+  SecShare = 1 << 11,
+  LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ SecShare)
+};
+
 } // namespace
 
 namespace llvm {
@@ -185,6 +211,65 @@ LLVM_ATTRIBUTE_NORETURN void reportError
 } // end namespace objcopy
 } // end namespace llvm
 
+static SectionFlag ParseSectionRenameFlag(StringRef SectionName) {
+  return llvm::StringSwitch<SectionFlag>(SectionName)
+      .Case("alloc", SectionFlag::SecAlloc)
+      .Case("load", SectionFlag::SecLoad)
+      .Case("noload", SectionFlag::SecNoload)
+      .Case("readonly", SectionFlag::SecReadonly)
+      .Case("debug", SectionFlag::SecDebug)
+      .Case("code", SectionFlag::SecCode)
+      .Case("data", SectionFlag::SecData)
+      .Case("rom", SectionFlag::SecRom)
+      .Case("merge", SectionFlag::SecMerge)
+      .Case("strings", SectionFlag::SecStrings)
+      .Case("contents", SectionFlag::SecContents)
+      .Case("share", SectionFlag::SecShare)
+      .Default(SectionFlag::SecNone);
+}
+
+static SectionRename ParseRenameSectionValue(StringRef FlagValue) {
+  if (!FlagValue.contains('='))
+    error("Bad format for --rename-section: missing '='");
+
+  // Initial split: ".foo" = ".bar,f1,f2,..."
+  auto Old2New = FlagValue.split('=');
+  SectionRename SR;
+  SR.OriginalName = Old2New.first;
+
+  // Flags split: ".bar" "f1" "f2" ...
+  SmallVector<StringRef, 6> NameAndFlags;
+  Old2New.second.split(NameAndFlags, ',');
+  SR.NewName = NameAndFlags[0];
+
+  if (NameAndFlags.size() > 1) {
+    SectionFlag Flags = SectionFlag::SecNone;
+    for (size_t I = 1, Size = NameAndFlags.size(); I < Size; ++I) {
+      SectionFlag Flag = ParseSectionRenameFlag(NameAndFlags[I]);
+      if (Flag == SectionFlag::SecNone)
+        error("Unrecognized section flag '" + NameAndFlags[I] +
+              "'. Flags supported for GNU compatibility: alloc, load, noload, "
+              "readonly, debug, code, data, rom, share, contents, merge, "
+              "strings.");
+      Flags |= Flag;
+    }
+
+    SR.NewFlags = 0;
+    if (Flags & SectionFlag::SecAlloc)
+      *SR.NewFlags |= ELF::SHF_ALLOC;
+    if (!(Flags & SectionFlag::SecReadonly))
+      *SR.NewFlags |= ELF::SHF_WRITE;
+    if (Flags & SectionFlag::SecCode)
+      *SR.NewFlags |= ELF::SHF_EXECINSTR;
+    if (Flags & SectionFlag::SecMerge)
+      *SR.NewFlags |= ELF::SHF_MERGE;
+    if (Flags & SectionFlag::SecStrings)
+      *SR.NewFlags |= ELF::SHF_STRINGS;
+  }
+
+  return SR;
+}
+
 static bool IsDebugSection(const SectionBase &Sec) {
   return Sec.Name.startswith(".debug") || Sec.Name.startswith(".zdebug") ||
          Sec.Name == ".gdb_index";
@@ -437,8 +522,20 @@ static void HandleArgs(const CopyConfig
   if (!Config.SectionsToRename.empty()) {
     for (auto &Sec : Obj.sections()) {
       const auto Iter = Config.SectionsToRename.find(Sec.Name);
-      if (Iter != Config.SectionsToRename.end())
-        Sec.Name = Iter->second;
+      if (Iter != Config.SectionsToRename.end()) {
+        const SectionRename &SR = Iter->second;
+        Sec.Name = SR.NewName;
+        if (SR.NewFlags.hasValue()) {
+          // Preserve some flags which should not be dropped when setting flags.
+          // Also, preserve anything OS/processor dependant.
+          const uint64_t PreserveMask = ELF::SHF_COMPRESSED | ELF::SHF_EXCLUDE |
+                                        ELF::SHF_GROUP | ELF::SHF_LINK_ORDER |
+                                        ELF::SHF_MASKOS | ELF::SHF_MASKPROC |
+                                        ELF::SHF_TLS | ELF::SHF_INFO_LINK;
+          Sec.Flags = (Sec.Flags & PreserveMask) |
+                      (SR.NewFlags.getValue() & ~PreserveMask);
+        }
+      }
     }
   }
 
@@ -600,11 +697,9 @@ static CopyConfig ParseObjcopyOptions(Ar
   }
 
   for (auto Arg : InputArgs.filtered(OBJCOPY_rename_section)) {
-    if (!StringRef(Arg->getValue()).contains('='))
-      error("Bad format for --rename-section");
-    auto Old2New = StringRef(Arg->getValue()).split('=');
-    if (!Config.SectionsToRename.insert(Old2New).second)
-      error("Already have a section rename for " + Old2New.first);
+    SectionRename SR = ParseRenameSectionValue(StringRef(Arg->getValue()));
+    if (!Config.SectionsToRename.try_emplace(SR.OriginalName, SR).second)
+      error("Multiple renames of section " + SR.OriginalName);
   }
 
   for (auto Arg : InputArgs.filtered(OBJCOPY_remove_section))




More information about the llvm-commits mailing list