Skip to content

Commit ca82401

Browse files
committed
[llvm-objdump] Add preliminary support for decoding binary files
$ echo '49 0f c7 0f' | xxd -r -p - > test.bin $ llvm-objdump -d -Mintel --binary --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 <[email protected]>
1 parent fe55c34 commit ca82401

File tree

12 files changed

+485
-7
lines changed

12 files changed

+485
-7
lines changed

llvm/include/llvm/Object/Binary.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Binary {
7171

7272
ID_GOFF,
7373
ID_Wasm,
74+
ID_Binary,
7475

7576
ID_EndObjects
7677
};
@@ -191,7 +192,8 @@ DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
191192
/// @param Source The data to create the Binary from.
192193
Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
193194
LLVMContext *Context = nullptr,
194-
bool InitContent = true);
195+
bool InitContent = true,
196+
bool RawBinary = false);
195197

196198
template <typename T> class OwningBinary {
197199
std::unique_ptr<T> Bin;
@@ -243,7 +245,8 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
243245

244246
Expected<OwningBinary<Binary>> createBinary(StringRef Path,
245247
LLVMContext *Context = nullptr,
246-
bool InitContent = true);
248+
bool InitContent = true,
249+
bool RawBinary = false);
247250

248251
} // end namespace object
249252

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
//===- BinaryObjectFile.h - Binary object file implementation ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares the BinaryObjectFile class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_OBJECT_RAWOBJECTFILE_H
14+
#define LLVM_OBJECT_RAWOBJECTFILE_H
15+
16+
#include "llvm/ADT/ArrayRef.h"
17+
#include "llvm/ADT/STLExtras.h"
18+
#include "llvm/ADT/StringRef.h"
19+
#include "llvm/ADT/iterator_range.h"
20+
#include "llvm/Object/Binary.h"
21+
#include "llvm/Object/Error.h"
22+
#include "llvm/Object/ObjectFile.h"
23+
#include "llvm/Object/SymbolicFile.h"
24+
#include "llvm/Support/Casting.h"
25+
#include "llvm/Support/Error.h"
26+
#include "llvm/Support/ErrorHandling.h"
27+
#include "llvm/Support/MemoryBufferRef.h"
28+
#include "llvm/Support/ScopedPrinter.h"
29+
#include "llvm/TargetParser/SubtargetFeature.h"
30+
#include "llvm/TargetParser/Triple.h"
31+
#include <cassert>
32+
#include <cstdint>
33+
34+
namespace llvm {
35+
36+
template <typename T> class SmallVectorImpl;
37+
38+
namespace object {
39+
40+
struct BinarySymbol {
41+
uint32_t Flags = 0;
42+
uint64_t Value = 0;
43+
StringRef Name;
44+
};
45+
46+
struct BinaryRelocation {
47+
uint64_t Offset = 0;
48+
uint64_t Symbol = 0;
49+
uint64_t Type = 0;
50+
};
51+
52+
struct BinarySection {
53+
uint64_t Offset = 0;
54+
uint64_t Index = 0;
55+
uint64_t Address = 0;
56+
uint64_t Size = 0;
57+
StringRef Name;
58+
std::vector<BinaryRelocation> Relocations;
59+
};
60+
61+
class BinaryObjectFile : public ObjectFile {
62+
private:
63+
std::vector<BinarySymbol> Symbols;
64+
std::vector<BinarySection> Sections;
65+
66+
public:
67+
BinaryObjectFile(MemoryBufferRef Source);
68+
69+
bool is64Bit() const override;
70+
71+
basic_symbol_iterator symbol_begin() const override;
72+
basic_symbol_iterator symbol_end() const override;
73+
section_iterator section_begin() const override;
74+
section_iterator section_end() const override;
75+
76+
const BinarySymbol &getBinarySymbol(const DataRefImpl &Symb) const;
77+
const BinarySymbol &getBinarySymbol(const SymbolRef &Symb) const;
78+
79+
void moveSymbolNext(DataRefImpl &Symb) const override;
80+
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
81+
Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
82+
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
83+
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
84+
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
85+
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
86+
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
87+
88+
const BinarySection &getBinarySection(const DataRefImpl Ref) const;
89+
const BinarySection &getBinarySection(const SectionRef &Section) const;
90+
91+
void moveSectionNext(DataRefImpl &Sec) const override;
92+
Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
93+
uint64_t getSectionAddress(DataRefImpl Sec) const override;
94+
uint64_t getSectionIndex(DataRefImpl Sec) const override;
95+
uint64_t getSectionSize(DataRefImpl Sec) const override;
96+
Expected<ArrayRef<uint8_t>>
97+
getSectionContents(DataRefImpl Sec) const override;
98+
uint64_t getSectionAlignment(DataRefImpl Sec) const override;
99+
bool isSectionCompressed(DataRefImpl Sec) const override;
100+
bool isSectionText(DataRefImpl Sec) const override;
101+
bool isSectionData(DataRefImpl Sec) const override;
102+
bool isSectionBSS(DataRefImpl Sec) const override;
103+
bool isSectionVirtual(DataRefImpl Sec) const override;
104+
105+
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
106+
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
107+
108+
const BinaryRelocation &getBinaryRelocation(const RelocationRef &Ref) const;
109+
const BinaryRelocation &getBinaryRelocation(DataRefImpl Ref) const;
110+
111+
// Overrides from RelocationRef.
112+
void moveRelocationNext(DataRefImpl &Rel) const override;
113+
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
114+
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
115+
uint64_t getRelocationType(DataRefImpl Rel) const override;
116+
void getRelocationTypeName(DataRefImpl Rel,
117+
SmallVectorImpl<char> &Result) const override;
118+
119+
uint8_t getBytesInAddress() const override;
120+
StringRef getFileFormatName() const override;
121+
Triple::ArchType getArch() const override;
122+
Expected<SubtargetFeatures> getFeatures() const override;
123+
std::optional<StringRef> tryGetCPUName() const override;
124+
bool isRelocatableObject() const override;
125+
};
126+
127+
} // end namespace object
128+
} // end namespace llvm
129+
130+
#endif // LLVM_OBJECT_RAWOBJECTFILE_H

llvm/include/llvm/Object/ObjectFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class SectionRef;
4343
class SymbolRef;
4444
class symbol_iterator;
4545
class WasmObjectFile;
46+
class BinaryObjectFile;
4647

4748
using section_iterator = content_iterator<SectionRef>;
4849

@@ -400,6 +401,9 @@ class ObjectFile : public SymbolicFile {
400401

401402
static Expected<std::unique_ptr<WasmObjectFile>>
402403
createWasmObjectFile(MemoryBufferRef Object);
404+
405+
static Expected<std::unique_ptr<BinaryObjectFile>>
406+
createBinaryObjectFile(MemoryBufferRef Object);
403407
};
404408

405409
/// A filtered iterator for SectionRefs that skips sections based on some given

llvm/lib/Object/Binary.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ADT/StringRef.h"
1515
#include "llvm/BinaryFormat/Magic.h"
1616
#include "llvm/Object/Archive.h"
17+
#include "llvm/Object/BinaryObjectFile.h"
1718
#include "llvm/Object/Error.h"
1819
#include "llvm/Object/MachOUniversal.h"
1920
#include "llvm/Object/Minidump.h"
@@ -44,9 +45,14 @@ MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
4445

4546
Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
4647
LLVMContext *Context,
47-
bool InitContent) {
48+
bool InitContent,
49+
bool RawBinary) {
4850
file_magic Type = identify_magic(Buffer.getBuffer());
4951

52+
if (RawBinary) {
53+
return ObjectFile::createBinaryObjectFile(Buffer);
54+
}
55+
5056
switch (Type) {
5157
case file_magic::archive:
5258
return Archive::create(Buffer);
@@ -103,8 +109,10 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
103109
llvm_unreachable("Unexpected Binary File Type");
104110
}
105111

106-
Expected<OwningBinary<Binary>>
107-
object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
112+
Expected<OwningBinary<Binary>> object::createBinary(StringRef Path,
113+
LLVMContext *Context,
114+
bool InitContent,
115+
bool RawBinary) {
108116
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
109117
MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/false,
110118
/*RequiresNullTerminator=*/false);
@@ -113,7 +121,7 @@ object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
113121
std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
114122

115123
Expected<std::unique_ptr<Binary>> BinOrErr =
116-
createBinary(Buffer->getMemBufferRef(), Context, InitContent);
124+
createBinary(Buffer->getMemBufferRef(), Context, InitContent, RawBinary);
117125
if (!BinOrErr)
118126
return BinOrErr.takeError();
119127
std::unique_ptr<Binary> &Bin = BinOrErr.get();

0 commit comments

Comments
 (0)