Annotation of lucent/sys/src/libmach/access.c, revision 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.