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