LLDB mainline
ObjectFileXCOFF.cpp
Go to the documentation of this file.
1//===-- ObjectFileXCOFF.cpp
2//-------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#include "ObjectFileXCOFF.h"
11#include "lldb/Core/Module.h"
14#include "lldb/Core/Progress.h"
15#include "lldb/Core/Section.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
24#include "lldb/Utility/Log.h"
26#include "lldb/Utility/Status.h"
27#include "lldb/Utility/Stream.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/BinaryFormat/XCOFF.h"
30#include "llvm/Object/XCOFFObjectFile.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include <algorithm>
33#include <cassert>
34#include <cstring>
35#include <unordered_map>
36
37using namespace llvm;
38using namespace lldb;
39using namespace lldb_private;
40
42
43// FIXME: target 64bit at this moment.
44
45// Static methods.
46void ObjectFileXCOFF::Initialize() {
47 PluginManager::RegisterPlugin(GetPluginNameStatic(),
48 GetPluginDescriptionStatic(), CreateInstance,
49 CreateMemoryInstance, GetModuleSpecifications);
50}
51
54}
55
57 DataBufferSP data_sp,
58 lldb::offset_t data_offset,
59 const lldb_private::FileSpec *file,
60 lldb::offset_t file_offset,
61 lldb::offset_t length) {
62 if (!data_sp) {
63 data_sp = MapFileData(*file, length, file_offset);
64 if (!data_sp)
65 return nullptr;
66 data_offset = 0;
67 }
68 if (!ObjectFileXCOFF::MagicBytesMatch(data_sp, data_offset, length))
69 return nullptr;
70 // Update the data to contain the entire file if it doesn't already
71 if (data_sp->GetByteSize() < length) {
72 data_sp = MapFileData(*file, length, file_offset);
73 if (!data_sp)
74 return nullptr;
75 data_offset = 0;
76 }
77 auto objfile_up = std::make_unique<ObjectFileXCOFF>(
78 module_sp, data_sp, data_offset, file, file_offset, length);
79 if (!objfile_up)
80 return nullptr;
81
82 // Cache xcoff binary.
83 if (!objfile_up->CreateBinary())
84 return nullptr;
85
86 if (!objfile_up->ParseHeader())
87 return nullptr;
88
89 return objfile_up.release();
90}
91
93 if (m_binary)
94 return true;
95
96 Log *log = GetLog(LLDBLog::Object);
97
98 auto binary = llvm::object::ObjectFile::createObjectFile(
99 llvm::MemoryBufferRef(toStringRef(m_data.GetData()),
101 file_magic::xcoff_object_64);
102 if (!binary) {
103 LLDB_LOG_ERROR(log, binary.takeError(),
104 "Failed to create binary for file ({1}): {0}", m_file);
105 return false;
106 }
107 // Make sure we only handle XCOFF format.
108 m_binary =
109 llvm::unique_dyn_cast<llvm::object::XCOFFObjectFile>(std::move(*binary));
110 if (!m_binary)
111 return false;
112
113 LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}",
114 this, GetModule().get(), GetModule()->GetSpecificationDescription(),
115 m_file.GetPath(), m_binary.get());
116
117 return true;
118}
119
121 const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
122 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
123 return nullptr;
124}
125
127 const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
128 lldb::offset_t data_offset, lldb::offset_t file_offset,
130 const size_t initial_count = specs.GetSize();
131
132 if (ObjectFileXCOFF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
133 ArchSpec arch_spec =
134 ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
135 ModuleSpec spec(file, arch_spec);
136 spec.GetArchitecture().SetArchitecture(eArchTypeXCOFF, XCOFF::TCPU_PPC64,
138 llvm::Triple::AIX);
139 specs.Append(spec);
140 }
141 return specs.GetSize() - initial_count;
142}
143
144static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) {
145 switch (magic) {
146 // TODO: 32bit not supported.
147 // case XCOFF::XCOFF32:
148 // return sizeof(struct llvm::object::XCOFFFileHeader32);
149 case XCOFF::XCOFF64:
150 return sizeof(struct llvm::object::XCOFFFileHeader64);
151 break;
152
153 default:
154 break;
155 }
156 return 0;
157}
158
160 lldb::addr_t data_offset,
161 lldb::addr_t data_length) {
163 data.SetData(data_sp, data_offset, data_length);
164 // Need to set this as XCOFF is only compatible with Big Endian
166 lldb::offset_t offset = 0;
167 uint16_t magic = data.GetU16(&offset);
168 return XCOFFHeaderSizeFromMagic(magic) != 0;
169}
170
172 // Only 64-bit is supported for now
173 return m_binary->fileHeader64()->Magic == XCOFF::XCOFF64;
174}
175
177
178bool ObjectFileXCOFF::IsExecutable() const { return true; }
179
181 // 32-bit not supported. return 8 for 64-bit XCOFF::XCOFF64
182 return 8;
183}
184
186 return AddressClass::eUnknown;
187}
188
190
191bool ObjectFileXCOFF::IsStripped() { return false; }
192
193void ObjectFileXCOFF::CreateSections(SectionList &unified_section_list) {}
194
196
198 ArchSpec arch_spec =
199 ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
200 return arch_spec;
201}
202
204
206
208 if (m_binary->fileHeader64()->Flags & XCOFF::F_EXEC)
209 return eTypeExecutable;
210 else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
211 return eTypeSharedLibrary;
212 return eTypeUnknown;
213}
214
216
219 uint64_t Offset) {
221 Offset);
222}
223
225 DataBufferSP data_sp,
226 lldb::offset_t data_offset,
227 const FileSpec *file,
228 lldb::offset_t file_offset,
229 lldb::offset_t length)
230 : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
231 if (file)
232 m_file = *file;
233}
234
236 DataBufferSP header_data_sp,
237 const lldb::ProcessSP &process_sp,
238 addr_t header_addr)
239 : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:369
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:392
static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic)
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:32
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.
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)
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 bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset, lldb::addr_t length)
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.
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
ObjectFileXCOFF(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 void Terminate()
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
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.
std::unique_ptr< llvm::object::XCOFFObjectFile > m_binary
An architecture specification class.
Definition: ArchSpec.h:31
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.
Definition: ArchSpec.cpp:869
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
An data extractor class.
Definition: DataExtractor.h:48
const void * GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const
Extract length bytes from *offset_ptr.
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
A file collection class.
Definition: FileSpecList.h:91
A file utility class.
Definition: FileSpec.h:56
const ConstString & GetFilename() const
Filename string const get accessor.
Definition: FileSpec.h:240
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
std::shared_ptr< WritableDataBuffer > CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
static FileSystem & Instance()
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
void Append(const ModuleSpec &spec)
Definition: ModuleSpec.h:308
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:89
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
DataExtractor m_data
The data for this object file so things can be parsed lazily.
Definition: ObjectFile.h:758
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
Definition: ObjectFile.cpp:673
@ eTypeExecutable
A normal executable.
Definition: ObjectFile.h:53
@ eTypeSharedLibrary
A shared library that can be used during execution.
Definition: ObjectFile.h:61
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
#define LLDB_INVALID_CPUTYPE
Definition: lldb-defines.h:104
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.
Definition: Log.h:332
Definition: SBAddress.h:15
uint64_t offset_t
Definition: lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
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
Definition: Debugger.h:54