diff --git a/llvm/test/tools/llvm-objcopy/ELF/dump-section-empty.test b/llvm/test/tools/llvm-objcopy/ELF/dump-section-empty.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/dump-section-empty.test @@ -0,0 +1,27 @@ +## Test that --dump-section works on a section with no contents. +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-objcopy --dump-section .empty=%t-empty.o %t.o %t2.o +# RUN: wc -c %t-empty.o | FileCheck %s --check-prefix=EMPTY + +## FIXME: this should be a warning, not an error. (Keep the text matching the +## same, but it should pass without 'not'). +# RUN: not llvm-objcopy --dump-section .nobits=%t-nobits.o %t.o %t2.o 2>&1 \ +# RUN: | FileCheck %s --check-prefix=NOBITS -DINPUT=%t.o + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .empty + Type: SHT_PROGBITS + Flags: [ SHF_WRITE ] + - Name: .nobits + Type: SHT_NOBITS + Flags: [ SHF_WRITE ] + +# EMPTY: 0 +# NOBITS: error: '[[INPUT]]': cannot dump section '.nobits': it has no contents diff --git a/llvm/test/tools/llvm-objcopy/ELF/dump-section.test b/llvm/test/tools/llvm-objcopy/ELF/dump-section.test --- a/llvm/test/tools/llvm-objcopy/ELF/dump-section.test +++ b/llvm/test/tools/llvm-objcopy/ELF/dump-section.test @@ -3,7 +3,6 @@ # RUN: llvm-objcopy -O binary --only-section .text %t %t3 # RUN: llvm-objcopy --dump-section .text=%t4 %t %t5 # RUN: llvm-objcopy --dump-section .foo=%t6 %t %t7 -# RUN: not llvm-objcopy --dump-section .bar=%t8 %t %t9 2>&1 | FileCheck %s --check-prefix=NOBITS -DINPUT=%t # RUN: od -t x1 %t2 | FileCheck %s --ignore-case # RUN: od -t x1 %t6 | FileCheck %s --ignore-case --check-prefix=NON-ALLOC # RUN: wc -c %t2 | FileCheck %s --check-prefix=SIZE @@ -26,9 +25,6 @@ Type: SHT_PROGBITS Flags: [ SHF_WRITE ] Content: "CAFE" - - Name: .bar - Type: SHT_NOBITS - Flags: [ SHF_WRITE ] ProgramHeaders: - Type: PT_LOAD Flags: [ PF_X, PF_R ] @@ -40,5 +36,3 @@ #NON-ALLOC: 0000000 ca fe #SIZE: 4 - -#NOBITS: error: '[[INPUT]]': cannot dump section '.bar': it has no contents 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 @@ -288,20 +288,17 @@ Object &Obj) { for (auto &Sec : Obj.sections()) { if (Sec.Name == SecName) { - if (Sec.OriginalData.empty()) + // FIXME: this should be a warning, not an error. + if (Sec.Type == SHT_NOBITS) return createStringError(object_error::parse_failed, "cannot dump section '%s': it has no contents", SecName.str().c_str()); - Expected> BufferOrErr = - FileOutputBuffer::create(Filename, Sec.OriginalData.size()); - if (!BufferOrErr) - return BufferOrErr.takeError(); - std::unique_ptr Buf = std::move(*BufferOrErr); - std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), - Buf->getBufferStart()); - if (Error E = Buf->commit()) + FileBuffer Buf = FileBuffer(Filename); + if (Error E = Buf.allocate(Sec.OriginalData.size())) return E; - return Error::success(); + if (!Sec.OriginalData.empty()) + llvm::copy(Sec.OriginalData, Buf.getBufferStart()); + return Buf.commit(); } } return createStringError(object_error::parse_failed, "section '%s' not found", diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/tools/llvm-objcopy/ELF/Object.h @@ -18,7 +18,6 @@ #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Errc.h" -#include "llvm/Support/FileOutputBuffer.h" #include #include #include diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -19,7 +19,6 @@ #include "llvm/Support/Compression.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/Path.h" #include #include diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -93,16 +93,12 @@ for (LoadCommand &LC : Obj.LoadCommands) for (const std::unique_ptr
&Sec : LC.Sections) { if (Sec->CanonicalName == SecName) { - Expected> BufferOrErr = - FileOutputBuffer::create(Filename, Sec->Content.size()); - if (!BufferOrErr) - return BufferOrErr.takeError(); - std::unique_ptr Buf = std::move(*BufferOrErr); - llvm::copy(Sec->Content, Buf->getBufferStart()); - - if (Error E = Buf->commit()) + FileBuffer Buf = FileBuffer(Filename); + if (Error E = Buf.allocate(Sec->Content.size())) return E; - return Error::success(); + if (!Sec->Content.empty()) + llvm::copy(Sec->Content, Buf.getBufferStart()); + return Buf.commit(); } } diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp --- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp @@ -26,15 +26,12 @@ for (const Section &Sec : Obj.Sections) { if (Sec.Name == SecName) { ArrayRef Contents = Sec.Contents; - Expected> BufferOrErr = - FileOutputBuffer::create(Filename, Contents.size()); - if (!BufferOrErr) - return BufferOrErr.takeError(); - std::unique_ptr Buf = std::move(*BufferOrErr); - std::copy(Contents.begin(), Contents.end(), Buf->getBufferStart()); - if (Error E = Buf->commit()) + FileBuffer Buf = FileBuffer(Filename); + if (Error E = Buf.allocate(Contents.size())) return E; - return Error::success(); + if (!Contents.empty()) + llvm::copy(Contents, Buf.getBufferStart()); + return Buf.commit(); } } return createStringError(errc::invalid_argument, "section '%s' not found",