1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.tools.jaotc.binformat.macho;
  25 
  26 /**
  27  *
  28  * Support for the creation of Mach-o Object files.
  29  * Current support is limited to 64 bit x86_64.
  30  *
  31  * File Format Overview:
  32  *
  33  *   mach_header
  34  *   load_commands
  35  *      Typical Mac OSX 64-bit object files have these 4 load_commands
  36  *      (LC_SEGMENT_64, LC_SYMTAB, LC_VERSIN_MIN_MACOSX, LC_DYSYMTAB)
  37  *   Segments corresponding to load_commands
  38  *      (which each include multiple Sections)
  39  */
  40 
  41 public class MachO {
  42 
  43     /**
  44      * mach_header_64 structure defines
  45      */
  46     public enum mach_header_64 {
  47                  magic( 0, 4),
  48                cputype( 4, 4),
  49             cpusubtype( 8, 4),
  50               filetype(12, 4),
  51                  ncmds(16, 4),
  52             sizeofcmds(20, 4),
  53                  flags(24, 4),
  54               reserved(28, 4);
  55 
  56         public final int off;
  57         public final int sz;
  58 
  59         mach_header_64(int offset, int size) {
  60             this.off = offset;
  61             this.sz = size;
  62         }
  63 
  64         public static int totalsize = 32;
  65 
  66         /**
  67          * mach_header_64 defines
  68          */
  69         public static final int MH_MAGIC                   = 0xfeedface;
  70         public static final int MH_MAGIC_64                = 0xfeedfacf;
  71         public static final int MH_SUBSECTIONS_VIA_SYMBOLS = 0x2000;
  72 
  73         /**
  74          * filetype
  75          */
  76         public static final int MH_OBJECT = 0x1;
  77 
  78         /**
  79          * cputype
  80          */
  81         public static final int CPU_TYPE_ANY              = -1;
  82         public static final int CPU_ARCH_ABI64            = 0x1000000;
  83         public static final int CPU_TYPE_X86_64           = 0x1000007;
  84         public static final int CPU_TYPE_ARM64            = 0x100000c;
  85         /**
  86          * cpusubtype
  87          */
  88         public static final int CPU_SUBTYPE_I386_ALL      = 3;
  89         public static final int CPU_SUBTYPE_ARM64_ALL     = 0;
  90         public static final int CPU_SUBTYPE_LITTLE_ENDIAN = 0;
  91         public static final int CPU_SUBTYPE_BIG_ENDIAN    = 1;
  92 
  93     }
  94 
  95     /**
  96      * segment_command_64 structure defines
  97      */
  98     public enum segment_command_64 {
  99                    cmd( 0, 4),
 100                cmdsize( 4, 4),
 101                segname( 8,16),
 102                 vmaddr(24, 8),
 103                 vmsize(32, 8),
 104                fileoff(40, 8),
 105               filesize(48, 8),
 106                maxprot(56, 4),
 107               initprot(60, 4),
 108                 nsects(64, 4),
 109                  flags(68, 4);
 110 
 111         public final int off;
 112         public final int sz;
 113 
 114         segment_command_64(int offset, int size) {
 115             this.off = offset;
 116             this.sz = size;
 117         }
 118 
 119         public static int totalsize = 72;
 120 
 121         public static final int LC_SEGMENT_64           = 0x19;
 122     }
 123 
 124     /**
 125      * section_64 structure defines
 126      */
 127     public enum section_64 {
 128               sectname( 0,16),
 129                segname(16,16),
 130                   addr(32, 8),
 131                   size(40, 8),
 132                 offset(48, 4),
 133                  align(52, 4),
 134                 reloff(56, 4),
 135                 nreloc(60, 4),
 136                  flags(64, 4),
 137              reserved1(68, 4),
 138              reserved2(72, 4),
 139              reserved3(76, 4);
 140 
 141         public final int off;
 142         public final int sz;
 143 
 144         section_64(int offset, int size) {
 145             this.off = offset;
 146             this.sz = size;
 147         }
 148 
 149         public static int totalsize = 80;
 150 
 151         public static int S_REGULAR                = 0x0;
 152         public static int S_CSTRING_LITERALS       = 0x2;
 153         public static int S_ATTR_PURE_INSTRUCTIONS = 0x80000000;
 154         public static int S_ATTR_SOME_INSTRUCTIONS = 0x400;
 155     }
 156 
 157     /**
 158      * version_min_command structure defines
 159      */
 160     public enum version_min_command {
 161                    cmd( 0, 4),
 162                cmdsize( 4, 4),
 163                version( 8, 4),
 164                    sdk(12, 4);
 165 
 166         public final int off;
 167         public final int sz;
 168 
 169         version_min_command(int offset, int size) {
 170             this.off = offset;
 171             this.sz = size;
 172         }
 173 
 174         public static int totalsize = 16;
 175 
 176         public static final int LC_VERSION_MIN_MACOSX   = 0x24;
 177         public static final int LC_VERSION_MIN_IPHONEOS = 0x25;
 178     }
 179 
 180     /**
 181      * symtab_command structure defines
 182      */
 183     public enum symtab_command {
 184                    cmd( 0, 4),
 185                cmdsize( 4, 4),
 186                 symoff( 8, 4),
 187                  nsyms(12, 4),
 188                 stroff(16, 4),
 189                strsize(20, 4);
 190 
 191         public final int off;
 192         public final int sz;
 193 
 194         symtab_command(int offset, int size) {
 195             this.off = offset;
 196             this.sz = size;
 197         }
 198 
 199         public static int totalsize = 24;
 200 
 201         public static final int LC_SYMTAB               = 0x2;
 202     }
 203 
 204     /**
 205      * Symbol table entry definitions
 206      *
 207      * nlist_64 structure defines
 208      */
 209     public enum nlist_64 {
 210                 n_strx( 0, 4),
 211                 n_type( 4, 1),
 212                 n_sect( 5, 1),
 213                 n_desc( 6, 2),
 214                n_value( 8, 8);
 215 
 216         public final int off;
 217         public final int sz;
 218 
 219         nlist_64(int offset, int size) {
 220             this.off = offset;
 221             this.sz = size;
 222         }
 223 
 224         public static int totalsize = 16;
 225 
 226         public static final int N_EXT                = 0x1;
 227         public static final int N_TYPE               = 0xe;
 228         public static final int N_UNDF               = 0x0;
 229         public static final int N_SECT               = 0xe;
 230     }
 231 
 232     /**
 233      * dysymtab_command structure defines
 234      */
 235     public enum dysymtab_command {
 236                    cmd( 0, 4),
 237                cmdsize( 4, 4),
 238              ilocalsym( 8, 4),
 239              nlocalsym(12, 4),
 240             iextdefsym(16, 4),
 241             nextdefsym(20, 4),
 242              iundefsym(24, 4),
 243              nundefsym(28, 4),
 244                 tocoff(32, 4),
 245                   ntoc(36, 4),
 246              modtaboff(40, 4),
 247                nmodtab(44, 4),
 248           extrefsymoff(48, 4),
 249            nextrefsyms(52, 4),
 250         indirectsymoff(56, 4),
 251          nindirectsyms(60, 4),
 252              extreloff(64, 4),
 253                nextrel(68, 4),
 254              locreloff(72, 4),
 255                nlocrel(76, 4);
 256 
 257         public final int off;
 258         public final int sz;
 259 
 260         dysymtab_command(int offset, int size) {
 261             this.off = offset;
 262             this.sz = size;
 263         }
 264 
 265         public static int totalsize = 80;
 266 
 267         public static final int LC_DYSYMTAB             = 0xb;
 268     }
 269 
 270     /**
 271      * relocation_info structure defines
 272      */
 273     public enum reloc_info {
 274              r_address( 0, 4),
 275            r_relocinfo( 4, 4);
 276 
 277         public final int off;
 278         public final int sz;
 279 
 280         reloc_info(int offset, int size) {
 281             this.off = offset;
 282             this.sz = size;
 283         }
 284 
 285         public static int totalsize = 8;
 286 
 287         public static final int REL_SYMNUM_MASK         = 0xffffff;
 288         public static final int REL_SYMNUM_SHIFT        = 0x0;
 289         public static final int REL_PCREL_MASK          = 0x1;
 290         public static final int REL_PCREL_SHIFT         = 0x18;
 291         public static final int REL_LENGTH_MASK         = 0x3;
 292         public static final int REL_LENGTH_SHIFT        = 0x19;
 293         public static final int REL_EXTERN_MASK         = 0x1;
 294         public static final int REL_EXTERN_SHIFT        = 0x1b;
 295         public static final int REL_TYPE_MASK           = 0xf;
 296         public static final int REL_TYPE_SHIFT          = 0x1c;
 297 
 298         /* reloc_type_x86_64 defines */
 299 
 300         public static final int X86_64_RELOC_NONE      = 0x0;
 301         public static final int X86_64_RELOC_BRANCH    = 0x2;
 302         public static final int X86_64_RELOC_GOT       = 0x4;
 303         public static final int X86_64_RELOC_GOT_LOAD  = 0x3;
 304         public static final int X86_64_RELOC_SIGNED    = 0x1;
 305         public static final int X86_64_RELOC_UNSIGNED  = 0x0;
 306     }
 307 }