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 --- /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 --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -270,7 +270,7 @@ 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 @@ } 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 @@ 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 @@ 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);