|
|
1.1 root 1: /*
2: * functions to read and write an executable or file image
3: */
4:
5: #include <u.h>
6: #include <libc.h>
7: #include <bio.h>
8: #include <mach.h>
9:
10: static int mget(Map*, ulong, char*, int);
11: static int mput(Map*, ulong, char*, int);
12: static int reloc(Map*, ulong, long*);
13:
14: /*
15: * routines to get/put various types
16: */
17:
18: int
19: get4(Map *map, ulong addr, long *x)
20: {
21: if (!map) {
22: werrstr("get4: invalid map");
23: return -1;
24: }
25:
26: if (map->fd < 0) {
27: *x = addr;
28: return 1;
29: }
30: if (mget(map, addr, (char *)x, 4) < 0)
31: return -1;
32: *x = machdata->swal(*x);
33: return (1);
34: }
35:
36: int
37: get2(Map *map, ulong addr, ushort *x)
38: {
39: if (!map) {
40: werrstr("get2: invalid map");
41: return -1;
42: }
43:
44: if (map->fd < 0) {
45: *x = addr;
46: return 1;
47: }
48: if (mget(map, addr, (char *)x, 2) < 0)
49: return -1;
50: *x = machdata->swab(*x);
51: return (1);
52: }
53:
54: int
55: get1(Map *map, ulong addr, uchar *x, int size)
56: {
57: uchar *cp;
58:
59: if (!map) {
60: werrstr("get1: invalid map");
61: return -1;
62: }
63:
64: if (map->fd < 0) {
65: cp = (uchar*)&addr;
66: while (cp < (uchar*)(&addr+1) && size-- > 0)
67: *x++ = *cp++;
68: while (size-- > 0)
69: *x++ = 0;
70: } else
71: return mget(map, addr, (char*)x, size);
72: return 1;
73: }
74:
75: int
76: put4(Map *map, ulong addr, long v)
77: {
78: if (!map || map->fd < 0) {
79: werrstr("put4: missing or unopened map");
80: return -1;
81: }
82: v = machdata->swal(v);
83: return mput(map, addr, (char *)&v, 4);
84: }
85:
86: int
87: put2(Map *map, ulong addr, ushort v)
88: {
89: if (!map || map->fd < 0) {
90: werrstr("put2: missing or unopened map");
91: return -1;
92: }
93: v = machdata->swab(v);
94: return mput(map, addr, (char *)&v, 2);
95: }
96:
97: int
98: put1(Map *map, ulong addr, uchar *v, int size)
99: {
100: if (!map || map->fd < 0) {
101: werrstr("put1: missing or unopened map");
102: return -1;
103: }
104: return mput(map, addr, (char *)v, size);
105: }
106:
107: static int
108: mget(Map *map, ulong addr, char *buf, int size)
109: {
110: long off;
111: int i, j, k;
112:
113: if (reloc(map, addr, &off) < 0)
114: return -1;
115:
116: seek(map->fd, off, 0);
117: for (i = j = 0; i < 2; i++) { /* in case read crosses page */
118: k = read(map->fd, buf, size-j);
119: if (k < 0) {
120: werrstr("can't read address %lux: %r", addr);
121: return -1;
122: }
123: j += k;
124: if (j == size)
125: return j;
126: }
127: werrstr("partial read at address %lux", addr);
128: return -1;
129: }
130:
131: static int
132: mput(Map *map, ulong addr, char *buf, int size)
133: {
134: long off;
135: int i, j, k;
136:
137: if (reloc(map, addr,&off) < 0)
138: return -1;
139:
140: seek(map->fd, off, 0);
141: for (i = j = 0; i < 2; i++) { /* in case read crosses page */
142: k = write(map->fd, buf, size-j);
143: if (k < 0) {
144: werrstr("can't write address %lux: %r", addr);
145: return -1;
146: }
147: j += k;
148: if (j == size)
149: return j;
150: }
151: werrstr("partial write at address %lux", addr);
152: return -1;
153: }
154:
155: /*
156: * convert address to file offset; returns nonzero if ok
157: */
158: static int
159: reloc(Map *map, ulong addr, long *offp)
160: {
161: int i;
162:
163: for (i = 0; i < map->nsegs; i++) {
164: if (map->seg[i].inuse)
165: if (map->seg[i].b <= addr && addr < map->seg[i].e) {
166: *offp = addr + map->seg[i].f - map->seg[i].b;
167: return 1;
168: }
169: }
170: werrstr("can't translate address %lux", addr);
171: return -1;
172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.