================
@@ -0,0 +1,770 @@
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/OperatingSystem.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+
+#include "DynamicLoaderFreeBSDKernel.h"
+#include <memory>
+#include <mutex>
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(DynamicLoaderFreeBSDKernel)
+
+void DynamicLoaderFreeBSDKernel::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance,
+                                DebuggerInit);
+}
+
+void DynamicLoaderFreeBSDKernel::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+llvm::StringRef DynamicLoaderFreeBSDKernel::GetPluginDescriptionStatic() {
+  return "The Dynamic Loader Plugin For FreeBSD Kernel";
+}
+
+static bool is_kernel(Module *module) {
+  if (!module)
+    return false;
+
+  ObjectFile *objfile = module->GetObjectFile();
+  if (!objfile)
+    return false;
+  if (objfile->GetType() != ObjectFile::eTypeExecutable)
+    return false;
+  if (objfile->GetStrata() != ObjectFile::eStrataUnknown &&
+      objfile->GetStrata() != ObjectFile::eStrataUser)
+    return false;
+
+  return true;
+}
+
+static bool is_kmod(Module *module) {
+  if (!module)
+    return false;
+  if (!module->GetObjectFile())
+    return false;
+  ObjectFile *objfile = module->GetObjectFile();
+  if (objfile->GetType() != ObjectFile::eTypeObjectFile &&
+      objfile->GetType() != ObjectFile::eTypeSharedLibrary)
+    return false;
+
+  return true;
+}
+
+static bool is_reloc(Module *module) {
+  if (!module)
+    return false;
+  if (!module->GetObjectFile())
+    return false;
+  ObjectFile *objfile = module->GetObjectFile();
+  if (objfile->GetType() != ObjectFile::eTypeObjectFile)
+    return false;
+
+  return true;
+}
+
+// Instantiate Function of the FreeBSD Kernel Dynamic Loader Plugin called when
+// Register the Plugin
+DynamicLoader *
+DynamicLoaderFreeBSDKernel::CreateInstance(lldb_private::Process *process,
+                                           bool force) {
+  // Check the environment when the plugin is not force loaded
+  Log *log = GetLog(LLDBLog::DynamicLoader);
+  LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::CreateInstance: "
+                 "Try to create instance");
+  if (!force) {
+    Module *exec = process->GetTarget().GetExecutableModulePointer();
+    // Check if the target is kernel
+    if (exec && !is_kernel(exec)) {
+      return nullptr;
+    }
+
+    const llvm::Triple &triple_ref =
+        process->GetTarget().GetArchitecture().GetTriple();
+    if (!triple_ref.isOSFreeBSD()) {
+      return nullptr;
+    }
+  }
+
+  // At this point we have checked the target is a FreeBSD kernel and all we
+  // have to do is to find the kernel address
+  const addr_t kernel_address = FindFreeBSDKernel(process);
+
+  if (CheckForKernelImageAtAddress(process, kernel_address).IsValid())
+    return new DynamicLoaderFreeBSDKernel(process, kernel_address);
+
+  return nullptr;
+}
+
+addr_t
+DynamicLoaderFreeBSDKernel::FindFreeBSDKernel(lldb_private::Process *process) {
+  addr_t kernel_addr = process->GetImageInfoAddress();
+  if (kernel_addr == LLDB_INVALID_ADDRESS)
+    kernel_addr = FindKernelAtLoadAddress(process);
+  return kernel_addr;
+}
+
+// Get the kernel address if the kernel is not loaded with a slide
+addr_t DynamicLoaderFreeBSDKernel::FindKernelAtLoadAddress(
+    lldb_private::Process *process) {
+  Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+
+  if (!is_kernel(exe_module))
+    return LLDB_INVALID_ADDRESS;
+
+  ObjectFile *exe_objfile = exe_module->GetObjectFile();
+
+  if (!exe_objfile->GetBaseAddress().IsValid())
+    return LLDB_INVALID_ADDRESS;
+
+  if (CheckForKernelImageAtAddress(
+          process, exe_objfile->GetBaseAddress().GetFileAddress())
+          .IsValid())
+    return exe_objfile->GetBaseAddress().GetFileAddress();
+
+  return LLDB_INVALID_ADDRESS;
+}
+
+// Read ELF header from memry and return
+bool DynamicLoaderFreeBSDKernel::ReadELFHeader(Process *process,
+                                               lldb::addr_t addr,
+                                               llvm::ELF::Elf32_Ehdr &header,
+                                               bool *read_error) {
+  Status error;
+  if (read_error)
+    *read_error = false;
+
+  if (process->ReadMemory(addr, &header, sizeof(header), error) !=
+      sizeof(header)) {
+    if (read_error)
+      *read_error = true;
+    return false;
+  }
+
+  if (!header.checkMagic())
+    return false;
+
+  return true;
+}
+
+// Check the correctness of Kernel and return UUID
+lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress(
+    Process *process, lldb::addr_t addr, bool *read_error) {
+  Log *log = GetLog(LLDBLog::DynamicLoader);
+
+  if (addr == LLDB_INVALID_ADDRESS) {
+    if (read_error)
+      *read_error = true;
+    return UUID();
+  }
+
+  LLDB_LOGF(log,
+            "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
+            "looking for kernel binary at 0x%" PRIx64,
+            addr);
+
+  llvm::ELF::Elf32_Ehdr header;
+  if (!ReadELFHeader(process, addr, header))
+    return UUID();
----------------
bulbazord wrote:

Should we not also set `read_error` here too? and some of the places below.

https://github.com/llvm/llvm-project/pull/67106
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to