unit macho;
{
   * Copyright (c) 1999-2008 Apple Inc.  All Rights Reserved.
   *
   * @APPLE_LICENSE_HEADER_START@
   *
   * This file contains Original Code and/or Modifications of Original Code
   * as defined in and that are subject to the Apple Public Source License
   * Version 2.0 (the 'License'). You may not use this file except in
   * compliance with the License. Please obtain a copy of the License at
   * http://www.opensource.apple.com/apsl/ and read it before using this
   * file.
   *
   * The Original Code and all software distributed under the License are
   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   * Please see the License for the specific language governing rights and
   * limitations under the License.
   *
   * @APPLE_LICENSE_HEADER_END@
    }

{ converted by Dmitry Boyarintsev 2009 }

{$i fpcdefs.inc}

{$H+}

interface

{$IFDEF FPC}
{$PACKRECORDS C}
{$PACKENUM 4}
{$ENDIF}


// mach/$arch/machine.h
// $arch can be: i386, x86_64, ppc, arm
// currently used is i386

type
  integer_t = Integer;
  uint8_t   = Byte;

  int16_t   = SmallInt;
  uint16_t  = Word;

  uint32_t  = LongWord;
  int32_t   = Integer;

  uint64_t  = QWord;

// mach/thread_status.h

{$ifdef i386}  

{$endif i386}
  
// mach/machine.h

type
  cpu_type_t       = integer_t;
  cpu_subtype_t    = integer_t;
  cpu_threadtype_t = integer_t;

const
  CPU_STATE_MAX		= 4;

  CPU_STATE_USER		= 0;
  CPU_STATE_SYSTEM	= 1;
  CPU_STATE_IDLE		= 2;
  CPU_STATE_NICE		= 3;

  {* Capability bits used in the definition of cpu_type. }
  CPU_ARCH_MASK	  = $ff000000;	{ mask for architecture bits } 
  CPU_ARCH_ABI64	= $01000000;	{ 64 bit ABI } 

  {	Machine types known by all. }

  CPU_TYPE_ANY		  = -1;
  CPU_TYPE_VAX		  = 1;
  CPU_TYPE_MC680x0	= 6;
  CPU_TYPE_X86		  = 7;
  CPU_TYPE_I386		  = CPU_TYPE_X86;		{ compatibility }
  CPU_TYPE_X86_64	  = CPU_TYPE_X86 or CPU_ARCH_ABI64;
  // skip CPU_TYPE_MIPS		= 8;
  CPU_TYPE_MC98000	= 10;
  CPU_TYPE_HPPA     = 11;
  CPU_TYPE_ARM		  = 12;
  CPU_TYPE_ARM64          = CPU_TYPE_ARM or CPU_ARCH_ABI64;
  CPU_TYPE_MC88000	= 13;
  CPU_TYPE_SPARC		= 14;
  CPU_TYPE_I860		  = 15;
  // skip	CPU_TYPE_ALPHA		= 16;	*/

  CPU_TYPE_POWERPC	  = 18;
  CPU_TYPE_POWERPC64	= CPU_TYPE_POWERPC or CPU_ARCH_ABI64;
  
{*
 *	Machine subtypes (these are defined here, instead of in a machine
 *	dependent directory, so that any program can get all definitions
 *	regardless of where is it compiled).
 *}

{*
 * Capability bits used in the definition of cpu_subtype.
 *}
  CPU_SUBTYPE_MASK 	= $ff000000;	{ mask for feature flags }
  CPU_SUBTYPE_LIB64	= $80000000;	{ 64 bit libraries }


{*
 *	Object files that are hand-crafted to run on any
 *	implementation of an architecture are tagged with
 *	CPU_SUBTYPE_MULTIPLE.  This functions essentially the same as
 *	the "ALL" subtype of an architecture except that it allows us
 *	to easily find object files that may need to be modified
 *	whenever a new implementation of an architecture comes out.
 *
 *	It is the responsibility of the implementor to make sure the
 *	software handles unsupported implementations elegantly.
 *}
 	CPU_SUBTYPE_MULTIPLE		  = -1;
  CPU_SUBTYPE_LITTLE_ENDIAN	= 0;
  CPU_SUBTYPE_BIG_ENDIAN		= 1;

{*
 *     Machine threadtypes.
 *     This is none - not defined - for most machine types/subtypes.
 *}
  CPU_THREADTYPE_NONE	=	0;

{*
 *	VAX subtypes (these do *not* necessary conform to the actual cpu
 *	ID assigned by DEC available via the SID register).
 *}

 	CPU_SUBTYPE_VAX_ALL	= 0; 
  CPU_SUBTYPE_VAX780	= 1;
  CPU_SUBTYPE_VAX785	= 2;
  CPU_SUBTYPE_VAX750	= 3;
  CPU_SUBTYPE_VAX730	= 4;
  CPU_SUBTYPE_UVAXI	  = 5;
  CPU_SUBTYPE_UVAXII	= 6;
  CPU_SUBTYPE_VAX8200	= 7;
  CPU_SUBTYPE_VAX8500	= 8;
  CPU_SUBTYPE_VAX8600	= 9;
  CPU_SUBTYPE_VAX8650	= 10;
  CPU_SUBTYPE_VAX8800	= 11;
  CPU_SUBTYPE_UVAXIII	= 12;

{*
 * 	680x0 subtypes
 *
 * The subtype definitions here are unusual for historical reasons.
 * NeXT used to consider 68030 code as generic 68000 code.  For
 * backwards compatability:
 * 
 *	CPU_SUBTYPE_MC68030 symbol has been preserved for source code
 *	compatability.
 *
 *	CPU_SUBTYPE_MC680x0_ALL has been defined to be the same
 *	subtype as CPU_SUBTYPE_MC68030 for binary comatability.
 *
 *	CPU_SUBTYPE_MC68030_ONLY has been added to allow new object
 *	files to be tagged as containing 68030-specific instructions.
 *}

 	CPU_SUBTYPE_MC680x0_ALL  = 1;
  CPU_SUBTYPE_MC68030		   = 1; { compat }
  CPU_SUBTYPE_MC68040		   = 2;
 	CPU_SUBTYPE_MC68030_ONLY = 3;

  {* I386 subtypes *}

 	CPU_SUBTYPE_I386_ALL	     =  3 + (0 shl 4);
  CPU_SUBTYPE_386				     =  3 + (0 shl 4);
  CPU_SUBTYPE_486				     =  4 + (0 shl 4);
  CPU_SUBTYPE_486SX			     =  4 + (8 shl 4); // 8 << 4 = 128
  CPU_SUBTYPE_586				     =  5 + (0 shl 4);
  CPU_SUBTYPE_PENT	         =  5 + (0 shl 4);
  CPU_SUBTYPE_PENTPRO	       =  6 + (1 shl 4);
  CPU_SUBTYPE_PENTII_M3	     =  6 + (3 shl 4);
  CPU_SUBTYPE_PENTII_M5	     =  6 + (5 shl 4);
  CPU_SUBTYPE_CELERON				 =  7 + (6 shl 4);
  CPU_SUBTYPE_CELERON_MOBILE =  7 + (7 shl 4);
  CPU_SUBTYPE_PENTIUM_3			 =  8 + (0 shl 4);
  CPU_SUBTYPE_PENTIUM_3_M		 =  8 + (1 shl 4);
  CPU_SUBTYPE_PENTIUM_3_XEON =  8 + (2 shl 4);
  CPU_SUBTYPE_PENTIUM_M			 =  9 + (0 shl 4);
  CPU_SUBTYPE_PENTIUM_4			 = 10 + (0 shl 4);
  CPU_SUBTYPE_PENTIUM_4_M		 = 10 + (1 shl 4);
  CPU_SUBTYPE_ITANIUM				 = 11 + (0 shl 4);
  CPU_SUBTYPE_ITANIUM_2		   = 11 + (1 shl 4);
  CPU_SUBTYPE_XEON				   = 12 + (0 shl 4);
  CPU_SUBTYPE_XEON_MP			   = 12 + (1 shl 4);
                                  
  CPU_SUBTYPE_INTEL_FAMILY_MAX	=  15;
  CPU_SUBTYPE_INTEL_MODEL_ALL	= 0;

  {* X86 subtypes. *}
 
  CPU_SUBTYPE_X86_ALL		 = 3;
  CPU_SUBTYPE_X86_64_ALL = 3;
  CPU_SUBTYPE_X86_ARCH1	 = 4;


  CPU_THREADTYPE_INTEL_HTT = 1;

  {*	Mips subtypes. *}

 	CPU_SUBTYPE_MIPS_ALL	  = 0;
  CPU_SUBTYPE_MIPS_R2300	= 1;
  CPU_SUBTYPE_MIPS_R2600	= 2;
  CPU_SUBTYPE_MIPS_R2800	= 3;
  CPU_SUBTYPE_MIPS_R2000a	= 4;	{* pmax *}
  CPU_SUBTYPE_MIPS_R2000	= 5;
  CPU_SUBTYPE_MIPS_R3000a	= 6;	{ 3max *}
  CPU_SUBTYPE_MIPS_R3000	= 7;

  {* MC98000 (PowerPC) subtypes *}
 	CPU_SUBTYPE_MC98000_ALL	= 0;
  CPU_SUBTYPE_MC98601	    = 1;

{*
 *	HPPA subtypes for Hewlett-Packard HP-PA family of
 *	risc processors. Port by NeXT to 700 series. 
 *}

 	CPU_SUBTYPE_HPPA_ALL		= 0;
  CPU_SUBTYPE_HPPA_7100		= 0; {* compat *}
  CPU_SUBTYPE_HPPA_7100LC	= 1;

  {* MC88000 subtypes. *}
  
 	CPU_SUBTYPE_MC88000_ALL	= 0;
  CPU_SUBTYPE_MC88100	    = 1;
  CPU_SUBTYPE_MC88110	    = 2;

  {* SPARC subtypes  *}
 	CPU_SUBTYPE_SPARC_ALL		= 0;

  {* I860 subtypes *}
  CPU_SUBTYPE_I860_ALL	=  0;
  CPU_SUBTYPE_I860_860	=  1;

  {* PowerPC subtypes *}
  
  CPU_SUBTYPE_POWERPC_ALL		= 0;
  CPU_SUBTYPE_POWERPC_601		= 1;
  CPU_SUBTYPE_POWERPC_602		= 2;
  CPU_SUBTYPE_POWERPC_603		= 3;
  CPU_SUBTYPE_POWERPC_603e	= 4;
  CPU_SUBTYPE_POWERPC_603ev	= 5;
  CPU_SUBTYPE_POWERPC_604		= 6;
  CPU_SUBTYPE_POWERPC_604e	= 7;
  CPU_SUBTYPE_POWERPC_620		= 8;
  CPU_SUBTYPE_POWERPC_750		= 9;
  CPU_SUBTYPE_POWERPC_7400	= 10;
  CPU_SUBTYPE_POWERPC_7450	= 11;
  CPU_SUBTYPE_POWERPC_970		= 100;

  {* ARM subtypes *}
  CPU_SUBTYPE_ARM_ALL       = 0;
  CPU_SUBTYPE_ARM_V4T       = 5;
  CPU_SUBTYPE_ARM_V6        = 6;
  CPU_SUBTYPE_ARM_V5TEJ     = 7;
  CPU_SUBTYPE_ARM_XSCALE		= 8;

{*
 *	CPU families (sysctl hw.cpufamily)
 *
 * These are meant to identify the CPU's marketing name - an
 * application can map these to (possibly) localized strings.
 * NB: the encodings of the CPU families are intentionally arbitrary.
 * There is no ordering, and you should never try to deduce whether
 * or not some feature is available based on the family.
 * Use feature flags (eg, hw.optional.altivec) to test for optional
 * functionality.
 *}
  CPUFAMILY_UNKNOWN    = 0;
  CPUFAMILY_POWERPC_G3 = $cee41549;
  CPUFAMILY_POWERPC_G4 = $77c184ae;
  CPUFAMILY_POWERPC_G5 = $ed76d8aa;
  CPUFAMILY_INTEL_6_13 = $aa33392b;
  CPUFAMILY_INTEL_6_14 = $73d67300;  { "Intel Core Solo" and "Intel Core Duo" (32-bit Pentium-M with SSE3) }
  CPUFAMILY_INTEL_6_15 = $426f69ef;  { "Intel Core 2 Duo" }
  CPUFAMILY_INTEL_6_23 = $78ea4fbc;  { Penryn }
  CPUFAMILY_INTEL_6_26 = $6b5a4cd2;  { Nehalem }
  CPUFAMILY_ARM_9      = $e73283ae;
  CPUFAMILY_ARM_11     = $8ff620d8;
  CPUFAMILY_ARM_XSCALE = $53b005f5;
  
  CPUFAMILY_INTEL_YONAH	  = CPUFAMILY_INTEL_6_14;
  CPUFAMILY_INTEL_MEROM	  = CPUFAMILY_INTEL_6_15;
  CPUFAMILY_INTEL_PENRYN	= CPUFAMILY_INTEL_6_23;
  CPUFAMILY_INTEL_NEHALEM	= CPUFAMILY_INTEL_6_26;
  
  CPUFAMILY_INTEL_CORE	 = CPUFAMILY_INTEL_6_14;
  CPUFAMILY_INTEL_CORE2	 = CPUFAMILY_INTEL_6_15;
  
// mach/vm_prot.h
type
  vm_prot_t = Integer;

const
  VM_PROT_NONE	 = $00;

  VM_PROT_READ	 = $01;	{* read permission *}
  VM_PROT_WRITE	 = $02;	{* write permission *}
  VM_PROT_EXECUTE	= $04;	{* execute permission *}

{*
 *	The default protection for newly-created virtual memory
 *}

  VM_PROT_DEFAULT	= VM_PROT_READ or VM_PROT_WRITE;

{*
 *	The maximum privileges possible, for parameter checking.
 *}

  VM_PROT_ALL	 = VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE;

{*
 *	An invalid protection value.
 *	Used only by memory_object_lock_request to indicate no change
 *	to page locks.  Using -1 here is a bad idea because it
 *	looks like VM_PROT_ALL and then some.
 *}

  VM_PROT_NO_CHANGE	= $08;

{*
 *      When a caller finds that he cannot obtain write permission on a
 *      mapped entry, the following flag can be used.  The entry will
 *      be made "needs copy" effectively copying the object (using COW),
 *      and write permission will be added to the maximum protections
 *      for the associated entry.
 *}

  VM_PROT_COPY = $10;


{*
 *	Another invalid protection value.
 *	Used only by memory_object_data_request upon an object
 *	which has specified a copy_call copy strategy. It is used
 *	when the kernel wants a page belonging to a copy of the
 *	object, and is only asking the object as a result of
 *	following a shadow chain. This solves the race between pages
 *	being pushed up by the memory manager and the kernel
 *	walking down the shadow chain.
 *}

  VM_PROT_WANTS_COPY = $10;

  
{ Constant for the magic field of the mach_header (32-bit architectures)  the mach magic number  }

const
  MH_MAGIC = $feedface;
  MH_CIGAM = $cefaedfe; { NXSwapInt(MH_MAGIC)  }


type
  { * The 32-bit mach header appears at the very beginning of the object file for 32-bit architectures. }
  mach_header = record
    magic       : uint32_t;      { mach magic number identifier  }
    cputype     : cpu_type_t;    { cpu specifier  }
    cpusubtype  : cpu_subtype_t; { machine specifier  }
    filetype    : uint32_t;      { type of file  }
    ncmds       : uint32_t;      { number of load commands  }
    sizeofcmds  : uint32_t;      { the size of all the load commands  }
    flags       : uint32_t;      { flags  }
  end;
  pmach_header = ^mach_header;

type
  {* The 64-bit mach header appears at the very beginning of object files for
   * 64-bit architectures. }
  mach_header_64 = record
    magic      : uint32_t;      { mach magic number identifier  }
    cputype    : cpu_type_t;    { cpu specifier  }
    cpusubtype : cpu_subtype_t; { machine specifier  }
    filetype   : uint32_t;      { type of file  }
    ncmds      : uint32_t;      { number of load commands  }
    sizeofcmds : uint32_t;      { the size of all the load commands  }
    flags      : uint32_t;      { flags  }
    reserved   : uint32_t;      { reserved  }
  end;
  pmach_header_64 = ^mach_header_64;

  { Constant for the magic field of the mach_header_64 (64-bit architectures)  }
  { the 64-bit mach magic number  }

const
   MH_MAGIC_64 = $feedfacf;
   MH_CIGAM_64 = $cffaedfe; { NXSwapInt(MH_MAGIC_64)  }

  {* The layout of the file depends on the filetype.  For all but the MH_OBJECT
   * file type the segments are padded out and aligned on a segment alignment
   * boundary for efficient demand pageing.  The MH_EXECUTE, MH_FVMLIB, MH_DYLIB,
   * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part
   * of their first segment.
   *
   * The file type MH_OBJECT is a compact format intended as output of the
   * assembler and input (and possibly output) of the link editor (the .o
   * format).  All sections are in one unnamed segment with no segment padding.
   * This format is used as an executable format when the file is so small the
   * segment padding greatly increases its size.
   *
   * The file type MH_PRELOAD is an executable format intended for things that
   * are not executed under the kernel (proms, stand alones, kernels, etc).  The
   * format can be executed under the kernel but may demand paged it and not
   * preload it before execution.
   *
   * A core file is in MH_CORE format and can be any in an arbritray legal
   * Mach-O file.
   *
   * Constants for the filetype field of the mach_header }
const
  MH_OBJECT     = $1; { relocatable object file  }
  MH_EXECUTE    = $2; { demand paged executable file  }
  MH_FVMLIB     = $3; { fixed VM shared library file  }
  MH_CORE       = $4; { core file  }
  MH_PRELOAD    = $5; { preloaded executable file  }
  MH_DYLIB      = $6; { dynamically bound shared library  }
  MH_DYLINKER   = $7; { dynamic link editor  }
  MH_BUNDLE     = $8; { dynamically bound bundle file  }
  MH_DYLIB_STUB = $9; { shared library stub for static  }
  MH_DSYM       = $a; { linking only, no section contents   }
                      { companion file with only debug sections  }

const
  { Constants for the flags field of the mach_header  }
  
  MH_NOUNDEFS     = $1;   { the object file has no undefined references  }
  MH_INCRLINK     = $2;   { the object file is the output of an  incremental link against a base file and can't be link edited again  }
  MH_DYLDLINK     = $4;   { the object file is input for the dynamic linker and can't be staticly link edited again  }
  MH_BINDATLOAD   = $8;   { the object file's undefined references are bound by the dynamic linker when loaded.  }
  MH_PREBOUND     = $10;  { the file has its dynamic undefined references prebound.  }
  MH_SPLIT_SEGS   = $20;  { the file has its read-only and read-write segments split  }
  MH_LAZY_INIT    = $40;  { the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete)  }
  MH_TWOLEVEL     = $80;  { the image is using two-level name space bindings  }
  MH_FORCE_FLAT   = $100; { the executable is forcing all images to use flat name space bindings  }
  MH_NOMULTIDEFS  = $200; { this umbrella guarantees no multiple defintions of symbols in its sub-images so the two-level namespace hints can always be used.  }
  MH_NOFIXPREBINDING = $400;  { do not have dyld notify the prebinding agent about this executable  }
  MH_PREBINDABLE     = $800;  { the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set.  }
  MH_ALLMODSBOUND    = $1000; { indicates that this binary binds to  all two-level namespace modules of                }
                 			    		{ its dependent libraries. only used  when MH_PREBINDABLE and MH_TWOLEVEL are both set.  }
  MH_SUBSECTIONS_VIA_SYMBOLS = $2000; { safe to divide up the sections into sub-sections via symbols for dead code stripping  }
  MH_CANONICAL      = $4000;  { the binary has been canonicalized via the unprebind operation  }
  MH_WEAK_DEFINES   = $8000;  { the final linked image contains external weak symbols  }
  MH_BINDS_TO_WEAK  = $10000; { the final linked image uses weak symbols  }
  MH_ALLOW_STACK_EXECUTION = $20000; { When this bit is set, all stacks in the task will be given stack }
                                     {	execution privilege.  Only used in MH_EXECUTE filetypes.        }
  MH_ROOT_SAFE = $40000; { When this bit is set, the binary declares it is safe for use in processes with uid zero  }
  MH_SETUID_SAFE = $80000; { When this bit is set, the binary declares it is safe for use in processes when issetugid() is true  }
  MH_NO_REEXPORTED_DYLIBS = $100000; { When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported  }
  MH_PIE = $200000; { When this bit is set, the OS will load the main executable at a random address.  Only used in MH_EXECUTE filetypes.  }

  {
   * The load commands directly follow the mach_header.  The total size of all
   * of the commands is given by the sizeofcmds field in the mach_header.  All
   * load commands must have as their first two fields cmd and cmdsize.  The cmd
   * field is filled in with a constant for that command type.  Each command type
   * has a structure specifically for it.  The cmdsize field is the size in bytes
   * of the particular load command structure plus anything that follows it that
   * is a part of the load command (i.e. section structures, strings, etc.).  To
   * advance to the next load command the cmdsize can be added to the offset or
   * pointer of the current load command.  The cmdsize for 32-bit architectures
   * MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple
   * of 8 bytes (these are forever the maximum alignment of any load commands).
   * The padded bytes must be zero.  All tables in the object file must also
   * follow these rules so the file can be memory mapped.  Otherwise the pointers
   * to these tables will not work well or at all on some machines.  With all
   * padding zeroed like objects will compare byte for byte.
    }

type
  load_command = record
    cmd     : uint32_t; { type of load command  }
    cmdsize : uint32_t; { total size of command in bytes  }
  end;
  pload_command = ^load_command;

  {
   * After MacOS X 10.1 when a new load command is added that is required to be
   * understood by the dynamic linker for the image to execute properly the
   * LC_REQ_DYLD bit will be or'ed into the load command constant.  If the dynamic
   * linker sees such a load command it it does not understand will issue a
   * "unknown load command required for execution" error and refuse to use the
   * image.  Other load commands without this bit that are not understood will
   * simply be ignored.
    }
const
  LC_REQ_DYLD   = $80000000;

{ Constants for the cmd field of all load commands, the type  }
const
  LC_SEGMENT        = $1;  { segment of this file to be mapped }
  LC_SYMTAB         = $2;  { link-edit stab symbol table info  }
  LC_SYMSEG         = $3;  { link-edit gdb symbol table info (obsolete)  }
  LC_THREAD         = $4;  { thread  }
  LC_UNIXTHREAD     = $5;  { unix thread (includes a stack)  }
  LC_LOADFVMLIB     = $6;  { load a specified fixed VM shared library  }
  LC_IDFVMLIB       = $7;  { fixed VM shared library identification  }
  LC_IDENT          = $8;  { object identification info (obsolete)  }
  LC_FVMFILE        = $9;  { fixed VM file inclusion (internal use)  }
  LC_PREPAGE        = $a;  { prepage command (internal use)  }
  LC_DYSYMTAB       = $b;  { dynamic link-edit symbol table info  }
  LC_LOAD_DYLIB     = $c;  { load a dynamically linked shared library  }
  LC_ID_DYLIB       = $d;  { dynamically linked shared lib ident  }
  LC_LOAD_DYLINKER  = $e;  { load a dynamic linker  }
  LC_ID_DYLINKER    = $f;  { dynamic linker identification  }
  LC_PREBOUND_DYLIB = $10; { modules prebound for a dynamically linked shared library  }
  LC_ROUTINES       = $11; { image routines  }
  LC_SUB_FRAMEWORK  = $12; { sub framework  }
  LC_SUB_UMBRELLA   = $13; { sub umbrella  }
  LC_SUB_CLIENT     = $14; { sub client  }
  LC_SUB_LIBRARY    = $15; { sub library  }
  LC_TWOLEVEL_HINTS = $16; { two-level namespace lookup hints  }
  LC_PREBIND_CKSUM  = $17; { prebind checksum  }
  LC_LOAD_WEAK_DYLIB = $18 or LC_REQ_DYLD; { load a dynamically linked shared library that is allowed to be missing  (all symbols are weak imported). }
  LC_SEGMENT_64   = $19; { 64-bit segment of this file to be mapped  }
  LC_ROUTINES_64  = $1a; { 64-bit image routines  }
  LC_UUID         = $1b; { the uuid  }
  LC_RPATH        = $1c or LC_REQ_DYLD; { runpath additions  }
  LC_CODE_SIGNATURE     = $1d; { local of code signature  }
  LC_SEGMENT_SPLIT_INFO = $1e; { local of info to split segments  }
  LC_REEXPORT_DYLIB     = $1f or LC_REQ_DYLD; { load and re-export dylib  }
  LC_LAZY_LOAD_DYLIB    = $20; { delay load of dylib until first use  }
  LC_ENCRYPTION_INFO    = $21; { encrypted segment information  }
  {
   * A variable length string in a load command is represented by an lc_str
   * union.  The strings are stored just after the load command structure and
   * the offset is from the start of the load command structure.  The size
   * of the string is reflected in the cmdsize field of the load command.
   * Once again any padded bytes to bring the cmdsize field to a multiple
   * of 4 bytes must be zero.
    }
  { offset to the string  }
{$ifndef __LP64__}
  { pointer to the string  }
{$endif}

type
  lc_str = record
  case longint of
    0 : ( offset : uint32_t );
    1 : ( ptr : ^char );
  end;

  {
   * The segment load command indicates that a part of this file is to be
   * mapped into the task's address space.  The size of this segment in memory,
   * vmsize, maybe equal to or larger than the amount to map from this file,
   * filesize.  The file is mapped starting at fileoff to the beginning of
   * the segment in memory, vmaddr.  The rest of the memory of the segment,
   * if any, is allocated zero fill on demand.  The segment's maximum virtual
   * memory protection and initial virtual memory protection are specified
   * by the maxprot and initprot fields.  If the segment has sections then the
   * section structures directly follow the segment command and their size is
   * reflected in cmdsize.
    }
  
  { for 32-bit architectures  }            
  
  segment_command = record           
    cmd      : uint32_t;             { LC_SEGMENT  }                          
    cmdsize  : uint32_t;             { includes sizeof section structs  }     
    segname  : array[0..15] of char; { segment name  }                        
    vmaddr   : uint32_t;             { memory address of this segment  }      
    vmsize   : uint32_t;             { memory size of this segment  }         
    fileoff  : uint32_t;             { file offset of this segment  }         
    filesize : uint32_t;             { amount to map from the file  }         
    maxprot  : vm_prot_t;            { maximum VM protection  }               
    initprot : vm_prot_t;            { initial VM protection  }               
    nsects   : uint32_t;             { number of sections in segment  }       
    flags    : uint32_t;             { flags  }                               
  end;
  psegment_command = ^segment_command;

  {
   * The 64-bit segment load command indicates that a part of this file is to be
   * mapped into a 64-bit task's address space.  If the 64-bit segment has
   * sections then section_64 structures directly follow the 64-bit segment
   * command and their size is reflected in cmdsize.
    }
  { for 64-bit architectures  }
  
  segment_command_64 = record
    cmd      : uint32_t;              { LC_SEGMENT_64  }                      
    cmdsize  : uint32_t;              { includes sizeof section_64 structs  }
    segname  : array[0..15] of char;  { segment name  }                      
    vmaddr   : uint64_t;              { memory address of this segment  }    
    vmsize   : uint64_t;              { memory size of this segment  }       
    fileoff  : uint64_t;              { file offset of this segment  }       
    filesize : uint64_t;              { amount to map from the file  }       
    maxprot  : vm_prot_t;             { maximum VM protection  }             
    initprot : vm_prot_t;             { initial VM protection  }             
    nsects   : uint32_t;              { number of sections in segment  }     
    flags    : uint32_t;              { flags  }                             
  end;
  psegment_command_64 = ^segment_command_64;

  { Constants for the flags field of the segment_command  }

const
   SG_HIGHVM = $1; { the file contents for this segment is for   }
                   { the high part of the VM space, the low part }
                   { is zero filled (for stacks in core files)   }

  SG_FVMLIB = $2;  { this segment is the VM that is allocated by }
                   {	a fixed VM library, for overlap checking in }
                   { the link editor  }                           
   
  SG_NORELOC = $4; { this segment has nothing that was relocated }
                   { in it and nothing relocated to it, that is  }
                   { it maybe safely replaced without relocation }
     
  SG_PROTECTED_VERSION_1 = $8;  { This segment is protected.  If the    }
                                {	segment starts at file offset 0, the  }
                                {	first page of the segment is not      }
                                {	protected.  All other pages of the    }
                                {	segment are protected.                }
     
  {* A segment is made up of zero or more sections.  Non-MH_OBJECT files have
   * all of their segments with the proper sections in each, and padded to the
   * specified segment alignment when produced by the link editor.  The first
   * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header
   * and load commands of the object file before its first section.  The zero
   * fill sections are always last in their segment (in all formats).  This
   * allows the zeroed segment padding to be mapped into memory where zero fill
   * sections might be. The gigabyte zero fill sections, those with the section
   * type S_GB_ZEROFILL, can only be in a segment with sections of this type.
   * These segments are then placed after all other segments.
   *
   * The MH_OBJECT format has all of its sections in one segment for
   * compactness.  There is no padding to a specified segment boundary and the
   * mach_header and load commands are not part of the segment.
   *
   * Sections with the same section name, sectname, going into the same segment,
   * segname, are combined by the link editor.  The resulting section is aligned
   * to the maximum alignment of the combined sections and is the new section's
   * alignment.  The combined sections are aligned to their original alignment in
   * the combined section.  Any padded bytes to get the specified alignment are
   * zeroed.
   *
   * The format of the relocation entries referenced by the reloff and nreloc
   * fields of the section structure for mach object files is described in the
   * header file <reloc.h>.  }

type
  { for 32-bit architectures  }
  section = record
    sectname  : array[0..15] of char; { name of this section  }
    segname   : array[0..15] of char; { segment this section goes in  }
    addr      : uint32_t;             { memory address of this section  }
    size      : uint32_t;             { size in bytes of this section  }
    offset    : uint32_t;             { file offset of this section  }
    align     : uint32_t;             { section alignment (power of 2)  }
    reloff    : uint32_t;             { file offset of relocation entries  }
    nreloc    : uint32_t;             { number of relocation entries  }
    flags     : uint32_t;             { flags (section type and attributes) }
    reserved1 : uint32_t;             { reserved (for offset or index)  }
    reserved2 : uint32_t;             { reserved (for count or sizeof)  }
  end;
  psection = ^section;


  { for 64-bit architectures  }
  section_64 = record
    sectname  : array[0..15] of char; { name of this section  }
    segname   : array[0..15] of char; { segment this section goes in  }
    addr      : uint64_t;             { memory address of this section  }
    size      : uint64_t;             { size in bytes of this section  }
    offset    : uint32_t;             { file offset of this section  }
    align     : uint32_t;             { section alignment (power of 2)  }
    reloff    : uint32_t;             { file offset of relocation entries  }
    nreloc    : uint32_t;             { number of relocation entries  }
    flags     : uint32_t;             { flags (section type and attributes) }
    reserved1 : uint32_t;             { reserved (for offset or index)  }
    reserved2 : uint32_t;             { reserved (for count or sizeof)  }
    reserved3 : uint32_t;             { reserved  }
  end;
  psection_64 = ^section_64;

  {* The flags field of a section structure is separated into two parts a section
   * type and section attributes.  The section types are mutually exclusive (it
   * can only have one type) but the section attributes are not (it may have more
   * than one attribute). }

  { 256 section types  }

const
  SECTION_TYPE       = $000000ff; { Constants for the type of a section  }
  SECTION_ATTRIBUTES = $ffffff00; {  24 section attributes  }
  S_REGULAR          = $0;        { regular section  }
  S_ZEROFILL         = $1;        { zero fill on demand section  }
  S_CSTRING_LITERALS = $2;        { section with only literal C strings }
  S_4BYTE_LITERALS   = $3;        { section with only 4 byte literals  }
  S_8BYTE_LITERALS   = $4;        { section with only 8 byte literals  }
  S_LITERAL_POINTERS = $5;        { section with only pointers to literals  }

  {* For the two types of symbol pointers sections and the symbol stubs section
   * they have indirect symbol table entries.  For each of the entries in the
   * section the indirect symbol table entries, in corresponding order in the
   * indirect symbol table, start at the index stored in the reserved1 field
   * of the section structure.  Since the indirect symbol table entries
   * correspond to the entries in the section the number of indirect symbol table
   * entries is inferred from the size of the section divided by the size of the
   * entries in the section.  For symbol pointers sections the size of the entries
   * in the section is 4 bytes and for symbol stubs sections the byte size of the
   * stubs is stored in the reserved2 field of the section structure.  }

  S_NON_LAZY_SYMBOL_POINTERS = $6;    { section with only non-lazy symbol pointers  }
  S_LAZY_SYMBOL_POINTERS     = $7;    { section with only lazy symbol pointers  }
  S_SYMBOL_STUBS             = $8;    { section with only symbol stubs, byte size of stub in the reserved2 field  }
  S_MOD_INIT_FUNC_POINTERS   = $9;    { section with only function pointers for initialization }
  S_MOD_TERM_FUNC_POINTERS   = $a;    { section with only function pointers for termination  }
  S_COALESCED                = $b;    { section contains symbols that are to be coalesced  }
  S_GB_ZEROFILL              = $c;    { zero fill on demand section (that can be larger than 4 gigabytes)  }
  S_INTERPOSING              = $d;    { section with only pairs of function pointers for interposing  }
  S_16BYTE_LITERALS          = $e;    { section with only 16 byte	literals  }
  S_DTRACE_DOF               = $f;    { section contains DTrace Object Format  }
  S_LAZY_DYLIB_SYMBOL_POINTERS = $10; { section with only lazy symbol pointers to lazy loaded dylibs  }

  {* Constants for the section attributes part of the flags field of a section structure.  }
  
  SECTION_ATTRIBUTES_USR     = $ff000000; { User setable attributes  }
  
  S_ATTR_PURE_INSTRUCTIONS   = $80000000; { section contains only true machine instructions  }
  S_ATTR_NO_TOC              = $40000000; { section contains coalesced symbols }
                                          { that are not to be in a ranlib table of contents  }
  S_ATTR_STRIP_STATIC_SYMS   = $20000000; { ok to strip static symbols this section }
                                          { in files with the MH_DYLDLINK flag  }
  S_ATTR_NO_DEAD_STRIP       = $10000000; { no dead stripping  }
  S_ATTR_LIVE_SUPPORT        = $08000000; { blocks are live if they reference live blocks  }
  S_ATTR_SELF_MODIFYING_CODE = $04000000; { Used with i386 code stubs written on by dyld  }
  
  {
   * If a segment contains any sections marked with S_ATTR_DEBUG then all
   * sections in that segment must have this attribute.  No section other than
   * a section marked with this attribute may reference the contents of this
   * section.  A section with this attribute may contain no symbols and must have
   * a section type S_REGULAR.  The static linker will not copy section contents
   * from sections with this attribute into its output file.  These sections
   * generally contain DWARF debugging info.
    }  { a debug section  }
     S_ATTR_DEBUG = $02000000;
  { system setable attributes  }
     SECTION_ATTRIBUTES_SYS = $00ffff00;
  { section contains some
  						   machine instructions  }
     S_ATTR_SOME_INSTRUCTIONS = $00000400;
  { section has external
  						   relocation entries  }
     S_ATTR_EXT_RELOC = $00000200;
  { section has local
  						   relocation entries  }
     S_ATTR_LOC_RELOC = $00000100;
  {
   * The names of segments and sections in them are mostly meaningless to the
   * link-editor.  But there are few things to support traditional UNIX
   * executables that require the link-editor and assembler to use some names
   * agreed upon by convention.
   *
   * The initial protection of the "__TEXT" segment has write protection turned
   * off (not writeable).
   *
   * The link-editor will allocate common symbols at the end of the "__common"
   * section in the "__DATA" segment.  It will create the section and segment
   * if needed.
    }
  { The currently known segment names and the section names in those segments  }


  SEG_PAGEZERO = '__PAGEZERO'; { the pagezero segment which has no  }
                               { protections and catches NULL references for MH_EXECUTE files  }

  SEG_TEXT  = '__TEXT';                 { the tradition UNIX text segment  }
  SECT_TEXT         = '__text';         { the real text part of the text  }
  SECT_FVMLIB_INIT0 = '__fvmlib_init0'; { the fvmlib initialization   section  }
  SECT_FVMLIB_INIT1 = '__fvmlib_init1'; { the section following the fvmlib initialization  section  }

  SEG_DATA = '__DATA';       { the tradition UNIX data segment  }
  SECT_DATA   = '__data';   { the real initialized data section no padding, no bss overlap  }
  SECT_BSS    = '__bss';    { the real uninitialized data section no padding  }
  SECT_COMMON = '__common'; { the section common symbols are allocated in by the link editor  }

  SEG_OBJC = '__OBJC';                   { objective-C runtime segment  }
  SECT_OBJC_SYMBOLS = '__symbol_table';  { symbol table  }
  SECT_OBJC_MODULES = '__module_info';   { module information  }
  SECT_OBJC_STRINGS = '__selector_strs'; { string table  }
  SECT_OBJC_REFS    = '__selector_refs'; { string table  }

  SEG_ICON = '__ICON';            { the icon segment  }
  SECT_ICON_HEADER = '__header';  { the icon headers  }
  SECT_ICON_TIFF   = '__tiff';    { the icons in tiff format  }

  SEG_LINKEDIT = '__LINKEDIT'; { the segment containing all structs  }
                               { created and maintained by the linkeditor. }
                               { Created with -seglinkedit  option to ld(1) for MH_EXECUTE and FVMLIB file types only  }

  SEG_UNIXSTACK = '__UNIXSTACK'; { the unix stack segment  }

  SEG_IMPORT = '__IMPORT'; { the segment for the self (dyld)  }
                           { modifing code stubs that has read, write and execute permissions  }

  {* Fixed virtual memory shared libraries are identified by two things.  The
   * target pathname (the name of the library as found for execution), and the
   * minor version number.  The address of where the headers are loaded is in
   * header_addr. (THIS IS OBSOLETE and no longer supported). }

type
  fvmlib = record
    name          : lc_str;   { library's target pathname  }
    minor_version : uint32_t; { library's minor version number  }
    header_addr   : uint32_t; { library's header address  }
  end;

  {* A fixed virtual shared library (filetype == MH_FVMLIB in the mach header)
   * contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library.
   * An object that uses a fixed virtual shared library also contains a
   * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses.
   * (THIS IS OBSOLETE and no longer supported). }

  fvmlib_command = record
    cmd     : uint32_t; { LC_IDFVMLIB or LC_LOADFVMLIB  }
    cmdsize : uint32_t; { includes pathname string  }
    fvmlib  : fvmlib;   { the library identification  }
  end;
  pfvmlib_command = ^fvmlib_command;

  {* Dynamicly linked shared libraries are identified by two things.  The
   * pathname (the name of the library as found for execution), and the
   * compatibility version number.  The pathname must match and the compatibility
   * number in the user of the library must be greater than or equal to the
   * library being used.  The time stamp is used to record the time a library was
   * built and copied into user so it can be use to determined if the library used
   * at runtime is exactly the same as used to built the program.  }

  dylib = record
    name                  : lc_str;   { library's path name  }
    timestamp             : uint32_t; { library's build time stamp  }
    current_version       : uint32_t; { library's current version number  }
    compatibility_version : uint32_t; { library's compatibility vers number }
  end;

  {* A dynamically linked shared library (filetype == MH_DYLIB in the mach header)
   * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library.
   * An object that uses a dynamically linked shared library also contains a
   * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or
   * LC_REEXPORT_DYLIB) for each library it uses. }

  dylib_command = record
    cmd     : uint32_t; { LC_ID_DYLIB, LC_LOAD_DYLIB,WEAK_DYLIB, LC_REEXPORT_DYLIB  }
    cmdsize : uint32_t; { includes pathname string  }
    dylib   : dylib;    { the library identification  }
  end;
  pdylib_command = ^dylib_command;

  {* A dynamically linked shared library may be a subframework of an umbrella
   * framework.  If so it will be linked with "-umbrella umbrella_name" where
   * Where "umbrella_name" is the name of the umbrella framework. A subframework
   * can only be linked against by its umbrella framework or other subframeworks
   * that are part of the same umbrella framework.  Otherwise the static link
   * editor produces an error and states to link against the umbrella framework.
   * The name of the umbrella framework for subframeworks is recorded in the
   * following structure. }

  sub_framework_command = record
    cmd       : uint32_t; { LC_SUB_FRAMEWORK  }
    cmdsize   : uint32_t; { includes umbrella string  }
    umbrella  : lc_str;   { the umbrella framework name  }
  end;
  psub_framework_command = ^sub_framework_command;


  {* For dynamically linked shared libraries that are subframework of an umbrella
   * framework they can allow clients other than the umbrella framework or other
   * subframeworks in the same umbrella framework.  To do this the subframework
   * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load
   * command is created for each -allowable_client flag.  The client_name is
   * usually a framework name.  It can also be a name used for bundles clients
   * where the bundle is built with "-client_name client_name". }

  sub_client_command = record
    cmd     : uint32_t; { LC_SUB_CLIENT  }
    cmdsize : uint32_t; { includes client string  }
    client  : lc_str;   { the client name  }
  end;
  psub_client_command = ^sub_client_command;

  {
   * A dynamically linked shared library may be a sub_umbrella of an umbrella
   * framework.  If so it will be linked with "-sub_umbrella umbrella_name" where
   * Where "umbrella_name" is the name of the sub_umbrella framework.  When
   * staticly linking when -twolevel_namespace is in effect a twolevel namespace
   * umbrella framework will only cause its subframeworks and those frameworks
   * listed as sub_umbrella frameworks to be implicited linked in.  Any other
   * dependent dynamic libraries will not be linked it when -twolevel_namespace
   * is in effect.  The primary library recorded by the static linker when
   * resolving a symbol in these libraries will be the umbrella framework.
   * Zero or more sub_umbrella frameworks may be use by an umbrella framework.
   * The name of a sub_umbrella framework is recorded in the following structure.
    }
  
  sub_umbrella_command = record
    cmd           : uint32_t; { LC_SUB_UMBRELLA  }                
    cmdsize       : uint32_t; { includes sub_umbrella string  }   
    sub_umbrella  : lc_str;   { the sub_umbrella framework name  }
  end;

  {* A dynamically linked shared library may be a sub_library of another shared
   * library.  If so it will be linked with "-sub_library library_name" where
   * Where "library_name" is the name of the sub_library shared library.  When
   * staticly linking when -twolevel_namespace is in effect a twolevel namespace
   * shared library will only cause its subframeworks and those frameworks
   * listed as sub_umbrella frameworks and libraries listed as sub_libraries to
   * be implicited linked in.  Any other dependent dynamic libraries will not be
   * linked it when -twolevel_namespace is in effect.  The primary library
   * recorded by the static linker when resolving a symbol in these libraries
   * will be the umbrella framework (or dynamic library). Zero or more sub_library
   * shared libraries may be use by an umbrella framework or (or dynamic library).
   * The name of a sub_library framework is recorded in the following structure.
   * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc".}
   
  sub_library_command = record
    cmd         : uint32_t; { LC_SUB_LIBRARY  }             
    cmdsize     : uint32_t; { includes sub_library string  }
    sub_library : lc_str;   { the sub_library name  }       
  end;
  psub_library_command = ^sub_library_command;

  {* A program (filetype == MH_EXECUTE) that is
   * prebound to its dynamic libraries has one of these for each library that
   * the static linker used in prebinding.  It contains a bit vector for the
   * modules in the library.  The bits indicate which modules are bound (1) and
   * which are not (0) from the library.  The bit for module 0 is the low bit
   * of the first byte.  So the bit for the Nth module is:
   * (linked_modules[N/8] >> N%8) & 1 }
  
  prebound_dylib_command = record
    cmd      : uint32_t;     { LC_PREBOUND_DYLIB  }           
    cmdsize  : uint32_t;     { includes strings  }            
    name     : lc_str;       { library's path name  }         
    nmodules : uint32_t;     { number of modules in library  }
    linked_modules : lc_str; { bit vector of linked modules  }
  end;
  pprebound_dylib_command = ^prebound_dylib_command;
       
       
  {* A program that uses a dynamic linker contains a dylinker_command to identify
   * the name of the dynamic linker (LC_LOAD_DYLINKER).  And a dynamic linker
   * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER).
   * A file can have at most one of these.}
  
  dylinker_command = record
    cmd     : uint32_t; { LC_ID_DYLINKER or LC_LOAD_DYLINKER  }
    cmdsize : uint32_t; { includes pathname string  }          
    name    : lc_str;   { dynamic linker's path name  }        
  end;
  pdylinker_command = ^dylinker_command;
  
  {
   * Thread commands contain machine-specific data structures suitable for
   * use in the thread state primitives.  The machine specific data structures
   * follow the struct thread_command as follows.
   * Each flavor of machine specific data structure is preceded by an unsigned
   * long constant for the flavor of that data structure, an uint32_t
   * that is the count of longs of the size of the state data structure and then
   * the state data structure follows.  This triple may be repeated for many
   * flavors.  The constants for the flavors, counts and state data structure
   * definitions are expected to be in the header file <machine/thread_status.h>.
   * These machine specific data structures sizes must be multiples of
   * 4 bytes  The cmdsize reflects the total size of the thread_command
   * and all of the sizes of the constants for the flavors, counts and state
   * data structures.
   *
   * For executable objects that are unix processes there will be one
   * thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor.
   * This is the same as a LC_THREAD, except that a stack is automatically
   * created (based on the shell's limit for the stack size).  Command arguments
   * and environment variables are copied onto that stack.
    }
  
  thread_command = record
    cmd     : uint32_t; { LC_THREAD or  LC_UNIXTHREAD  }                                        
    cmdsize : uint32_t; { total size of this command  }                                  
    flavor  : uint32_t; { uint32_t flavor		   flavor of thread state  }                 
    count   : uint32_t; { uint32_t count		   count of longs in thread state  }         
                        { struct XXX_thread_state state   thread state for this flavor  }
                        { ...  }                                                         
  end;
  pthread_command = ^thread_command;

  {* The routines command contains the address of the dynamic shared library
   * initialization routine and an index into the module table for the module
   * that defines the routine.  Before any modules are used from the library the
   * dynamic linker fully binds the module that defines the initialization routine
   * and then calls it.  This gets called before any module initialization
   * routines (used for C++ static constructors) in the library.  }
  { for 32-bit architectures  }
  
  routines_command = record
    cmd     : uint32_t;       { LC_ROUTINES  }                      
    cmdsize : uint32_t;       { total size of this command  }       
    init_address : uint32_t;  { address of initialization routine  }
    init_module  : uint32_t;  { index into the module table that the init routine is defined in }
    reserved1 : uint32_t;
    reserved2 : uint32_t;
    reserved3 : uint32_t;
    reserved4 : uint32_t;
    reserved5 : uint32_t;
    reserved6 : uint32_t;
  end;
  proutines_command = ^routines_command;

  { * The 64-bit routines command.  Same use as above. }
  { for 64-bit architectures  }
  
  routines_command_64 = record
    cmd     : uint32_t;         { LC_ROUTINES_64  }                   
    cmdsize : uint32_t;         { total size of this command  }       
    init_address : uint64_t;    { address of initialization routine  }
    init_module  : uint64_t;    { index into the module table that  } 
                                {  the init routine is defined in  }  
    reserved1 : uint64_t;
    reserved2 : uint64_t;
    reserved3 : uint64_t;
    reserved4 : uint64_t;
    reserved5 : uint64_t;
    reserved6 : uint64_t;
  end;
  proutines_command_64 = ^routines_command_64;

  {* The symtab_command contains the offsets and sizes of the link-edit 4.3BSD
   * "stab" style symbol table information as described in the header files
   * <nlist.h> and <stab.h>.
    }

  symtab_command = record
    cmd     : uint32_t;  { LC_SYMTAB  }                       
    cmdsize : uint32_t;  { sizeof(struct symtab_command)  }   
    symoff  : uint32_t;  { symbol table offset  }             
    nsyms   : uint32_t;  { number of symbol table entries  }  
    stroff  : uint32_t;  { string table offset  }             
    strsize : uint32_t;  { string table size in bytes  }      
  end;
  psymtab_command = ^symtab_command;

  {
   * This is the second set of the symbolic information which is used to support
   * the data structures for the dynamically link editor.
   *
   * The original set of symbolic information in the symtab_command which contains
   * the symbol and string tables must also be present when this load command is
   * present.  When this load command is present the symbol table is organized
   * into three groups of symbols:
   *	local symbols (static and debugging symbols) - grouped by module
   *	defined external symbols - grouped by module (sorted by name if not lib)
   *	undefined external symbols (sorted by name if MH_BINDATLOAD is not set,
   *	     			    and in order the were seen by the static
   *				    linker if MH_BINDATLOAD is set)
   * In this load command there are offsets and counts to each of the three groups
   * of symbols.
   *
   * This load command contains a the offsets and sizes of the following new
   * symbolic information tables:
   *	table of contents
   *	module table
   *	reference symbol table
   *	indirect symbol table
   * The first three tables above (the table of contents, module table and
   * reference symbol table) are only present if the file is a dynamically linked
   * shared library.  For executable and object modules, which are files
   * containing only one module, the information that would be in these three
   * tables is determined as follows:
   * 	table of contents - the defined external symbols are sorted by name
   *	module table - the file contains only one module so everything in the
   *		       file is part of the module.
   *	reference symbol table - is the defined and undefined external symbols
   *
   * For dynamically linked shared library files this load command also contains
   * offsets and sizes to the pool of relocation entries for all sections
   * separated into two groups:
   *	external relocation entries
   *	local relocation entries
   * For executable and object modules the relocation entries continue to hang
   * off the section structures.
    }

  dysymtab_command = record
    cmd             : uint32_t; { LC_DYSYMTAB  }
    cmdsize         : uint32_t; { sizeof(struct dysymtab_command)  }
  {
       * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command
       * are grouped into the following three groups:
       *    local symbols (further grouped by the module they are from)
       *    defined external symbols (further grouped by the module they are from)
       *    undefined symbols
       *
       * The local symbols are used only for debugging.  The dynamic binding
       * process may have to use them to indicate to the debugger the local
       * symbols for a module that is being bound.
       *
       * The last two groups are used by the dynamic binding process to do the
       * binding (indirectly through the module table and the reference symbol
       * table when this is a dynamically linked shared library file).
        }
    ilocalsym       : uint32_t; { index to local symbols  }
    nlocalsym       : uint32_t; { number of local symbols  }
    iextdefsym      : uint32_t; { index to externally defined symbols  }
    nextdefsym      : uint32_t; { number of externally defined symbols  }
    iundefsym       : uint32_t; { index to undefined symbols  }
    nundefsym       : uint32_t; { number of undefined symbols  }
  {
       * For the for the dynamic binding process to find which module a symbol
       * is defined in the table of contents is used (analogous to the ranlib
       * structure in an archive) which maps defined external symbols to modules
       * they are defined in.  This exists only in a dynamically linked shared
       * library file.  For executable and object modules the defined external
       * symbols are sorted by name and is use as the table of contents.
        }
    tocoff          : uint32_t; { file offset to table of contents  }
    ntoc            : uint32_t; { number of entries in table of contents  }
  {
       * To support dynamic binding of "modules" (whole object files) the symbol
       * table must reflect the modules that the file was created from.  This is
       * done by having a module table that has indexes and counts into the merged
       * tables for each module.  The module structure that these two entries
       * refer to is described below.  This exists only in a dynamically linked
       * shared library file.  For executable and object modules the file only
       * contains one module so everything in the file belongs to the module.
        }
    modtaboff       : uint32_t; { file offset to module table  }
    nmodtab         : uint32_t; { number of module table entries  }
  {
       * To support dynamic module binding the module structure for each module
       * indicates the external references (defined and undefined) each module
       * makes.  For each module there is an offset and a count into the
       * reference symbol table for the symbols that the module references.
       * This exists only in a dynamically linked shared library file.  For
       * executable and object modules the defined external symbols and the
       * undefined external symbols indicates the external references.
        }
    extrefsymoff    : uint32_t; { offset to referenced symbol table  }
    nextrefsyms     : uint32_t; { number of referenced symbol table entries  }
  {
       * The sections that contain "symbol pointers" and "routine stubs" have
       * indexes and (implied counts based on the size of the section and fixed
       * size of the entry) into the "indirect symbol" table for each pointer
       * and stub.  For every section of these two types the index into the
       * indirect symbol table is stored in the section header in the field
       * reserved1.  An indirect symbol table entry is simply a 32bit index into
       * the symbol table to the symbol that the pointer or stub is referring to.
       * The indirect symbol table is ordered to match the entries in the section.
        }
    indirectsymoff  : uint32_t; { file offset to the indirect symbol table  }
    nindirectsyms   : uint32_t; { number of indirect symbol table entries  }
  {    * To support relocating an individual module in a library file quickly the
       * external relocation entries for each module in the library need to be
       * accessed efficiently.  Since the relocation entries can't be accessed
       * through the section headers for a library file they are separated into
       * groups of local and external entries further grouped by module.  In this
       * case the presents of this load command who's extreloff, nextrel,
       * locreloff and nlocrel fields are non-zero indicates that the relocation
       * entries of non-merged sections are not referenced through the section
       * structures (and the reloff and nreloc fields in the section headers are
       * set to zero).
       *
       * Since the relocation entries are not accessed through the section headers
       * this requires the r_address field to be something other than a section
       * offset to identify the item to be relocated.  In this case r_address is
       * set to the offset from the vmaddr of the first LC_SEGMENT command.
       * For MH_SPLIT_SEGS images r_address is set to the the offset from the
       * vmaddr of the first read-write LC_SEGMENT command.
       *
       * The relocation entries are grouped by module and the module table
       * entries have indexes and counts into them for the group of external
       * relocation entries for that the module.
       *
       * For sections that are merged across modules there must not be any
       * remaining external relocation entries for them (for merged sections
       * remaining relocation entries must be local).
        }
    extreloff       : uint32_t; { offset to external relocation entries  }
    nextrel         : uint32_t; { number of external relocation entries  }
    {   * All the local relocation entries are grouped together (they are not
       * grouped by their module since they are only used if the object is moved
       * from it staticly link edited address).      }
    locreloff       : uint32_t; { offset to local relocation entries  }
    nlocrel         : uint32_t; { number of local relocation entries  }
  end;

  {
   * An indirect symbol table entry is simply a 32bit index into the symbol table
   * to the symbol that the pointer or stub is refering to.  Unless it is for a
   * non-lazy symbol pointer section for a defined symbol which strip(1) as
   * removed.  In which case it has the value INDIRECT_SYMBOL_LOCAL.  If the
   * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that.
    }

const
  INDIRECT_SYMBOL_LOCAL = $80000000;
  INDIRECT_SYMBOL_ABS = $40000000;

type
  dylib_table_of_contents = record { a table of contents entry  }
    symbol_index : uint32_t; { the defined external symbol (index into the symbol table)  }
    module_index : uint32_t; { index into the module table this symbol is defined in  }
  end;

  dylib_module = record     { a module table entry  }
    module_name : uint32_t; { the module name (index into string table)  }
    iextdefsym  : uint32_t; { index into externally defined symbols  }
    nextdefsym  : uint32_t; { number of externally defined symbols  }
    irefsym     : uint32_t; { index into reference symbol table  }
    nrefsym     : uint32_t; { number of reference symbol table entries  }
    ilocalsym   : uint32_t; { index into symbols for local symbols  }
    nlocalsym   : uint32_t; { number of local symbols  }
    iextrel     : uint32_t; { index into external relocation entries  }
    nextrel     : uint32_t; { number of external relocation entries  }
    iinit_iterm : uint32_t; { low 16 bits are the index into the init
  				   section, high 16 bits are the index into
  			           the term section  }
    ninit_nterm : uint32_t; { low 16 bits are the number of init section
  				   entries, high 16 bits are the number of
  				   term section entries  }
    objc_module_info_addr : uint32_t;  { for this module address of the start of the (__OBJC,__module_info) section  }
    objc_module_info_size : uint32_t;  { for this module size of  the (__OBJC,__module_info) section  }
  end;

  dylib_module_64 = record   { a 64-bit module table entry  }
    module_name : uint32_t;  { the module name (index into string table)  }
    iextdefsym  : uint32_t;  { index into externally defined symbols  }
    nextdefsym  : uint32_t;  { number of externally defined symbols  }
    irefsym     : uint32_t;  { index into reference symbol table  }
    nrefsym     : uint32_t;  { number of reference symbol table entries  }
    ilocalsym   : uint32_t;  { index into symbols for local symbols  }
    nlocalsym   : uint32_t;  { number of local symbols  }
    iextrel     : uint32_t;  { index into external relocation entries  }
    nextrel     : uint32_t;  { number of external relocation entries  }
    iinit_iterm : uint32_t;  { low 16 bits are the index into the init
                    				   section, high 16 bits are the index into
                    				   the term section  }
    ninit_nterm : uint32_t; { low 16 bits are the number of init section
                    				  entries, high 16 bits are the number of
                    				  term section entries  }
    objc_module_info_size : uint32_t; { for this module size of the (__OBJC,__module_info) section  }
    objc_module_info_addr : uint64_t; { for this module address of the start of the (__OBJC,__module_info) section  }
  end;

  {
   * The entries in the reference symbol table are used when loading the module
   * (both by the static and dynamic link editors) and if the module is unloaded
   * or replaced.  Therefore all external symbols (defined and undefined) are
   * listed in the module's reference table.  The flags describe the type of
   * reference that is being made.  The constants for the flags are defined in
   * <mach-o/nlist.h> as they are also used for symbol table entries.
    }
  { index into the symbol table  }
  { flags to indicate the type of reference  }
  dylib_reference = record
    flag0 : longint;
  end;


{  const
     bm_dylib_reference_isym = $FFFFFF;
     bp_dylib_reference_isym = 0;
     bm_dylib_reference_flags = $FF000000;
     bp_dylib_reference_flags = 24;

  function isym(var a : dylib_reference) : uint32_t;
  procedure set_isym(var a : dylib_reference; __isym : uint32_t);
  function flags(var a : dylib_reference) : uint32_t;
  procedure set_flags(var a : dylib_reference; __flags : uint32_t);}

  {* The twolevel_hints_command contains the offset and number of hints in the
   * two-level namespace lookup hints table.}
 
type
  twolevel_hints_command = record
    cmd     : uint32_t; { LC_TWOLEVEL_HINTS  }                    
    cmdsize : uint32_t; { sizeof(struct twolevel_hints_command)  }
    offset  : uint32_t; { offset to the hint table  }             
    nhints  : uint32_t; { number of hints in the hint table  }    
  end;

  {
   * The entries in the two-level namespace lookup hints table are twolevel_hint
   * structs.  These provide hints to the dynamic link editor where to start
   * looking for an undefined symbol in a two-level namespace image.  The
   * isub_image field is an index into the sub-images (sub-frameworks and
   * sub-umbrellas list) that made up the two-level image that the undefined
   * symbol was found in when it was built by the static link editor.  If
   * isub-image is 0 the the symbol is expected to be defined in library and not
   * in the sub-images.  If isub-image is non-zero it is an index into the array
   * of sub-images for the umbrella with the first index in the sub-images being
   * 1. The array of sub-images is the ordered list of sub-images of the umbrella
   * that would be searched for a symbol that has the umbrella recorded as its
   * primary library.  The table of contents index is an index into the
   * library's table of contents.  This is used as the starting point of the
   * binary search or a directed linear search.
    }
  { index into the sub images  }
  { index into the table of contents  }
  twolevel_hint = record
    flag0 : longint;
  end;


{  const
     bm_twolevel_hint_isub_image = $FF;
     bp_twolevel_hint_isub_image = 0;
     bm_twolevel_hint_itoc = $FFFFFF00;
     bp_twolevel_hint_itoc = 8;

  function isub_image(var a : twolevel_hint) : uint32_t;
  procedure set_isub_image(var a : twolevel_hint; __isub_image : uint32_t);
  function itoc(var a : twolevel_hint) : uint32_t;
  procedure set_itoc(var a : twolevel_hint; __itoc : uint32_t);
}

type
  {* The prebind_cksum_command contains the value of the original check sum for
   * prebound files or zero.  When a prebound file is first created or modified
   * for other than updating its prebinding information the value of the check sum
   * is set to zero.  When the file has it prebinding re-done and if the value of
   * the check sum is zero the original check sum is calculated and stored in
   * cksum field of this load command in the output file.  If when the prebinding
   * is re-done and the cksum field is non-zero it is left unchanged from the
   * input file. }
   
  prebind_cksum_command = record
    cmd     : uint32_t; { LC_PREBIND_CKSUM  }                    
    cmdsize : uint32_t; { sizeof(struct prebind_cksum_command)  }
    cksum   : uint32_t; { the check sum or zero  }               
  end;
  pprebind_cksum_command = ^prebind_cksum_command;
  
       
  {* The uuid load command contains a single 128-bit unique random number that
   * identifies an object produced by the static link editor. }

  uuid_command = record                
    cmd     : uint32_t;                { LC_UUID  }                    
    cmdsize : uint32_t;                { sizeof(struct uuid_command)  }
    uuid    : array[0..15] of uint8_t; { the 128-bit uuid  }           
  end;
  puuid_command = ^uuid_command;
  
  
  {* The rpath_command contains a path which at runtime should be added to
   * the current run path used to find @rpath prefixed dylibs.}
    
  rpath_command = record
    cmd     : uint32_t; { LC_RPATH  }               
    cmdsize : uint32_t; { includes string  }        
    path    : lc_str;   { path to add to run path  }
  end;
  prpath_command = ^rpath_command;

  
  {* The linkedit_data_command contains the offsets and sizes of a blob
   * of data in the __LINKEDIT segment.}
  
  linkedit_data_command = record
    cmd      : uint32_t; { LC_CODE_SIGNATURE or LC_SEGMENT_SPLIT_INFO  }
    cmdsize  : uint32_t; { sizeof(struct linkedit_data_command)  }      
    dataoff  : uint32_t; { file offset of data in __LINKEDIT segment  } 
    datasize : uint32_t; { file size of data in __LINKEDIT segment   }  
  end;
  plinkedit_data_command = ^linkedit_data_command;
  
  
  {* The encryption_info_command contains the file offset and size of an
   * of an encrypted segment.}
  
  encryption_info_command = record
    cmd       : uint32_t; { LC_ENCRYPTION_INFO  }                               
    cmdsize   : uint32_t; { sizeof(struct encryption_info_command)  }           
    cryptoff  : uint32_t; { file offset of encrypted range  }                   
    cryptsize : uint32_t; { file size of encrypted range  }                     
    cryptid   : uint32_t; { which enryption system, 0 means not-encrypted yet  }
  end;
  pencryption_info_command = ^encryption_info_command;
  
  
  {* The symseg_command contains the offset and size of the GNU style
   * symbol table information as described in the header file <symseg.h>.
   * The symbol roots of the symbol segments must also be aligned properly
   * in the file.  So the requirement of keeping the offsets aligned to a
   * multiple of a 4 bytes translates to the length field of the symbol
   * roots also being a multiple of a long.  Also the padding must again be
   * zeroed. (THIS IS OBSOLETE and no longer supported). }
  
  symseg_command = record
    cmd     : uint32_t; { LC_SYMSEG  }                    
    cmdsize : uint32_t; { sizeof(struct symseg_command)  }
    offset  : uint32_t; { symbol segment offset  }        
    size    : uint32_t; { symbol segment size in bytes  } 
  end;
  psymseg_command = ^symseg_command;


  {* The ident_command contains a free format string table following the
   * ident_command structure.  The strings are null terminated and the size of
   * the command is padded out with zero bytes to a multiple of 4 bytes/
   * (THIS IS OBSOLETE and no longer supported).}
  
  ident_command = record
    cmd     : uint32_t; { LC_IDENT  }                        
    cmdsize : uint32_t; { strings that follow this command  }
  end;
  pident_command = ^ident_command;
  
  
  {* The fvmfile_command contains a reference to a file to be loaded at the
   * specified virtual address.  (Presently, this command is reserved for
   * internal use.  The kernel ignores this command when loading a program into
   * memory).  }
  
  fvmfile_command = record
    cmd         : uint32_t;  { LC_FVMFILE  }              
    cmdsize     : uint32_t;  { includes pathname string  }
    name        : lc_str;    { files pathname  }          
    header_addr : uint32_t;  { files virtual address  }   
  end;
  pfvmfile_command = ^fvmfile_command;

  
  {* This header file describes the structures of the file format for "fat"
   * architecture specific file (wrapper design).  At the begining of the file
   * there is one fat_header structure followed by a number of fat_arch
   * structures.  For each architecture in the file, specified by a pair of
   * cputype and cpusubtype, the fat_header describes the file offset, file
   * size and alignment in the file of the architecture specific member.
   * The padded bytes in the file to place each member on it's specific alignment
   * are defined to be read as zeros and can be left as "holes" if the file system
   * can support them as long as they read as zeros.
   *
   * All structures defined here are always written and read to/from disk
   * in big-endian order.}
  {* <mach/machine.h> is needed here for the cpu_type_t and cpu_subtype_t types
   * and contains the constants for the possible values of these types.}

const
  FAT_MAGIC = $cafebabe;
  FAT_CIGAM = $bebafeca;

type
  fat_header = record
    magic       : uint32_t;      { FAT_MAGIC  }
    nfat_arch   : uint32_t;      { number of structs that follow  }
  end;

  fat_arch = record
    cputype     : cpu_type_t;    { cpu specifier (int)  }
    cpusubtype  : cpu_subtype_t; { machine specifier (int)  }
    offset      : uint32_t;      { file offset to this object file  }
    size        : uint32_t;      { size of this object file  }
    align       : uint32_t;      { alignment as a power of 2  }
  end;


  {
   * Format of a symbol table entry of a Mach-O file for 32-bit architectures.
   * Modified from the BSD format.  The modifications from the original format
   * were changing n_other (an unused field) to n_sect and the addition of the
   * N_SECT type.  These modifications are required to support symbols in a larger
   * number of sections not just the three sections (text, data and bss) in a BSD
   * file.
    }

type
  nlist = record
    n_un : record
    case longint of
      {$ifndef __LP64__}
      0 : ( n_name : Pchar );   { for use when in-core }
      {$endif}
      1 : ( n_strx : int32_t ); { index into the string table  }
    end;
    n_type  : uint8_t;  { type flag, see below  }
    n_sect  : uint8_t;  { section number or NO_SECT  }
    n_desc  : int16_t;  { see <mach-o/stab.h>  }
    n_value : uint32_t; { value of this symbol (or stab offset)  }
  end;
  pnlist = ^nlist;

  {* This is the symbol table entry structure for 64-bit architectures.}
  nlist_64 = record
    n_un : record
    case longint of
      0 : ( n_strx : uint32_t ); { index into the string table  }
    end;
    n_type  : uint8_t;  { type flag, see below  }
    n_sect  : uint8_t;  { section number or NO_SECT  }
    n_desc  : uint16_t; { see <mach-o/stab.h>  }
    n_value : uint64_t; { value of this symbol (or stab offset)  }
  end;
  pnlist_64 = ^nlist_64;

  {* Symbols with a index into the string table of zero (n_un.n_strx == 0) are
   * defined to have a null, "", name.  Therefore all string indexes to non null
   * names must not have a zero string index.  This is bit historical information
   * that has never been well documented. }
  {* The n_type field really contains four fields:
   *	unsigned char N_STAB:3,
   *		      N_PEXT:1,
   *		      N_TYPE:3,
   *		      N_EXT:1;
   * which are used via the following masks.}

const
  N_STAB = $e0; { if any of these bits set, a symbolic debugging entry  }
  N_PEXT = $10; { private external symbol bit  }
  N_TYPE = $0e; { mask for the type bits  }
  N_EXT  = $01; { external symbol bit, set for external symbols  }

  {* 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> }

  {* Values for N_TYPE bits of the n_type field. }

  N_UNDF = $0; { undefined, n_sect == NO_SECT  }
  N_ABS  = $2; { absolute, n_sect == NO_SECT  }
  N_SECT = $e; { defined in section number n_sect  }
  N_PBUD = $c; { prebound undefined (defined in a dylib)  }
  N_INDR = $a; { indirect  }

  {* 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.}

  {* 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.}

  NO_SECT = 0;    { symbol is not in any section  }
  MAX_SECT = 255; { 1 thru 255 inclusive  }
  {* 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.}

  { ----- Process manually -----
  #define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f)
  #define SET_COMM_ALIGN(n_desc,align) \
      (n_desc) = (((n_desc) & 0xf0ff) | (((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.}

  { Reference type bits of the n_desc field of undefined symbols  }
  REFERENCE_TYPE = $7;

  { types of references  }
  REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0;
  REFERENCE_FLAG_UNDEFINED_LAZY = 1;
  REFERENCE_FLAG_DEFINED = 2;
  REFERENCE_FLAG_PRIVATE_DEFINED = 3;
  REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4;
  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 = $0010;

  {* 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 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.}

  { was #define dname(params) para_def_expr }
  { argument types are unknown }
  { return type might be wrong }
//  function GET_LIBRARY_ORDINAL(n_desc : longint) : longint;

  { -- Process Manually ---
  #define SET_LIBRARY_ORDINAL(n_desc,ordinal) \
  	(n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8))
   }

const
  SELF_LIBRARY_ORDINAL   = $0;
  MAX_LIBRARY_ORDINAL    = $fd;
  DYNAMIC_LOOKUP_ORDINAL = $fe;
  EXECUTABLE_ORDINAL     = $ff;

  {* 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. }

  {* 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 = $0020; { symbol is not to be dead stripped  }



  {* 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 = $0020; { symbol is discarded  }

  {* 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 = $0040; { symbol is weak referenced  }

  {* 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 = $0080; { coalesed symbol is a weak definition  }

  {* 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 = $0080; { reference to a weak symbol  }

  {* 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 = $0008; { symbol is a Thumb function (ARM)  }

  {* There are two known orders of table of contents for archives.  The first is
   * the order ranlib(1) originally produced and still produces without any
   * options.  This table of contents has the archive member name "__.SYMDEF"
   * This order has the ranlib structures in the order the objects appear in the
   * archive and the symbol names of those objects in the order of symbol table.
   * The second know order is sorted by symbol name and is produced with the -s
   * option to ranlib(1).  This table of contents has the archive member name
   * "__.SYMDEF SORTED" and many programs (notably the 1.0 version of ld(1) can't
   * tell the difference between names because of the imbedded blank in the name
   * and works with either table of contents).  This second order is used by the
   * post 1.0 link editor to produce faster linking.  The original 1.0 version of
   * ranlib(1) gets confused when it is run on a archive with the second type of
   * table of contents because it and ar(1) which it uses use different ways to
   * determined the member name (ar(1) treats all blanks in the name as
   * significant and ranlib(1) only checks for the first one).}

const
  SYMDEF = '__.SYMDEF';
  SYMDEF_SORTED = '__.SYMDEF SORTED';

  {
   * Structure of the __.SYMDEF table of contents for an archive.
   * __.SYMDEF begins with a long giving the size in bytes of the ranlib
   * structures which immediately follow, and then continues with a string
   * table consisting of a long giving the number of bytes of strings which
   * follow and then the strings themselves.  The ran_strx fields index the
   * string table whose first byte is numbered 0.
    }

type
  ranlib = record
    ran_un : record
      case longint of
        0 : ( ran_strx : uint32_t );
        1 : ( ran_name : ^char );
      end;
    ran_off : uint32_t;
  end;

type
   {* Format of a relocation entry of a Mach-O file.  Modified from the 4.3BSD
   * format.  The modifications from the original format were changing the value
   * of the r_symbolnum field for "local" (r_extern == 0) relocation entries.
   * This modification is required to support symbols in an arbitrary number of
   * sections not just the three sections (text, data and bss) in a 4.3BSD file.
   * Also the last 4 bits have had the r_type tag added to them. }

  relocation_info = record
    r_address : int32_t;  { offset in the section to what is being relocated  }
    r_info    : longint;
    // r_symbolnum:24,	{* symbol index if r_extern == 1 or section  ordinal if r_extern == 0 *}
		// r_pcrel:1; 	    {* was relocated pc relative already *}
 		// r_length:2;	    {* 0=byte, 1=word, 2=long, 3=quad *}
 		// r_extern:1;     	{* does not include value of sym referenced *}
	 	// r_type:4; 	      {* if not 0, machine specific relocation type *}
  end;


{ absolute relocation type for Mach-O files  }

const
  R_ABS = 0;
  R_SCATTERED = $80000000;   { mask to be applied to the r_address field }
            { of a relocation_info structure to tell that }
  				  { is is really a scattered_relocation_info }
  				  { stucture  }

  {
   * The r_address is not really the address as it's name indicates but an offset.
   * In 4.3BSD a.out objects this offset is from the start of the "segment" for
   * which relocation entry is for (text or data).  For Mach-O object files it is
   * also an offset but from the start of the "section" for which the relocation
   * entry is for.  See comments in <mach-o/loader.h> about the r_address feild
   * in images for used with the dynamic linker.
   *
   * In 4.3BSD a.out objects if r_extern is zero then r_symbolnum is an ordinal
   * for the segment the symbol being relocated is in.  These ordinals are the
   * symbol types N_TEXT, N_DATA, N_BSS or N_ABS.  In Mach-O object files these
   * ordinals refer to the sections in the object file in the order their section
   * structures appear in the headers of the object file they are in.  The first
   * section has the ordinal 1, the second 2, and so on.  This means that the
   * same ordinal in two different object files could refer to two different
   * sections.  And further could have still different ordinals when combined
   * by the link-editor.  The value R_ABS is used for relocation entries for
   * absolute symbols which need no further relocation.
    }
  {
   * For RISC machines some of the references are split across two instructions
   * and the instruction does not contain the complete value of the reference.
   * In these cases a second, or paired relocation entry, follows each of these
   * relocation entries, using a PAIR r_type, which contains the other part of the
   * reference not contained in the instruction.  This other part is stored in the
   * pair's r_address field.  The exact number of bits of the other part of the
   * reference store in the r_address field is dependent on the particular
   * relocation type for the particular architecture.
    }
  {
   * To make scattered loading by the link editor work correctly "local"
   * relocation entries can't be used when the item to be relocated is the value
   * of a symbol plus an offset (where the resulting expresion is outside the
   * block the link editor is moving, a blocks are divided at symbol addresses).
   * In this case. where the item is a symbol value plus offset, the link editor
   * needs to know more than just the section the symbol was defined.  What is
   * needed is the actual value of the symbol without the offset so it can do the
   * relocation correctly based on where the value of the symbol got relocated to
   * not the value of the expression (with the offset added to the symbol value).
   * So for the NeXT 2.0 release no "local" relocation entries are ever used when
   * there is a non-zero offset added to a symbol.  The "external" and "local"
   * relocation entries remain unchanged.
   *
   * The implemention is quite messy given the compatibility with the existing
   * relocation entry format.  The ASSUMPTION is that a section will never be
   * bigger than 2**24 - 1 (0x00ffffff or 16,777,215) bytes.  This assumption
   * allows the r_address (which is really an offset) to fit in 24 bits and high
   * bit of the r_address field in the relocation_info structure to indicate
   * it is really a scattered_relocation_info structure.  Since these are only
   * used in places where "local" relocation entries are used and not where
   * "external" relocation entries are used the r_extern field has been removed.
   *
   * For scattered loading to work on a RISC machine where some of the references
   * are split across two instructions the link editor needs to be assured that
   * each reference has a unique 32 bit reference (that more than one reference is
   * NOT sharing the same high 16 bits for example) so it move each referenced
   * item independent of each other.  Some compilers guarantees this but the
   * compilers don't so scattered loading can be done on those that do guarantee
   * this.
    }

  {
   * The reason for the ifdef's of __BIG_ENDIAN__ and __LITTLE_ENDIAN__ are that
   * when stattered relocation entries were added the mistake of using a mask
   * against a structure that is made up of bit fields was used.  To make this
   * design work this structure must be laid out in memory the same way so the
   * mask can be applied can check the same bit each time (r_scattered).
    }


type
  scattered_relocation_info = record
    {$ifdef ENDIAN_BIG}
    r_info  : longint;  { r_scattered:1,	/* 1=scattered, 0=non-scattered (see above) */
                          r_pcrel:1,   	/* was relocated pc relative already */
                  		    r_length:2, 	/* 0=byte, 1=word, 2=long, 3=quad */
                  		    r_type:4,   	/* if not 0, machine specific relocation type */
                          r_address:24;	/* offset in the section to what is being relocated */}
    r_value : int32_t;  {* the value the item to be relocated is refering to (without any offset added) *}
    {$else}
    r_value : int32_t;
    r_info  : longint; {*	r_address:24,	  /* offset in the section to what is being relocated */
                      		r_type:4,	      /* if not 0, machine specific relocation type */
                      		r_length:2,	    /* 0=byte, 1=word, 2=long, 3=quad */
                      		r_pcrel:1, 	    /* was relocated pc relative already */
                      		r_scattered:1;	/* 1=scattered, 0=non-scattered (see above) */   *}
    {$endif}
  end;

  {
   * Relocation types used in a generic implementation.  Relocation entries for
   * normal things use the generic relocation as discribed above and their r_type
   * is GENERIC_RELOC_VANILLA (a value of zero).
   *
   * Another type of generic relocation, GENERIC_RELOC_SECTDIFF, is to support
   * the difference of two symbols defined in different sections.  That is the
   * expression "symbol1 - symbol2 + constant" is a relocatable expression when
   * both symbols are defined in some section.  For this type of relocation the
   * both relocations entries are scattered relocation entries.  The value of
   * symbol1 is stored in the first relocation entry's r_value field and the
   * value of symbol2 is stored in the pair's r_value field.
   *
   * A special case for a prebound lazy pointer is needed to beable to set the
   * value of the lazy pointer back to its non-prebound state.  This is done
   * using the GENERIC_RELOC_PB_LA_PTR r_type.  This is a scattered relocation
   * entry where the r_value feild is the value of the lazy pointer not prebound.
    }

const
  GENERIC_RELOC_VANILLA        = 0; { generic relocation as discribed above  }
  GENERIC_RELOC_PAIR           = 1; { Only follows a GENERIC_RELOC_SECTDIFF  }
  GENERIC_RELOC_SECTDIFF       = 2;
  GENERIC_RELOC_PB_LA_PTR      = 3; { prebound lazy pointer  }
  GENERIC_RELOC_LOCAL_SECTDIFF = 4;

{*
 * Relocations for x86_64 are a bit different than for other architectures in
 * Mach-O: Scattered relocations are not used.  Almost all relocations produced
 * by the compiler are external relocations.  An external relocation has the
 * r_extern bit set to 1 and the r_symbolnum field contains the symbol table
 * index of the target label.
 *
 * When the assembler is generating relocations, if the target label is a local
 * label (begins with 'L'), then the previous non-local label in the same
 * section is used as the target of the external relocation.  An addend is used
 * with the distance from that non-local label to the target label.  Only when
 * there is no previous non-local label in the section is an internal
 * relocation used.
 *
 * The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does
 * not have RELA relocations).  For PC-relative relocations, the addend is
 * stored directly in the instruction.  This is different from other Mach-O
 * architectures, which encode the addend minus the current section offset.
 *
 * The relocation types are:
 *
 * 	X86_64_RELOC_UNSIGNED	// for absolute addresses
 * 	X86_64_RELOC_SIGNED		// for signed 32-bit displacement
 * 	X86_64_RELOC_BRANCH		// a CALL/JMP instruction with 32-bit displacement
 * 	X86_64_RELOC_GOT_LOAD	// a MOVQ load of a GOT entry
 * 	X86_64_RELOC_GOT		// other GOT references
 * 	X86_64_RELOC_SUBTRACTOR	// must be followed by a X86_64_RELOC_UNSIGNED
 *
 * The following are sample assembly instructions, followed by the relocation
 * and section content they generate in an object file:
 *
 * 	call _foo
 * 		r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		E8 00 00 00 00
 *
 * 	call _foo+4
 * 		r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		E8 04 00 00 00
 *
 * 	movq _foo@GOTPCREL(%rip), %rax
 * 		r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		48 8B 05 00 00 00 00
 *
 * 	pushq _foo@GOTPCREL(%rip)
 * 		r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		FF 35 00 00 00 00
 *
 * 	movl _foo(%rip), %eax
 * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		8B 05 00 00 00 00
 *
 * 	movl _foo+4(%rip), %eax
 * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		8B 05 04 00 00 00
 *
 * 	movb  $0x12, _foo(%rip)
 * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		C6 05 FF FF FF FF 12
 *
 * 	movl  $0x12345678, _foo(%rip)
 * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
 * 		C7 05 FC FF FF FF 78 56 34 12
 *
 * 	.quad _foo
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		00 00 00 00 00 00 00 00
 *
 * 	.quad _foo+4
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		04 00 00 00 00 00 00 00
 *
 * 	.quad _foo - _bar
 * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		00 00 00 00 00 00 00 00
 *
 * 	.quad _foo - _bar + 4
 * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		04 00 00 00 00 00 00 00
 *
 * 	.long _foo - _bar
 * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		00 00 00 00
 *
 * 	lea L1(%rip), %rax
 * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev
 * 		48 8d 05 12 00 00 00
 * 		// assumes _prev is the first non-local label 0x12 bytes before L1
 *
 * 	lea L0(%rip), %rax
 * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
 * 		48 8d 05 56 00 00 00
 * 		// assumes L0 is in third section, has an address of 0x00000056 in .o
 * 		// file, and there is no previous non-local label
 *
 * 	.quad L1
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
 * 		12 00 00 00 00 00 00 00
 * 		// assumes _prev is the first non-local label 0x12 bytes before L1
 *
 * 	.quad L0
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3
 * 		56 00 00 00 00 00 00 00
 * 		// assumes L0 is in third section, has an address of 0x00000056 in .o
 * 		// file, and there is no previous non-local label
 *
 * 	.quad _foo - .
 * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		EE FF FF FF FF FF FF FF
 * 		// assumes _prev is the first non-local label 0x12 bytes before this
 * 		// .quad
 *
 * 	.quad _foo - L1
 * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
 * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
 * 		EE FF FF FF FF FF FF FF
 * 		// assumes _prev is the first non-local label 0x12 bytes before L1
 *
 * 	.quad L1 - _prev
 * 		// No relocations.  This is an assembly time constant.
 * 		12 00 00 00 00 00 00 00
 * 		// assumes _prev is the first non-local label 0x12 bytes before L1
 *
 *
 *
 * In final linked images, there are only two valid relocation kinds:
 *
 *     r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index
 *	This tells dyld to add the address of a symbol to a pointer sized (8-byte)
 *  piece of data (i.e on disk the 8-byte piece of data contains the addend). The
 *  r_symbolnum contains the index into the symbol table of the target symbol.
 *
 *     r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0
 * This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount
 * the containing image was loaded from its base address (e.g. slide).
 *
 *}

const
  X86_64_RELOC_UNSIGNED   = 0; // for absolute addresses
  X86_64_RELOC_SIGNED     = 1; // for signed 32-bit displacement
  X86_64_RELOC_BRANCH     = 2; // a CALL/JMP instruction with 32-bit displacement
  X86_64_RELOC_GOT_LOAD   = 3; // a MOVQ load of a GOT entry
  X86_64_RELOC_GOT        = 4; // other GOT references
  X86_64_RELOC_SUBTRACTOR = 5; // must be followed by a X86_64_RELOC_UNSIGNED
  X86_64_RELOC_SIGNED_1   = 6; // for signed 32-bit displacement with a -1 addend
  X86_64_RELOC_SIGNED_2   = 7; // for signed 32-bit displacement with a -2 addend
  X86_64_RELOC_SIGNED_4   = 8; // for signed 32-bit displacement with a -4 addend




  {* Relocation types used in the ppc implementation.  Relocation entries for
   * things other than instructions use the same generic relocation as discribed
   * above and their r_type is RELOC_VANILLA.  The rest of the relocation types
   * are for instructions.  Since they are for instructions the r_address field
   * indicates the 32 bit instruction that the relocation is to be preformed on.
   * The fields r_pcrel and r_length are ignored for non-RELOC_VANILLA r_types
   * except for PPC_RELOC_BR14.
   *
   * For PPC_RELOC_BR14 if the r_length is the unused value 3, then the branch was
   * statically predicted setting or clearing the Y-bit based on the sign of the
   * displacement or the opcode.  If this is the case the static linker must flip
   * the value of the Y-bit if the sign of the displacement changes for non-branch
   * always conditions.
    }

const
  PPC_RELOC_VANILLA   = 0; { generic relocation as discribed above  }
  PPC_RELOC_PAIR      = 1; { the second relocation entry of a pair  }
  PPC_RELOC_BR14      = 2; { 14 bit branch displacement (to a word address)  }
  PPC_RELOC_BR24      = 3; { 24 bit branch displacement (to a word address)  }
  PPC_RELOC_HI16      = 4; { a PAIR follows with the low half  }
  PPC_RELOC_LO16      = 5; { a PAIR follows with the high half  }
  PPC_RELOC_HA16      = 6; { Same as the RELOC_HI16 except the low 16 bits and the  }
                      		 { * high 16 bits are added together with the low 16 bits }
                      		 { * sign extened first.  This means if bit 15 of the low }
                      		 { * 16 bits is set the high 16 bits stored in the        }
                      		 { * instruction will be adjusted. }
  PPC_RELOC_LO14      = 7; { Same as the LO16 except that the low 2 bits are not    }
                      		 { * stored in the instruction and are always zero.  This }
                       		 { * is used in double word load/store instructions.      }
  PPC_RELOC_SECTDIFF  = 8;       { a PAIR follows with subtract symbol value  }
  PPC_RELOC_PB_LA_PTR = 9;       { prebound lazy pointer  }
  PPC_RELOC_HI16_SECTDIFF  = 10; { section difference forms of above.  a PAIR  }
  PPC_RELOC_LO16_SECTDIFF  = 11; { follows these with subtract symbol value  }
  PPC_RELOC_HA16_SECTDIFF  = 12;
  PPC_RELOC_JBSR           = 13;
  PPC_RELOC_LO14_SECTDIFF  = 14;
  PPC_RELOC_LOCAL_SECTDIFF = 15; { like PPC_RELOC_SECTDIFF, but the symbol referenced was local.   }

  {
   * Symbolic debugger symbols.  The comments give the conventional use for
   *
   * 	.stabs "n_name", n_type, n_sect, n_desc, n_value
   *
   * where n_type is the defined constant and not listed in the comment.  Other
   * fields not listed are zero. n_sect is the section ordinal the entry is
   * refering to.
    }

const
   N_GSYM    = $20; { global symbol: name,,NO_SECT,type,0  }
   N_FNAME   = $22; { procedure name (f77 kludge): name,,NO_SECT,0,0  }
   N_FUN     = $24; { procedure: name,,n_sect,linenumber,address  }
   N_STSYM   = $26; { static symbol: name,,n_sect,type,address  }
   N_LCSYM   = $28; { .lcomm symbol: name,,n_sect,type,address  }
   N_BNSYM   = $2e; { begin nsect sym: 0,,n_sect,0,address  }
   N_OPT     = $3c; { emitted with gcc2_compiled and in gcc source  }
   N_RSYM    = $40; { register sym: name,,NO_SECT,type,register  }
   N_SLINE   = $44; { src line: 0,,n_sect,linenumber,address  }
   N_ENSYM   = $4e; { end nsect sym: 0,,n_sect,0,address  }
   N_SSYM    = $60; { structure elt: name,,NO_SECT,type,struct_offset  }
   N_SO      = $64; { source file name: name,,n_sect,0,address  }
   N_OSO     = $66; { object file name: name,,0,0,st_mtime  }
   N_LSYM    = $80; { local sym: name,,NO_SECT,type,offset  }
   N_BINCL   = $82; { include file beginning: name,,NO_SECT,0,sum  }
   N_SOL     = $84; { #included file name: name,,n_sect,0,address  }
   N_PARAMS  = $86; { compiler parameters: name,,NO_SECT,0,0  }
   N_VERSION = $88; { compiler version: name,,NO_SECT,0,0  }
   N_OLEVEL  = $8A; { compiler -O level: name,,NO_SECT,0,0  }
   N_PSYM    = $a0; { parameter: name,,NO_SECT,type,offset  }
   N_EINCL   = $a2; { include file end: name,,NO_SECT,0,0  }
   N_ENTRY   = $a4; { alternate entry: name,,n_sect,linenumber,address  }
   N_LBRAC   = $c0; { left bracket: 0,,NO_SECT,nesting level,address  }
   N_EXCL    = $c2; { deleted include file: name,,NO_SECT,0,sum  }
   N_RBRAC   = $e0; { right bracket: 0,,NO_SECT,nesting level,address  }
   N_BCOMM   = $e2; { begin common: name,,NO_SECT,0,0  }
   N_ECOMM   = $e4; { end common: name,,n_sect,0,0  }
   N_ECOML   = $e8; { end common (local name): 0,,n_sect,0,address  }
   N_LENG    = $fe; { second stab entry with length information  }
   { * for the berkeley pascal compiler, pc(1): }
   N_PC      = $30; {   global pascal symbol: name,,NO_SECT,subtype,line  }

implementation

end.



