Annotation of lucent/sys/src/libmach/access.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.