Blame


1 a84cbb2a 2004-04-19 devnull #include <u.h>
2 a84cbb2a 2004-04-19 devnull #include <libc.h>
3 a84cbb2a 2004-04-19 devnull #include <mach.h>
4 a84cbb2a 2004-04-19 devnull #include "macho.h"
5 a84cbb2a 2004-04-19 devnull
6 a84cbb2a 2004-04-19 devnull /*
7 a84cbb2a 2004-04-19 devnull http://www.channelu.com/NeXT/NeXTStep/3.3/nd/DevTools/14_MachO/MachO.htmld/
8 a84cbb2a 2004-04-19 devnull */
9 a84cbb2a 2004-04-19 devnull
10 a84cbb2a 2004-04-19 devnull Macho*
11 a84cbb2a 2004-04-19 devnull machoopen(char *name)
12 a84cbb2a 2004-04-19 devnull {
13 a84cbb2a 2004-04-19 devnull int fd;
14 a84cbb2a 2004-04-19 devnull Macho *m;
15 a84cbb2a 2004-04-19 devnull
16 a84cbb2a 2004-04-19 devnull if((fd = open(name, OREAD)) < 0)
17 a84cbb2a 2004-04-19 devnull return nil;
18 a84cbb2a 2004-04-19 devnull m = machoinit(fd);
19 a84cbb2a 2004-04-19 devnull if(m == nil)
20 a84cbb2a 2004-04-19 devnull close(fd);
21 a84cbb2a 2004-04-19 devnull return m;
22 a84cbb2a 2004-04-19 devnull }
23 a84cbb2a 2004-04-19 devnull
24 a84cbb2a 2004-04-19 devnull static int
25 a84cbb2a 2004-04-19 devnull unpackseg(uchar *p, Macho *m, MachoCmd *c, uint type, uint sz)
26 a84cbb2a 2004-04-19 devnull {
27 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
28 a84cbb2a 2004-04-19 devnull
29 a84cbb2a 2004-04-19 devnull e4 = m->e4;
30 a84cbb2a 2004-04-19 devnull
31 a84cbb2a 2004-04-19 devnull c->type = type;
32 a84cbb2a 2004-04-19 devnull c->size = sz;
33 a84cbb2a 2004-04-19 devnull switch(type){
34 a84cbb2a 2004-04-19 devnull default:
35 a84cbb2a 2004-04-19 devnull return -1;
36 a84cbb2a 2004-04-19 devnull case MachoCmdSegment:
37 a84cbb2a 2004-04-19 devnull if(sz < 56)
38 a84cbb2a 2004-04-19 devnull return -1;
39 a84cbb2a 2004-04-19 devnull strecpy(c->seg.name, c->seg.name+sizeof c->seg.name, (char*)p+8);
40 a84cbb2a 2004-04-19 devnull c->seg.vmaddr = e4(p+24);
41 a84cbb2a 2004-04-19 devnull c->seg.vmsize = e4(p+28);
42 a84cbb2a 2004-04-19 devnull c->seg.fileoff = e4(p+32);
43 a84cbb2a 2004-04-19 devnull c->seg.filesz = e4(p+36);
44 a84cbb2a 2004-04-19 devnull c->seg.maxprot = e4(p+40);
45 a84cbb2a 2004-04-19 devnull c->seg.initprot = e4(p+44);
46 a84cbb2a 2004-04-19 devnull c->seg.nsect = e4(p+48);
47 a84cbb2a 2004-04-19 devnull c->seg.flags = e4(p+52);
48 a84cbb2a 2004-04-19 devnull break;
49 a84cbb2a 2004-04-19 devnull case MachoCmdSymtab:
50 a84cbb2a 2004-04-19 devnull if(sz < 24)
51 a84cbb2a 2004-04-19 devnull return -1;
52 a84cbb2a 2004-04-19 devnull c->sym.symoff = e4(p+8);
53 a84cbb2a 2004-04-19 devnull c->sym.nsyms = e4(p+12);
54 a84cbb2a 2004-04-19 devnull c->sym.stroff = e4(p+16);
55 a84cbb2a 2004-04-19 devnull c->sym.strsize = e4(p+20);
56 a84cbb2a 2004-04-19 devnull break;
57 a84cbb2a 2004-04-19 devnull }
58 a84cbb2a 2004-04-19 devnull return 0;
59 a84cbb2a 2004-04-19 devnull }
60 a84cbb2a 2004-04-19 devnull
61 a84cbb2a 2004-04-19 devnull
62 a84cbb2a 2004-04-19 devnull Macho*
63 a84cbb2a 2004-04-19 devnull machoinit(int fd)
64 a84cbb2a 2004-04-19 devnull {
65 a84cbb2a 2004-04-19 devnull int i;
66 a84cbb2a 2004-04-19 devnull uchar hdr[7*4], *cmdp;
67 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
68 a84cbb2a 2004-04-19 devnull ulong ncmd, cmdsz, ty, sz, off;
69 a84cbb2a 2004-04-19 devnull Macho *m;
70 a84cbb2a 2004-04-19 devnull
71 a84cbb2a 2004-04-19 devnull if(seek(fd, 0, 0) < 0 || readn(fd, hdr, sizeof hdr) != sizeof hdr)
72 a84cbb2a 2004-04-19 devnull return nil;
73 a84cbb2a 2004-04-19 devnull
74 a84cbb2a 2004-04-19 devnull if(beload4(hdr) == 0xFEEDFACE)
75 a84cbb2a 2004-04-19 devnull e4 = beload4;
76 a84cbb2a 2004-04-19 devnull else if(leload4(hdr) == 0xFEEDFACE)
77 a84cbb2a 2004-04-19 devnull e4 = leload4;
78 a84cbb2a 2004-04-19 devnull else{
79 a84cbb2a 2004-04-19 devnull werrstr("bad magic - not mach-o file");
80 a84cbb2a 2004-04-19 devnull return nil;
81 a84cbb2a 2004-04-19 devnull }
82 a84cbb2a 2004-04-19 devnull
83 a84cbb2a 2004-04-19 devnull ncmd = e4(hdr+4*4);
84 a84cbb2a 2004-04-19 devnull cmdsz = e4(hdr+5*4);
85 a84cbb2a 2004-04-19 devnull if(ncmd > 0x10000 || cmdsz >= 0x01000000){
86 a84cbb2a 2004-04-19 devnull werrstr("implausible mach-o header ncmd=%lud cmdsz=%lud", ncmd, cmdsz);
87 a84cbb2a 2004-04-19 devnull return nil;
88 a84cbb2a 2004-04-19 devnull }
89 a84cbb2a 2004-04-19 devnull
90 a84cbb2a 2004-04-19 devnull m = mallocz(sizeof(*m)+ncmd*sizeof(MachoCmd)+cmdsz, 1);
91 a84cbb2a 2004-04-19 devnull if(m == nil)
92 a84cbb2a 2004-04-19 devnull return nil;
93 a84cbb2a 2004-04-19 devnull
94 a84cbb2a 2004-04-19 devnull m->fd = fd;
95 a84cbb2a 2004-04-19 devnull m->e4 = e4;
96 a84cbb2a 2004-04-19 devnull m->cputype = e4(hdr+1*4);
97 a84cbb2a 2004-04-19 devnull m->subcputype = e4(hdr+2*4);
98 a84cbb2a 2004-04-19 devnull m->filetype = e4(hdr+3*4);
99 a84cbb2a 2004-04-19 devnull m->ncmd = ncmd;
100 a84cbb2a 2004-04-19 devnull m->flags = e4(hdr+6*4);
101 a84cbb2a 2004-04-19 devnull
102 a84cbb2a 2004-04-19 devnull m->cmd = (MachoCmd*)(m+1);
103 a84cbb2a 2004-04-19 devnull off = sizeof hdr;
104 a84cbb2a 2004-04-19 devnull cmdp = (uchar*)(m->cmd+ncmd);
105 a84cbb2a 2004-04-19 devnull if(readn(fd, cmdp, cmdsz) != cmdsz){
106 a84cbb2a 2004-04-19 devnull werrstr("reading cmds: %r");
107 a84cbb2a 2004-04-19 devnull free(m);
108 a84cbb2a 2004-04-19 devnull return nil;
109 a84cbb2a 2004-04-19 devnull }
110 a84cbb2a 2004-04-19 devnull
111 a84cbb2a 2004-04-19 devnull for(i=0; i<ncmd; i++){
112 a84cbb2a 2004-04-19 devnull ty = e4(cmdp);
113 a84cbb2a 2004-04-19 devnull sz = e4(cmdp+4);
114 a84cbb2a 2004-04-19 devnull m->cmd[i].off = off;
115 a84cbb2a 2004-04-19 devnull unpackseg(cmdp, m, &m->cmd[i], ty, sz);
116 a84cbb2a 2004-04-19 devnull cmdp += sz;
117 a84cbb2a 2004-04-19 devnull off += sz;
118 a84cbb2a 2004-04-19 devnull }
119 a84cbb2a 2004-04-19 devnull
120 a84cbb2a 2004-04-19 devnull return m;
121 a84cbb2a 2004-04-19 devnull }
122 a84cbb2a 2004-04-19 devnull
123 a84cbb2a 2004-04-19 devnull void
124 a84cbb2a 2004-04-19 devnull machoclose(Macho *m)
125 a84cbb2a 2004-04-19 devnull {
126 a84cbb2a 2004-04-19 devnull close(m->fd);
127 a84cbb2a 2004-04-19 devnull free(m);
128 a84cbb2a 2004-04-19 devnull }