[llvm] 7c03b7d - [llvm-objcopy][ELF] Allow --set-section-flags src=... and --rename-section src=tst

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 11 09:04:50 PDT 2022


Author: Fangrui Song
Date: 2022-07-11T09:04:45-07:00
New Revision: 7c03b7d668dcc0c6937d41e131fa0a07b62f907b

URL: https://github.com/llvm/llvm-project/commit/7c03b7d668dcc0c6937d41e131fa0a07b62f907b
DIFF: https://github.com/llvm/llvm-project/commit/7c03b7d668dcc0c6937d41e131fa0a07b62f907b.diff

LOG: [llvm-objcopy][ELF] Allow --set-section-flags src=... and --rename-section src=tst

* GNU objcopy supports --set-section-flags src=... --rename-section src=tst and --set-section-flags runs first.
* GNU objcopy processes --update-section before --rename-section.

To match the two behaviors, postpone --rename-section and allow its use together
with --set-section-flags.

As a side effect, --rename-section=.foo1=.foo2 --add-section=.foo1=/dev/null
leads to .foo2 while GNU objcopy surprisingly produces .foo1 (so
--set-section-flags --add-section --rename-section do not form a total order).
I think the deviation is fine as a total order makes more sense.

Rename set-section-flags-and-rename.test to
set-section-attr-and-rename.test and additionally test --set-section-alignment

Reviewed By: jhenderson

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

Added: 
    llvm/test/tools/llvm-objcopy/ELF/rename-section-and-update.test
    llvm/test/tools/llvm-objcopy/ELF/set-section-attr-and-rename.test

Modified: 
    llvm/docs/ReleaseNotes.rst
    llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
    llvm/tools/llvm-objcopy/ObjcopyOptions.cpp

Removed: 
    llvm/test/tools/llvm-objcopy/ELF/set-section-flags-and-rename.test


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 9b0eb6f719a9b..1268cc71c9b54 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -233,6 +233,8 @@ Changes to the LLVM tools
   filter :doc:`Symbolizer Markup </SymbolizerMarkupFormat>` into human-readable
   form.
 * :doc:`llvm-objcopy <CommandGuide/llvm-objcopy>` has removed support for the legacy ``zlib-gnu`` format.
+* :doc:`llvm-objcopy <CommandGuide/llvm-objcopy>` now allows ``--set-section-flags src=... --rename-section src=tst``.
+  ``--add-section=.foo1=... --rename-section=.foo1=.foo2`` now adds ``.foo1`` instead of ``.foo2``.
 
 Changes to LLDB
 ---------------------------------

diff  --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index 2d388f8a867ed..ee592bb9f3883 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -629,6 +629,63 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
   if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj))
     return E;
 
+  if (!Config.SetSectionAlignment.empty()) {
+    for (SectionBase &Sec : Obj.sections()) {
+      auto I = Config.SetSectionAlignment.find(Sec.Name);
+      if (I != Config.SetSectionAlignment.end())
+        Sec.Align = I->second;
+    }
+  }
+
+  if (Config.OnlyKeepDebug)
+    for (auto &Sec : Obj.sections())
+      if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE)
+        Sec.Type = SHT_NOBITS;
+
+  for (const NewSectionInfo &AddedSection : Config.AddSection) {
+    auto AddSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
+      OwnedDataSection &NewSection =
+          Obj.addSection<OwnedDataSection>(Name, Data);
+      if (Name.startswith(".note") && Name != ".note.GNU-stack")
+        NewSection.Type = SHT_NOTE;
+      return Error::success();
+    };
+    if (Error E = handleUserSection(AddedSection, AddSection))
+      return E;
+  }
+
+  for (const NewSectionInfo &NewSection : Config.UpdateSection) {
+    auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
+      return Obj.updateSection(Name, Data);
+    };
+    if (Error E = handleUserSection(NewSection, UpdateSection))
+      return E;
+  }
+
+  if (!Config.AddGnuDebugLink.empty())
+    Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink,
+                                        Config.GnuDebugLinkCRC32);
+
+  // If the symbol table was previously removed, we need to create a new one
+  // before adding new symbols.
+  if (!Obj.SymbolTable && !Config.SymbolsToAdd.empty())
+    if (Error E = Obj.addNewSymbolTable())
+      return E;
+
+  for (const NewSymbolInfo &SI : Config.SymbolsToAdd)
+    addSymbol(Obj, SI, ELFConfig.NewSymbolVisibility);
+
+  // --set-section-flags works with sections added by --add-section.
+  if (!Config.SetSectionFlags.empty()) {
+    for (auto &Sec : Obj.sections()) {
+      const auto Iter = Config.SetSectionFlags.find(Sec.Name);
+      if (Iter != Config.SetSectionFlags.end()) {
+        const SectionFlagsUpdate &SFU = Iter->second;
+        setSectionFlagsAndType(Sec, SFU.NewFlags);
+      }
+    }
+  }
+
   if (!Config.SectionsToRename.empty()) {
     std::vector<RelocationSectionBase *> RelocSections;
     DenseSet<SectionBase *> RenamedSections;
@@ -693,63 +750,6 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
     }
   }
 
-  if (!Config.SetSectionAlignment.empty()) {
-    for (SectionBase &Sec : Obj.sections()) {
-      auto I = Config.SetSectionAlignment.find(Sec.Name);
-      if (I != Config.SetSectionAlignment.end())
-        Sec.Align = I->second;
-    }
-  }
-
-  if (Config.OnlyKeepDebug)
-    for (auto &Sec : Obj.sections())
-      if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE)
-        Sec.Type = SHT_NOBITS;
-
-  for (const NewSectionInfo &AddedSection : Config.AddSection) {
-    auto AddSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
-      OwnedDataSection &NewSection =
-          Obj.addSection<OwnedDataSection>(Name, Data);
-      if (Name.startswith(".note") && Name != ".note.GNU-stack")
-        NewSection.Type = SHT_NOTE;
-      return Error::success();
-    };
-    if (Error E = handleUserSection(AddedSection, AddSection))
-      return E;
-  }
-
-  for (const NewSectionInfo &NewSection : Config.UpdateSection) {
-    auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
-      return Obj.updateSection(Name, Data);
-    };
-    if (Error E = handleUserSection(NewSection, UpdateSection))
-      return E;
-  }
-
-  if (!Config.AddGnuDebugLink.empty())
-    Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink,
-                                        Config.GnuDebugLinkCRC32);
-
-  // If the symbol table was previously removed, we need to create a new one
-  // before adding new symbols.
-  if (!Obj.SymbolTable && !Config.SymbolsToAdd.empty())
-    if (Error E = Obj.addNewSymbolTable())
-      return E;
-
-  for (const NewSymbolInfo &SI : Config.SymbolsToAdd)
-    addSymbol(Obj, SI, ELFConfig.NewSymbolVisibility);
-
-  // --set-section-flags works with sections added by --add-section.
-  if (!Config.SetSectionFlags.empty()) {
-    for (auto &Sec : Obj.sections()) {
-      const auto Iter = Config.SetSectionFlags.find(Sec.Name);
-      if (Iter != Config.SetSectionFlags.end()) {
-        const SectionFlagsUpdate &SFU = Iter->second;
-        setSectionFlagsAndType(Sec, SFU.NewFlags);
-      }
-    }
-  }
-
   if (ELFConfig.EntryExpr)
     Obj.Entry = ELFConfig.EntryExpr(Obj.Entry);
   return Error::success();

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/rename-section-and-update.test b/llvm/test/tools/llvm-objcopy/ELF/rename-section-and-update.test
new file mode 100644
index 0000000000000..a684e7ad9153a
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/rename-section-and-update.test
@@ -0,0 +1,29 @@
+## --add-section is handled before --rename-section. Note: GNU objcopy produces .foo2.
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy --rename-section=.foo1=.foo2 --add-section=.foo1=/dev/null %t %t.1
+# RUN: llvm-readobj -S %t.1 | FileCheck %s
+
+# CHECK:      Name: .foo2
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+
+## --update-section is handled before --rename-section.
+# RUN: echo 00 > %t.nop
+# RUN: llvm-objcopy --rename-section=.text=.text2 --update-section=.text=%t.nop %t %t.2
+# RUN: llvm-readelf -x .text2 %t.2 | FileCheck %s --check-prefix=CHECK2
+
+# CHECK2:      Hex dump of section '.text2':
+# CHECK2-NEXT: 0x00000000 30300a
+
+!ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:    .text
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC, SHF_EXECINSTR ]
+    Content: "c3c3c3"

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/set-section-attr-and-rename.test b/llvm/test/tools/llvm-objcopy/ELF/set-section-attr-and-rename.test
new file mode 100644
index 0000000000000..ba6f521f77654
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-section-attr-and-rename.test
@@ -0,0 +1,29 @@
+# RUN: yaml2obj %s -o %t
+
+# RUN: llvm-objcopy --rename-section=.foo=.bar --set-section-alignment=.foo=16 --set-section-flags=.foo=alloc %t %t.1
+# RUN: llvm-readobj -S %t.1 | FileCheck %s
+
+# CHECK:      Name: .bar
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT:   SHF_ALLOC
+# CHECK-NEXT:   SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK:      AddressAlignment:
+# CHECK-SAME:   {{^}} 16
+
+# RUN: not llvm-objcopy --rename-section=.foo=.bar --set-section-flags=.bar=alloc %t %t.2 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=SET-BAR
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:  .foo
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC ]
+
+# SET-BAR: --set-section-flags=.bar conflicts with --rename-section=.foo=.bar

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/set-section-flags-and-rename.test b/llvm/test/tools/llvm-objcopy/ELF/set-section-flags-and-rename.test
deleted file mode 100644
index 4b553b3304e45..0000000000000
--- a/llvm/test/tools/llvm-objcopy/ELF/set-section-flags-and-rename.test
+++ /dev/null
@@ -1,14 +0,0 @@
-# RUN: yaml2obj %s -o %t
-
-# RUN: not llvm-objcopy --rename-section=.foo=.bar --set-section-flags=.foo=alloc %t %t.2 2>&1 | FileCheck %s --check-prefix=SET-FOO
-# RUN: not llvm-objcopy --rename-section=.foo=.bar --set-section-flags=.bar=alloc %t %t.2 2>&1 | FileCheck %s --check-prefix=SET-BAR
-
-!ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
-
-# SET-FOO: --set-section-flags=.foo conflicts with --rename-section=.foo=.bar
-# SET-BAR: --set-section-flags=.bar conflicts with --rename-section=.foo=.bar

diff  --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 94841eff37144..30ca506f79e39 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -810,15 +810,9 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
           SFU->Name.str().c_str());
   }
   // Prohibit combinations of --set-section-flags when the section name is used
-  // by --rename-section, either as a source or a destination.
+  // as the destination of a --rename-section.
   for (const auto &E : Config.SectionsToRename) {
     const SectionRename &SR = E.second;
-    if (Config.SetSectionFlags.count(SR.OriginalName))
-      return createStringError(
-          errc::invalid_argument,
-          "--set-section-flags=%s conflicts with --rename-section=%s=%s",
-          SR.OriginalName.str().c_str(), SR.OriginalName.str().c_str(),
-          SR.NewName.str().c_str());
     if (Config.SetSectionFlags.count(SR.NewName))
       return createStringError(
           errc::invalid_argument,


        


More information about the llvm-commits mailing list