xref: /inferno-os/libdynld/dynld-arm.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include <a.out.h>
3 #include <dynld.h>
4 
5 #define	CHK(i,ntab)	if((unsigned)(i)>=(ntab))return "bad relocation index"
6 
7 long
dynmagic(void)8 dynmagic(void)
9 {
10 	return DYN_MAGIC | E_MAGIC;
11 }
12 
13 char*
dynreloc(uchar * b,ulong p,int m,Dynsym ** tab,int ntab)14 dynreloc(uchar *b, ulong p, int m, Dynsym **tab, int ntab)
15 {
16 	int i;
17 	ulong v, *pp;
18 
19 	p <<= 2;
20 	p += (ulong)b;
21 	pp = (ulong*)p;
22 	v = *pp;
23 	switch(m){
24 	case 0:
25 		v += (ulong)b;
26 		break;
27 	case 1:
28 		i = v>>22;
29 		v &= 0x3fffff;
30 		CHK(i, ntab);
31 		v += tab[i]->addr;
32 		break;
33 	case 2:
34 		i = v&0x3ff;
35 		v &= ~0x3ff;
36 		CHK(i, ntab);
37 		v |= ((tab[i]->addr-p-8)>>2)&0xffffff;
38 		break;
39 	default:
40 		return "invalid relocation mode";
41 	}
42 	*pp = v;
43 	return nil;
44 }
45