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 } 173