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 = {0} ({1}), file = {2}",
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);
120 if (!extractor_sp || !extractor_sp->HasData())
127 extractor_sp->GetContiguousDataExtractorSP();
128 if (!contiguous_extractor_sp)
133 MemoryBufferRef buffer{toStringRef(contiguous_extractor_sp->GetData()),
135 Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
139 "Failed to create binary for file ({1}): {0}",
144 std::unique_ptr<COFFObjectFile>
object =
145 unique_dyn_cast<COFFObjectFile>(std::move(*binary));
147 switch (
static_cast<COFF::MachineTypes
>(object->getMachine())) {
150 case COFF::IMAGE_FILE_MACHINE_AMD64:
153 case COFF::IMAGE_FILE_MACHINE_ARMNT:
156 case COFF::IMAGE_FILE_MACHINE_ARM64:
170 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
172 stream->
Printf(
"%p: ",
static_cast<void *
>(
this));
175 *stream <<
", file = '" <<
m_file
180 true, std::numeric_limits<uint32_t>::max());
188 switch (
static_cast<COFF::MachineTypes
>(
m_object->getMachine())) {
189 case COFF::IMAGE_FILE_MACHINE_I386:
190 return ArchSpec(
"i686-unknown-windows-msvc");
191 case COFF::IMAGE_FILE_MACHINE_AMD64:
192 return ArchSpec(
"x86_64-unknown-windows-msvc");
193 case COFF::IMAGE_FILE_MACHINE_ARMNT:
194 return ArchSpec(
"armv7-unknown-windows-msvc");
195 case COFF::IMAGE_FILE_MACHINE_ARM64:
196 return ArchSpec(
"aarch64-unknown-windows-msvc");
211 std::lock_guard<std::recursive_mutex> guard(module->GetMutex());
216 if (Name.consume_front(
".debug_"))
227 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_CODE)
229 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
231 if (
Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
235 auto Permissions = [](
const object::coff_section *
Section) -> uint32_t {
236 uint32_t permissions = 0;
237 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE)
238 permissions |= lldb::ePermissionsExecutable;
239 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_READ)
240 permissions |= lldb::ePermissionsReadable;
241 if (
Section->Characteristics & COFF::IMAGE_SCN_MEM_WRITE)
242 permissions |= lldb::ePermissionsWritable;
246 for (
const auto &SecRef :
m_object->sections()) {
247 const auto COFFSection =
m_object->getCOFFSection(SecRef);
249 llvm::Expected<StringRef> Name = SecRef.getName();
250 StringRef SectionName = Name ? *Name : COFFSection->Name;
252 consumeError(Name.takeError());
255 std::make_unique<Section>(module,
this,
256 static_cast<user_id_t>(SecRef.getIndex()),
259 COFFSection->VirtualAddress,
260 COFFSection->VirtualSize,
261 COFFSection->PointerToRawData,
262 COFFSection->SizeOfRawData,
263 COFFSection->getAlignment(),
265 section->SetPermissions(Permissions(COFFSection));
279 if (
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
281 if (
Symbol.getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
282 Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_NULL)
287 for (
const auto &SymRef :
m_object->symbols()) {
288 const auto COFFSymRef =
m_object->getCOFFSymbol(SymRef);
290 Expected<StringRef> NameOrErr = SymRef.getName();
293 "ObjectFileCOFF: failed to get symbol name: {0}");
300 int16_t SecIdx =
static_cast<int16_t
>(COFFSymRef.getSectionNumber());
301 if (SecIdx == COFF::IMAGE_SYM_ABSOLUTE) {
304 }
else if (SecIdx >= 1) {
306 COFFSymRef.getValue());
313 LLDB_LOG(log,
"ObjectFileCOFF::ParseSymtab processed {0} symbols",
322 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 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
static lldb_private::ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
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