LLDB mainline
ObjectFilePECOFF.h
Go to the documentation of this file.
1//===-- ObjectFilePECOFF.h --------------------------------------*- 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#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H
10#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H
11
12#include <optional>
13#include <vector>
14
16#include "llvm/Object/COFF.h"
17
19public:
22 MachineAm33 = 0x1d3,
23 MachineAmd64 = 0x8664,
24 MachineArm = 0x1c0,
25 MachineArmNt = 0x1c4,
26 MachineArm64 = 0xaa64,
27 MachineArm64X = 0xa64e,
28 MachineEbc = 0xebc,
29 MachineX86 = 0x14c,
30 MachineIA64 = 0x200,
31 MachineM32R = 0x9041,
37 MachineR4000 = 0x166,
38 MachineSh3 = 0x1a2,
40 MachineSh4 = 0x1a6,
41 MachineSh5 = 0x1a8,
42 MachineThumb = 0x1c2,
43 MachineWcemIpsv2 = 0x169
44 };
45
46 ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
47 lldb::offset_t data_offset,
48 const lldb_private::FileSpec *file,
49 lldb::offset_t file_offset, lldb::offset_t length);
50
51 ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
52 lldb::WritableDataBufferSP header_data_sp,
53 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
54
56
57 // Static Functions
58 static void Initialize();
59
60 static void DebuggerInitialize(lldb_private::Debugger &debugger);
61
62 static void Terminate();
63
64 static llvm::StringRef GetPluginNameStatic() { return "pe-coff"; }
65
66 static llvm::StringRef GetPluginDescriptionStatic();
67
68 static ObjectFile *
69 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
70 lldb::offset_t data_offset, const lldb_private::FileSpec *file,
71 lldb::offset_t offset, lldb::offset_t length);
72
74 const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
75 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
76
77 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
78 lldb::DataBufferSP &data_sp,
79 lldb::offset_t data_offset,
80 lldb::offset_t file_offset,
81 lldb::offset_t length,
83
84 static bool SaveCore(const lldb::ProcessSP &process_sp,
85 const lldb_private::SaveCoreOptions &options,
87
88 static bool MagicBytesMatch(lldb::DataBufferSP data_sp);
89
90 static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
91
92 // LLVM RTTI support
93 static char ID;
94 bool isA(const void *ClassID) const override {
95 return ClassID == &ID || ObjectFile::isA(ClassID);
96 }
97 static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
98
99 bool ParseHeader() override;
100
102 bool value_is_offset) override;
103
104 lldb::ByteOrder GetByteOrder() const override;
105
106 bool IsExecutable() const override;
107
108 uint32_t GetAddressByteSize() const override;
109
110 // virtual lldb_private::AddressClass
111 // GetAddressClass (lldb::addr_t file_addr);
112
113 void ParseSymtab(lldb_private::Symtab &symtab) override;
114
115 bool IsStripped() override;
116
117 void CreateSections(lldb_private::SectionList &unified_section_list) override;
118
119 void Dump(lldb_private::Stream *s) override;
120
122
123 lldb_private::UUID GetUUID() override;
124
125 /// Return the contents of the .gnu_debuglink section, if the object file
126 /// contains it.
127 std::optional<lldb_private::FileSpec> GetDebugLink();
128
129 uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
130
132
134
135 ObjectFile::Type CalculateType() override;
136
137 ObjectFile::Strata CalculateStrata() override;
138
139 // PluginInterface protocol
140 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
141
142 bool IsWindowsSubsystem();
143
144 uint32_t GetRVA(const lldb_private::Address &addr) const;
145 lldb_private::Address GetAddress(uint32_t rva);
146 lldb::addr_t GetFileAddress(uint32_t rva) const;
147
148 lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
149 lldb_private::DataExtractor ReadImageDataByRVA(uint32_t rva, size_t size);
150
151 std::unique_ptr<lldb_private::CallFrameInfo> CreateCallFrameInfo() override;
152
153protected:
154 bool NeedsEndianSwap() const;
155
156 typedef struct dos_header { // DOS .EXE header
157 uint16_t e_magic = 0; // Magic number
158 uint16_t e_cblp = 0; // Bytes on last page of file
159 uint16_t e_cp = 0; // Pages in file
160 uint16_t e_crlc = 0; // Relocations
161 uint16_t e_cparhdr = 0; // Size of header in paragraphs
162 uint16_t e_minalloc = 0; // Minimum extra paragraphs needed
163 uint16_t e_maxalloc = 0; // Maximum extra paragraphs needed
164 uint16_t e_ss = 0; // Initial (relative) SS value
165 uint16_t e_sp = 0; // Initial SP value
166 uint16_t e_csum = 0; // Checksum
167 uint16_t e_ip = 0; // Initial IP value
168 uint16_t e_cs = 0; // Initial (relative) CS value
169 uint16_t e_lfarlc = 0; // File address of relocation table
170 uint16_t e_ovno = 0; // Overlay number
171 uint16_t e_res[4]; // Reserved words
172 uint16_t e_oemid = 0; // OEM identifier (for e_oeminfo)
173 uint16_t e_oeminfo = 0; // OEM information; e_oemid specific
174 uint16_t e_res2[10] = {}; // Reserved words
175 uint32_t e_lfanew = 0; // File address of new exe header
177
178 typedef struct coff_header {
179 uint16_t machine = 0;
180 uint16_t nsects = 0;
181 uint32_t modtime = 0;
182 uint32_t symoff = 0;
183 uint32_t nsyms = 0;
184 uint16_t hdrsize = 0;
185 uint16_t flags = 0;
187
188 typedef struct data_directory {
189 uint32_t vmaddr = 0;
190 uint32_t vmsize = 0;
192
193 typedef struct coff_opt_header {
194 uint16_t magic = 0;
197 uint32_t code_size = 0;
198 uint32_t data_size = 0;
199 uint32_t bss_size = 0;
200 uint32_t entry = 0;
201 uint32_t code_offset = 0;
202 uint32_t data_offset = 0;
203
204 uint64_t image_base = 0;
205 uint32_t sect_alignment = 0;
206 uint32_t file_alignment = 0;
213 uint32_t reserved1 = 0;
214 uint32_t image_size = 0;
215 uint32_t header_size = 0;
216 uint32_t checksum = 0;
217 uint16_t subsystem = 0;
218 uint16_t dll_flags = 0;
219 uint64_t stack_reserve_size = 0;
220 uint64_t stack_commit_size = 0;
221 uint64_t heap_reserve_size = 0;
222 uint64_t heap_commit_size = 0;
223 uint32_t loader_flags = 0;
224 // uint32_t num_data_dir_entries;
225 std::vector<data_directory>
226 data_dirs; // will contain num_data_dir_entries entries
228
229 typedef struct section_header {
230 char name[8] = {};
231 uint32_t vmsize = 0; // Virtual Size
232 uint32_t vmaddr = 0; // Virtual Addr
233 uint32_t size = 0; // File size
234 uint32_t offset = 0; // File offset
235 uint32_t reloff = 0; // Offset to relocations
236 uint32_t lineoff = 0; // Offset to line table entries
237 uint16_t nreloc = 0; // Number of relocation entries
238 uint16_t nline = 0; // Number of line table entries
239 uint32_t flags = 0;
241
243 dos_header_t &dos_header);
245 lldb::offset_t *offset_ptr,
246 coff_header_t &coff_header);
247 bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
248 bool ParseSectionHeaders(uint32_t offset);
249
250 uint32_t ParseDependentModules();
251
252 static void DumpDOSHeader(lldb_private::Stream *s,
253 const dos_header_t &header);
255 const coff_header_t &header);
257 const coff_opt_header_t &header);
261
262 llvm::StringRef GetSectionName(const section_header_t &sect);
263 static lldb::SectionType GetSectionType(llvm::StringRef sect_name,
264 const section_header_t &sect);
265 size_t GetSectionDataSize(lldb_private::Section *section) override;
266
267 typedef std::vector<section_header_t> SectionHeaderColl;
268 typedef SectionHeaderColl::iterator SectionHeaderCollIter;
269 typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
270
271private:
272 bool CreateBinary();
273 typedef std::vector<std::pair<uint32_t, uint32_t>> rva_symbol_list_t;
275 lldb_private::Symtab &symtab,
276 const rva_symbol_list_t &sorted_exports);
278 lldb_private::Symtab &symtab);
279
286 std::optional<lldb_private::FileSpecList> m_deps_filespec;
287 std::unique_ptr<llvm::object::COFFObjectFile> m_binary;
289};
290
291#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H
static llvm::raw_ostream & error(Stream &strm)
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
void DumpSectionHeaders(lldb_private::Stream *s)
std::unique_ptr< llvm::object::COFFObjectFile > m_binary
dos_header_t m_dos_header
lldb_private::DataExtractor ReadImageDataByRVA(uint32_t rva, size_t size)
llvm::StringRef GetSectionName(const section_header_t &sect)
lldb_private::Address GetEntryPointAddress() override
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
std::optional< lldb_private::FileSpecList > m_deps_filespec
~ObjectFilePECOFF() override
static bool ParseDOSHeader(lldb_private::DataExtractor &data, dos_header_t &dos_header)
static bool classof(const ObjectFile *obj)
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
Extract the dependent modules from an object file.
lldb_private::Address GetBaseAddress() override
Returns base address of this object file.
lldb::addr_t m_image_base
void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh)
std::unique_ptr< lldb_private::CallFrameInfo > CreateCallFrameInfo() override
Creates a plugin-specific call frame info.
size_t GetSectionDataSize(lldb_private::Section *section) override
static void DebuggerInitialize(lldb_private::Debugger &debugger)
struct ObjectFilePECOFF::data_directory data_directory_t
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
static void DumpCOFFHeader(lldb_private::Stream *s, const coff_header_t &header)
bool ParseHeader() override
Attempts to parse the object header.
struct ObjectFilePECOFF::section_header section_header_t
void DumpDependentModules(lldb_private::Stream *s)
lldb_private::UUID m_uuid
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
std::vector< std::pair< uint32_t, uint32_t > > rva_symbol_list_t
static llvm::StringRef GetPluginNameStatic()
bool isA(const void *ClassID) const override
SectionHeaderColl::const_iterator SectionHeaderCollConstIter
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
SectionHeaderColl::iterator SectionHeaderCollIter
SectionHeaderColl m_sect_headers
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
static llvm::StringRef GetPluginDescriptionStatic()
coff_opt_header_t m_coff_header_opt
bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr)
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
uint32_t ParseDependentModules()
struct ObjectFilePECOFF::coff_header coff_header_t
bool NeedsEndianSwap() const
lldb::addr_t GetFileAddress(uint32_t rva) const
struct ObjectFilePECOFF::coff_opt_header coff_opt_header_t
void ParseSymtab(lldb_private::Symtab &symtab) override
Parse the symbol table into the provides symbol table object.
void CreateSections(lldb_private::SectionList &unified_section_list) override
llvm::StringRef GetPluginName() override
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
rva_symbol_list_t AppendFromExportTable(lldb_private::SectionList *sect_list, lldb_private::Symtab &symtab)
coff_header_t m_coff_header
lldb_private::Address GetAddress(uint32_t rva)
static void Initialize()
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size)
void AppendFromCOFFSymbolTable(lldb_private::SectionList *sect_list, lldb_private::Symtab &symtab, const rva_symbol_list_t &sorted_exports)
std::optional< lldb_private::FileSpec > GetDebugLink()
Return the contents of the .gnu_debuglink section, if the object file contains it.
std::vector< section_header_t > SectionHeaderColl
bool ParseSectionHeaders(uint32_t offset)
static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type)
uint32_t GetRVA(const lldb_private::Address &addr) const
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
static void DumpOptCOFFHeader(lldb_private::Stream *s, const coff_opt_header_t &header)
static lldb::SectionType GetSectionType(llvm::StringRef sect_name, const section_header_t &sect)
static ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
static bool ParseCOFFHeader(lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header)
static bool SaveCore(const lldb::ProcessSP &process_sp, const lldb_private::SaveCoreOptions &options, lldb_private::Status &error)
static bool MagicBytesMatch(lldb::DataBufferSP data_sp)
struct ObjectFilePECOFF::dos_header dos_header_t
static void Terminate()
lldb_private::Address m_entry_point_address
static void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t &header)
static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs)
A section + offset based address class.
Definition: Address.h:62
An architecture specification class.
Definition: ArchSpec.h:31
An data extractor class.
Definition: DataExtractor.h:48
A class to manage flag bits.
Definition: Debugger.h:80
A file collection class.
Definition: FileSpecList.h:85
A file utility class.
Definition: FileSpec.h:56
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataBufferSP data_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
Definition: ObjectFile.cpp:250
An error handling class.
Definition: Status.h:44
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
uint64_t offset_t
Definition: lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:386
SymbolType
Symbol types.
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
Definition: lldb-forward.h:333
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
Definition: lldb-forward.h:334
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:370
std::vector< data_directory > data_dirs