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