VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGPlugInLinuxModuleCodeTmpl.cpp.h@ 90408

Last change on this file since 90408 was 90408, checked in by vboxsync, 4 years ago

Debugger/DBGPlugInLinux: Fix loaded kernel module processing for kernels starting with 4.5.0, the struct module layout has changed significantly.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 KB
Line 
1/* $Id: DBGPlugInLinuxModuleCodeTmpl.cpp.h 90408 2021-07-29 13:21:10Z vboxsync $ */
2/** @file
3 * DBGPlugInLinux - Code template for struct module processing.
4 */
5
6/*
7 * Copyright (C) 2019-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Defined Constants And Macros *
21*********************************************************************************************************************************/
22#ifndef LNX_MK_VER
23# define LNX_MK_VER(major, minor, build) (((major) << 22) | ((minor) << 12) | (build))
24#endif
25#if LNX_64BIT
26# define LNX_ULONG_T uint64_t
27#else
28# define LNX_ULONG_T uint32_t
29#endif
30#if LNX_64BIT
31# define PAD32ON64(seq) uint32_t RT_CONCAT(u32Padding,seq);
32#else
33# define PAD32ON64(seq)
34#endif
35
36
37/*********************************************************************************************************************************
38* Structures and Typedefs *
39*********************************************************************************************************************************/
40#if LNX_VER >= LNX_MK_VER(2,6,11)
41typedef struct RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX)
42{
43 LNX_PTR_T uPtrKName;
44# if LNX_VER < LNX_MK_VER(2,6,24)
45 char name[20];
46# endif
47# if LNX_VER < LNX_MK_VER(2,6,27)
48 int32_t cRefs;
49# if LNX_VER >= LNX_MK_VER(2,6,24)
50 PAD32ON64(0)
51# endif
52# endif
53 LNX_PTR_T uPtrNext;
54 LNX_PTR_T uPtrPrev;
55 LNX_PTR_T uPtrParent; /**< struct kobject pointer */
56 LNX_PTR_T uPtrKset; /**< struct kset pointer */
57 LNX_PTR_T uPtrKtype; /**< struct kobj_type pointer */
58 LNX_PTR_T uPtrDirEntry; /**< struct dentry pointer; 2.6.23+ sysfs_dirent. */
59# if LNX_VER >= LNX_MK_VER(2,6,17) && LNX_VER < LNX_MK_VER(2,6,24)
60 LNX_PTR_T aPtrWaitQueueHead[3];
61# endif
62# if LNX_VER >= LNX_MK_VER(2,6,27)
63 int32_t cRefs;
64 uint32_t uStateStuff;
65# elif LNX_VER >= LNX_MK_VER(2,6,25)
66 LNX_ULONG_T uStateStuff;
67# endif
68 /* non-kobject: */
69 LNX_PTR_T uPtrModule; /**< struct module pointer. */
70# if LNX_VER >= LNX_MK_VER(2,6,21)
71 LNX_PTR_T uPtrDriverDir; /**< Points to struct kobject. */
72# endif
73# if LNX_VER >= LNX_MK_VER(4,5,0)
74 LNX_PTR_T uPtrMp;
75 LNX_PTR_T uPtrCompletion; /**< Points to struct completion. */
76# endif
77} RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX);
78#endif
79#if LNX_VER == LNX_MK_VER(2,6,24) && LNX_64BIT
80AssertCompileMemberOffset(RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX), uPtrParent, 32);
81AssertCompileMemberOffset(RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX), uPtrParent, 32);
82AssertCompileSize(RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX), 80);
83#endif
84
85
86#if LNX_VER >= LNX_MK_VER(4,5,0)
87/**
88 * Red black tree node.
89 */
90typedef struct RT_CONCAT(LNXRBNODE,LNX_SUFFIX)
91{
92 LNX_ULONG_T uRbParentColor;
93 LNX_PTR_T uPtrRbRight;
94 LNX_PTR_T uPtrRbLeft;
95} RT_CONCAT(LNXRBNODE,LNX_SUFFIX);
96
97
98/**
99 * Latch tree node.
100 */
101typedef struct RT_CONCAT(LNXLATCHTREENODE,LNX_SUFFIX)
102{
103 RT_CONCAT(LNXRBNODE,LNX_SUFFIX) aNode[2];
104} RT_CONCAT(LNXLATCHTREENODE,LNX_SUFFIX);
105
106
107/**
108 * Module tree node.
109 */
110typedef struct RT_CONCAT(LNXMODTREENODE,LNX_SUFFIX)
111{
112 LNX_PTR_T uPtrKMod;
113 RT_CONCAT(LNXLATCHTREENODE,LNX_SUFFIX) Node;
114} RT_CONCAT(LNXMODTREENODE,LNX_SUFFIX);
115
116
117/**
118 * Module layout.
119 */
120typedef struct RT_CONCAT(LNXKMODLAYOUT,LNX_SUFFIX)
121{
122 LNX_PTR_T uPtrBase; /**< Base pointer to text and data. */
123 uint32_t cb; /**< Size of the module. */
124 uint32_t cbText; /**< Size of the text section. */
125 uint32_t cbRo; /**< Size of the readonly portion (text + ro data). */
126 RT_CONCAT(LNXMODTREENODE,LNX_SUFFIX) ModTreeNd; /**< Only available when CONFIG_MODULES_TREE_LOOKUP is set (default). */
127} RT_CONCAT(LNXKMODLAYOUT,LNX_SUFFIX);
128
129
130/**
131 * Mutex.
132 */
133typedef struct RT_CONCAT(LNXMUTEX,LNX_SUFFIX)
134{
135 LNX_ULONG_T uOwner;
136 uint32_t wait_lock; /**< Actually spinlock_t */
137 PAD32ON64(0)
138 LNX_PTR_T uWaitLstPtrNext;
139 LNX_PTR_T uWaitLstPtrPrev;
140} RT_CONCAT(LNXMUTEX,LNX_SUFFIX);
141#endif
142
143
144/**
145 * Maps to the start of struct module in include/linux/module.h.
146 */
147typedef struct RT_CONCAT(LNXKMODULE,LNX_SUFFIX)
148{
149#if LNX_VER >= LNX_MK_VER(4,5,0)
150 /* Completely new layout to not feed the spaghetti dragons further. */
151 int32_t state;
152 PAD32ON64(0)
153 LNX_PTR_T uPtrNext;
154 LNX_PTR_T uPtrPrev;
155 char name[64 - sizeof(LNX_PTR_T)];
156
157 RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX) mkobj;
158 LNX_PTR_T uPtrModInfoAttrs; /**< Points to struct module_attribute. */
159 LNX_PTR_T uPtrVersion; /**< String pointers. */
160 LNX_PTR_T uPtrSrcVersion; /**< String pointers. */
161 LNX_PTR_T uPtrHolderDir; /**< Points to struct kobject. */
162
163 /** @name Exported Symbols
164 * @{ */
165 LNX_PTR_T uPtrSyms; /**< Array of struct kernel_symbol. */
166 LNX_PTR_T uPtrCrcs; /**< unsigned long array */
167 uint32_t num_syms;
168 /** @} */
169
170 /** @name Kernel parameters
171 * @{ */
172 RT_CONCAT(LNXMUTEX,LNX_SUFFIX) Mtx; /**< Mutex. */
173 LNX_PTR_T uPtrKp; /**< Points to struct kernel_param */
174 uint32_t num_kp;
175 /** @} */
176
177 /** @name GPL Symbols
178 * @{ */
179 uint32_t num_gpl_syms;
180 LNX_PTR_T uPtrGplSyms; /**< Array of struct kernel_symbol. */
181 LNX_PTR_T uPtrGplCrcs; /**< unsigned long array */
182 /** @} */
183
184 /** @name Unused symbols
185 * @{ */
186 LNX_PTR_T uPtrUnusedSyms; /**< Array of struct kernel_symbol. */
187 LNX_PTR_T uPtrUnusedCrcs; /**< unsigned long array */
188 uint32_t num_unused_syms;
189 uint32_t num_unused_gpl_syms;
190 LNX_PTR_T uPtrUnusedGplSyms; /**< Array of struct kernel_symbol. */
191 LNX_PTR_T uPtrUnusedGplCrcs; /**< unsigned long array */
192 /** @} */
193
194 uint8_t sig_ok;
195 uint8_t async_probe_requested;
196
197 /** @name Future GPL Symbols
198 * @{ */
199 LNX_PTR_T uPtrGplFutureSyms; /**< Array of struct kernel_symbol. */
200 LNX_PTR_T uPtrGplFutureCrcs; /**< unsigned long array */
201 uint32_t num_gpl_future_syms;
202 /** @} */
203
204 /** @name Exception table.
205 * @{ */
206 uint32_t num_exentries;
207 LNX_PTR_T uPtrEntries; /**< struct exception_table_entry array. */
208 /** @} */
209
210 LNX_PTR_T pfnInit;
211 RT_CONCAT(LNXKMODLAYOUT,LNX_SUFFIX) CoreLayout; /**< Should be aligned on a cache line. */
212 RT_CONCAT(LNXKMODLAYOUT,LNX_SUFFIX) InitLayout;
213
214#elif LNX_VER >= LNX_MK_VER(2,5,48)
215 /*
216 * This first part is mostly always the same.
217 */
218 int32_t state;
219 PAD32ON64(0)
220 LNX_PTR_T uPtrNext;
221 LNX_PTR_T uPtrPrev;
222 char name[64 - sizeof(LNX_PTR_T)];
223
224 /*
225 * Here be spaghetti dragons.
226 */
227# if LNX_VER >= LNX_MK_VER(2,6,11)
228 RT_CONCAT(LNXMODKOBJECT,LNX_SUFFIX) mkobj; /**< Was just kobj for a while. */
229 LNX_PTR_T uPtrParamAttrs; /**< Points to struct module_param_attrs. */
230# if LNX_VER >= LNX_MK_VER(2,6,17)
231 LNX_PTR_T uPtrModInfoAttrs; /**< Points to struct module_attribute. */
232# endif
233# if LNX_VER == LNX_MK_VER(2,6,20)
234 LNX_PTR_T uPtrDriverDir; /**< Points to struct kobject. */
235# elif LNX_VER >= LNX_MK_VER(2,6,21)
236 LNX_PTR_T uPtrHolderDir; /**< Points to struct kobject. */
237# endif
238# if LNX_VER >= LNX_MK_VER(2,6,13)
239 LNX_PTR_T uPtrVersion; /**< String pointers. */
240 LNX_PTR_T uPtrSrcVersion; /**< String pointers. */
241# endif
242# else
243# if LNX_VER >= LNX_MK_VER(2,6,7)
244 LNX_PTR_T uPtrMkObj;
245# endif
246# if LNX_VER >= LNX_MK_VER(2,6,10)
247 LNX_PTR_T uPtrParamsKobject;
248# endif
249# endif
250
251 /** @name Exported Symbols
252 * @{ */
253# if LNX_VER < LNX_MK_VER(2,5,67)
254 LNX_PTR_T uPtrSymsNext, uPtrSymsPrev, uPtrSymsOwner;
255# if LNX_VER >= LNX_MK_VER(2,5,55)
256 int32_t syms_gplonly;
257 uint32_t num_syms;
258# else
259 uint32_t num_syms;
260 PAD32ON64(1)
261# endif
262# endif
263 LNX_PTR_T uPtrSyms; /**< Array of struct kernel_symbol. */
264# if LNX_VER >= LNX_MK_VER(2,5,67)
265 uint32_t num_syms;
266 PAD32ON64(1)
267# endif
268# if LNX_VER >= LNX_MK_VER(2,5,60)
269 LNX_PTR_T uPtrCrcs; /**< unsigned long array */
270# endif
271 /** @} */
272
273 /** @name GPL Symbols
274 * @since 2.5.55
275 * @{ */
276# if LNX_VER >= LNX_MK_VER(2,5,55)
277# if LNX_VER < LNX_MK_VER(2,5,67)
278 LNX_PTR_T uPtrGplSymsNext, uPtrGplSymsPrev, uPtrGplSymsOwner;
279# if LNX_VER >= LNX_MK_VER(2,5,55)
280 int32_t gpl_syms_gplonly;
281 uint32_t num_gpl_syms;
282# else
283 uint32_t num_gpl_syms;
284 PAD32ON64(2)
285# endif
286# endif
287 LNX_PTR_T uPtrGplSyms; /**< Array of struct kernel_symbol. */
288# if LNX_VER >= LNX_MK_VER(2,5,67)
289 uint32_t num_gpl_syms;
290 PAD32ON64(2)
291# endif
292# if LNX_VER >= LNX_MK_VER(2,5,60)
293 LNX_PTR_T uPtrGplCrcs; /**< unsigned long array */
294# endif
295# endif /* > 2.5.55 */
296 /** @} */
297
298 /** @name Unused Exported Symbols
299 * @since 2.6.18
300 * @{ */
301# if LNX_VER >= LNX_MK_VER(2,6,18)
302 LNX_PTR_T uPtrUnusedSyms; /**< Array of struct kernel_symbol. */
303 uint32_t num_unused_syms;
304 PAD32ON64(4)
305 LNX_PTR_T uPtrUnusedCrcs; /**< unsigned long array */
306# endif
307 /** @} */
308
309 /** @name Unused GPL Symbols
310 * @since 2.6.18
311 * @{ */
312# if LNX_VER >= LNX_MK_VER(2,6,18)
313 LNX_PTR_T uPtrUnusedGplSyms; /**< Array of struct kernel_symbol. */
314 uint32_t num_unused_gpl_syms;
315 PAD32ON64(5)
316 LNX_PTR_T uPtrUnusedGplCrcs; /**< unsigned long array */
317# endif
318 /** @} */
319
320 /** @name Future GPL Symbols
321 * @since 2.6.17
322 * @{ */
323# if LNX_VER >= LNX_MK_VER(2,6,17)
324 LNX_PTR_T uPtrGplFutureSyms; /**< Array of struct kernel_symbol. */
325 uint32_t num_gpl_future_syms;
326 PAD32ON64(3)
327 LNX_PTR_T uPtrGplFutureCrcs; /**< unsigned long array */
328# endif
329 /** @} */
330
331 /** @name Exception table.
332 * @{ */
333# if LNX_VER < LNX_MK_VER(2,5,67)
334 LNX_PTR_T uPtrXcptTabNext, uPtrXcptTabPrev;
335# endif
336 uint32_t num_exentries;
337 PAD32ON64(6)
338 LNX_PTR_T uPtrEntries; /**< struct exception_table_entry array. */
339 /** @} */
340
341 /*
342 * Hopefully less spaghetti from here on...
343 */
344 LNX_PTR_T pfnInit;
345 LNX_PTR_T uPtrModuleInit;
346 LNX_PTR_T uPtrModuleCore;
347 LNX_ULONG_T cbInit;
348 LNX_ULONG_T cbCore;
349# if LNX_VER >= LNX_MK_VER(2,5,74)
350 LNX_ULONG_T cbInitText;
351 LNX_ULONG_T cbCoreText;
352# endif
353
354# if LNX_VER >= LNX_MK_VER(2,6,18)
355 LNX_PTR_T uPtrUnwindInfo;
356# endif
357#else
358 uint32_t structure_size;
359
360#endif
361} RT_CONCAT(LNXKMODULE,LNX_SUFFIX);
362
363# if LNX_VER == LNX_MK_VER(2,6,24) && LNX_64BIT
364AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), uPtrParamAttrs, 160);
365AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), num_syms, 208);
366AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), num_gpl_syms, 232);
367AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), num_unused_syms, 256);
368AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), num_unused_gpl_syms, 280);
369AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), num_gpl_future_syms, 304);
370AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), num_exentries, 320);
371AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), uPtrModuleCore, 352);
372AssertCompileMemberOffset(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), uPtrUnwindInfo, 392);
373#endif
374
375
376
377/**
378 * Version specific module processing code.
379 */
380static uint64_t RT_CONCAT(dbgDiggerLinuxLoadModule,LNX_SUFFIX)(PDBGDIGGERLINUX pThis, PUVM pUVM, PDBGFADDRESS pAddrModule)
381{
382 RT_CONCAT(LNXKMODULE,LNX_SUFFIX) Module;
383
384 int rc = DBGFR3MemRead(pUVM, 0, DBGFR3AddrSub(pAddrModule, RT_UOFFSETOF(RT_CONCAT(LNXKMODULE,LNX_SUFFIX), uPtrNext)),
385 &Module, sizeof(Module));
386 if (RT_FAILURE(rc))
387 {
388 LogRelFunc(("Failed to read module structure at %#RX64: %Rrc\n", pAddrModule->FlatPtr, rc));
389 return 0;
390 }
391
392 /*
393 * Check the module name.
394 */
395#if LNX_VER >= LNX_MK_VER(2,5,48)
396 const char *pszName = Module.name;
397 size_t const cbName = sizeof(Module.name);
398#else
399
400#endif
401 if ( RTStrNLen(pszName, cbName) >= cbName
402 || RT_FAILURE(RTStrValidateEncoding(pszName))
403 || *pszName == '\0')
404 {
405 LogRelFunc(("%#RX64: Bad name: %.*Rhxs\n", pAddrModule->FlatPtr, (int)cbName, pszName));
406 return 0;
407 }
408
409 /*
410 * Create a simple module for it.
411 */
412#if LNX_VER >= LNX_MK_VER(4,5,0)
413 LNX_PTR_T uPtrModuleCore = Module.CoreLayout.uPtrBase;
414 uint32_t cbCore = Module.CoreLayout.cb;
415#else
416 LNX_PTR_T uPtrModuleCore = Module.uPtrModuleCore;
417 uint32_t cbCore = (uint32_t)Module.cbCore;
418#endif
419 LogRelFunc((" %#RX64: %#RX64 LB %#RX32 %s\n", pAddrModule->FlatPtr, uPtrModuleCore, cbCore, pszName));
420
421 RTDBGMOD hDbgMod;
422 rc = RTDbgModCreate(&hDbgMod, pszName, cbCore, 0 /*fFlags*/);
423 if (RT_SUCCESS(rc))
424 {
425 rc = RTDbgModSetTag(hDbgMod, DIG_LNX_MOD_TAG);
426 if (RT_SUCCESS(rc))
427 {
428 RTDBGAS hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
429 rc = RTDbgAsModuleLink(hAs, hDbgMod, uPtrModuleCore, RTDBGASLINK_FLAGS_REPLACE /*fFlags*/);
430 RTDbgAsRelease(hAs);
431 }
432 else
433 LogRel(("DbgDiggerOs2: RTDbgModSetTag failed: %Rrc\n", rc));
434 RTDbgModRelease(hDbgMod);
435 }
436
437 RT_NOREF(pThis);
438 return Module.uPtrNext;
439}
440
441#undef LNX_VER
442#undef LNX_SUFFIX
443#undef LNX_ULONG_T
444#undef PAD32ON64
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette