Skip to content

[lldb][AIX] Added new plugin AIX-DYLD (Dynamic Loader) Base Support #115714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lldb/source/Plugins/DynamicLoader/AIX-DYLD/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
add_lldb_library(lldbPluginDynamicLoaderAIXDYLD PLUGIN
DynamicLoaderAIXDYLD.cpp

LINK_LIBS
lldbCore
lldbTarget
LINK_COMPONENTS
Support
)
146 changes: 146 additions & 0 deletions lldb/source/Plugins/DynamicLoader/AIX-DYLD/DynamicLoaderAIXDYLD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//===-- DynamicLoaderAIXDYLD.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DynamicLoaderAIXDYLD.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlanStepInstruction.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(DynamicLoaderAIXDYLD)

DynamicLoaderAIXDYLD::DynamicLoaderAIXDYLD(Process *process)
: DynamicLoader(process) {}

DynamicLoaderAIXDYLD::~DynamicLoaderAIXDYLD() = default;

void DynamicLoaderAIXDYLD::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance);
}

void DynamicLoaderAIXDYLD::Terminate() {}

llvm::StringRef DynamicLoaderAIXDYLD::GetPluginDescriptionStatic() {
return "Dynamic loader plug-in that watches for shared library "
"loads/unloads in AIX processes.";
}

DynamicLoader *DynamicLoaderAIXDYLD::CreateInstance(Process *process,
bool force) {
bool should_create = force;
if (!should_create) {
const llvm::Triple &triple_ref =
process->GetTarget().GetArchitecture().GetTriple();
if (triple_ref.getOS() == llvm::Triple::AIX)
should_create = true;
}

if (should_create)
return new DynamicLoaderAIXDYLD(process);

return nullptr;
}

void DynamicLoaderAIXDYLD::OnLoadModule(lldb::ModuleSP module_sp,
const ModuleSpec module_spec,
lldb::addr_t module_addr) {

// Resolve the module unless we already have one.
if (!module_sp) {
Status error;
module_sp = m_process->GetTarget().GetOrCreateModule(
module_spec, true /* notify */, &error);
if (error.Fail())
return;
}

m_loaded_modules[module_sp] = module_addr;
UpdateLoadedSectionsCommon(module_sp, module_addr, false);
ModuleList module_list;
module_list.Append(module_sp);
m_process->GetTarget().ModulesDidLoad(module_list);
}

void DynamicLoaderAIXDYLD::OnUnloadModule(lldb::addr_t module_addr) {
Address resolved_addr;
if (!m_process->GetTarget().ResolveLoadAddress(module_addr, resolved_addr))
return;

ModuleSP module_sp = resolved_addr.GetModule();
if (module_sp) {
m_loaded_modules.erase(module_sp);
UnloadSectionsCommon(module_sp);
ModuleList module_list;
module_list.Append(module_sp);
m_process->GetTarget().ModulesDidUnload(module_list, false);
}
}

lldb::addr_t DynamicLoaderAIXDYLD::GetLoadAddress(ModuleSP executable) {
// First, see if the load address is already cached.
auto it = m_loaded_modules.find(executable);
if (it != m_loaded_modules.end() && it->second != LLDB_INVALID_ADDRESS)
return it->second;

lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;

// Second, try to get it through the process plugins. For a remote process,
// the remote platform will be responsible for providing it.
FileSpec file_spec(executable->GetPlatformFileSpec());
bool is_loaded = false;
Status status =
m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
// Servers other than lldb server could respond with a bogus address.
if (status.Success() && is_loaded && load_addr != LLDB_INVALID_ADDRESS) {
m_loaded_modules[executable] = load_addr;
return load_addr;
}
return LLDB_INVALID_ADDRESS;
}

void DynamicLoaderAIXDYLD::DidAttach() {}

void DynamicLoaderAIXDYLD::DidLaunch() {
Log *log = GetLog(LLDBLog::DynamicLoader);
LLDB_LOGF(log, "DynamicLoaderAIXDYLD::%s()", __FUNCTION__);

ModuleSP executable = GetTargetExecutable();
if (!executable.get())
return;

lldb::addr_t load_addr = GetLoadAddress(executable);
if (load_addr != LLDB_INVALID_ADDRESS) {
// Update the loaded sections so that the breakpoints can be resolved.
UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);

ModuleList module_list;
module_list.Append(executable);
m_process->GetTarget().ModulesDidLoad(module_list);
auto error = m_process->LoadModules();
LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
}
}

Status DynamicLoaderAIXDYLD::CanLoadImage() { return Status(); }

ThreadPlanSP DynamicLoaderAIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
bool stop) {
// FIXME
return ThreadPlanSP();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===-- DynamicLoaderAIXDYLD.h ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_AIX_DYLD_DYNAMICLOADERAIXDYLD_H
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_AIX_DYLD_DYNAMICLOADERAIXDYLD_H

#include "lldb/Target/DynamicLoader.h"
#include "lldb/lldb-forward.h"

#include <map>

namespace lldb_private {

class DynamicLoaderAIXDYLD : public DynamicLoader {
public:
DynamicLoaderAIXDYLD(Process *process);

~DynamicLoaderAIXDYLD() override;

static void Initialize();
static void Terminate();
static llvm::StringRef GetPluginNameStatic() { return "aix-dyld"; }
static llvm::StringRef GetPluginDescriptionStatic();

static DynamicLoader *CreateInstance(Process *process, bool force);

void OnLoadModule(lldb::ModuleSP module_sp, const ModuleSpec module_spec,
lldb::addr_t module_addr);
void OnUnloadModule(lldb::addr_t module_addr);

void DidAttach() override;
void DidLaunch() override;
Status CanLoadImage() override;
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
bool stop) override;

llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

protected:
lldb::addr_t GetLoadAddress(lldb::ModuleSP executable);

private:
std::map<lldb::ModuleSP, lldb::addr_t> m_loaded_modules;
};

} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_AIX_DYLD_DYNAMICLOADERWAIXDYLD_H
1 change: 1 addition & 0 deletions lldb/source/Plugins/DynamicLoader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ add_subdirectory(POSIX-DYLD)
add_subdirectory(Static)
add_subdirectory(Hexagon-DYLD)
add_subdirectory(Windows-DYLD)
add_subdirectory(AIX-DYLD)
add_subdirectory(wasm-DYLD)
Loading