[llvm] [llvm-objdump] Add preliminary support for decoding binary files (PR #115667)
Michael Clark via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 12 13:59:09 PST 2024
https://github.com/michaeljclark updated https://github.com/llvm/llvm-project/pull/115667
>From 9022bc925f57d7d52c901fe65eea4d6beace48f2 Mon Sep 17 00:00:00 2001
From: Michael Clark <michaeljclark at mac.com>
Date: Sun, 10 Nov 2024 17:13:19 +1300
Subject: [PATCH] [llvm-objdump] Add preliminary support for decoding binary
files
$ echo '49 0f c7 0f' | xxd -r -p - > test.bin
$ llvm-objdump -d --binary -Mintel --triple x86_64 test.bin
test.bin: file format binary
Disassembly of section :
0000000000000000 <.data>:
0: 49 0f c7 0f cmpxchg16b xmmword ptr [r15]
Signed-off-by: Michael Clark <michaeljclark at mac.com>
---
llvm/include/llvm/Object/Binary.h | 7 +-
llvm/include/llvm/Object/BinaryObjectFile.h | 130 +++++++++++
llvm/include/llvm/Object/ObjectFile.h | 4 +
llvm/lib/Object/Binary.cpp | 16 +-
llvm/lib/Object/BinaryObjectFile.cpp | 242 ++++++++++++++++++++
llvm/lib/Object/CMakeLists.txt | 1 +
llvm/tools/llvm-objdump/BinaryDump.cpp | 42 ++++
llvm/tools/llvm-objdump/BinaryDump.h | 30 +++
llvm/tools/llvm-objdump/CMakeLists.txt | 1 +
llvm/tools/llvm-objdump/ObjdumpOpts.td | 4 +
llvm/tools/llvm-objdump/llvm-objdump.cpp | 14 +-
llvm/tools/llvm-objdump/llvm-objdump.h | 2 +
12 files changed, 486 insertions(+), 7 deletions(-)
create mode 100644 llvm/include/llvm/Object/BinaryObjectFile.h
create mode 100644 llvm/lib/Object/BinaryObjectFile.cpp
create mode 100644 llvm/tools/llvm-objdump/BinaryDump.cpp
create mode 100644 llvm/tools/llvm-objdump/BinaryDump.h
diff --git a/llvm/include/llvm/Object/Binary.h b/llvm/include/llvm/Object/Binary.h
index ce870e25acafe0..112c3ef66c7363 100644
--- a/llvm/include/llvm/Object/Binary.h
+++ b/llvm/include/llvm/Object/Binary.h
@@ -71,6 +71,7 @@ class Binary {
ID_GOFF,
ID_Wasm,
+ ID_Binary,
ID_EndObjects
};
@@ -191,7 +192,8 @@ DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
/// @param Source The data to create the Binary from.
Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
LLVMContext *Context = nullptr,
- bool InitContent = true);
+ bool InitContent = true,
+ bool RawBinary = false);
template <typename T> class OwningBinary {
std::unique_ptr<T> Bin;
@@ -243,7 +245,8 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
Expected<OwningBinary<Binary>> createBinary(StringRef Path,
LLVMContext *Context = nullptr,
- bool InitContent = true);
+ bool InitContent = true,
+ bool RawBinary = false);
} // end namespace object
diff --git a/llvm/include/llvm/Object/BinaryObjectFile.h b/llvm/include/llvm/Object/BinaryObjectFile.h
new file mode 100644
index 00000000000000..622c7fa4fbc63c
--- /dev/null
+++ b/llvm/include/llvm/Object/BinaryObjectFile.h
@@ -0,0 +1,130 @@
+//===- BinaryObjectFile.h - Binary object file implementation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the BinaryObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_RAWOBJECTFILE_H
+#define LLVM_OBJECT_RAWOBJECTFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBufferRef.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
+#include "llvm/TargetParser/Triple.h"
+#include <cassert>
+#include <cstdint>
+
+namespace llvm {
+
+template <typename T> class SmallVectorImpl;
+
+namespace object {
+
+struct BinarySymbol {
+ uint32_t Flags = 0;
+ uint64_t Value = 0;
+ StringRef Name;
+};
+
+struct BinaryRelocation {
+ uint64_t Offset = 0;
+ uint64_t Symbol = 0;
+ uint64_t Type = 0;
+};
+
+struct BinarySection {
+ uint64_t Offset = 0;
+ uint64_t Index = 0;
+ uint64_t Address = 0;
+ uint64_t Size = 0;
+ StringRef Name;
+ std::vector<BinaryRelocation> Relocations;
+};
+
+class BinaryObjectFile : public ObjectFile {
+private:
+ std::vector<BinarySymbol> Symbols;
+ std::vector<BinarySection> Sections;
+
+public:
+ BinaryObjectFile(MemoryBufferRef Source);
+
+ bool is64Bit() const override;
+
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ const BinarySymbol &getBinarySymbol(const DataRefImpl &Symb) const;
+ const BinarySymbol &getBinarySymbol(const SymbolRef &Symb) const;
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+
+ const BinarySection &getBinarySection(const DataRefImpl Ref) const;
+ const BinarySection &getBinarySection(const SectionRef &Section) const;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ const BinaryRelocation &getBinaryRelocation(const RelocationRef &Ref) const;
+ const BinaryRelocation &getBinaryRelocation(DataRefImpl Ref) const;
+
+ // Overrides from RelocationRef.
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ Expected<SubtargetFeatures> getFeatures() const override;
+ std::optional<StringRef> tryGetCPUName() const override;
+ bool isRelocatableObject() const override;
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_RAWOBJECTFILE_H
diff --git a/llvm/include/llvm/Object/ObjectFile.h b/llvm/include/llvm/Object/ObjectFile.h
index f49763e31a9c76..886cd9be2b018d 100644
--- a/llvm/include/llvm/Object/ObjectFile.h
+++ b/llvm/include/llvm/Object/ObjectFile.h
@@ -43,6 +43,7 @@ class SectionRef;
class SymbolRef;
class symbol_iterator;
class WasmObjectFile;
+class BinaryObjectFile;
using section_iterator = content_iterator<SectionRef>;
@@ -400,6 +401,9 @@ class ObjectFile : public SymbolicFile {
static Expected<std::unique_ptr<WasmObjectFile>>
createWasmObjectFile(MemoryBufferRef Object);
+
+ static Expected<std::unique_ptr<BinaryObjectFile>>
+ createBinaryObjectFile(MemoryBufferRef Object);
};
/// A filtered iterator for SectionRefs that skips sections based on some given
diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp
index 2dfae8ab5d3c64..740e5169fc91ca 100644
--- a/llvm/lib/Object/Binary.cpp
+++ b/llvm/lib/Object/Binary.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/BinaryObjectFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/Minidump.h"
@@ -44,9 +45,14 @@ MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
LLVMContext *Context,
- bool InitContent) {
+ bool InitContent,
+ bool RawBinary) {
file_magic Type = identify_magic(Buffer.getBuffer());
+ if (RawBinary) {
+ return ObjectFile::createBinaryObjectFile(Buffer);
+ }
+
switch (Type) {
case file_magic::archive:
return Archive::create(Buffer);
@@ -103,8 +109,10 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
llvm_unreachable("Unexpected Binary File Type");
}
-Expected<OwningBinary<Binary>>
-object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
+Expected<OwningBinary<Binary>> object::createBinary(StringRef Path,
+ LLVMContext *Context,
+ bool InitContent,
+ bool RawBinary) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/false,
/*RequiresNullTerminator=*/false);
@@ -113,7 +121,7 @@ object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
Expected<std::unique_ptr<Binary>> BinOrErr =
- createBinary(Buffer->getMemBufferRef(), Context, InitContent);
+ createBinary(Buffer->getMemBufferRef(), Context, InitContent, RawBinary);
if (!BinOrErr)
return BinOrErr.takeError();
std::unique_ptr<Binary> &Bin = BinOrErr.get();
diff --git a/llvm/lib/Object/BinaryObjectFile.cpp b/llvm/lib/Object/BinaryObjectFile.cpp
new file mode 100644
index 00000000000000..a3a3846fa822db
--- /dev/null
+++ b/llvm/lib/Object/BinaryObjectFile.cpp
@@ -0,0 +1,242 @@
+//===- BinaryObjectFile.cpp - Binary object file implementation -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Part of the BinaryObjectFile class implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/BinaryObjectFile.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
+#include "llvm/TargetParser/Triple.h"
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+
+using namespace llvm;
+using namespace object;
+
+BinaryObjectFile::BinaryObjectFile(MemoryBufferRef Source)
+ : ObjectFile(ID_Binary, Source), Symbols(), Sections() {
+ Symbols.push_back(BinarySymbol{});
+ Symbols[0].Name = ".data";
+ Sections.push_back(BinarySection{});
+ Sections[0].Size = Source.getBufferSize();
+}
+
+Expected<std::unique_ptr<BinaryObjectFile>>
+ObjectFile::createBinaryObjectFile(MemoryBufferRef Obj) {
+ Error Err = Error::success();
+ auto ObjectFile = std::make_unique<BinaryObjectFile>(Obj);
+ return std::move(ObjectFile);
+}
+
+bool BinaryObjectFile::is64Bit() const { return true; }
+
+basic_symbol_iterator BinaryObjectFile::symbol_begin() const {
+ DataRefImpl Ref;
+ Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
+ Ref.d.b = 0; // Symbol index
+ return BasicSymbolRef(Ref, this);
+}
+
+basic_symbol_iterator BinaryObjectFile::symbol_end() const {
+ DataRefImpl Ref;
+ Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
+ Ref.d.b = Symbols.size(); // Symbol index
+ return BasicSymbolRef(Ref, this);
+}
+
+void BinaryObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
+
+const BinarySymbol &
+BinaryObjectFile::getBinarySymbol(const DataRefImpl &Symb) const {
+ assert(Symb.d.b < Symbols.size());
+ return Symbols[Symb.d.b];
+}
+
+const BinarySymbol &
+BinaryObjectFile::getBinarySymbol(const SymbolRef &Symb) const {
+ return getBinarySymbol(Symb.getRawDataRefImpl());
+}
+
+const BinarySection &
+BinaryObjectFile::getBinarySection(const DataRefImpl Ref) const {
+ assert(Ref.d.a < Sections.size());
+ return Sections[Ref.d.a];
+}
+
+const BinarySection &
+BinaryObjectFile::getBinarySection(const SectionRef &Section) const {
+ return getBinarySection(Section.getRawDataRefImpl());
+}
+
+const BinaryRelocation &
+BinaryObjectFile::getBinaryRelocation(const RelocationRef &Ref) const {
+ return getBinaryRelocation(Ref.getRawDataRefImpl());
+}
+
+const BinaryRelocation &
+BinaryObjectFile::getBinaryRelocation(DataRefImpl Ref) const {
+ assert(Ref.d.a < Sections.size());
+ const BinarySection &Sec = Sections[Ref.d.a];
+ assert(Ref.d.b < Sec.Relocations.size());
+ return Sec.Relocations[Ref.d.b];
+}
+
+Expected<StringRef> BinaryObjectFile::getSymbolName(DataRefImpl Symb) const {
+ return getBinarySymbol(Symb).Name;
+}
+
+Expected<uint32_t> BinaryObjectFile::getSymbolFlags(DataRefImpl Symb) const {
+ return getBinarySymbol(Symb).Flags;
+}
+
+uint64_t BinaryObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
+ return getBinarySymbol(Symb).Value;
+}
+
+uint64_t BinaryObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
+ llvm_unreachable("not yet implemented");
+ return 0;
+}
+
+Expected<SymbolRef::Type>
+BinaryObjectFile::getSymbolType(DataRefImpl Symb) const {
+ return SymbolRef::ST_Other;
+}
+
+Expected<section_iterator>
+BinaryObjectFile::getSymbolSection(DataRefImpl Symb) const {
+ DataRefImpl Ref;
+ Ref.d.a = 0;
+ return section_iterator(SectionRef(Ref, this));
+}
+
+Expected<uint64_t> BinaryObjectFile::getSymbolAddress(DataRefImpl Sym) const {
+ return getSymbolValue(Sym);
+}
+
+section_iterator BinaryObjectFile::section_begin() const {
+ DataRefImpl Ref;
+ Ref.d.a = 0;
+ return section_iterator(SectionRef(Ref, this));
+}
+
+section_iterator BinaryObjectFile::section_end() const {
+ DataRefImpl Ref;
+ Ref.d.a = Sections.size();
+ return section_iterator(SectionRef(Ref, this));
+}
+void BinaryObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
+
+Expected<StringRef> BinaryObjectFile::getSectionName(DataRefImpl Ref) const {
+ return getBinarySection(Ref).Name;
+}
+
+uint64_t BinaryObjectFile::getSectionAddress(DataRefImpl Ref) const {
+ return getBinarySection(Ref).Address;
+}
+uint64_t BinaryObjectFile::getSectionIndex(DataRefImpl Ref) const {
+ return getBinarySection(Ref).Index;
+}
+uint64_t BinaryObjectFile::getSectionSize(DataRefImpl Ref) const {
+ return getBinarySection(Ref).Size;
+}
+
+Expected<ArrayRef<uint8_t>>
+BinaryObjectFile::getSectionContents(DataRefImpl Sec) const {
+ return ArrayRef<uint8_t>((const uint8_t *)Data.getBuffer().data(),
+ Data.getBufferSize());
+}
+
+uint64_t BinaryObjectFile::getSectionAlignment(DataRefImpl Sec) const {
+ return 1;
+}
+
+bool BinaryObjectFile::isSectionCompressed(DataRefImpl Sec) const {
+ return false;
+}
+bool BinaryObjectFile::isSectionText(DataRefImpl Sec) const { return true; }
+bool BinaryObjectFile::isSectionData(DataRefImpl Sec) const { return false; }
+bool BinaryObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
+bool BinaryObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
+
+relocation_iterator BinaryObjectFile::section_rel_begin(DataRefImpl Ref) const {
+ DataRefImpl RelocRef;
+ RelocRef.d.a = Ref.d.a;
+ RelocRef.d.b = 0;
+ return relocation_iterator(RelocationRef(RelocRef, this));
+}
+
+relocation_iterator BinaryObjectFile::section_rel_end(DataRefImpl Ref) const {
+ const BinarySection &Sec = getBinarySection(Ref);
+ DataRefImpl RelocRef;
+ RelocRef.d.a = Ref.d.a;
+ RelocRef.d.b = Sec.Relocations.size();
+ return relocation_iterator(RelocationRef(RelocRef, this));
+}
+
+void BinaryObjectFile::moveRelocationNext(DataRefImpl &Rel) const { Rel.d.b++; }
+
+uint64_t BinaryObjectFile::getRelocationOffset(DataRefImpl Ref) const {
+ const BinaryRelocation &Rel = getBinaryRelocation(Ref);
+ return Rel.Offset;
+}
+
+symbol_iterator BinaryObjectFile::getRelocationSymbol(DataRefImpl Ref) const {
+ const BinaryRelocation &Rel = getBinaryRelocation(Ref);
+ DataRefImpl Sym;
+ Sym.d.a = 1;
+ Sym.d.b = Rel.Symbol;
+ return symbol_iterator(SymbolRef(Sym, this));
+}
+
+uint64_t BinaryObjectFile::getRelocationType(DataRefImpl Ref) const {
+ const BinaryRelocation &Rel = getBinaryRelocation(Ref);
+ return Rel.Type;
+}
+
+void BinaryObjectFile::getRelocationTypeName(
+ DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
+ const BinaryRelocation &Rel = getBinaryRelocation(Ref);
+ StringRef Res;
+ switch (Rel.Type) {
+ case 0:
+ default:
+ Res = "unknown";
+ break;
+ }
+ Result.append(Res.begin(), Res.end());
+}
+
+uint8_t BinaryObjectFile::getBytesInAddress() const {
+ return is64Bit() ? 8 : 4;
+}
+
+StringRef BinaryObjectFile::getFileFormatName() const { return "binary"; }
+
+Triple::ArchType BinaryObjectFile::getArch() const {
+ return Triple::UnknownArch;
+}
+
+Expected<SubtargetFeatures> BinaryObjectFile::getFeatures() const {
+ return SubtargetFeatures();
+}
+
+std::optional<StringRef> BinaryObjectFile::tryGetCPUName() const {
+ return std::nullopt;
+}
+
+bool BinaryObjectFile::isRelocatableObject() const { return false; }
diff --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt
index bfb420e57a7f49..0b1a3d32b0ef0d 100644
--- a/llvm/lib/Object/CMakeLists.txt
+++ b/llvm/lib/Object/CMakeLists.txt
@@ -33,6 +33,7 @@ add_llvm_component_library(LLVMObject
WindowsMachineFlag.cpp
WindowsResource.cpp
XCOFFObjectFile.cpp
+ BinaryObjectFile.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/Object
diff --git a/llvm/tools/llvm-objdump/BinaryDump.cpp b/llvm/tools/llvm-objdump/BinaryDump.cpp
new file mode 100644
index 00000000000000..6c2c691ef1d74e
--- /dev/null
+++ b/llvm/tools/llvm-objdump/BinaryDump.cpp
@@ -0,0 +1,42 @@
+//===-- BinaryDump.cpp - raw-binary dumper ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the raw binary dumper for llvm-objdump.
+///
+//===----------------------------------------------------------------------===//
+
+#include "BinaryDump.h"
+
+#include "llvm-objdump.h"
+#include "llvm/Object/BinaryObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+namespace {
+class BinaryDumper : public objdump::Dumper {
+ const BinaryObjectFile &Obj;
+
+public:
+ BinaryDumper(const BinaryObjectFile &O) : Dumper(O), Obj(O) {}
+};
+} // namespace
+
+std::unique_ptr<objdump::Dumper>
+objdump::createBinaryDumper(const BinaryObjectFile &Obj) {
+ return std::make_unique<BinaryDumper>(Obj);
+}
+
+Error objdump::getBinaryRelocationValueString(const BinaryObjectFile *Obj,
+ const RelocationRef &RelRef,
+ SmallVectorImpl<char> &Result) {
+ return Error::success();
+}
diff --git a/llvm/tools/llvm-objdump/BinaryDump.h b/llvm/tools/llvm-objdump/BinaryDump.h
new file mode 100644
index 00000000000000..f8c76e11b20088
--- /dev/null
+++ b/llvm/tools/llvm-objdump/BinaryDump.h
@@ -0,0 +1,30 @@
+//===-- BinaryDump.h - raw-binary dumper ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_OBJDUMP_BINARYDUMP_H
+#define LLVM_TOOLS_LLVM_OBJDUMP_BINARYDUMP_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+class Error;
+namespace object {
+class BinaryObjectFile;
+class RelocationRef;
+} // namespace object
+
+namespace objdump {
+
+Error getBinaryRelocationValueString(const object::BinaryObjectFile *Obj,
+ const object::RelocationRef &RelRef,
+ llvm::SmallVectorImpl<char> &Result);
+
+} // namespace objdump
+} // namespace llvm
+
+#endif
diff --git a/llvm/tools/llvm-objdump/CMakeLists.txt b/llvm/tools/llvm-objdump/CMakeLists.txt
index 0306736388979b..9034b2a0bf5b63 100644
--- a/llvm/tools/llvm-objdump/CMakeLists.txt
+++ b/llvm/tools/llvm-objdump/CMakeLists.txt
@@ -30,6 +30,7 @@ add_llvm_tool(llvm-objdump
ELFDump.cpp
MachODump.cpp
OffloadDump.cpp
+ BinaryDump.cpp
WasmDump.cpp
XCOFFDump.cpp
DEPENDS
diff --git a/llvm/tools/llvm-objdump/ObjdumpOpts.td b/llvm/tools/llvm-objdump/ObjdumpOpts.td
index c3764c6e97534a..63d74a6f1e3d47 100644
--- a/llvm/tools/llvm-objdump/ObjdumpOpts.td
+++ b/llvm/tools/llvm-objdump/ObjdumpOpts.td
@@ -38,6 +38,10 @@ def arch_name_EQ : Joined<["--"], "arch-name=">,
def archive_headers : Flag<["--"], "archive-headers">,
HelpText<"Display archive header information">;
+def binary : Flag<["--"], "binary">,
+ HelpText<"Treat the file as binary, to be combined with --triple=">;
+def : Flag<["-"], "b">, Alias<binary>, HelpText<"Alias for --binary">;
+
defm build_id :
Eq<"build-id", "Build ID to look up. Once found, added as an input file">,
MetaVarName<"<hex>">;
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index b69d14b4e7609a..037f9d3883b478 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -16,6 +16,7 @@
//===----------------------------------------------------------------------===//
#include "llvm-objdump.h"
+#include "BinaryDump.h"
#include "COFFDump.h"
#include "ELFDump.h"
#include "MachODump.h"
@@ -51,6 +52,7 @@
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/BinaryObjectFile.h"
#include "llvm/Object/BuildID.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
@@ -300,6 +302,7 @@ enum class ColorOutput {
static uint64_t AdjustVMA;
static bool AllHeaders;
+static bool BinaryFile;
static std::string ArchName;
bool objdump::ArchiveHeaders;
bool objdump::Demangle;
@@ -386,6 +389,8 @@ static Expected<std::unique_ptr<Dumper>> createDumper(const ObjectFile &Obj) {
return createWasmDumper(*O);
if (const auto *O = dyn_cast<XCOFFObjectFile>(&Obj))
return createXCOFFDumper(*O);
+ if (const auto *O = dyn_cast<BinaryObjectFile>(&Obj))
+ return createBinaryDumper(*O);
return createStringError(errc::invalid_argument,
"unsupported object file format");
@@ -553,6 +558,8 @@ static Error getRelocationValueString(const RelocationRef &Rel,
if (auto *XCOFF = dyn_cast<XCOFFObjectFile>(Obj))
return getXCOFFRelocationValueString(*XCOFF, Rel, SymbolDescription,
Result);
+ if (auto *Binary = dyn_cast<BinaryObjectFile>(Obj))
+ return getBinaryRelocationValueString(Binary, Rel, Result);
llvm_unreachable("unknown object file format");
}
@@ -3392,7 +3399,8 @@ static void dumpInput(StringRef file) {
}
// Attempt to open the binary.
- OwningBinary<Binary> OBinary = unwrapOrError(createBinary(file), file);
+ OwningBinary<Binary> OBinary =
+ unwrapOrError(createBinary(file, nullptr, true, BinaryFile), file);
Binary &Binary = *OBinary.getBinary();
if (Archive *A = dyn_cast<Archive>(&Binary))
@@ -3577,6 +3585,10 @@ static void parseObjdumpOptions(const llvm::opt::InputArgList &InputArgs) {
parseMachOOptions(InputArgs);
+ if (InputArgs.getLastArg(OBJDUMP_binary)) {
+ BinaryFile = true;
+ }
+
// Parse -M (--disassembler-options) and deprecated
// --x86-asm-syntax={att,intel}.
//
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 7778cf6c2784eb..38c3c10c9b0c22 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -38,6 +38,7 @@ class ELFObjectFileBase;
class MachOObjectFile;
class WasmObjectFile;
class XCOFFObjectFile;
+class BinaryObjectFile;
} // namespace object
namespace objdump {
@@ -104,6 +105,7 @@ std::unique_ptr<Dumper> createELFDumper(const object::ELFObjectFileBase &Obj);
std::unique_ptr<Dumper> createMachODumper(const object::MachOObjectFile &Obj);
std::unique_ptr<Dumper> createWasmDumper(const object::WasmObjectFile &Obj);
std::unique_ptr<Dumper> createXCOFFDumper(const object::XCOFFObjectFile &Obj);
+std::unique_ptr<Dumper> createBinaryDumper(const object::BinaryObjectFile &Obj);
// Various helper functions.
More information about the llvm-commits
mailing list