Blame


1 a84cbb2a 2004-04-19 devnull /*
2 a84cbb2a 2004-04-19 devnull * File map routines
3 a84cbb2a 2004-04-19 devnull */
4 a84cbb2a 2004-04-19 devnull #include <u.h>
5 a84cbb2a 2004-04-19 devnull #include <libc.h>
6 a84cbb2a 2004-04-19 devnull #include <bio.h>
7 a84cbb2a 2004-04-19 devnull #include <mach.h>
8 a84cbb2a 2004-04-19 devnull
9 443d6288 2012-02-19 rsc static int fdrw(Map*, Seg*, u64int, void*, uint, int);
10 443d6288 2012-02-19 rsc static int zerorw(Map*, Seg*, u64int, void*, uint, int);
11 443d6288 2012-02-19 rsc static int mrw(Map*, u64int, void*, uint, int);
12 443d6288 2012-02-19 rsc static int datarw(Map*, Seg*, u64int, void*, uint, int);
13 a84cbb2a 2004-04-19 devnull
14 a84cbb2a 2004-04-19 devnull Map*
15 a84cbb2a 2004-04-19 devnull allocmap(void)
16 a84cbb2a 2004-04-19 devnull {
17 a84cbb2a 2004-04-19 devnull return mallocz(sizeof(Map), 1);
18 a84cbb2a 2004-04-19 devnull }
19 a84cbb2a 2004-04-19 devnull
20 a84cbb2a 2004-04-19 devnull void
21 a84cbb2a 2004-04-19 devnull freemap(Map *map)
22 a84cbb2a 2004-04-19 devnull {
23 a84cbb2a 2004-04-19 devnull if(map == nil)
24 a84cbb2a 2004-04-19 devnull return;
25 a84cbb2a 2004-04-19 devnull free(map->seg);
26 a84cbb2a 2004-04-19 devnull free(map);
27 a84cbb2a 2004-04-19 devnull }
28 a84cbb2a 2004-04-19 devnull
29 a84cbb2a 2004-04-19 devnull int
30 a84cbb2a 2004-04-19 devnull addseg(Map *map, Seg seg)
31 a84cbb2a 2004-04-19 devnull {
32 a84cbb2a 2004-04-19 devnull Seg *ss;
33 a84cbb2a 2004-04-19 devnull
34 dd944ec7 2005-01-23 devnull if(map == nil){
35 a84cbb2a 2004-04-19 devnull werrstr("invalid map");
36 a84cbb2a 2004-04-19 devnull return -1;
37 a84cbb2a 2004-04-19 devnull }
38 a84cbb2a 2004-04-19 devnull
39 a84cbb2a 2004-04-19 devnull ss = realloc(map->seg, (map->nseg+1)*sizeof(ss[0]));
40 a84cbb2a 2004-04-19 devnull if(ss == nil)
41 a84cbb2a 2004-04-19 devnull return -1;
42 a84cbb2a 2004-04-19 devnull map->seg = ss;
43 a8763864 2004-07-09 devnull if(seg.rw == 0){
44 a84cbb2a 2004-04-19 devnull if(seg.name && strcmp(seg.name, "zero") == 0)
45 a84cbb2a 2004-04-19 devnull seg.rw = zerorw;
46 a84cbb2a 2004-04-19 devnull else if(seg.p)
47 a84cbb2a 2004-04-19 devnull seg.rw = datarw;
48 a84cbb2a 2004-04-19 devnull else
49 a84cbb2a 2004-04-19 devnull seg.rw = fdrw;
50 a84cbb2a 2004-04-19 devnull }
51 a84cbb2a 2004-04-19 devnull map->seg[map->nseg] = seg;
52 a84cbb2a 2004-04-19 devnull return map->nseg++;
53 a84cbb2a 2004-04-19 devnull }
54 a84cbb2a 2004-04-19 devnull
55 a84cbb2a 2004-04-19 devnull int
56 a84cbb2a 2004-04-19 devnull findseg(Map *map, char *name, char *file)
57 a84cbb2a 2004-04-19 devnull {
58 a84cbb2a 2004-04-19 devnull int i;
59 a84cbb2a 2004-04-19 devnull
60 dd944ec7 2005-01-23 devnull if(map == nil)
61 a84cbb2a 2004-04-19 devnull return -1;
62 a84cbb2a 2004-04-19 devnull for(i=0; i<map->nseg; i++){
63 a84cbb2a 2004-04-19 devnull if(name && (!map->seg[i].name || strcmp(map->seg[i].name, name) != 0))
64 a84cbb2a 2004-04-19 devnull continue;
65 a84cbb2a 2004-04-19 devnull if(file && (!map->seg[i].file || strcmp(map->seg[i].file, file) != 0))
66 a84cbb2a 2004-04-19 devnull continue;
67 a84cbb2a 2004-04-19 devnull return i;
68 a84cbb2a 2004-04-19 devnull }
69 a84cbb2a 2004-04-19 devnull werrstr("segment %s in %s not found", name, file);
70 a84cbb2a 2004-04-19 devnull return -1;
71 a84cbb2a 2004-04-19 devnull }
72 a84cbb2a 2004-04-19 devnull
73 a84cbb2a 2004-04-19 devnull int
74 443d6288 2012-02-19 rsc addrtoseg(Map *map, u64int addr, Seg *sp)
75 a84cbb2a 2004-04-19 devnull {
76 a84cbb2a 2004-04-19 devnull int i;
77 a84cbb2a 2004-04-19 devnull Seg *s;
78 a84cbb2a 2004-04-19 devnull
79 a84cbb2a 2004-04-19 devnull if(map == nil){
80 a84cbb2a 2004-04-19 devnull werrstr("no map");
81 a84cbb2a 2004-04-19 devnull return -1;
82 a84cbb2a 2004-04-19 devnull }
83 a84cbb2a 2004-04-19 devnull for(i=map->nseg-1; i>=0; i--){
84 a84cbb2a 2004-04-19 devnull s = &map->seg[i];
85 a84cbb2a 2004-04-19 devnull if(s->base <= addr && addr-s->base < s->size){
86 a84cbb2a 2004-04-19 devnull if(sp)
87 a84cbb2a 2004-04-19 devnull *sp = *s;
88 a84cbb2a 2004-04-19 devnull return i;
89 a84cbb2a 2004-04-19 devnull }
90 a84cbb2a 2004-04-19 devnull }
91 a84cbb2a 2004-04-19 devnull werrstr("address 0x%lux is not mapped", addr);
92 a84cbb2a 2004-04-19 devnull return -1;
93 a84cbb2a 2004-04-19 devnull }
94 a84cbb2a 2004-04-19 devnull
95 a84cbb2a 2004-04-19 devnull int
96 443d6288 2012-02-19 rsc addrtosegafter(Map *map, u64int addr, Seg *sp)
97 a84cbb2a 2004-04-19 devnull {
98 a84cbb2a 2004-04-19 devnull int i;
99 a84cbb2a 2004-04-19 devnull Seg *s, *best;
100 a84cbb2a 2004-04-19 devnull ulong bdist;
101 a84cbb2a 2004-04-19 devnull
102 a84cbb2a 2004-04-19 devnull if(map == nil){
103 a84cbb2a 2004-04-19 devnull werrstr("no map");
104 a84cbb2a 2004-04-19 devnull return -1;
105 a84cbb2a 2004-04-19 devnull }
106 a84cbb2a 2004-04-19 devnull
107 a84cbb2a 2004-04-19 devnull /*
108 a84cbb2a 2004-04-19 devnull * If segments were sorted this would be easier,
109 a84cbb2a 2004-04-19 devnull * but since segments may overlap, sorting also
110 a84cbb2a 2004-04-19 devnull * requires splitting and rejoining, and that's just
111 a84cbb2a 2004-04-19 devnull * too complicated.
112 a84cbb2a 2004-04-19 devnull */
113 a84cbb2a 2004-04-19 devnull best = nil;
114 a84cbb2a 2004-04-19 devnull bdist = 0;
115 a84cbb2a 2004-04-19 devnull for(i=map->nseg-1; i>=0; i--){
116 a84cbb2a 2004-04-19 devnull s = &map->seg[i];
117 a84cbb2a 2004-04-19 devnull if(s->base > addr){
118 a84cbb2a 2004-04-19 devnull if(best==nil || s->base-addr < bdist){
119 a84cbb2a 2004-04-19 devnull bdist = s->base - addr;
120 a84cbb2a 2004-04-19 devnull best = s;
121 a84cbb2a 2004-04-19 devnull }
122 a84cbb2a 2004-04-19 devnull }
123 a84cbb2a 2004-04-19 devnull }
124 a84cbb2a 2004-04-19 devnull if(best){
125 a84cbb2a 2004-04-19 devnull if(sp)
126 a84cbb2a 2004-04-19 devnull *sp = *best;
127 a84cbb2a 2004-04-19 devnull return best-map->seg;
128 a84cbb2a 2004-04-19 devnull }
129 a84cbb2a 2004-04-19 devnull werrstr("nothing mapped after address 0x%lux", addr);
130 a84cbb2a 2004-04-19 devnull return -1;
131 a84cbb2a 2004-04-19 devnull }
132 a84cbb2a 2004-04-19 devnull
133 a84cbb2a 2004-04-19 devnull void
134 a84cbb2a 2004-04-19 devnull removeseg(Map *map, int i)
135 a84cbb2a 2004-04-19 devnull {
136 a84cbb2a 2004-04-19 devnull if(map == nil)
137 a84cbb2a 2004-04-19 devnull return;
138 a84cbb2a 2004-04-19 devnull if(i < 0 || i >= map->nseg)
139 a84cbb2a 2004-04-19 devnull return;
140 a84cbb2a 2004-04-19 devnull memmove(&map->seg[i], &map->seg[i+1], (map->nseg-(i+1))*sizeof(Seg));
141 a84cbb2a 2004-04-19 devnull map->nseg--;
142 a84cbb2a 2004-04-19 devnull }
143 a84cbb2a 2004-04-19 devnull
144 a84cbb2a 2004-04-19 devnull int
145 443d6288 2012-02-19 rsc get1(Map *map, u64int addr, uchar *a, uint n)
146 a84cbb2a 2004-04-19 devnull {
147 a84cbb2a 2004-04-19 devnull return mrw(map, addr, a, n, 1);
148 a84cbb2a 2004-04-19 devnull }
149 a84cbb2a 2004-04-19 devnull
150 a84cbb2a 2004-04-19 devnull int
151 443d6288 2012-02-19 rsc get2(Map *map, u64int addr, u16int *u)
152 a84cbb2a 2004-04-19 devnull {
153 a84cbb2a 2004-04-19 devnull u16int v;
154 a84cbb2a 2004-04-19 devnull
155 a84cbb2a 2004-04-19 devnull if(mrw(map, addr, &v, 2, 1) < 0)
156 a84cbb2a 2004-04-19 devnull return -1;
157 a84cbb2a 2004-04-19 devnull *u = mach->swap2(v);
158 a84cbb2a 2004-04-19 devnull return 2;
159 a84cbb2a 2004-04-19 devnull }
160 a84cbb2a 2004-04-19 devnull
161 a84cbb2a 2004-04-19 devnull int
162 443d6288 2012-02-19 rsc get4(Map *map, u64int addr, u32int *u)
163 a84cbb2a 2004-04-19 devnull {
164 a84cbb2a 2004-04-19 devnull u32int v;
165 a84cbb2a 2004-04-19 devnull
166 a84cbb2a 2004-04-19 devnull if(mrw(map, addr, &v, 4, 1) < 0)
167 a84cbb2a 2004-04-19 devnull return -1;
168 a84cbb2a 2004-04-19 devnull *u = mach->swap4(v);
169 a84cbb2a 2004-04-19 devnull return 4;
170 a84cbb2a 2004-04-19 devnull }
171 a84cbb2a 2004-04-19 devnull
172 a84cbb2a 2004-04-19 devnull int
173 443d6288 2012-02-19 rsc get8(Map *map, u64int addr, u64int *u)
174 a84cbb2a 2004-04-19 devnull {
175 a84cbb2a 2004-04-19 devnull u64int v;
176 a84cbb2a 2004-04-19 devnull
177 2e965b33 2004-05-05 devnull if(mrw(map, addr, &v, 8, 1) < 0)
178 a84cbb2a 2004-04-19 devnull return -1;
179 a84cbb2a 2004-04-19 devnull *u = mach->swap8(v);
180 a84cbb2a 2004-04-19 devnull return 8;
181 a84cbb2a 2004-04-19 devnull }
182 a84cbb2a 2004-04-19 devnull
183 a84cbb2a 2004-04-19 devnull int
184 443d6288 2012-02-19 rsc geta(Map *map, u64int addr, u64int *u)
185 a84cbb2a 2004-04-19 devnull {
186 443d6288 2012-02-19 rsc u32int v;
187 443d6288 2012-02-19 rsc
188 443d6288 2012-02-19 rsc if(machcpu == &machamd64)
189 443d6288 2012-02-19 rsc return get8(map, addr, u);
190 443d6288 2012-02-19 rsc if(get4(map, addr, &v) < 0)
191 443d6288 2012-02-19 rsc return -1;
192 443d6288 2012-02-19 rsc *u = v;
193 443d6288 2012-02-19 rsc return 4;
194 443d6288 2012-02-19 rsc }
195 443d6288 2012-02-19 rsc
196 443d6288 2012-02-19 rsc int
197 443d6288 2012-02-19 rsc put1(Map *map, u64int addr, uchar *a, uint n)
198 443d6288 2012-02-19 rsc {
199 a84cbb2a 2004-04-19 devnull return mrw(map, addr, a, n, 0);
200 a84cbb2a 2004-04-19 devnull }
201 a84cbb2a 2004-04-19 devnull
202 a84cbb2a 2004-04-19 devnull int
203 443d6288 2012-02-19 rsc put2(Map *map, u64int addr, u16int u)
204 a84cbb2a 2004-04-19 devnull {
205 a84cbb2a 2004-04-19 devnull u = mach->swap2(u);
206 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 2, 0);
207 a84cbb2a 2004-04-19 devnull }
208 a84cbb2a 2004-04-19 devnull
209 a84cbb2a 2004-04-19 devnull int
210 443d6288 2012-02-19 rsc put4(Map *map, u64int addr, u32int u)
211 a84cbb2a 2004-04-19 devnull {
212 a84cbb2a 2004-04-19 devnull u = mach->swap4(u);
213 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 4, 0);
214 a84cbb2a 2004-04-19 devnull }
215 a84cbb2a 2004-04-19 devnull
216 a84cbb2a 2004-04-19 devnull int
217 443d6288 2012-02-19 rsc put8(Map *map, u64int addr, u64int u)
218 a84cbb2a 2004-04-19 devnull {
219 a84cbb2a 2004-04-19 devnull u = mach->swap8(u);
220 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 8, 0);
221 a84cbb2a 2004-04-19 devnull }
222 a84cbb2a 2004-04-19 devnull
223 a84cbb2a 2004-04-19 devnull static Seg*
224 443d6288 2012-02-19 rsc reloc(Map *map, u64int addr, uint n, u64int *off, uint *nn)
225 a84cbb2a 2004-04-19 devnull {
226 a84cbb2a 2004-04-19 devnull int i;
227 4f0073fe 2004-06-11 devnull ulong o;
228 a84cbb2a 2004-04-19 devnull
229 a84cbb2a 2004-04-19 devnull if(map == nil){
230 a84cbb2a 2004-04-19 devnull werrstr("invalid map");
231 a84cbb2a 2004-04-19 devnull return nil;
232 a84cbb2a 2004-04-19 devnull }
233 a84cbb2a 2004-04-19 devnull
234 a84cbb2a 2004-04-19 devnull for(i=map->nseg-1; i>=0; i--){
235 a84cbb2a 2004-04-19 devnull if(map->seg[i].base <= addr){
236 a84cbb2a 2004-04-19 devnull o = addr - map->seg[i].base;
237 a84cbb2a 2004-04-19 devnull if(o >= map->seg[i].size)
238 a84cbb2a 2004-04-19 devnull continue;
239 a84cbb2a 2004-04-19 devnull if(o+n > map->seg[i].size)
240 a84cbb2a 2004-04-19 devnull *nn = map->seg[i].size - o;
241 a84cbb2a 2004-04-19 devnull else
242 a84cbb2a 2004-04-19 devnull *nn = n;
243 a84cbb2a 2004-04-19 devnull *off = o;
244 a84cbb2a 2004-04-19 devnull return &map->seg[i];
245 a84cbb2a 2004-04-19 devnull }
246 a84cbb2a 2004-04-19 devnull }
247 a84cbb2a 2004-04-19 devnull werrstr("address 0x%lux not mapped", addr);
248 a84cbb2a 2004-04-19 devnull return nil;
249 a84cbb2a 2004-04-19 devnull }
250 a84cbb2a 2004-04-19 devnull
251 a84cbb2a 2004-04-19 devnull static int
252 443d6288 2012-02-19 rsc mrw(Map *map, u64int addr, void *a, uint n, int r)
253 a84cbb2a 2004-04-19 devnull {
254 a84cbb2a 2004-04-19 devnull uint nn;
255 a84cbb2a 2004-04-19 devnull uint tot;
256 a84cbb2a 2004-04-19 devnull Seg *s;
257 443d6288 2012-02-19 rsc u64int off;
258 a84cbb2a 2004-04-19 devnull
259 a84cbb2a 2004-04-19 devnull for(tot=0; tot<n; tot+=nn){
260 a84cbb2a 2004-04-19 devnull s = reloc(map, addr+tot, n-tot, &off, &nn);
261 a84cbb2a 2004-04-19 devnull if(s == nil)
262 a84cbb2a 2004-04-19 devnull return -1;
263 a84cbb2a 2004-04-19 devnull if(s->rw(map, s, off, a, nn, r) < 0)
264 a84cbb2a 2004-04-19 devnull return -1;
265 a84cbb2a 2004-04-19 devnull }
266 a84cbb2a 2004-04-19 devnull return 0;
267 a84cbb2a 2004-04-19 devnull }
268 a84cbb2a 2004-04-19 devnull
269 a84cbb2a 2004-04-19 devnull static int
270 443d6288 2012-02-19 rsc fdrw(Map *map, Seg *seg, u64int addr, void *a, uint n, int r)
271 a84cbb2a 2004-04-19 devnull {
272 a84cbb2a 2004-04-19 devnull int nn;
273 a84cbb2a 2004-04-19 devnull uint tot;
274 4f0073fe 2004-06-11 devnull ulong off;
275 a84cbb2a 2004-04-19 devnull
276 a84cbb2a 2004-04-19 devnull USED(map);
277 a84cbb2a 2004-04-19 devnull off = seg->offset + addr;
278 a84cbb2a 2004-04-19 devnull for(tot=0; tot<n; tot+=nn){
279 a84cbb2a 2004-04-19 devnull if(r)
280 a84cbb2a 2004-04-19 devnull nn = pread(seg->fd, a, n-tot, off+tot);
281 a84cbb2a 2004-04-19 devnull else
282 a84cbb2a 2004-04-19 devnull nn = pwrite(seg->fd, a, n-tot, off+tot);
283 a84cbb2a 2004-04-19 devnull if(nn < 0)
284 fa325e9b 2020-01-10 cross return -1;
285 a84cbb2a 2004-04-19 devnull if(nn == 0){
286 a84cbb2a 2004-04-19 devnull werrstr("partial %s at address 0x%lux in %s",
287 a84cbb2a 2004-04-19 devnull r ? "read" : "write", off+tot, seg->file);
288 a84cbb2a 2004-04-19 devnull return -1;
289 a84cbb2a 2004-04-19 devnull }
290 a84cbb2a 2004-04-19 devnull }
291 a84cbb2a 2004-04-19 devnull return 0;
292 a84cbb2a 2004-04-19 devnull }
293 a84cbb2a 2004-04-19 devnull
294 a84cbb2a 2004-04-19 devnull static int
295 443d6288 2012-02-19 rsc zerorw(Map *map, Seg *seg, u64int addr, void *a, uint n, int r)
296 a84cbb2a 2004-04-19 devnull {
297 a84cbb2a 2004-04-19 devnull USED(map);
298 a84cbb2a 2004-04-19 devnull USED(seg);
299 a84cbb2a 2004-04-19 devnull USED(addr);
300 a84cbb2a 2004-04-19 devnull
301 a84cbb2a 2004-04-19 devnull if(r==0){
302 a84cbb2a 2004-04-19 devnull werrstr("cannot write zero segment");
303 a84cbb2a 2004-04-19 devnull return -1;
304 a84cbb2a 2004-04-19 devnull }
305 a84cbb2a 2004-04-19 devnull memset(a, 0, n);
306 a84cbb2a 2004-04-19 devnull return 0;
307 a84cbb2a 2004-04-19 devnull }
308 a84cbb2a 2004-04-19 devnull
309 a84cbb2a 2004-04-19 devnull static int
310 443d6288 2012-02-19 rsc datarw(Map *map, Seg *seg, u64int addr, void *a, uint n, int r)
311 a84cbb2a 2004-04-19 devnull {
312 a84cbb2a 2004-04-19 devnull USED(map);
313 a84cbb2a 2004-04-19 devnull
314 a84cbb2a 2004-04-19 devnull if(r)
315 a84cbb2a 2004-04-19 devnull memmove(a, seg->p+addr, n);
316 a84cbb2a 2004-04-19 devnull else
317 a84cbb2a 2004-04-19 devnull memmove(seg->p+addr, a, n);
318 a84cbb2a 2004-04-19 devnull return 0;
319 a84cbb2a 2004-04-19 devnull }