Index: llvm/test/tools/llvm-objcopy/COFF/update-section.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/COFF/update-section.test @@ -0,0 +1,31 @@ +# RUN: echo -n AAAB > %t.diff +# RUN: echo -n AAA > %t.smaller +# RUN: echo -n AAAAA > %t.larger + +# RUN: yaml2obj %s -o %t + +# RUN: llvm-objcopy --update-section=.text=%t.diff %t - | obj2yaml | FileCheck %s +# CHECK: SectionData: '41414142' + +# RUN: llvm-objcopy --update-section=.text=%t.smaller %t - | obj2yaml | FileCheck %s --check-prefix=SMALLER +# SMALLER: SectionData: '41414100' + +# RUN: not llvm-objcopy --update-section=.text=%t.larger %t /dev/null 2>&1 | FileCheck %s --check-prefix=TOO-LARGE +# TOO-LARGE: error: {{.*}}new section cannot be larger than previous section + +# RUN: not llvm-objcopy --update-section=.text=%t.noexist %t /dev/null + +# RUN: not llvm-objcopy --update-section=.noexist=%t.diff %t /dev/null 2>&1 | FileCheck %s --check-prefix=NO-SECTION +# NO-SECTION: error: {{.*}}could not find section with name '.noexist' + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ ] + Alignment: 4 + SectionData: '41414141' +symbols: +... Index: llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -253,6 +253,30 @@ Characteristics); } + for (StringRef Flag : Config.UpdateSection) { + StringRef SecName, FileName; + std::tie(SecName, FileName) = Flag.split("="); + + auto BufOrErr = MemoryBuffer::getFile(FileName); + if (!BufOrErr) + return createFileError(FileName, errorCodeToError(BufOrErr.getError())); + auto Buf = std::move(*BufOrErr); + + auto MutableSections = Obj.getMutableSections(); + auto It = llvm::find_if(MutableSections, [SecName](auto &Sec) { + return Sec.Name == SecName; + }); + if (It == MutableSections.end()) + return createStringError( + errc::invalid_argument, + "could not find section with name '%s'", SecName.str().c_str()); + if (It->getContents().size() < Buf->getBufferSize()) + return createStringError( + errc::invalid_argument, + "new section cannot be larger than previous section"); + It->setOwnedContents({Buf->getBufferStart(), Buf->getBufferEnd()}); + } + if (!Config.AddGnuDebugLink.empty()) if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink)) return E;