17#include "llvm/Support/Error.h"
18#include "llvm/Support/FormatAdapters.h"
24using namespace llvm::object;
27 return identify_magic(toStringRef(data)) == file_magic::coff_object;
53 if (!extractor_sp || !extractor_sp->HasData()) {
57 "Failed to create ObjectFileCOFF instance: cannot read file {0}",
61 extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
65 assert(extractor_sp && extractor_sp->HasData() &&
66 "must have mapped file at this point");
72 extractor_sp->GetContiguousDataExtractorSP();
76 if (contiguous_extractor_sp->GetByteSize() < length) {
80 "Failed to create ObjectFileCOFF instance: cannot read file {0}",
84 contiguous_extractor_sp =
85 std::make_shared<lldb_private::DataExtractor>(data_sp);
89 MemoryBufferRef buffer{toStringRef(contiguous_extractor_sp->GetData()),
92 Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
95 "Failed to create binary for file ({1}): {0}",
100 LLDB_LOG(log,
"ObjectFileCOFF::ObjectFileCOFF module = {1} ({2}), file = {3}",
101 module_sp.get(), module_sp->GetSpecificationDescription(),
104 return new ObjectFileCOFF(unique_dyn_cast<COFFObjectFile>(std::move(*binary)),
105 module_sp, contiguous_extractor_sp, data_offset,
106 file, file_offset, length);
119 if (!extractor_sp || !extractor_sp->HasData())
126 extractor_sp->GetContiguousDataExtractorSP();
127 if (!contiguous_extractor_sp)
132 MemoryBufferRef buffer{toStringRef(contiguous_extractor_sp->GetData()),
134 Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
138 "Failed to create binary for file ({1}): {0}",
143 std::unique_ptr<COFFObjectFile>
object =
144 unique_dyn_cast<COFFObjectFile>(std::move(*binary));
145 switch (
static_cast<COFF::MachineTypes
>(object->getMachine())) {
146 case COFF::IMAGE_FILE_MACHINE_I386:
149 case COFF::IMAGE_FILE_MACHINE_AMD64:
152 case COFF::IMAGE_FILE_MACHINE_ARMNT:
155 case COFF::IMAGE_FILE_MACHINE_ARM64:
168 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
170 stream->
Printf(
"%p: ",
static_cast<void *
>(
this));
173 *stream <<
", file = '" <<
m_file
178 true, std::numeric_limits<uint32_t>::max());
186 switch (
static_cast<COFF::MachineTypes
>(
m_object->getMachine())) {
187 case COFF::IMAGE_FILE_MACHINE_I386:
188 return ArchSpec(
"i686-unknown-windows-msvc");
189 case COFF::IMAGE_FILE_MACHINE_AMD64:
190 return ArchSpec(
"x86_64-unknown-windows-msvc");
191 case COFF::IMAGE_FILE_MACHINE_ARMNT:
192 return ArchSpec(
"armv7-unknown-windows-msvc");
193 case COFF::IMAGE_FILE_MACHINE_ARM64:
194 return ArchSpec(
"aarch64-unknown-windows-msvc");
209 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
214 if (Name.consume_front(
".debug_"))
225 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_CODE)
227 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
229 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
233 auto Permissions = [](
const object::coff_section *
Section) -> uint32_t {
234 uint32_t permissions = 0;
235 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE)
236 permissions |= lldb::ePermissionsExecutable;
237 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_READ)
238 permissions |= lldb::ePermissionsReadable;
239 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_WRITE)
240 permissions |= lldb::ePermissionsWritable;
244 for (
const auto &SecRef :
m_object->sections()) {
245 const auto COFFSection =
m_object->getCOFFSection(SecRef);
247 llvm::Expected<StringRef> Name = SecRef.getName();
248 StringRef SectionName = Name ? *Name : COFFSection->Name;
250 consumeError(Name.takeError());
253 std::make_unique<Section>(module,
this,
254 static_cast<user_id_t>(SecRef.getIndex()),
257 COFFSection->VirtualAddress,
258 COFFSection->VirtualSize,
259 COFFSection->PointerToRawData,
260 COFFSection->SizeOfRawData,
261 COFFSection->getAlignment(),
263 section->SetPermissions(Permissions(COFFSection));
277 if (
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
279 if (
Symbol.getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
280 Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_NULL)
285 for (
const auto &SymRef :
m_object->symbols()) {
286 const auto COFFSymRef =
m_object->getCOFFSymbol(SymRef);
288 Expected<StringRef> NameOrErr = SymRef.getName();
291 "ObjectFileCOFF: failed to get symbol name: {0}");
298 int16_t SecIdx =
static_cast<int16_t
>(COFFSymRef.getSectionNumber());
299 if (SecIdx == COFF::IMAGE_SYM_ABSOLUTE) {
302 }
else if (SecIdx >= 1) {
304 COFFSymRef.getValue());
311 LLDB_LOG(log,
"ObjectFileCOFF::ParseSymtab processed {0} symbols",
320 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 llvm::ArrayRef< uint8_t > 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::DataExtractorSP &extractor_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