2 a84cbb2a 2004-04-19 devnull * File map routines
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>
9 4f0073fe 2004-06-11 devnull static int fdrw(Map*, Seg*, ulong, void*, uint, int);
10 4f0073fe 2004-06-11 devnull static int zerorw(Map*, Seg*, ulong, void*, uint, int);
11 4f0073fe 2004-06-11 devnull static int mrw(Map*, ulong, void*, uint, int);
12 4f0073fe 2004-06-11 devnull static int datarw(Map*, Seg*, ulong, void*, uint, int);
15 a84cbb2a 2004-04-19 devnull allocmap(void)
17 a84cbb2a 2004-04-19 devnull return mallocz(sizeof(Map), 1);
21 a84cbb2a 2004-04-19 devnull freemap(Map *map)
23 a84cbb2a 2004-04-19 devnull if(map == nil)
25 a84cbb2a 2004-04-19 devnull free(map->seg);
26 a84cbb2a 2004-04-19 devnull free(map);
30 a84cbb2a 2004-04-19 devnull addseg(Map *map, Seg seg)
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;
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;
49 a84cbb2a 2004-04-19 devnull seg.rw = fdrw;
51 a84cbb2a 2004-04-19 devnull map->seg[map->nseg] = seg;
52 a84cbb2a 2004-04-19 devnull return map->nseg++;
56 a84cbb2a 2004-04-19 devnull findseg(Map *map, char *name, char *file)
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;
69 a84cbb2a 2004-04-19 devnull werrstr("segment %s in %s not found", name, file);
70 a84cbb2a 2004-04-19 devnull return -1;
74 4f0073fe 2004-06-11 devnull addrtoseg(Map *map, ulong addr, Seg *sp)
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;
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){
87 a84cbb2a 2004-04-19 devnull *sp = *s;
88 a84cbb2a 2004-04-19 devnull return i;
91 a84cbb2a 2004-04-19 devnull werrstr("address 0x%lux is not mapped", addr);
92 a84cbb2a 2004-04-19 devnull return -1;
96 4f0073fe 2004-06-11 devnull addrtosegafter(Map *map, ulong addr, Seg *sp)
99 a84cbb2a 2004-04-19 devnull Seg *s, *best;
100 a84cbb2a 2004-04-19 devnull ulong bdist;
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;
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.
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;
124 a84cbb2a 2004-04-19 devnull if(best){
126 a84cbb2a 2004-04-19 devnull *sp = *best;
127 a84cbb2a 2004-04-19 devnull return best-map->seg;
129 a84cbb2a 2004-04-19 devnull werrstr("nothing mapped after address 0x%lux", addr);
130 a84cbb2a 2004-04-19 devnull return -1;
134 a84cbb2a 2004-04-19 devnull removeseg(Map *map, int i)
136 a84cbb2a 2004-04-19 devnull if(map == nil)
138 a84cbb2a 2004-04-19 devnull if(i < 0 || i >= map->nseg)
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--;
145 4f0073fe 2004-06-11 devnull get1(Map *map, ulong addr, uchar *a, uint n)
147 a84cbb2a 2004-04-19 devnull return mrw(map, addr, a, n, 1);
151 4f0073fe 2004-06-11 devnull get2(Map *map, ulong addr, u16int *u)
153 a84cbb2a 2004-04-19 devnull u16int v;
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;
162 4f0073fe 2004-06-11 devnull get4(Map *map, ulong addr, u32int *u)
164 a84cbb2a 2004-04-19 devnull u32int v;
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;
173 4f0073fe 2004-06-11 devnull get8(Map *map, ulong addr, u64int *u)
175 a84cbb2a 2004-04-19 devnull u64int v;
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;
184 4f0073fe 2004-06-11 devnull put1(Map *map, ulong addr, uchar *a, uint n)
186 a84cbb2a 2004-04-19 devnull return mrw(map, addr, a, n, 0);
190 4f0073fe 2004-06-11 devnull put2(Map *map, ulong addr, u16int u)
192 a84cbb2a 2004-04-19 devnull u = mach->swap2(u);
193 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 2, 0);
197 4f0073fe 2004-06-11 devnull put4(Map *map, ulong addr, u32int u)
199 a84cbb2a 2004-04-19 devnull u = mach->swap4(u);
200 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 4, 0);
204 4f0073fe 2004-06-11 devnull put8(Map *map, ulong addr, u64int u)
206 a84cbb2a 2004-04-19 devnull u = mach->swap8(u);
207 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 8, 0);
210 a84cbb2a 2004-04-19 devnull static Seg*
211 4f0073fe 2004-06-11 devnull reloc(Map *map, ulong addr, uint n, ulong *off, uint *nn)
214 4f0073fe 2004-06-11 devnull ulong o;
216 a84cbb2a 2004-04-19 devnull if(map == nil){
217 a84cbb2a 2004-04-19 devnull werrstr("invalid map");
218 a84cbb2a 2004-04-19 devnull return nil;
221 a84cbb2a 2004-04-19 devnull for(i=map->nseg-1; i>=0; i--){
222 a84cbb2a 2004-04-19 devnull if(map->seg[i].base <= addr){
223 a84cbb2a 2004-04-19 devnull o = addr - map->seg[i].base;
224 a84cbb2a 2004-04-19 devnull if(o >= map->seg[i].size)
225 a84cbb2a 2004-04-19 devnull continue;
226 a84cbb2a 2004-04-19 devnull if(o+n > map->seg[i].size)
227 a84cbb2a 2004-04-19 devnull *nn = map->seg[i].size - o;
229 a84cbb2a 2004-04-19 devnull *nn = n;
230 a84cbb2a 2004-04-19 devnull *off = o;
231 a84cbb2a 2004-04-19 devnull return &map->seg[i];
234 a84cbb2a 2004-04-19 devnull werrstr("address 0x%lux not mapped", addr);
235 a84cbb2a 2004-04-19 devnull return nil;
238 a84cbb2a 2004-04-19 devnull static int
239 4f0073fe 2004-06-11 devnull mrw(Map *map, ulong addr, void *a, uint n, int r)
241 a84cbb2a 2004-04-19 devnull uint nn;
242 a84cbb2a 2004-04-19 devnull uint tot;
244 4f0073fe 2004-06-11 devnull ulong off;
246 a84cbb2a 2004-04-19 devnull for(tot=0; tot<n; tot+=nn){
247 a84cbb2a 2004-04-19 devnull s = reloc(map, addr+tot, n-tot, &off, &nn);
248 a84cbb2a 2004-04-19 devnull if(s == nil)
249 a84cbb2a 2004-04-19 devnull return -1;
250 a84cbb2a 2004-04-19 devnull if(s->rw(map, s, off, a, nn, r) < 0)
251 a84cbb2a 2004-04-19 devnull return -1;
253 a84cbb2a 2004-04-19 devnull return 0;
256 a84cbb2a 2004-04-19 devnull static int
257 4f0073fe 2004-06-11 devnull fdrw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
260 a84cbb2a 2004-04-19 devnull uint tot;
261 4f0073fe 2004-06-11 devnull ulong off;
263 a84cbb2a 2004-04-19 devnull USED(map);
264 a84cbb2a 2004-04-19 devnull off = seg->offset + addr;
265 a84cbb2a 2004-04-19 devnull for(tot=0; tot<n; tot+=nn){
267 a84cbb2a 2004-04-19 devnull nn = pread(seg->fd, a, n-tot, off+tot);
269 a84cbb2a 2004-04-19 devnull nn = pwrite(seg->fd, a, n-tot, off+tot);
270 a84cbb2a 2004-04-19 devnull if(nn < 0)
271 a84cbb2a 2004-04-19 devnull return -1;
272 a84cbb2a 2004-04-19 devnull if(nn == 0){
273 a84cbb2a 2004-04-19 devnull werrstr("partial %s at address 0x%lux in %s",
274 a84cbb2a 2004-04-19 devnull r ? "read" : "write", off+tot, seg->file);
275 a84cbb2a 2004-04-19 devnull return -1;
278 a84cbb2a 2004-04-19 devnull return 0;
281 a84cbb2a 2004-04-19 devnull static int
282 4f0073fe 2004-06-11 devnull zerorw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
284 a84cbb2a 2004-04-19 devnull USED(map);
285 a84cbb2a 2004-04-19 devnull USED(seg);
286 a84cbb2a 2004-04-19 devnull USED(addr);
288 a84cbb2a 2004-04-19 devnull if(r==0){
289 a84cbb2a 2004-04-19 devnull werrstr("cannot write zero segment");
290 a84cbb2a 2004-04-19 devnull return -1;
292 a84cbb2a 2004-04-19 devnull memset(a, 0, n);
293 a84cbb2a 2004-04-19 devnull return 0;
296 a84cbb2a 2004-04-19 devnull static int
297 4f0073fe 2004-06-11 devnull datarw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
299 a84cbb2a 2004-04-19 devnull USED(map);
302 a84cbb2a 2004-04-19 devnull memmove(a, seg->p+addr, n);
304 a84cbb2a 2004-04-19 devnull memmove(seg->p+addr, a, n);
305 a84cbb2a 2004-04-19 devnull return 0;