[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