URI:
       tcrackmacho.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tcrackmacho.c (3930B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <mach.h>
            4 #include "macho.h"
            5 
            6 static int mapmacho(Fhdr *fp, u64int base, Map *map, Regs**);
            7 
            8 static struct
            9 {
           10         uint etype;
           11         uint mtype;
           12         Mach *mach;
           13         char *name;
           14         int (*coreregs)(Macho*, uchar**);
           15 } mtab[] =
           16 {
           17         MachoCpuPower,        MPOWER,                &machpower,                 "powerpc",        coreregsmachopower,
           18 };
           19 
           20 static uchar*
           21 load(int fd, ulong off, int size)
           22 {
           23         uchar *a;
           24 
           25         a = malloc(size);
           26         if(a == nil)
           27                 return nil;
           28         if(seek(fd, off, 0) < 0 || readn(fd, a, size) != size){
           29                 free(a);
           30                 return nil;
           31         }
           32         return a;
           33 }
           34 
           35 int
           36 crackmacho(int fd, Fhdr *fp)
           37 {
           38         int i;
           39         Macho *m;
           40 
           41         if((m = machoinit(fd)) == nil)
           42                 return -1;
           43 
           44         fp->fd = fd;
           45         fp->macho = m;
           46 
           47         for(i=0; i<nelem(mtab); i++){
           48                 if(m->cputype != mtab[i].etype)
           49                         continue;
           50                 fp->mach = mtab[i].mach;
           51                 fp->mtype = mtab[i].mtype;
           52                 fp->mname = mtab[i].name;
           53                 m->coreregs = mtab[i].coreregs;
           54                 break;
           55         }
           56         if(i == nelem(mtab)){
           57                 werrstr("unsupported cpu type %ud", m->cputype);
           58                 goto err;
           59         }
           60 
           61         fp->atype = AMACH;
           62         fp->aname = "mach";
           63 
           64         if(mach == nil)
           65                 mach = fp->mach;
           66 
           67         switch(m->filetype){
           68         default:
           69                 werrstr("unsupported macho file type %lud", m->filetype);
           70                 goto err;
           71         case MachoFileObject:
           72                 fp->ftype = FOBJ;
           73                 fp->fname = "object";
           74                 break;
           75         case MachoFileExecutable:
           76                 fp->ftype = FEXEC;
           77                 fp->fname = "executable";
           78                 break;
           79         case MachoFileFvmlib:
           80                 fp->ftype = FSHLIB;
           81                 fp->fname = "shared library";
           82                 break;
           83         case MachoFileCore:
           84                 fp->ftype = FCORE;
           85                 fp->fname = "core";
           86                 break;
           87         case MachoFilePreload:
           88                 fp->ftype = FBOOT;
           89                 fp->fname = "preloaded executable";
           90                 break;
           91         }
           92 
           93         fp->txtaddr = fp->dataddr = 0;
           94         fp->txtsz = fp->datsz = 0;
           95         for(i=0; i<m->ncmd; i++){
           96                 if(m->cmd[i].type != MachoCmdSegment)
           97                         continue;
           98                 if(strcmp(m->cmd[i].seg.name, "__TEXT") == 0){
           99                         fp->txtaddr = m->cmd[i].seg.vmaddr;
          100                         fp->txtsz = m->cmd[i].seg.vmsize;
          101                         fp->txtoff = m->cmd[i].seg.fileoff;
          102                 }
          103                 if(strcmp(m->cmd[i].seg.name, "__DATA") == 0){
          104                         fp->dataddr = m->cmd[i].seg.vmaddr;
          105                         fp->datsz = m->cmd[i].seg.filesz;
          106                         fp->datoff = m->cmd[i].seg.fileoff;
          107                         fp->bsssz = m->cmd[i].seg.vmsize - fp->datsz;
          108                 }
          109         }
          110 
          111         fp->map = mapmacho;
          112         fp->syminit = symmacho;
          113 
          114         for(i=0; i<m->ncmd; i++)
          115                 if(m->cmd[i].type == MachoCmdSymtab)
          116                         break;
          117         if(i < m->ncmd){
          118                 fp->stabs.stabbase = load(fp->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsym*16);
          119                 fp->stabs.stabsize = m->cmd[i].sym.nsym*16;
          120                 fp->stabs.strbase = (char*)load(fp->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
          121                 if(fp->stabs.stabbase == nil || fp->stabs.strbase == nil){
          122                         fp->stabs.stabbase = nil;
          123                         fp->stabs.strbase = nil;
          124                 }else{
          125                         fp->stabs.strsize = m->cmd[i].sym.strsize;
          126                         fp->stabs.e2 = (m->e4==beload4 ? beload2 : leload2);
          127                         fp->stabs.e4 = m->e4;
          128                 }
          129         }
          130 
          131         return 0;
          132 
          133 err:
          134         machoclose(m);
          135         return -1;
          136 }
          137 
          138 static int
          139 mapmacho(Fhdr *fp, u64int base, Map *map, Regs **rp)
          140 {
          141         int i, n;
          142         uchar *u;
          143         Macho *m;
          144         MachoCmd *c;
          145         Seg s;
          146         UregRegs *r;
          147 
          148         m = fp->macho;
          149         if(m == nil){
          150                 werrstr("not a macho file");
          151                 return -1;
          152         }
          153 
          154         for(i=0; i<m->ncmd; i++){
          155                 c = &m->cmd[i];
          156                 if(c->type != MachoCmdSegment)
          157                         continue;
          158                 if(c->seg.filesz){
          159                         memset(&s, 0, sizeof s);
          160                         s.file = fp->filename;
          161                         s.fd = fp->fd;
          162                         if(fp->ftype == FCORE)
          163                                 s.name = "core";
          164                         else if(strcmp(c->seg.name, "__DATA") == 0)
          165                                 s.name = "data";
          166                         else
          167                                 s.name = "text";
          168                         s.base = base+c->seg.vmaddr;
          169                         s.size = c->seg.filesz;
          170                         s.offset = c->seg.fileoff;
          171                         if(addseg(map, s) < 0)
          172                                 return -1;
          173                 }
          174                 if(c->seg.filesz < c->seg.vmsize){
          175                         memset(&s, 0, sizeof s);
          176                         s.name = "zero";
          177                         s.base = base + c->seg.vmaddr + c->seg.filesz;
          178                         s.size = c->seg.vmsize - c->seg.filesz;
          179                         if(addseg(map, s) < 0)
          180                                 return -1;
          181                 }
          182         }
          183 
          184         if(fp->ftype == FCORE && m->coreregs){
          185                 n = m->coreregs(m, &u);
          186                 if(n < 0){
          187                         fprint(2, "mapping registers: %r\n");
          188                         goto noregs;
          189                 }
          190                 if((r = mallocz(sizeof *r, 1)) == nil)
          191                         return -1;
          192                 r->r.rw = _uregrw;
          193                 r->ureg = u;
          194                 *rp = &r->r;
          195         }
          196 noregs:
          197         return 0;
          198 }