Skip to content

Commit a97f6c4

Browse files
committed
Associate types with program
I originally envisioned types as dumb descriptors. This mostly works for C because in C, types are fairly simple. However, even then the drgn_program_member_info() API is awkward. You should be able to look up a member directly from a type, but we need the program for caching purposes. This has also held me back from adding offsetof() or has_member() APIs. Things get even messier with C++. C++ template parameters can be objects (e.g., template <int N>). Such parameters would best be represented by a drgn object, which we need a drgn program for. Static members are a similar case. So, let's reimagine types as being owned by a program. This has a few parts: 1. In libdrgn, simple types are now created by factory functions, drgn_foo_type_create(). 2. To handle their variable length fields, compound types, enum types, and function types are constructed with a "builder" API. 3. Simple types are deduplicated. 4. The Python type factory functions are replaced by methods of the Program class. 5. While we're changing the API, the parameters to pointer_type() and array_type() are reordered to be more logical (and to allow pointer_type() to take a default size of None for the program's default pointer size). 6. Likewise, the type factory methods take qualifiers as a keyword argument only. A big part of this change is updating the tests and splitting up large test cases into smaller ones in a few places. Signed-off-by: Omar Sandoval <[email protected]>
1 parent c31208f commit a97f6c4

26 files changed

+6535
-4814
lines changed

_drgn.pyi

Lines changed: 279 additions & 236 deletions
Large diffs are not rendered by default.

docs/api_reference.rst

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Programs
77
--------
88

99
.. drgndoc:: Program
10+
:exclude: (void|int|bool|float|complex|struct|union|class|enum|typedef|pointer|array|function)_type
1011
.. drgndoc:: ProgramFlags
1112
.. drgndoc:: FindObjectFlags
1213

@@ -95,19 +96,19 @@ Type Constructors
9596
Custom drgn types can be created with the following factory functions. These
9697
can be used just like types obtained from :meth:`Program.type()`.
9798

98-
.. drgndoc:: void_type
99-
.. drgndoc:: int_type
100-
.. drgndoc:: bool_type
101-
.. drgndoc:: float_type
102-
.. drgndoc:: complex_type
103-
.. drgndoc:: struct_type
104-
.. drgndoc:: union_type
105-
.. drgndoc:: class_type
106-
.. drgndoc:: enum_type
107-
.. drgndoc:: typedef_type
108-
.. drgndoc:: pointer_type
109-
.. drgndoc:: array_type
110-
.. drgndoc:: function_type
99+
.. drgndoc:: Program.void_type
100+
.. drgndoc:: Program.int_type
101+
.. drgndoc:: Program.bool_type
102+
.. drgndoc:: Program.float_type
103+
.. drgndoc:: Program.complex_type
104+
.. drgndoc:: Program.struct_type
105+
.. drgndoc:: Program.union_type
106+
.. drgndoc:: Program.class_type
107+
.. drgndoc:: Program.enum_type
108+
.. drgndoc:: Program.typedef_type
109+
.. drgndoc:: Program.pointer_type
110+
.. drgndoc:: Program.array_type
111+
.. drgndoc:: Program.function_type
111112

112113
Miscellaneous
113114
-------------

drgn/__init__.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,15 @@
7272
TypeMember,
7373
TypeParameter,
7474
_with_libkdumpfile as _with_libkdumpfile,
75-
array_type,
76-
bool_type,
7775
cast,
78-
class_type,
79-
complex_type,
8076
container_of,
81-
enum_type,
8277
filename_matches,
83-
float_type,
84-
function_type,
8578
host_platform,
86-
int_type,
87-
pointer_type,
8879
program_from_core_dump,
8980
program_from_kernel,
9081
program_from_pid,
9182
reinterpret,
9283
sizeof,
93-
struct_type,
94-
typedef_type,
95-
union_type,
96-
void_type,
9784
)
9885

9986
__all__ = (
@@ -122,29 +109,16 @@
122109
"TypeKind",
123110
"TypeMember",
124111
"TypeParameter",
125-
"array_type",
126-
"bool_type",
127112
"cast",
128-
"class_type",
129-
"complex_type",
130113
"container_of",
131-
"enum_type",
132114
"execscript",
133115
"filename_matches",
134-
"float_type",
135-
"function_type",
136116
"host_platform",
137-
"int_type",
138-
"pointer_type",
139117
"program_from_core_dump",
140118
"program_from_kernel",
141119
"program_from_pid",
142120
"reinterpret",
143121
"sizeof",
144-
"struct_type",
145-
"typedef_type",
146-
"union_type",
147-
"void_type",
148122
)
149123

150124

drgn/helpers/linux/list.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def list_first_entry_or_null(
8585
head = head.read_()
8686
pos = head.next.read_()
8787
if pos == head:
88+
if isinstance(type, str):
89+
type = head.prog_.type(type)
8890
return NULL(head.prog_, head.prog_.pointer_type(type))
8991
else:
9092
return container_of(pos, type, member)

libdrgn/drgn.h.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ struct drgn_type {
425425
enum drgn_primitive_type primitive;
426426
/* These are the qualifiers for the wrapped type, not this type. */
427427
enum drgn_qualifiers qualifiers;
428+
struct drgn_program *program;
428429
const struct drgn_language *language;
429430
/*
430431
* This mess of unions is used to make this as compact as possible. Use
@@ -493,6 +494,12 @@ static inline bool drgn_type_is_complete(struct drgn_type *type)
493494
return type->_private.is_complete;
494495
}
495496

497+
static inline struct drgn_program *
498+
drgn_type_program(struct drgn_type *type)
499+
{
500+
return type->_private.program;
501+
}
502+
496503
/** Get the language of a type. */
497504
static inline const struct drgn_language *
498505
drgn_type_language(struct drgn_type *type)

0 commit comments

Comments
 (0)