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
17#include "llvm/Object/COFF.h"
18
20public:
23 MachineAm33 = 0x1d3,
24 MachineAmd64 = 0x8664,
25 MachineArm = 0x1c0,
26 MachineArmNt = 0x1c4,
27 MachineArm64 = 0xaa64,
28 MachineArm64X = 0xa64e,
29 MachineEbc = 0xebc,
30 MachineX86 = 0x14c,
31 MachineIA64 = 0x200,
32 MachineM32R = 0x9041,
38 MachineR4000 = 0x166,
39 MachineSh3 = 0x1a2,
41 MachineSh4 = 0x1a6,
42 MachineSh5 = 0x1a8,
43 MachineThumb = 0x1c2,
45 };
46
47 ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
48 lldb::DataExtractorSP extractor_sp,
49 lldb::offset_t data_offset,
50 const lldb_private::FileSpec *file,
51 lldb::offset_t file_offset, lldb::offset_t length);
52
53 ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
54 lldb::WritableDataBufferSP header_data_sp,
55 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
56
58
59 // Static Functions
60 static void Initialize();
61
62 static void DebuggerInitialize(lldb_private::Debugger &debugger);
63
64 static void Terminate();
65
66 static llvm::StringRef GetPluginNameStatic() { return "pe-coff"; }
67
68 static llvm::StringRef GetPluginDescriptionStatic();
69
70 static ObjectFile *CreateInstance(const lldb::ModuleSP &module_sp,
71 lldb::DataExtractorSP extractor_sp,
72 lldb::offset_t data_offset,
73 const lldb_private::FileSpec *file,
74 lldb::offset_t offset,
75 lldb::offset_t length);
76
78 const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
79 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
80
81 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
82 lldb::DataBufferSP &data_sp,
83 lldb::offset_t data_offset,
84 lldb::offset_t file_offset,
85 lldb::offset_t length,
87
88 static bool SaveCore(const lldb::ProcessSP &process_sp,
91
92 static bool MagicBytesMatch(lldb::DataBufferSP data_sp);
93
94 static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
95
96 // LLVM RTTI support
97 static char ID;
98 bool isA(const void *ClassID) const override {
99 return ClassID == &ID || ObjectFile::isA(ClassID);
100 }
101 static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
102
103 bool ParseHeader() override;
104
106 bool value_is_offset) override;
107
108 lldb::ByteOrder GetByteOrder() const override;
109
110 bool IsExecutable() const override;
111
112 uint32_t GetAddressByteSize() const override;
113
114 // virtual lldb_private::AddressClass
115 // GetAddressClass (lldb::addr_t file_addr);
116
117 void ParseSymtab(lldb_private::Symtab &symtab) override;
118
119 bool IsStripped() override;
120
121 void CreateSections(lldb_private::SectionList &unified_section_list) override;
122
123 void Dump(lldb_private::Stream *s) override;
124
126
127 lldb_private::UUID GetUUID() override;
128
129 /// Return the contents of the .gnu_debuglink section, if the object file
130 /// contains it.
131 std::optional<lldb_private::FileSpec> GetDebugLink();
132
133 uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
134
136
138
139 ObjectFile::Type CalculateType() override;
140
141 ObjectFile::Strata CalculateStrata() override;
142
143 // PluginInterface protocol
144 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
145
146 bool IsWindowsSubsystem();
147
148 uint32_t GetRVA(const lldb_private::Address &addr) const;
149 lldb_private::Address GetAddress(uint32_t rva);
150 lldb::addr_t GetFileAddress(uint32_t rva) const;
151
152 lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
153 lldb_private::DataExtractor ReadImageDataByRVA(uint32_t rva, size_t size);
154
155 std::unique_ptr<lldb_private::CallFrameInfo> CreateCallFrameInfo() override;
156
157protected:
158 bool NeedsEndianSwap() const;
159
160 typedef struct dos_header { // DOS .EXE header
161 uint16_t e_magic = 0; // Magic number
162 uint16_t e_cblp = 0; // Bytes on last page of file
163 uint16_t e_cp = 0; // Pages in file
164 uint16_t e_crlc = 0; // Relocations
165 uint16_t e_cparhdr = 0; // Size of header in paragraphs
166 uint16_t e_minalloc = 0; // Minimum extra paragraphs needed
167 uint16_t e_maxalloc = 0; // Maximum extra paragraphs needed
168 uint16_t e_ss = 0; // Initial (relative) SS value
169 uint16_t e_sp = 0; // Initial SP value
170 uint16_t e_csum = 0; // Checksum
171 uint16_t e_ip = 0; // Initial IP value
172 uint16_t e_cs = 0; // Initial (relative) CS value
173 uint16_t e_lfarlc = 0; // File address of relocation table
174 uint16_t e_ovno = 0; // Overlay number
175 uint16_t e_res[4]; // Reserved words
176 uint16_t e_oemid = 0; // OEM identifier (for e_oeminfo)
177 uint16_t e_oeminfo = 0; // OEM information; e_oemid specific
178 uint16_t e_res2[10] = {}; // Reserved words
179 uint32_t e_lfanew = 0; // File address of new exe header
181
182 typedef struct coff_header {
183 uint16_t machine = 0;
184 uint16_t nsects = 0;
185 uint32_t modtime = 0;
186 uint32_t symoff = 0;
187 uint32_t nsyms = 0;
188 uint16_t hdrsize = 0;
189 uint16_t flags = 0;
191
192 typedef struct data_directory {
193 uint32_t vmaddr = 0;
194 uint32_t vmsize = 0;
196
197 typedef struct coff_opt_header {
198 uint16_t magic = 0;
201 uint32_t code_size = 0;
202 uint32_t data_size = 0;
203 uint32_t bss_size = 0;
204 uint32_t entry = 0;
205 uint32_t code_offset = 0;
206 uint32_t data_offset = 0;
207
208 uint64_t image_base = 0;
209 uint32_t sect_alignment = 0;
210 uint32_t file_alignment = 0;
217 uint32_t reserved1 = 0;
218 uint32_t image_size = 0;
219 uint32_t header_size = 0;
220 uint32_t checksum = 0;
221 uint16_t subsystem = 0;
222 uint16_t dll_flags = 0;
223 uint64_t stack_reserve_size = 0;
224 uint64_t stack_commit_size = 0;
225 uint64_t heap_reserve_size = 0;
226 uint64_t heap_commit_size = 0;
227 uint32_t loader_flags = 0;
228 // uint32_t num_data_dir_entries;
229 std::vector<data_directory>
230 data_dirs; // will contain num_data_dir_entries entries
232
233 typedef struct section_header {
234 char name[8] = {};
235 uint32_t vmsize = 0; // Virtual Size
236 uint32_t vmaddr = 0; // Virtual Addr
237 uint32_t size = 0; // File size
238 uint32_t offset = 0; // File offset
239 uint32_t reloff = 0; // Offset to relocations
240 uint32_t lineoff = 0; // Offset to line table entries
241 uint16_t nreloc = 0; // Number of relocation entries
242 uint16_t nline = 0; // Number of line table entries
243 uint32_t flags = 0;
245
247 dos_header_t &dos_header);
249 lldb::offset_t *offset_ptr,
250 coff_header_t &coff_header);
251 bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
252 bool ParseSectionHeaders(uint32_t offset);
253
254 uint32_t ParseDependentModules();
255
256 static void DumpDOSHeader(lldb_private::Stream *s,
257 const dos_header_t &header);
259 const coff_header_t &header);
261 const coff_opt_header_t &header);
265
266 llvm::StringRef GetSectionName(const section_header_t &sect);
267 static lldb::SectionType GetSectionType(llvm::StringRef sect_name,
268 const section_header_t &sect);
269 size_t GetSectionDataSize(lldb_private::Section *section) override;
270
271 typedef std::vector<section_header_t> SectionHeaderColl;
272 typedef SectionHeaderColl::iterator SectionHeaderCollIter;
273 typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
274
275private:
276 bool CreateBinary();
277 typedef std::vector<std::pair<uint32_t, uint32_t>> rva_symbol_list_t;
279 lldb_private::Symtab &symtab,
280 const rva_symbol_list_t &sorted_exports);
282 lldb_private::Symtab &symtab);
283
290 std::optional<lldb_private::FileSpecList> m_deps_filespec;
291 std::unique_ptr<llvm::object::COFFObjectFile> m_binary;
293};
294
295#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
static bool SaveCore(const lldb::ProcessSP &process_sp, lldb_private::SaveCoreOptions &options, lldb_private::Status &error)
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
static ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
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()
ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
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 bool ParseCOFFHeader(lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header)
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.
A class to manage flag bits.
Definition Debugger.h:80
A file collection class.
A file utility class.
Definition FileSpec.h:57
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
An error handling class.
Definition Status.h:118
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Represents UUID's of various sizes.
Definition UUID.h:27
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
SymbolType
Symbol types.
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP
std::vector< data_directory > data_dirs