317 lines
11 KiB
D
317 lines
11 KiB
D
/**
|
|
* 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,
|
|
}
|