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