Skip to content
MachO.h 17.5 KiB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
//=== MachO.h - Mach-O structures and constants -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines MachO .
//
//===----------------------------------------------------------------------===//

#ifndef MACHO_H
#define MACHO_H

#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/Target/TargetAsmInfo.h"
#include <string>
#include <vector>

namespace llvm {

typedef std::vector<unsigned char> DataBuffer;
  
/// MachOSym - This struct contains information about each symbol that is
/// added to logical symbol table for the module.  This is eventually
/// turned into a real symbol table in the file.
struct MachOSym {
  const GlobalValue *GV;    // The global value this corresponds to.
  std::string GVName;       // The mangled name of the global value.
  uint32_t    n_strx;       // index into the string table
  uint8_t     n_type;       // type flag
  uint8_t     n_sect;       // section number or NO_SECT
  int16_t     n_desc;       // see <mach-o/stab.h>
  uint64_t    n_value;      // value for this symbol (or stab offset)
  
  // Constants for the n_sect field
  // see <mach-o/nlist.h>
  enum { NO_SECT = 0 };   // symbol is not in any section

  // Constants for the n_type field
  // see <mach-o/nlist.h>
  enum { N_UNDF  = 0x0,  // undefined, n_sect == NO_SECT
         N_ABS   = 0x2,  // absolute, n_sect == NO_SECT
         N_SECT  = 0xe,  // defined in section number n_sect
         N_PBUD  = 0xc,  // prebound undefined (defined in a dylib)
         N_INDR  = 0xa   // indirect
  };
  // The following bits are OR'd into the types above. For example, a type
  // of 0x0f would be an external N_SECT symbol (0x0e | 0x01).
  enum { N_EXT  = 0x01,   // external symbol bit
         N_PEXT = 0x10    // private external symbol bit
  };
  
  // Constants for the n_desc field
  // see <mach-o/loader.h>
  enum { 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
  };
  enum { N_NO_DEAD_STRIP = 0x0020, // symbol is not to be dead stripped
         N_WEAK_REF      = 0x0040, // symbol is weak referenced
         N_WEAK_DEF      = 0x0080  // coalesced symbol is a weak definition
  };
  
  MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
           const TargetAsmInfo *TAI);

  struct SymCmp {
    // FIXME: this does not appear to be sorting 'f' after 'F'
    bool operator()(const MachOSym &LHS, const MachOSym &RHS) {
      return LHS.GVName < RHS.GVName;
    }
  };


  /// PartitionByLocal - Simple boolean predicate that returns true if Sym is
  /// a local symbol rather than an external symbol.
  
  static inline bool PartitionByLocal(const MachOSym &Sym) {
    return (Sym.n_type & (MachOSym::N_EXT | MachOSym::N_PEXT)) == 0;
  }
  
  /// PartitionByDefined - Simple boolean predicate that returns true if Sym is
  /// defined in this module.
  
  static inline bool PartitionByDefined(const MachOSym &Sym) {
    // FIXME: Do N_ABS or N_INDR count as defined?
    return (Sym.n_type & MachOSym::N_SECT) == MachOSym::N_SECT;
  }

}; // end struct MachOSym

/// MachOHeader - This struct contains the header information about a
/// specific architecture type/subtype pair that is emitted to the file.

struct MachOHeader {
  uint32_t  magic;      // mach magic number identifier
  uint32_t  filetype;   // type of file
  uint32_t  ncmds;      // number of load commands
  uint32_t  sizeofcmds; // the size of all the load commands
  uint32_t  flags;      // flags
  uint32_t  reserved;   // 64-bit only
  
  /// HeaderData - The actual data for the header which we are building
  /// up for emission to the file.
  DataBuffer HeaderData;

  // Constants for the filetype field
  // see <mach-o/loader.h> for additional info on the various types
  enum { 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 linking only
         MH_DSYM       = 10 // companion file wiht only debug sections
  };
  
  // Constants for the flags field
  enum { MH_NOUNDEFS                = 1 << 0,
            // the object file has no undefined references
         MH_INCRLINK                = 1 << 1,
            // the object file is the output of an incremental link against
            // a base file and cannot be link edited again
         MH_DYLDLINK                = 1 << 2,
            // the object file is input for the dynamic linker and cannot be
            // statically link edited again.
         MH_BINDATLOAD              = 1 << 3,
            // the object file's undefined references are bound by the
            // dynamic linker when loaded.
         MH_PREBOUND                = 1 << 4,
            // the file has its dynamic undefined references prebound
         MH_SPLIT_SEGS              = 1 << 5,
            // the file has its read-only and read-write segments split
            // see <mach/shared_memory_server.h>
         MH_LAZY_INIT               = 1 << 6,
            // the shared library init routine is to be run lazily via
            // catching memory faults to its writable segments (obsolete)
         MH_TWOLEVEL                = 1 << 7,
            // the image is using two-level namespace bindings
         MH_FORCE_FLAT              = 1 << 8,
            // the executable is forcing all images to use flat namespace
            // bindings.
         MH_NOMULTIDEFS             = 1 << 8,
            // this umbrella guarantees no multiple definitions of symbols
            // in its sub-images so the two-level namespace hints can
            // always be used.
         MH_NOFIXPREBINDING         = 1 << 10,
            // do not have dyld notify the prebidning agent about this
            // executable.
         MH_PREBINDABLE             = 1 << 11,
            // the binary is not prebound but can have its prebinding
            // redone.  only used when MH_PREBOUND is not set.
         MH_ALLMODSBOUND            = 1 << 12,
            // 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 = 1 << 13,
            // safe to divide up the sections into sub-sections via symbols
            // for dead code stripping.
         MH_CANONICAL               = 1 << 14,
            // the binary has been canonicalized via the unprebind operation
         MH_WEAK_DEFINES            = 1 << 15,
            // the final linked image contains external weak symbols
         MH_BINDS_TO_WEAK           = 1 << 16,
            // the final linked image uses weak symbols
         MH_ALLOW_STACK_EXECUTION   = 1 << 17
            // When this bit is set, all stacks in the task will be given
            // stack execution privilege.  Only used in MH_EXECUTE filetype
  };

  MachOHeader() : magic(0), filetype(0), ncmds(0), sizeofcmds(0), flags(0),
                  reserved(0) { }
  
  /// cmdSize - This routine returns the size of the MachOSection as written
  /// to disk, depending on whether the destination is a 64 bit Mach-O file.
  unsigned cmdSize(bool is64Bit) const {
    if (is64Bit)
      return 8 * sizeof(uint32_t);
    else
      return 7 * sizeof(uint32_t);
  }

  /// setMagic - This routine sets the appropriate value for the 'magic'
  /// field based on pointer size and endianness.
  void setMagic(bool isLittleEndian, bool is64Bit) {
    if (isLittleEndian)
      if (is64Bit) magic = 0xcffaedfe;
      else         magic = 0xcefaedfe;
    else
      if (is64Bit) magic = 0xfeedfacf;
      else         magic = 0xfeedface;
  }

}; // end struct MachOHeader
    
/// MachOSegment - This struct contains the necessary information to
/// emit the load commands for each section in the file.
struct MachOSegment {
  uint32_t    cmd;      // LC_SEGMENT or LC_SEGMENT_64
  uint32_t    cmdsize;  // Total size of this struct and section commands
  std::string segname;  // segment name
  uint64_t    vmaddr;   // address of this segment
  uint64_t    vmsize;   // size of this segment, may be larger than filesize
  uint64_t    fileoff;  // offset in file
  uint64_t    filesize; // amount to read from file
  uint32_t    maxprot;  // maximum VM protection
  uint32_t    initprot; // initial VM protection
  uint32_t    nsects;   // number of sections in this segment
  uint32_t    flags;    // flags
  
  // The following constants are getting pulled in by one of the
  // system headers, which creates a neat clash with the enum.
#if !defined(VM_PROT_NONE)
#define VM_PROT_NONE    0x00
#endif
#if !defined(VM_PROT_READ)
#define VM_PROT_READ    0x01
#endif
#if !defined(VM_PROT_WRITE)
#define VM_PROT_WRITE   0x02
#endif
#if !defined(VM_PROT_EXECUTE)
#define VM_PROT_EXECUTE 0x04
#endif
#if !defined(VM_PROT_ALL)
#define VM_PROT_ALL     0x07
#endif

  // Constants for the vm protection fields
  // see <mach-o/vm_prot.h>
  enum { SEG_VM_PROT_NONE     = VM_PROT_NONE, 
         SEG_VM_PROT_READ     = VM_PROT_READ, // read permission
         SEG_VM_PROT_WRITE    = VM_PROT_WRITE, // write permission
         SEG_VM_PROT_EXECUTE  = VM_PROT_EXECUTE,
         SEG_VM_PROT_ALL      = VM_PROT_ALL
  };
  
  // Constants for the cmd field
  // see <mach-o/loader.h>
  enum { LC_SEGMENT    = 0x01,  // segment of this file to be mapped
         LC_SEGMENT_64 = 0x19   // 64-bit segment of this file to be mapped
  };
  
  /// cmdSize - This routine returns the size of the MachOSection as written
  /// to disk, depending on whether the destination is a 64 bit Mach-O file.
  unsigned cmdSize(bool is64Bit) const {
    if (is64Bit)
      return 6 * sizeof(uint32_t) + 4 * sizeof(uint64_t) + 16;
    else
      return 10 * sizeof(uint32_t) + 16;  // addresses only 32 bits
  }

  MachOSegment(const std::string &seg, bool is64Bit)
    : cmd(is64Bit ? LC_SEGMENT_64 : LC_SEGMENT), cmdsize(0), segname(seg),
      vmaddr(0), vmsize(0), fileoff(0), filesize(0), maxprot(VM_PROT_ALL),
      initprot(VM_PROT_ALL), nsects(0), flags(0) { }
};

/// MachOSection - This struct contains information about each section in a 
/// particular segment that is emitted to the file.  This is eventually
/// turned into the SectionCommand in the load command for a particlar
/// segment.

struct MachOSection { 
  std::string  sectname; // name of this section, 
  std::string  segname;  // segment this section goes in
  uint64_t  addr;        // memory address of this section
  uint64_t  size;        // size in bytes of this section
  uint32_t  offset;      // file offset of this section
  uint32_t  align;       // section alignment (power of 2)
  uint32_t  reloff;      // file offset of relocation entries
  uint32_t  nreloc;      // number of relocation entries
  uint32_t  flags;       // flags (section type and attributes)
  uint32_t  reserved1;   // reserved (for offset or index)
  uint32_t  reserved2;   // reserved (for count or sizeof)
  uint32_t  reserved3;   // reserved (64 bit only)
  
  /// A unique number for this section, which will be used to match symbols
  /// to the correct section.
  uint32_t Index;
  
  /// SectionData - The actual data for this section which we are building
  /// up for emission to the file.
  DataBuffer SectionData;

  /// RelocBuffer - A buffer to hold the mach-o relocations before we write
  /// them out at the appropriate location in the file.
  DataBuffer RelocBuffer;
  
  /// Relocations - The relocations that we have encountered so far in this 
  /// section that we will need to convert to MachORelocation entries when
  /// the file is written.
  std::vector<MachineRelocation> Relocations;
  
  // Constants for the section types (low 8 bits of flags field)
  // see <mach-o/loader.h>
  enum { 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
         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 = 10,
            // section with only function pointers for termination
         S_COALESCED = 11,
            // section contains symbols that are coalesced
         S_GB_ZEROFILL = 12,
            // zero fill on demand section (that can be larger than 4GB)
         S_INTERPOSING = 13,
            // section with only pairs of function pointers for interposing
         S_16BYTE_LITERALS = 14
            // section with only 16 byte literals
  };
  
  // Constants for the section flags (high 24 bits of flags field)
  // see <mach-o/loader.h>
  enum { S_ATTR_PURE_INSTRUCTIONS   = 1 << 31,
            // section contains only true machine instructions
         S_ATTR_NO_TOC              = 1 << 30,
            // section contains coalesced symbols that are not to be in a 
            // ranlib table of contents
         S_ATTR_STRIP_STATIC_SYMS   = 1 << 29,
            // ok to strip static symbols in this section in files with the
            // MY_DYLDLINK flag
         S_ATTR_NO_DEAD_STRIP       = 1 << 28,
            // no dead stripping
         S_ATTR_LIVE_SUPPORT        = 1 << 27,
            // blocks are live if they reference live blocks
         S_ATTR_SELF_MODIFYING_CODE = 1 << 26,
            // used with i386 code stubs written on by dyld
         S_ATTR_DEBUG               = 1 << 25,
            // a debug section
         S_ATTR_SOME_INSTRUCTIONS   = 1 << 10,
            // section contains some machine instructions
         S_ATTR_EXT_RELOC           = 1 << 9,
            // section has external relocation entries
         S_ATTR_LOC_RELOC           = 1 << 8
            // section has local relocation entries
  };

  /// cmdSize - This routine returns the size of the MachOSection as written
  /// to disk, depending on whether the destination is a 64 bit Mach-O file.
  unsigned cmdSize(bool is64Bit) const {
    if (is64Bit)
      return 7 * sizeof(uint32_t) + 2 * sizeof(uint64_t) + 32;
    else
      return 9 * sizeof(uint32_t) + 32;  // addresses only 32 bits
  }

  MachOSection(const std::string &seg, const std::string &sect)
    : sectname(sect), segname(seg), addr(0), size(0), offset(0), align(2),
      reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
      reserved3(0) { }

}; // end struct MachOSection

    /// MachOSymTab - This struct contains information about the offsets and 
    /// size of symbol table information.
    /// segment.
    struct MachODySymTab {
      uint32_t cmd;             // LC_DYSYMTAB
      uint32_t cmdsize;         // sizeof( MachODySymTab )
      uint32_t ilocalsym;       // index to local symbols
      uint32_t nlocalsym;       // number of local symbols
      uint32_t iextdefsym;      // index to externally defined symbols
      uint32_t nextdefsym;      // number of externally defined symbols
      uint32_t iundefsym;       // index to undefined symbols
      uint32_t nundefsym;       // number of undefined symbols
      uint32_t tocoff;          // file offset to table of contents
      uint32_t ntoc;            // number of entries in table of contents
      uint32_t modtaboff;       // file offset to module table
      uint32_t nmodtab;         // number of module table entries
      uint32_t extrefsymoff;    // offset to referenced symbol table
      uint32_t nextrefsyms;     // number of referenced symbol table entries
      uint32_t indirectsymoff;  // file offset to the indirect symbol table
      uint32_t nindirectsyms;   // number of indirect symbol table entries
      uint32_t extreloff;       // offset to external relocation entries
      uint32_t nextrel;         // number of external relocation entries
      uint32_t locreloff;       // offset to local relocation entries
      uint32_t nlocrel;         // number of local relocation entries

      // Constants for the cmd field
      // see <mach-o/loader.h>
      enum { LC_DYSYMTAB = 0x0B  // dynamic link-edit symbol table info
      };
      
      MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
        ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
        iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
        nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
        nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { }
    };

} // end namespace llvm

#endif