-
-
Notifications
You must be signed in to change notification settings - Fork 594
/
nlist.d
317 lines (292 loc) · 11.1 KB
/
nlist.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/**
* Bindings for symbols and defines in `mach-o/nlist.h`
*
* This file was created based on the MacOSX 10.15 SDK.
*
* Copyright:
* D Language Foundation 2020
* Some documentation was extracted from the C headers
* and is the property of Apple Inc.
*
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Mathias 'Geod24' Lang
* Source: $(DRUNTIMESRC core/sys/darwin/mach/_nlist.d)
*/
module core.sys.darwin.mach.nlist;
import core.stdc.config;
extern(C):
nothrow:
@nogc:
pure:
/**
* An entry in a list of symbols for 64-bits architectures
*
* Said symbols can be used to describe many different type of data,
* including STABS debug infos. Introduced in MacOSX 10.8 SDK.
*
* See_Also:
* https://developer.apple.com/documentation/kernel/nlist_64
*/
struct nlist_64
{
/// Compatibility alias, as `n_strx` is in an union in C code
alias n_un = n_strx;
/**
* Index of this symbol's name into the string table
*
* All names are stored as NUL-terminated strings into the string table.
* For historical reason, the very first entry into the string table is `0`,
* hence all non-NULL names have an index > 0.
*/
uint n_strx;
/**
* A bitfield that describes the type of this symbol
*
* In reality, this describes 4 fields:
* - N_STAB (top 3 bits)
* - N_PEXT (next 1 bit)
* - N_TYPE (next 3 bits)
* - N_EXT (last 1 bit)
*
* The enum values `N_STAB`, `N_PEXT`, `N_TYPE`, and `N_EXT` should be used
* as masks to check which type this `nlist_64` actually is.
*/
ubyte n_type;
/// Section number (note that `0` means `NO_SECT`)
ubyte n_sect;
/* see <mach-o/stab.h> */
ushort n_desc;
/* value of this symbol (or stab offset) */
ulong n_value;
// Note: `n_value` *is* `uint64_t`, not `c_ulong` !
}
/// Mask to use with `nlist_64.n_type` to check what the entry describes
enum
{
/**
* If any of these bits set, a symbolic debugging entry
*
* Only symbolic debugging entries have some of the N_STAB bits set and if any
* of these bits are set then it is a symbolic debugging entry (a stab). In
* which case then the values of the n_type field (the entire field) are given
* in <mach-o/stab.h>
*/
N_STAB = 0xe0,
/// Private external symbol bit
N_PEXT = 0x10,
/// Mask for the type bits
N_TYPE = 0x0e, /* mask for the type bits */
/// External symbol bit, set for external symbols
N_EXT = 0x01,
}
/// Values for `NTypeMask.N_TYPE` bits of the `nlist_64.n_type` field.
enum
{
/// Undefined (`n_sect == NO_SECT`)
N_UNDF = 0x0,
/// Absolute (`n_sect == NO_SECT`)
N_ABS = 0x2,
/// Defined in section number `nlist_64.n_sect`
N_SECT = 0xe,
/// Prebound undefined (defined in a dylib)
N_PBUD = 0xc,
/**
* Indirect symbol
*
* If the type is `N_INDR` then the symbol is defined to be the same as
* another symbol. In this case the `n_value` field is an index into
* the string table of the other symbol's name. When the other symbol
* is defined then they both take on the defined type and value.
*/
N_INDR = 0xa,
}
/**
* Symbol is not in any section
*
* If the type is N_SECT then the n_sect field contains an ordinal of the
* section the symbol is defined in. The sections are numbered from 1 and
* refer to sections in order they appear in the load commands for the file
* they are in. This means the same ordinal may very well refer to different
* sections in different files.
*
* The n_value field for all symbol table entries (including N_STAB's) gets
* updated by the link editor based on the value of it's n_sect field and where
* the section n_sect references gets relocated. If the value of the n_sect
* field is NO_SECT then it's n_value field is not changed by the link editor.
*/
enum NO_SECT = 0;
/// Maximum number of sections: 1 thru 255 inclusive
enum MAX_SECT = 255;
/**
* Common symbols are represented by undefined (N_UNDF) external (N_EXT) types
* who's values (n_value) are non-zero. In which case the value of the n_value
* field is the size (in bytes) of the common symbol. The n_sect field is set
* to NO_SECT. The alignment of a common symbol may be set as a power of 2
* between 2^1 and 2^15 as part of the n_desc field using the macros below. If
* the alignment is not set (a value of zero) then natural alignment based on
* the size is used.
*/
extern(D) ubyte GET_COMM_ALIGN(uint n_desc) @safe
{
return (((n_desc) >> 8) & 0x0f);
}
/// Ditto
extern(D) ref ushort SET_COMM_ALIGN(return ref ushort n_desc, size_t wanted_align) @safe
{
return n_desc = (((n_desc) & 0xf0ff) | (((wanted_align) & 0x0f) << 8));
}
/**
* To support the lazy binding of undefined symbols in the dynamic link-editor,
* the undefined symbols in the symbol table (the nlist structures) are marked
* with the indication if the undefined reference is a lazy reference or
* non-lazy reference. If both a non-lazy reference and a lazy reference is
* made to the same symbol the non-lazy reference takes precedence. A reference
* is lazy only when all references to that symbol are made through a symbol
* pointer in a lazy symbol pointer section.
*
* The implementation of marking nlist structures in the symbol table for
* undefined symbols will be to use some of the bits of the n_desc field as a
* reference type. The mask REFERENCE_TYPE will be applied to the n_desc field
* of an nlist structure for an undefined symbol to determine the type of
* undefined reference (lazy or non-lazy).
*
* The constants for the REFERENCE FLAGS are propagated to the reference table
* in a shared library file. In that case the constant for a defined symbol,
* REFERENCE_FLAG_DEFINED, is also used.
*/
enum
{
/// Reference type bits of the n_desc field of undefined symbols
REFERENCE_TYPE = 0x7,
/// types of references
REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
/// Ditto
REFERENCE_FLAG_UNDEFINED_LAZY = 1,
/// Ditto
REFERENCE_FLAG_DEFINED = 2,
/// Ditto
REFERENCE_FLAG_PRIVATE_DEFINED = 3,
/// Ditto
REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
/// Ditto
REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5,
/**
* To simplify stripping of objects that use are used with the dynamic link
* editor, the static link editor marks the symbols defined an object that are
* referenced by a dynamicly bound object (dynamic shared libraries, bundles).
* With this marking strip knows not to strip these symbols.
*/
REFERENCED_DYNAMICALLY = 0x0010,
}
/**
* For images created by the static link editor with the -twolevel_namespace
* option in effect the flags field of the mach header is marked with
* MH_TWOLEVEL. And the binding of the undefined references of the image are
* determined by the static link editor. Which library an undefined symbol is
* bound to is recorded by the static linker in the high 8 bits of the n_desc
* field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded
* references the libraries listed in the Mach-O's LC_LOAD_DYLIB,
* LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and
* LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the
* headers. The library ordinals start from 1.
* For a dynamic library that is built as a two-level namespace image the
* undefined references from module defined in another use the same nlist struct
* an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For
* defined symbols in all images they also must have the library ordinal set to
* SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable
* image for references from plugins that refer to the executable that loads
* them.
*
* The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace
* image that are looked up by the dynamic linker with flat namespace semantics.
* This ordinal was added as a feature in Mac OS X 10.3 by reducing the
* value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries
* or binaries built with older tools to have 0xfe (254) dynamic libraries. In
* this case the ordinal value 0xfe (254) must be treated as a library ordinal
* for compatibility.
*/
ubyte GET_LIBRARY_ORDINAL(uint n_desc) @safe { return ((n_desc) >> 8) & 0xff; }
/// Ditto
ref ushort SET_LIBRARY_ORDINAL(return ref ushort n_desc, uint ordinal) @safe
{
return n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
}
/// Ditto
enum
{
SELF_LIBRARY_ORDINAL = 0x00,
MAX_LIBRARY_ORDINAL = 0xfd,
DYNAMIC_LOOKUP_ORDINAL = 0xfe,
EXECUTABLE_ORDINAL = 0xff,
}
/**
* The bit 0x0020 of the n_desc field is used for two non-overlapping purposes
* and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED.
*/
enum
{
/**
* Symbol is not to be dead stripped
*
* The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a
* relocatable .o file (MH_OBJECT filetype). And is used to indicate to the
* static link editor it is never to dead strip the symbol.
*/
N_NO_DEAD_STRIP = 0x0020,
/**
* Symbol is discarded
*
* The N_DESC_DISCARDED bit of the n_desc field never appears in linked image.
* But is used in very rare cases by the dynamic link editor to mark an in
* memory symbol as discared and longer used for linking.
*/
N_DESC_DISCARDED =0x0020,
/**
* Symbol is weak referenced
*
* The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that
* the undefined symbol is allowed to be missing and is to have the address of
* zero when missing.
*/
N_WEAK_REF = 0x0040,
/**
* Coalesed symbol is a weak definition
*
* The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic
* linkers that the symbol definition is weak, allowing a non-weak symbol to
* also be used which causes the weak definition to be discared. Currently this
* is only supported for symbols in coalesed sections.
*/
N_WEAK_DEF = 0x0080,
/**
* Reference to a weak symbol
*
* The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker
* that the undefined symbol should be resolved using flat namespace searching.
*/
N_REF_TO_WEAK = 0x0080,
/**
* Symbol is a Thumb function (ARM)
*
* The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is
* a defintion of a Thumb function.
*/
N_ARM_THUMB_DEF = 0x0008,
/**
* The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the
* that the function is actually a resolver function and should
* be called to get the address of the real function to use.
* This bit is only available in .o files (MH_OBJECT filetype)
*/
N_SYMBOL_RESOLVER = 0x0100,
/**
* The N_ALT_ENTRY bit of the n_desc field indicates that the
* symbol is pinned to the previous content.
*/
N_ALT_ENTRY = 0x0200,
/**
* The N_COLD_FUNC bit of the n_desc field indicates that the symbol is used
* infrequently and the linker should order it towards the end of the section.
*/
N_COLD_FUNC = 0x0400,
}