|
|
1.1 root 1: #include "../machine/alignment.h"
2:
3: long readable(infop, address, length)
4: process_info *infop;
5: long address, length;
6: /*
7: * Return TRUE (= -1) if the specified bytes can be read without an access
8: * control violation (limit and/or protection). Page faults are OK.
9: * If problems, return the code that would be pushed by HW on the
10: * stack (see the architecture manual).
11: * Assumption is that in most cases, access is OK, so a quick 'prober'
12: * will be enough. If not, we have to work harder to determine the exact
13: * cause and return the right code, without getting the fault here in
14: * the kernel !!.
15: *
16: * The address is assumed to be read for the user.!
17: */
18: {
19: register long Register_12; /* Has to be first reg ! */
20: register long Register_11;
21: register long Register_10;
22: register long Register_9;
23: register long Register_8;
24: register long subspace;
25: register long last_page;
26:
27: Register_12 = address;
28: Register_11 = length-1;
29: asm (" prober $1,(r12),$1 "); /* Yeach ... */
30: asm (" beql no_access ");
31: asm (" addl2 r11,r12 "); /* last byte */
32: asm (" prober $1,(r12),$1 ");
33: asm (" beql no_access ");
34: asm (" movl $-1,r0 "); /* TRUE */
35: asm (" ret#1 ");
36: asm ("no_access: ");
37: /*
38: * Now the hard work. Have to check length violation first.
39: * If any byte (first or last) causes a length violation, report it as such.
40: */
41: asm (" mfpr $3,r8 "); /* Get length registers. P0LR */
42: asm (" mfpr $5,r9 "); /* P1LR */
43: asm (" mfpr $7,r10 "); /* P2LR */
44: asm (" mfpr $1,r11 "); /* SLR */
45:
46: subspace = (address >> 30) & 3;
47: Register_12 = (address >> 10) & 0xfffff; /* 1'st byte page # */
48: last_page = ( (address+length-1) >> 10) & 0xfffff;
49: switch ( subspace ) {
50: case 0:
51: if ( (Register_12 >= Register_8) ||
52: (last_page >= Register_8) ) return (1);
53: break;
54: case 1:
55: if ( (Register_12 >= Register_9) ||
56: (last_page >= Register_9) ) return (1);
57: break;
58: case 2:
59: if ( (Register_12 < Register_10) ||
60: (last_page < Register_10) ) return (1);
61: break;
62: case 3:
63: if ( (Register_12 >= Register_11) ||
64: (last_page >= Register_11) ) return (1);
65: break;
66: }
67: /*
68: * OK, it's not a length violation. Must have been an access problem
69: * (no read by user).
70: *
71: * NOTE : I definitely ignore the case of 'no PTE access' since I
72: * assume that's not the case for user mode. Besides, the poor
73: * guy will just get an access violation that will most probably
74: * send him into hyperspace anyway, so no need to be too acurate here.
75: */
76: return (0);
77: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.