Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,10 @@
add_lldb_library(lldbPluginObjectContainerBSDArchive PLUGIN
ObjectContainerBSDArchive.cpp
LINK_LIBS
lldbCore
lldbHost
lldbSymbol
LINK_COMPONENTS
Support
)

View File

@ -0,0 +1,178 @@
//===-- ObjectContainerBSDArchive.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_ObjectContainerBSDArchive_h_
#define liblldb_ObjectContainerBSDArchive_h_
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
// Other libraries and framework includes
#include "llvm/Support/Chrono.h"
// C Includes
// C++ Includes
#include <map>
#include <memory>
#include <mutex>
class ObjectContainerBSDArchive : public lldb_private::ObjectContainer {
public:
ObjectContainerBSDArchive(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);
~ObjectContainerBSDArchive() override;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
static void Initialize();
static void Terminate();
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
static lldb_private::ObjectContainer *
CreateInstance(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 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(const lldb_private::DataExtractor &data);
//------------------------------------------------------------------
// Member Functions
//------------------------------------------------------------------
bool ParseHeader() override;
size_t GetNumObjects() const override {
if (m_archive_sp)
return m_archive_sp->GetNumObjects();
return 0;
}
void Dump(lldb_private::Stream *s) const override;
lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
protected:
struct Object {
Object();
void Clear();
lldb::offset_t Extract(const lldb_private::DataExtractor &data,
lldb::offset_t offset);
lldb_private::ConstString ar_name; // name
uint32_t ar_date; // modification time
uint16_t ar_uid; // user id
uint16_t ar_gid; // group id
uint16_t ar_mode; // octal file permissions
uint32_t ar_size; // size in bytes
lldb::offset_t ar_file_offset; // file offset in bytes from the beginning of
// the file of the object data
lldb::offset_t ar_file_size; // length of the object data
typedef std::vector<Object> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
};
class Archive {
public:
typedef std::shared_ptr<Archive> shared_ptr;
typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map;
Archive(const lldb_private::ArchSpec &arch,
const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
lldb_private::DataExtractor &data);
~Archive();
static Map &GetArchiveCache();
static std::recursive_mutex &GetArchiveCacheMutex();
static Archive::shared_ptr FindCachedArchive(
const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset);
static Archive::shared_ptr ParseAndCacheArchiveForFile(
const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
lldb_private::DataExtractor &data);
size_t GetNumObjects() const { return m_objects.size(); }
const Object *GetObjectAtIndex(size_t idx) {
if (idx < m_objects.size())
return &m_objects[idx];
return NULL;
}
size_t ParseObjects();
Object *FindObject(const lldb_private::ConstString &object_name,
const llvm::sys::TimePoint<> &object_mod_time);
lldb::offset_t GetFileOffset() const { return m_file_offset; }
const llvm::sys::TimePoint<> &GetModificationTime() { return m_time; }
const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; }
void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; }
bool HasNoExternalReferences() const;
lldb_private::DataExtractor &GetData() { return m_data; }
protected:
typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
//----------------------------------------------------------------------
// Member Variables
//----------------------------------------------------------------------
lldb_private::ArchSpec m_arch;
llvm::sys::TimePoint<> m_time;
lldb::offset_t m_file_offset;
Object::collection m_objects;
ObjectNameToIndexMap m_object_name_to_index_map;
lldb_private::DataExtractor m_data; ///< The data for this object container
///so we don't lose data if the .a files
///gets modified
};
void SetArchive(Archive::shared_ptr &archive_sp);
Archive::shared_ptr m_archive_sp;
};
#endif // liblldb_ObjectContainerBSDArchive_h_

View File

@ -0,0 +1,2 @@
add_subdirectory(BSD-Archive)
add_subdirectory(Universal-Mach-O)

View File

@ -0,0 +1,10 @@
add_lldb_library(lldbPluginObjectContainerMachOArchive PLUGIN
ObjectContainerUniversalMachO.cpp
LINK_LIBS
lldbCore
lldbHost
lldbSymbol
lldbTarget
lldbUtility
)

View File

@ -0,0 +1,239 @@
//===-- ObjectContainerUniversalMachO.cpp -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ObjectContainerUniversalMachO.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;
void ObjectContainerUniversalMachO::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
GetModuleSpecifications);
}
void ObjectContainerUniversalMachO::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
lldb_private::ConstString ObjectContainerUniversalMachO::GetPluginNameStatic() {
static ConstString g_name("mach-o");
return g_name;
}
const char *ObjectContainerUniversalMachO::GetPluginDescriptionStatic() {
return "Universal mach-o object container reader.";
}
ObjectContainer *ObjectContainerUniversalMachO::CreateInstance(
const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
lldb::offset_t data_offset, const FileSpec *file,
lldb::offset_t file_offset, lldb::offset_t length) {
// We get data when we aren't trying to look for cached container information,
// so only try and look for an architecture slice if we get data
if (data_sp) {
DataExtractor data;
data.SetData(data_sp, data_offset, length);
if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
std::unique_ptr<ObjectContainerUniversalMachO> container_ap(
new ObjectContainerUniversalMachO(module_sp, data_sp, data_offset,
file, file_offset, length));
if (container_ap->ParseHeader()) {
return container_ap.release();
}
}
}
return NULL;
}
bool ObjectContainerUniversalMachO::MagicBytesMatch(const DataExtractor &data) {
lldb::offset_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return magic == FAT_MAGIC || magic == FAT_CIGAM;
}
ObjectContainerUniversalMachO::ObjectContainerUniversalMachO(
const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
lldb::offset_t data_offset, const FileSpec *file,
lldb::offset_t file_offset, lldb::offset_t length)
: ObjectContainer(module_sp, file, file_offset, length, data_sp,
data_offset),
m_header(), m_fat_archs() {
memset(&m_header, 0, sizeof(m_header));
}
ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() {}
bool ObjectContainerUniversalMachO::ParseHeader() {
bool success = ParseHeader(m_data, m_header, m_fat_archs);
// We no longer need any data, we parsed all we needed to parse
// and cached it in m_header and m_fat_archs
m_data.Clear();
return success;
}
bool ObjectContainerUniversalMachO::ParseHeader(
lldb_private::DataExtractor &data, llvm::MachO::fat_header &header,
std::vector<llvm::MachO::fat_arch> &fat_archs) {
bool success = false;
// Store the file offset for this universal file as we could have a universal
// .o file
// in a BSD archive, or be contained in another kind of object.
// Universal mach-o files always have their headers in big endian.
lldb::offset_t offset = 0;
data.SetByteOrder(eByteOrderBig);
header.magic = data.GetU32(&offset);
fat_archs.clear();
if (header.magic == FAT_MAGIC) {
data.SetAddressByteSize(4);
header.nfat_arch = data.GetU32(&offset);
// Now we should have enough data for all of the fat headers, so lets index
// them so we know how many architectures that this universal binary
// contains.
uint32_t arch_idx = 0;
for (arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx) {
if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch))) {
fat_arch arch;
if (data.GetU32(&offset, &arch, sizeof(fat_arch) / sizeof(uint32_t)))
fat_archs.push_back(arch);
}
}
success = true;
} else {
memset(&header, 0, sizeof(header));
}
return success;
}
void ObjectContainerUniversalMachO::Dump(Stream *s) const {
s->Printf("%p: ", static_cast<const void *>(this));
s->Indent();
const size_t num_archs = GetNumArchitectures();
const size_t num_objects = GetNumObjects();
s->Printf("ObjectContainerUniversalMachO, num_archs = %zu, num_objects = %zu",
num_archs, num_objects);
uint32_t i;
ArchSpec arch;
s->IndentMore();
for (i = 0; i < num_archs; i++) {
s->Indent();
GetArchitectureAtIndex(i, arch);
s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
}
for (i = 0; i < num_objects; i++) {
s->Indent();
s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex(i));
}
s->IndentLess();
s->EOL();
}
size_t ObjectContainerUniversalMachO::GetNumArchitectures() const {
return m_header.nfat_arch;
}
bool ObjectContainerUniversalMachO::GetArchitectureAtIndex(
uint32_t idx, ArchSpec &arch) const {
if (idx < m_header.nfat_arch) {
arch.SetArchitecture(eArchTypeMachO, m_fat_archs[idx].cputype,
m_fat_archs[idx].cpusubtype);
return true;
}
return false;
}
ObjectFileSP
ObjectContainerUniversalMachO::GetObjectFile(const FileSpec *file) {
uint32_t arch_idx = 0;
ArchSpec arch;
// If the module hasn't specified an architecture yet, set it to the default
// architecture:
ModuleSP module_sp(GetModule());
if (module_sp) {
if (!module_sp->GetArchitecture().IsValid()) {
arch = Target::GetDefaultArchitecture();
if (!arch.IsValid())
arch.SetTriple(LLDB_ARCH_DEFAULT);
} else
arch = module_sp->GetArchitecture();
ArchSpec curr_arch;
// First, try to find an exact match for the Arch of the Target.
for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
arch.IsExactMatch(curr_arch))
break;
}
// Failing an exact match, try to find a compatible Arch of the Target.
if (arch_idx >= m_header.nfat_arch) {
for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
arch.IsCompatibleMatch(curr_arch))
break;
}
}
if (arch_idx < m_header.nfat_arch) {
DataBufferSP data_sp;
lldb::offset_t data_offset = 0;
return ObjectFile::FindPlugin(
module_sp, file, m_offset + m_fat_archs[arch_idx].offset,
m_fat_archs[arch_idx].size, data_sp, data_offset);
}
}
return ObjectFileSP();
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString ObjectContainerUniversalMachO::GetPluginName() {
return GetPluginNameStatic();
}
uint32_t ObjectContainerUniversalMachO::GetPluginVersion() { return 1; }
size_t ObjectContainerUniversalMachO::GetModuleSpecifications(
const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
lldb::offset_t data_offset, lldb::offset_t file_offset,
lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
const size_t initial_count = specs.GetSize();
DataExtractor data;
data.SetData(data_sp, data_offset, data_sp->GetByteSize());
if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
llvm::MachO::fat_header header;
std::vector<llvm::MachO::fat_arch> fat_archs;
if (ParseHeader(data, header, fat_archs)) {
for (const llvm::MachO::fat_arch &fat_arch : fat_archs) {
const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
if (fat_arch.offset < file_size && file_size > slice_file_offset) {
ObjectFile::GetModuleSpecifications(
file, slice_file_offset, file_size - slice_file_offset, specs);
}
}
}
}
return specs.GetSize() - initial_count;
}

View File

@ -0,0 +1,86 @@
//===-- ObjectContainerUniversalMachO.h -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_ObjectContainerUniversalMachO_h_
#define liblldb_ObjectContainerUniversalMachO_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/SafeMachO.h"
class ObjectContainerUniversalMachO : public lldb_private::ObjectContainer {
public:
ObjectContainerUniversalMachO(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);
~ObjectContainerUniversalMachO() override;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
static void Initialize();
static void Terminate();
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
static lldb_private::ObjectContainer *
CreateInstance(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 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(const lldb_private::DataExtractor &data);
//------------------------------------------------------------------
// Member Functions
//------------------------------------------------------------------
bool ParseHeader() override;
void Dump(lldb_private::Stream *s) const override;
size_t GetNumArchitectures() const override;
bool GetArchitectureAtIndex(uint32_t cpu_idx,
lldb_private::ArchSpec &arch) const override;
lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
protected:
llvm::MachO::fat_header m_header;
std::vector<llvm::MachO::fat_arch> m_fat_archs;
static bool ParseHeader(lldb_private::DataExtractor &data,
llvm::MachO::fat_header &header,
std::vector<llvm::MachO::fat_arch> &fat_archs);
};
#endif // liblldb_ObjectContainerUniversalMachO_h_