From a018b538a6177b7fb50bad067ca4e828a85dbf76 Mon Sep 17 00:00:00 2001 From: Sameer Arora Date: Fri, 5 Jun 2020 10:42:19 -0700 Subject: [PATCH] [llvm-objcopy] Reorder --dump-section before --remove-section for ELF Reorder `DumpSection` under `handleArgs` in file `ELFObjcopy.cpp`. `DumpSection` is placed before `replaceAndRemoveSections` and is therefore now the first operation under `handleArgs`. Thus, it is now performed before both `add` and `remove` section operations. Change for the MachO format at D81123. Together fixes https://bugs.llvm.org/show_bug.cgi?id=44283. Reviewed By: alexshap, jhenderson, MaskRay Differential Revision: https://reviews.llvm.org/D81097 --- .../ELF/dump-section-before-add-remove.test | 35 ++++++++++++++++++++++ llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 23 +++++++------- 2 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 llvm/test/tools/llvm-objcopy/ELF/dump-section-before-add-remove.test diff --git a/llvm/test/tools/llvm-objcopy/ELF/dump-section-before-add-remove.test b/llvm/test/tools/llvm-objcopy/ELF/dump-section-before-add-remove.test new file mode 100644 index 0000000..7ecac36 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/dump-section-before-add-remove.test @@ -0,0 +1,35 @@ +# RUN: yaml2obj %s -o %t + +## Verify that section is dumped before it is removed. +# RUN: llvm-objcopy --dump-section .test2=%t1.dump -R .test2 %t %t1 +# RUN: od -t x1 %t1.dump | FileCheck %s --ignore-case --match-full-lines + +# CHECK: 0000000 de ad be ef +# CHECK-NEXT: 0000004 + +## Verify that the newly added section is not dumped. +# RUN: echo CAFE > %t3.txt +# RUN: not llvm-objcopy --dump-section .test3=%t3.dump --add-section .test3=%t3.txt %t %t3 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NODUMP -DINPUT=%t + +# NODUMP: error: '[[INPUT]]': section '.test3' not found + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .test1 + Type: SHT_PROGBITS + Flags: [ ] + - Name: .test2 + Type: SHT_PROGBITS + Flags: [ ] + Content: "DEADBEEF" + - Name: .test4 + Type: SHT_PROGBITS + Flags: [ ] + Content: "BEEFDEAD" +Symbols: [] diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp index aaf3b73..3e657d0 100644 --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -270,7 +270,7 @@ static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader, auto OnlyKeepDWOPred = [&DWOFile](const SectionBase &Sec) { return onlyKeepDWOPred(*DWOFile, Sec); }; - if (Error E = DWOFile->removeSections(Config.AllowBrokenLinks, + if (Error E = DWOFile->removeSections(Config.AllowBrokenLinks, OnlyKeepDWOPred)) return E; if (Config.OutputArch) { @@ -578,11 +578,11 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) { } if (Config.CompressionType != DebugCompressionType::None) - replaceDebugSections(Obj, RemovePred, isCompressable, + replaceDebugSections(Obj, RemovePred, isCompressable, [&Config, &Obj](const SectionBase *S) { return &Obj.addSection( *S, Config.CompressionType); - }); + }); else if (Config.DecompressDebugSections) replaceDebugSections( Obj, RemovePred, @@ -617,6 +617,15 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj, Obj.OSABI = Config.OutputArch.getValue().OSABI; } + // Dump sections before add/remove for compatibility with GNU objcopy. + for (StringRef Flag : Config.DumpSection) { + StringRef SectionName; + StringRef FileName; + std::tie(SectionName, FileName) = Flag.split('='); + if (Error E = dumpSectionToFile(SectionName, FileName, Obj)) + return E; + } + // It is important to remove the sections first. For example, we want to // remove the relocation sections before removing the symbols. That allows // us to avoid reporting the inappropriate errors about removing symbols @@ -725,14 +734,6 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj, NewSection.Type = SHT_NOTE; } - for (const auto &Flag : Config.DumpSection) { - std::pair SecPair = Flag.split("="); - StringRef SecName = SecPair.first; - StringRef File = SecPair.second; - if (Error E = dumpSectionToFile(SecName, File, Obj)) - return E; - } - if (!Config.AddGnuDebugLink.empty()) Obj.addSection(Config.AddGnuDebugLink, Config.GnuDebugLinkCRC32); -- 2.7.4