29#include "llvm/ADT/StringRef.h"
30#include "llvm/BinaryFormat/XCOFF.h"
31#include "llvm/Object/XCOFFObjectFile.h"
32#include "llvm/Support/MemoryBuffer.h"
36#include <unordered_map>
62 if (!extractor_sp || !extractor_sp->HasData()) {
67 extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
72 if (extractor_sp->GetByteSize() < length) {
77 extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
79 auto objfile_up = std::make_unique<ObjectFileXCOFF>(
80 module_sp, extractor_sp, data_offset, file, file_offset, length);
85 if (!objfile_up->CreateBinary())
88 if (!objfile_up->ParseHeader())
91 return objfile_up.release();
100 auto memory_ref = llvm::MemoryBufferRef(toStringRef(
m_data_nsp->GetData()),
102 llvm::file_magic magic = llvm::identify_magic(memory_ref.getBuffer());
104 auto binary = llvm::object::ObjectFile::createObjectFile(memory_ref, magic);
107 "Failed to create binary for file ({1}): {0}",
m_file);
112 llvm::unique_dyn_cast<llvm::object::XCOFFObjectFile>(std::move(*binary));
116 LLDB_LOG(log,
"this = {0}, module = {1} ({2}), file = {3}, binary = {4}",
132 if (!extractor_sp || !extractor_sp->HasData())
137 extractor_sp, 0, extractor_sp->GetByteSize())) {
138 const uint32_t cpu_type =
139 (*magic == XCOFF::XCOFF64) ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC;
150std::optional<XCOFF::MagicNumber>
155 extractor_sp->GetSubsetExtractorSP(data_offset);
159 uint16_t magic = magic_extractor_sp->GetU16(&offset);
161 if (magic == XCOFF::XCOFF64 || magic == XCOFF::XCOFF32)
162 return static_cast<llvm::XCOFF::MagicNumber
>(magic);
169 return m_binary->fileHeader64()->Magic == XCOFF::XCOFF64;
170 return m_binary->fileHeader32()->Magic == XCOFF::XCOFF32;
189 case llvm::object::SymbolRef::ST_Function:
191 case llvm::object::SymbolRef::ST_Data:
193 case llvm::object::SymbolRef::ST_File:
204 for (
const auto &symbol_ref :
m_binary->symbols()) {
205 llvm::object::XCOFFSymbolRef xcoff_sym_ref(symbol_ref);
207 llvm::Expected<llvm::StringRef> name_or_err = xcoff_sym_ref.getName();
210 log, name_or_err.takeError(),
211 "Unable to extract name from the xcoff symbol ref object: {0}");
215 llvm::StringRef symbolName = name_or_err.get();
220 llvm::StringRef name_no_dot =
221 symbolName.starts_with(
".") ? symbolName.drop_front() : symbolName;
222 auto storageClass = xcoff_sym_ref.getStorageClass();
225 if (storageClass == XCOFF::C_HIDEXT && symbolName !=
"TOC") {
228 if (xcoff_sym_ref.getNumberOfAuxEntries() != 1)
231 auto aux_csect_or_err = xcoff_sym_ref.getXCOFFCsectAuxRef();
232 if (!aux_csect_or_err) {
234 "Unable to access xcoff csect aux ref object: {0}");
238 const llvm::object::XCOFFCsectAuxRef csect_aux = aux_csect_or_err.get();
242 if (csect_aux.getStorageMappingClass() != XCOFF::XMC_PR)
249 if (csect_aux.getAuxType64() != XCOFF::AUX_CSECT)
256 int16_t sectionNumber = xcoff_sym_ref.getSectionNumber();
258 size_t sectionIndex =
static_cast<size_t>(sectionNumber - 1);
259 if (sectionNumber > 0) {
260 if (sectionIndex < sectionList->GetSize()) {
269 if (symbolValue < file_addr)
276 Expected<llvm::object::SymbolRef::Type> sym_type_or_err =
277 symbol_ref.getType();
278 if (!sym_type_or_err) {
280 "Unable to access xcoff symbol type: {0}");
306 if constexpr (T::Is64Bit)
307 return binary->sections64();
309 return binary->sections32();
319 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
322 for (
const typename T::SectionHeader §ion :
328 if (section.Flags & XCOFF::STYP_TEXT)
330 else if (section.Flags & XCOFF::STYP_DATA)
332 else if (section.Flags & XCOFF::STYP_BSS)
334 else if (section.Flags & XCOFF::STYP_DWARF) {
335 section_type = llvm::StringSwitch<SectionType>(section.Name)
343 SectionSP section_sp = std::make_shared<Section>(
344 module_sp,
this, ++idx, const_sect_name, section_type,
345 section.VirtualAddress, section.SectionSize,
346 section.FileOffsetToRawData, section.SectionSize, 0, section.Flags);
348 uint32_t permissions = ePermissionsReadable;
349 if (section.Flags & (XCOFF::STYP_DATA | XCOFF::STYP_BSS))
350 permissions |= ePermissionsWritable;
351 if (section.Flags & XCOFF::STYP_TEXT)
352 permissions |= ePermissionsExecutable;
354 section_sp->SetPermissions(permissions);
363 const uint32_t cpu_type =
364 m_binary->is64Bit() ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC;
377 if (flags & XCOFF::F_EXEC)
379 else if (flags & XCOFF::F_SHROBJ)
399 :
ObjectFile(module_sp, file, file_offset, length, extractor_sp,
410 module_sp, process_sp, header_addr,
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
static lldb::SymbolType MapSymbolType(llvm::object::SymbolRef::Type sym_type)
static auto GetSections(llvm::object::XCOFFObjectFile *binary)
#define LLDB_PLUGIN_DEFINE(PluginName)
Generic XCOFF object file reader.
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
bool ParseHeader() override
Attempts to parse the object header.
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
static lldb::WritableDataBufferSP MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size, uint64_t Offset)
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
Extract the dependent modules from an object file.
void ParseSymtab(lldb_private::Symtab &symtab) override
Parse the symbol table into the provides symbol table object.
static llvm::StringRef GetPluginNameStatic()
static std::optional< llvm::XCOFF::MagicNumber > GetMagicBytes(lldb::DataExtractorSP &extractor_sp, lldb::addr_t offset, lldb::addr_t length)
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
void CreateSections(lldb_private::SectionList &unified_section_list) override
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override
Get the address type given a file address in an object file.
static llvm::StringRef GetPluginDescriptionStatic()
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)
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
static lldb_private::ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
void CreateSectionsWithBitness(lldb_private::SectionList &unified_section_list)
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
ObjectFileXCOFF(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)
std::unique_ptr< llvm::object::XCOFFObjectFile > m_binary
A section + offset based address class.
An architecture specification class.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
A uniqued constant string class.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
std::shared_ptr< WritableDataBuffer > CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
static FileSystem & Instance()
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)
ArchSpec & GetArchitecture()
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
@ eTypeExecutable
A normal executable.
@ eTypeSharedLibrary
A shared library that can be used during execution.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
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.
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.
void SetType(lldb::SymbolType type)
Address & GetAddressRef()
uint32_t AddSymbol(const Symbol &symbol)
Represents UUID's of various sizes.
#define LLDB_INVALID_CPUTYPE
#define LLDB_INVALID_ADDRESS
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
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugAbbrev
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP