Test for various ELF64 GOT references
[nasm.git] / raa.c
blob9635312329f0bbc01ad7c31e32cea5ed8bde8b80
1 #include "nasmlib.h"
2 #include "raa.h"
4 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
5 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
7 #define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
9 static struct RAA *real_raa_init(int layers)
11 struct RAA *r;
12 int i;
14 if (layers == 0) {
15 r = nasm_zalloc(LEAFSIZ);
16 r->shift = 0;
17 } else {
18 r = nasm_malloc(BRANCHSIZ);
19 r->layers = layers;
20 for (i = 0; i < RAA_LAYERSIZE; i++)
21 r->u.b.data[i] = NULL;
22 r->shift =
23 (RAA_BLKSHIFT - RAA_LAYERSHIFT) + layers * RAA_LAYERSHIFT;
25 return r;
28 struct RAA *raa_init(void)
30 return real_raa_init(0);
33 void raa_free(struct RAA *r)
35 if (r->layers) {
36 struct RAA **p;
37 for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
38 if (*p)
39 raa_free(*p);
41 nasm_free(r);
44 int64_t raa_read(struct RAA *r, int32_t posn)
46 if ((uint32_t) posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
47 return 0; /* Return 0 for undefined entries */
48 while (r->layers > 0) {
49 int32_t l = posn >> r->shift;
50 posn &= (UINT32_C(1) << r->shift) - 1;
51 r = r->u.b.data[l];
52 if (!r)
53 return 0; /* Return 0 for undefined entries */
55 return r->u.l.data[posn];
58 struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
60 struct RAA *result;
62 if (posn < 0)
63 nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
65 while ((UINT32_C(1) << (r->shift + LAYERSHIFT(r))) <= (uint32_t) posn) {
67 * Must add a layer.
69 struct RAA *s;
70 int i;
72 s = nasm_malloc(BRANCHSIZ);
73 for (i = 0; i < RAA_LAYERSIZE; i++)
74 s->u.b.data[i] = NULL;
75 s->layers = r->layers + 1;
76 s->shift = LAYERSHIFT(r) + r->shift;
77 s->u.b.data[0] = r;
78 r = s;
81 result = r;
83 while (r->layers > 0) {
84 struct RAA **s;
85 int32_t l = posn >> r->shift;
86 posn &= (UINT32_C(1) << r->shift) - 1;
87 s = &r->u.b.data[l];
88 if (!*s)
89 *s = real_raa_init(r->layers - 1);
90 r = *s;
93 r->u.l.data[posn] = value;
95 return result;