[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

Ed Maste via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 22 15:55:14 PDT 2023


================
@@ -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)
----------------
emaste wrote:

We can identify a FreeBSD kernel by the bogus PT_INTERP it specifies:
```
  INTERP         0x000238 0xffffffff80200238 0x0000000000200238 0x00000d 0x00000d R   0x1
      [Requesting program interpreter: /red/herring]
```

There are a bunch of ELF notes, but nothing that would uniquely identify it as a FreeBSD kernel. I suspect the Xen notes are unique to kernels, but won't be present if built without Xen support I guess. (As an aside I guess we should teach llvm-readelf about those note types.)

```
Displaying notes found in: .note.gnu.build-id
  Owner                Data size        Description
  GNU                  0x00000014       NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 984b7de7a87159b85761dc6bdc9645e28407e890

Displaying notes found in: .note.Xen
  Owner                Data size        Description
  Xen                  0x00000008       Unknown note type: (0x00000006)
   description data: 46 72 65 65 42 53 44 00
  Xen                  0x00000009       Unknown note type: (0x00000007)
   description data: 30 78 31 33 64 36 37 37 00
  Xen                  0x00000008       Unknown note type: (0x00000005)
   description data: 78 65 6e 2d 33 2e 30 00
  Xen                  0x00000008       Unknown note type: (0x00000003)
   description data: 00 00 00 80 ff ff ff ff
  Xen                  0x00000008       Unknown note type: (0x00000004)
   description data: 00 00 00 00 00 00 00 00
  Xen                  0x00000008       NT_VERSION (version)
   description data: 00 b0 03 81 ff ff ff ff
  Xen                  0x00000008       NT_ARCH (architecture)
   description data: 00 a0 03 81 ff ff ff ff
  Xen                  0x00000008       Unknown note type: (0x0000000c)
   description data: 00 00 00 00 00 80 ff ff
  Xen                  0x0000005e       Unknown note type: (0x0000000a)
   description data: 77 72 69 74 61 62 6c 65 5f 64 65 73 63 72 69 70 74 6f 72 5f 74 61 62 6c 65 73 7c 61 75 74 6f 5f 74 72 61 6e 73 6c 61 74 65 64 5f 70 68 79 73 6d 61 70 7c 73 75 70 65 72 76 69 73 6f 72 5f 6d 6f 64 65 5f 6b 65 72 6e 65 6c 7c 68 76 6d 5f 63 61 6c 6c 62 61 63 6b 5f 76 65 63 74 6f 72 00
  Xen                  0x00000004       Unknown note type: (0x00000009)
   description data: 79 65 73 00
  Xen                  0x00000008       Unknown note type: (0x0000000d)
   description data: 01 00 00 00 01 00 00 00
  Xen                  0x00000008       Unknown note type: (0x00000008)
   description data: 67 65 6e 65 72 69 63 00
  Xen                  0x00000004       Unknown note type: (0x0000000e)
   description data: 00 00 00 00
  Xen                  0x00000004       Unknown note type: (0x0000000b)
   description data: 79 65 73 00
  Xen                  0x00000004       Unknown note type: (0x00000012)
   description data: 30 b0 03 01
```

Oh, I guess a section named `set_sysinit_set` could be a decent indication.
```
There are 61 section headers, starting at offset 0x19a0c38:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        ffffffff802002a8 0002a8 00000d 00   A  0   0  1
  [ 2] .hash             HASH            ffffffff802002b8 0002b8 02dc10 04   A  4   0  4
...
  [49] set_sysinit_set   PROGBITS        ffffffff81746070 1546070 003878 00  WA  0   0  8
```

There are a bunch of `set_*_set` sections but the SYSINT linker set is always going to be present.

https://github.com/llvm/llvm-project/pull/67106


More information about the lldb-commits mailing list