|
|
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.