17#include "llvm/Support/Error.h"
18#include "llvm/Support/FormatAdapters.h"
24using namespace llvm::object;
27 return identify_magic(toStringRef(data->GetData())) ==
28 file_magic::coff_object;
54 if (!extractor_sp || !extractor_sp->HasData()) {
58 "Failed to create ObjectFileCOFF instance: cannot read file {0}",
62 extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
66 assert(extractor_sp && extractor_sp->HasData() &&
67 "must have mapped file at this point");
72 if (extractor_sp->GetByteSize() < length) {
76 "Failed to create ObjectFileCOFF instance: cannot read file {0}",
80 extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
84 MemoryBufferRef buffer{
85 toStringRef(extractor_sp->GetSharedDataBuffer()->GetData()),
88 Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
91 "Failed to create binary for file ({1}): {0}",
96 LLDB_LOG(log,
"ObjectFileCOFF::ObjectFileCOFF module = {1} ({2}), file = {3}",
97 module_sp.get(), module_sp->GetSpecificationDescription(),
100 return new ObjectFileCOFF(unique_dyn_cast<COFFObjectFile>(std::move(*binary)),
101 module_sp, extractor_sp, data_offset, file,
102 file_offset, length);
118 MemoryBufferRef buffer{toStringRef(data_sp->GetData()),
120 Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
124 "Failed to create binary for file ({1}): {0}",
129 std::unique_ptr<COFFObjectFile>
object =
130 unique_dyn_cast<COFFObjectFile>(std::move(*binary));
131 switch (
static_cast<COFF::MachineTypes
>(object->getMachine())) {
132 case COFF::IMAGE_FILE_MACHINE_I386:
135 case COFF::IMAGE_FILE_MACHINE_AMD64:
138 case COFF::IMAGE_FILE_MACHINE_ARMNT:
141 case COFF::IMAGE_FILE_MACHINE_ARM64:
154 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
156 stream->
Printf(
"%p: ",
static_cast<void *
>(
this));
159 *stream <<
", file = '" <<
m_file
164 true, std::numeric_limits<uint32_t>::max());
172 switch (
static_cast<COFF::MachineTypes
>(
m_object->getMachine())) {
173 case COFF::IMAGE_FILE_MACHINE_I386:
174 return ArchSpec(
"i686-unknown-windows-msvc");
175 case COFF::IMAGE_FILE_MACHINE_AMD64:
176 return ArchSpec(
"x86_64-unknown-windows-msvc");
177 case COFF::IMAGE_FILE_MACHINE_ARMNT:
178 return ArchSpec(
"armv7-unknown-windows-msvc");
179 case COFF::IMAGE_FILE_MACHINE_ARM64:
180 return ArchSpec(
"aarch64-unknown-windows-msvc");
195 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
200 if (Name.consume_front(
".debug_"))
211 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_CODE)
213 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
215 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
219 auto Permissions = [](
const object::coff_section *
Section) -> uint32_t {
220 uint32_t permissions = 0;
221 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE)
222 permissions |= lldb::ePermissionsExecutable;
223 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_READ)
224 permissions |= lldb::ePermissionsReadable;
225 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_WRITE)
226 permissions |= lldb::ePermissionsWritable;
230 for (
const auto &SecRef :
m_object->sections()) {
231 const auto COFFSection =
m_object->getCOFFSection(SecRef);
233 llvm::Expected<StringRef> Name = SecRef.getName();
234 StringRef SectionName = Name ? *Name : COFFSection->Name;
236 consumeError(Name.takeError());
239 std::make_unique<Section>(module,
this,
240 static_cast<user_id_t>(SecRef.getIndex()),
243 COFFSection->VirtualAddress,
244 COFFSection->VirtualSize,
245 COFFSection->PointerToRawData,
246 COFFSection->SizeOfRawData,
247 COFFSection->getAlignment(),
249 section->SetPermissions(Permissions(COFFSection));
263 if (
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
265 if (
Symbol.getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
266 Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_NULL)
271 for (
const auto &SymRef :
m_object->symbols()) {
272 const auto COFFSymRef =
m_object->getCOFFSymbol(SymRef);
274 Expected<StringRef> NameOrErr = SymRef.getName();
277 "ObjectFileCOFF: failed to get symbol name: {0}");
284 int16_t SecIdx =
static_cast<int16_t
>(COFFSymRef.getSectionNumber());
285 if (SecIdx == COFF::IMAGE_SYM_ABSOLUTE) {
288 }
else if (SecIdx >= 1) {
290 COFFSymRef.getValue());
297 LLDB_LOG(log,
"ObjectFileCOFF::ParseSymtab processed {0} symbols",
306 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
static bool IsCOFFObjectFile(const DataBufferSP &data)
#define LLDB_PLUGIN_DEFINE(PluginName)
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
void ParseSymtab(lldb_private::Symtab &) override
Parse the symbol table into the provides symbol table object.
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)
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header)
void Dump(lldb_private::Stream *stream) override
Dump a description of this object to a Stream.
void CreateSections(lldb_private::SectionList &) override
static llvm::StringRef GetPluginDescriptionStatic()
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
~ObjectFileCOFF() override
bool ParseHeader() override
Attempts to parse the object header.
std::unique_ptr< llvm::object::COFFObjectFile > m_object
ObjectFileCOFF(std::unique_ptr< llvm::object::COFFObjectFile > object, 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)
static lldb_private::ObjectFile * CreateInstance(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)
static llvm::StringRef GetPluginNameStatic()
A section + offset based address class.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const ConstString & GetFilename() const
Filename string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetValue(ConstString name)
Set the string value in this object.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const ModuleSpec &spec)
A plug-in interface definition class for object file parsers.
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
size_t AddSection(const lldb::SectionSP §ion_sp)
lldb::SectionSP GetSectionAtIndex(size_t idx) const
A stream class that can stream formatted output to a file.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
unsigned GetIndentLevel() const
Get the current indentation level.
void SetType(lldb::SymbolType type)
Address & GetAddressRef()
uint32_t AddSymbol(const Symbol &symbol)
size_t GetNumSymbols() const
void Reserve(size_t count)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP