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,
44 MachineWcemIpsv2 = 0x169
45 };
46
47 ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
48 lldb::offset_t data_offset,
49 const lldb_private::FileSpec *file,
50 lldb::offset_t file_offset, lldb::offset_t length);
51
52 ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
53 lldb::WritableDataBufferSP header_data_sp,
54 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
55
57
58 // Static Functions
59 static void Initialize();
60
61 static void DebuggerInitialize(lldb_private::Debugger &debugger);
62
63 static void Terminate();
64
65 static llvm::StringRef GetPluginNameStatic() { return "pe-coff"; }
66
67 static llvm::StringRef GetPluginDescriptionStatic();
68
69 static ObjectFile *
70 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
71 lldb::offset_t data_offset, const lldb_private::FileSpec *file,
72 lldb::offset_t offset, lldb::offset_t length);
73
75 const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
76 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
77
78 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
79 lldb::DataBufferSP &data_sp,
80 lldb::offset_t data_offset,
81 lldb::offset_t file_offset,
82 lldb::offset_t length,
84
85 static bool SaveCore(const lldb::ProcessSP &process_sp,
88
89 static bool MagicBytesMatch(lldb::DataBufferSP data_sp);
90
91 static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
92
93 // LLVM RTTI support
94 static char ID;
95 bool isA(const void *ClassID) const override {
96 return ClassID == &ID || ObjectFile::isA(ClassID);
97 }
98 static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
99
100 bool ParseHeader() override;
101
103 bool value_is_offset) override;
104
105 lldb::ByteOrder GetByteOrder() const override;
106
107 bool IsExecutable() const override;
108
109 uint32_t GetAddressByteSize() const override;
110
111 // virtual lldb_private::AddressClass
112 // GetAddressClass (lldb::addr_t file_addr);
113
114 void ParseSymtab(lldb_private::Symtab &symtab) override;
115
116 bool IsStripped() override;
117
118 void CreateSections(lldb_private::SectionList &unified_section_list) override;
119
120 void Dump(lldb_private::Stream *s) override;
121
123
124 lldb_private::UUID GetUUID() override;
125
126 /// Return the contents of the .gnu_debuglink section, if the object file
127 /// contains it.
128 std::optional<lldb_private::FileSpec> GetDebugLink();
129
130 uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
131
133
135
136 ObjectFile::Type CalculateType() override;
137
138 ObjectFile::Strata CalculateStrata() override;
139
140 // PluginInterface protocol
141 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
142
143 bool IsWindowsSubsystem();
144
145 uint32_t GetRVA(const lldb_private::Address &addr) const;
146 lldb_private::Address GetAddress(uint32_t rva);
147 lldb::addr_t GetFileAddress(uint32_t rva) const;
148
149 lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
150 lldb_private::DataExtractor ReadImageDataByRVA(uint32_t rva, size_t size);
151
152 std::unique_ptr<lldb_private::CallFrameInfo> CreateCallFrameInfo() override;
153
154protected:
155 bool NeedsEndianSwap() const;
156
157 typedef struct dos_header { // DOS .EXE header
158 uint16_t e_magic = 0; // Magic number
159 uint16_t e_cblp = 0; // Bytes on last page of file
160 uint16_t e_cp = 0; // Pages in file
161 uint16_t e_crlc = 0; // Relocations
162 uint16_t e_cparhdr = 0; // Size of header in paragraphs
163 uint16_t e_minalloc = 0; // Minimum extra paragraphs needed
164 uint16_t e_maxalloc = 0; // Maximum extra paragraphs needed
165 uint16_t e_ss = 0; // Initial (relative) SS value
166 uint16_t e_sp = 0; // Initial SP value
167 uint16_t e_csum = 0; // Checksum
168 uint16_t e_ip = 0; // Initial IP value
169 uint16_t e_cs = 0; // Initial (relative) CS value
170 uint16_t e_lfarlc = 0; // File address of relocation table
171 uint16_t e_ovno = 0; // Overlay number
172 uint16_t e_res[4]; // Reserved words
173 uint16_t e_oemid = 0; // OEM identifier (for e_oeminfo)
174 uint16_t e_oeminfo = 0; // OEM information; e_oemid specific
175 uint16_t e_res2[10] = {}; // Reserved words
176 uint32_t e_lfanew = 0; // File address of new exe header
178
179 typedef struct coff_header {
180 uint16_t machine = 0;
181 uint16_t nsects = 0;
182 uint32_t modtime = 0;
183 uint32_t symoff = 0;
184 uint32_t nsyms = 0;
185 uint16_t hdrsize = 0;
186 uint16_t flags = 0;
188
189 typedef struct data_directory {
190 uint32_t vmaddr = 0;
191 uint32_t vmsize = 0;
193
194 typedef struct coff_opt_header {
195 uint16_t magic = 0;
198 uint32_t code_size = 0;
199 uint32_t data_size = 0;
200 uint32_t bss_size = 0;
201 uint32_t entry = 0;
202 uint32_t code_offset = 0;
203 uint32_t data_offset = 0;
204
205 uint64_t image_base = 0;
206 uint32_t sect_alignment = 0;
207 uint32_t file_alignment = 0;
214 uint32_t reserved1 = 0;
215 uint32_t image_size = 0;
216 uint32_t header_size = 0;
217 uint32_t checksum = 0;
218 uint16_t subsystem = 0;
219 uint16_t dll_flags = 0;
220 uint64_t stack_reserve_size = 0;
221 uint64_t stack_commit_size = 0;
222 uint64_t heap_reserve_size = 0;
223 uint64_t heap_commit_size = 0;
224 uint32_t loader_flags = 0;
225 // uint32_t num_data_dir_entries;
226 std::vector<data_directory>
227 data_dirs; // will contain num_data_dir_entries entries
229
230 typedef struct section_header {
231 char name[8] = {};
232 uint32_t vmsize = 0; // Virtual Size
233 uint32_t vmaddr = 0; // Virtual Addr
234 uint32_t size = 0; // File size
235 uint32_t offset = 0; // File offset
236 uint32_t reloff = 0; // Offset to relocations
237 uint32_t lineoff = 0; // Offset to line table entries
238 uint16_t nreloc = 0; // Number of relocation entries
239 uint16_t nline = 0; // Number of line table entries
240 uint32_t flags = 0;
242
244 dos_header_t &dos_header);
246 lldb::offset_t *offset_ptr,
247 coff_header_t &coff_header);
248 bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
249 bool ParseSectionHeaders(uint32_t offset);
250
251 uint32_t ParseDependentModules();
252
253 static void DumpDOSHeader(lldb_private::Stream *s,
254 const dos_header_t &header);
256 const coff_header_t &header);
258 const coff_opt_header_t &header);
262
263 llvm::StringRef GetSectionName(const section_header_t &sect);
264 static lldb::SectionType GetSectionType(llvm::StringRef sect_name,
265 const section_header_t &sect);
266 size_t GetSectionDataSize(lldb_private::Section *section) override;
267
268 typedef std::vector<section_header_t> SectionHeaderColl;
269 typedef SectionHeaderColl::iterator SectionHeaderCollIter;
270 typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
271
272private:
273 bool CreateBinary();
274 typedef std::vector<std::pair<uint32_t, uint32_t>> rva_symbol_list_t;
276 lldb_private::Symtab &symtab,
277 const rva_symbol_list_t &sorted_exports);
279 lldb_private::Symtab &symtab);
280
287 std::optional<lldb_private::FileSpecList> m_deps_filespec;
288 std::unique_ptr<llvm::object::COFFObjectFile> m_binary;
290};
291
292#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
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 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:91
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:115
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:389
SymbolType
Symbol types.
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
Definition: lldb-forward.h:336
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
Definition: lldb-forward.h:337
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
std::vector< data_directory > data_dirs