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 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);
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 4f0073fe 2004-06-11 devnull addrtoseg(Map *map, ulong 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 4f0073fe 2004-06-11 devnull addrtosegafter(Map *map, ulong 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 4f0073fe 2004-06-11 devnull get1(Map *map, ulong 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 4f0073fe 2004-06-11 devnull get2(Map *map, ulong 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 4f0073fe 2004-06-11 devnull get4(Map *map, ulong 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 4f0073fe 2004-06-11 devnull get8(Map *map, ulong 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 4f0073fe 2004-06-11 devnull put1(Map *map, ulong addr, uchar *a, uint n)
185 a84cbb2a 2004-04-19 devnull {
186 a84cbb2a 2004-04-19 devnull return mrw(map, addr, a, n, 0);
187 a84cbb2a 2004-04-19 devnull }
188 a84cbb2a 2004-04-19 devnull
189 a84cbb2a 2004-04-19 devnull int
190 4f0073fe 2004-06-11 devnull put2(Map *map, ulong addr, u16int u)
191 a84cbb2a 2004-04-19 devnull {
192 a84cbb2a 2004-04-19 devnull u = mach->swap2(u);
193 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 2, 0);
194 a84cbb2a 2004-04-19 devnull }
195 a84cbb2a 2004-04-19 devnull
196 a84cbb2a 2004-04-19 devnull int
197 4f0073fe 2004-06-11 devnull put4(Map *map, ulong addr, u32int u)
198 a84cbb2a 2004-04-19 devnull {
199 a84cbb2a 2004-04-19 devnull u = mach->swap4(u);
200 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 4, 0);
201 a84cbb2a 2004-04-19 devnull }
202 a84cbb2a 2004-04-19 devnull
203 a84cbb2a 2004-04-19 devnull int
204 4f0073fe 2004-06-11 devnull put8(Map *map, ulong addr, u64int u)
205 a84cbb2a 2004-04-19 devnull {
206 a84cbb2a 2004-04-19 devnull u = mach->swap8(u);
207 a84cbb2a 2004-04-19 devnull return mrw(map, addr, &u, 8, 0);
208 a84cbb2a 2004-04-19 devnull }
209 a84cbb2a 2004-04-19 devnull
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)
212 a84cbb2a 2004-04-19 devnull {
213 a84cbb2a 2004-04-19 devnull int i;
214 4f0073fe 2004-06-11 devnull ulong o;
215 a84cbb2a 2004-04-19 devnull
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;
219 a84cbb2a 2004-04-19 devnull }
220 a84cbb2a 2004-04-19 devnull
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;
228 a84cbb2a 2004-04-19 devnull else
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];
232 a84cbb2a 2004-04-19 devnull }
233 a84cbb2a 2004-04-19 devnull }
234 a84cbb2a 2004-04-19 devnull werrstr("address 0x%lux not mapped", addr);
235 a84cbb2a 2004-04-19 devnull return nil;
236 a84cbb2a 2004-04-19 devnull }
237 a84cbb2a 2004-04-19 devnull
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)
240 a84cbb2a 2004-04-19 devnull {
241 a84cbb2a 2004-04-19 devnull uint nn;
242 a84cbb2a 2004-04-19 devnull uint tot;
243 a84cbb2a 2004-04-19 devnull Seg *s;
244 4f0073fe 2004-06-11 devnull ulong off;
245 a84cbb2a 2004-04-19 devnull
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;
252 a84cbb2a 2004-04-19 devnull }
253 a84cbb2a 2004-04-19 devnull return 0;
254 a84cbb2a 2004-04-19 devnull }
255 a84cbb2a 2004-04-19 devnull
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)
258 a84cbb2a 2004-04-19 devnull {
259 a84cbb2a 2004-04-19 devnull int nn;
260 a84cbb2a 2004-04-19 devnull uint tot;
261 4f0073fe 2004-06-11 devnull ulong off;
262 a84cbb2a 2004-04-19 devnull
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){
266 a84cbb2a 2004-04-19 devnull if(r)
267 a84cbb2a 2004-04-19 devnull nn = pread(seg->fd, a, n-tot, off+tot);
268 a84cbb2a 2004-04-19 devnull else
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;
276 a84cbb2a 2004-04-19 devnull }
277 a84cbb2a 2004-04-19 devnull }
278 a84cbb2a 2004-04-19 devnull return 0;
279 a84cbb2a 2004-04-19 devnull }
280 a84cbb2a 2004-04-19 devnull
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)
283 a84cbb2a 2004-04-19 devnull {
284 a84cbb2a 2004-04-19 devnull USED(map);
285 a84cbb2a 2004-04-19 devnull USED(seg);
286 a84cbb2a 2004-04-19 devnull USED(addr);
287 a84cbb2a 2004-04-19 devnull
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;
291 a84cbb2a 2004-04-19 devnull }
292 a84cbb2a 2004-04-19 devnull memset(a, 0, n);
293 a84cbb2a 2004-04-19 devnull return 0;
294 a84cbb2a 2004-04-19 devnull }
295 a84cbb2a 2004-04-19 devnull
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)
298 a84cbb2a 2004-04-19 devnull {
299 a84cbb2a 2004-04-19 devnull USED(map);
300 a84cbb2a 2004-04-19 devnull
301 a84cbb2a 2004-04-19 devnull if(r)
302 a84cbb2a 2004-04-19 devnull memmove(a, seg->p+addr, n);
303 a84cbb2a 2004-04-19 devnull else
304 a84cbb2a 2004-04-19 devnull memmove(seg->p+addr, a, n);
305 a84cbb2a 2004-04-19 devnull return 0;
306 a84cbb2a 2004-04-19 devnull }