Path: blob/main/contrib/llvm-project/lldb/source/Expression/ObjectFileJIT.cpp
39587 views
//===-- ObjectFileJIT.cpp -------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/ADT/StringRef.h"910#include "lldb/Core/Module.h"11#include "lldb/Core/ModuleSpec.h"12#include "lldb/Core/PluginManager.h"13#include "lldb/Core/Section.h"14#include "lldb/Expression/ObjectFileJIT.h"15#include "lldb/Target/Process.h"16#include "lldb/Target/SectionLoadList.h"17#include "lldb/Target/Target.h"18#include "lldb/Utility/ArchSpec.h"19#include "lldb/Utility/DataBuffer.h"20#include "lldb/Utility/DataBufferHeap.h"21#include "lldb/Utility/FileSpec.h"22#include "lldb/Utility/FileSpecList.h"23#include "lldb/Utility/Log.h"24#include "lldb/Utility/Timer.h"25#include "lldb/Utility/UUID.h"2627using namespace lldb;28using namespace lldb_private;2930char ObjectFileJIT::ID;3132void ObjectFileJIT::Initialize() {33PluginManager::RegisterPlugin(GetPluginNameStatic(),34GetPluginDescriptionStatic(), CreateInstance,35CreateMemoryInstance, GetModuleSpecifications);36}3738void ObjectFileJIT::Terminate() {39PluginManager::UnregisterPlugin(CreateInstance);40}4142ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,43DataBufferSP data_sp,44lldb::offset_t data_offset,45const FileSpec *file,46lldb::offset_t file_offset,47lldb::offset_t length) {48// JIT'ed object file is backed by the ObjectFileJITDelegate, never read from49// a file50return nullptr;51}5253ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp,54WritableDataBufferSP data_sp,55const ProcessSP &process_sp,56lldb::addr_t header_addr) {57// JIT'ed object file is backed by the ObjectFileJITDelegate, never read from58// memory59return nullptr;60}6162size_t ObjectFileJIT::GetModuleSpecifications(63const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,64lldb::offset_t data_offset, lldb::offset_t file_offset,65lldb::offset_t length, lldb_private::ModuleSpecList &specs) {66// JIT'ed object file can't be read from a file on disk67return 0;68}6970ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,71const ObjectFileJITDelegateSP &delegate_sp)72: ObjectFile(module_sp, nullptr, 0, 0, DataBufferSP(), 0), m_delegate_wp() {73if (delegate_sp) {74m_delegate_wp = delegate_sp;75m_data.SetByteOrder(delegate_sp->GetByteOrder());76m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize());77}78}7980ObjectFileJIT::~ObjectFileJIT() = default;8182bool ObjectFileJIT::ParseHeader() {83// JIT code is never in a file, nor is it required to have any header84return false;85}8687ByteOrder ObjectFileJIT::GetByteOrder() const { return m_data.GetByteOrder(); }8889bool ObjectFileJIT::IsExecutable() const { return false; }9091uint32_t ObjectFileJIT::GetAddressByteSize() const {92return m_data.GetAddressByteSize();93}9495void ObjectFileJIT::ParseSymtab(Symtab &symtab) {96ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());97if (delegate_sp)98delegate_sp->PopulateSymtab(this, symtab);99}100101bool ObjectFileJIT::IsStripped() {102return false; // JIT code that is in a module is never stripped103}104105void ObjectFileJIT::CreateSections(SectionList &unified_section_list) {106if (!m_sections_up) {107m_sections_up = std::make_unique<SectionList>();108ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());109if (delegate_sp) {110delegate_sp->PopulateSectionList(this, *m_sections_up);111unified_section_list = *m_sections_up;112}113}114}115116void ObjectFileJIT::Dump(Stream *s) {117ModuleSP module_sp(GetModule());118if (module_sp) {119std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());120s->Printf("%p: ", static_cast<void *>(this));121s->Indent();122s->PutCString("ObjectFileJIT");123124if (ArchSpec arch = GetArchitecture())125*s << ", arch = " << arch.GetArchitectureName();126127s->EOL();128129SectionList *sections = GetSectionList();130if (sections)131sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,132UINT32_MAX);133134if (m_symtab_up)135m_symtab_up->Dump(s, nullptr, eSortOrderNone);136}137}138139UUID ObjectFileJIT::GetUUID() {140// TODO: maybe get from delegate, not needed for first pass141return UUID();142}143144uint32_t ObjectFileJIT::GetDependentModules(FileSpecList &files) {145// JIT modules don't have dependencies, but they could146// if external functions are called and we know where they are147files.Clear();148return 0;149}150151lldb_private::Address ObjectFileJIT::GetEntryPointAddress() {152return Address();153}154155lldb_private::Address ObjectFileJIT::GetBaseAddress() { return Address(); }156157ObjectFile::Type ObjectFileJIT::CalculateType() { return eTypeJIT; }158159ObjectFile::Strata ObjectFileJIT::CalculateStrata() { return eStrataJIT; }160161ArchSpec ObjectFileJIT::GetArchitecture() {162if (ObjectFileJITDelegateSP delegate_sp = m_delegate_wp.lock())163return delegate_sp->GetArchitecture();164return ArchSpec();165}166167bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,168bool value_is_offset) {169size_t num_loaded_sections = 0;170SectionList *section_list = GetSectionList();171if (section_list) {172const size_t num_sections = section_list->GetSize();173// "value" is an offset to apply to each top level segment174for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {175// Iterate through the object file sections to find all of the sections176// that size on disk (to avoid __PAGEZERO) and load them177SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));178if (section_sp && section_sp->GetFileSize() > 0 &&179!section_sp->IsThreadSpecific()) {180if (target.GetSectionLoadList().SetSectionLoadAddress(181section_sp, section_sp->GetFileAddress() + value))182++num_loaded_sections;183}184}185}186return num_loaded_sections > 0;187}188189size_t ObjectFileJIT::ReadSectionData(lldb_private::Section *section,190lldb::offset_t section_offset, void *dst,191size_t dst_len) {192lldb::offset_t file_size = section->GetFileSize();193if (section_offset < file_size) {194size_t src_len = file_size - section_offset;195if (src_len > dst_len)196src_len = dst_len;197const uint8_t *src =198((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset;199200memcpy(dst, src, src_len);201return src_len;202}203return 0;204}205206size_t207ObjectFileJIT::ReadSectionData(lldb_private::Section *section,208lldb_private::DataExtractor §ion_data) {209if (section->GetFileSize()) {210const void *src = (void *)(uintptr_t)section->GetFileOffset();211212DataBufferSP data_sp =213std::make_shared<DataBufferHeap>(src, section->GetFileSize());214section_data.SetData(data_sp, 0, data_sp->GetByteSize());215section_data.SetByteOrder(GetByteOrder());216section_data.SetAddressByteSize(GetAddressByteSize());217return section_data.GetByteSize();218}219section_data.Clear();220return 0;221}222223224