RPA Toolkit
Going back to dynamic strings. No support for static strings for now.
[rpatk.git] / rvm / rvmrelocmap.c
1 #include "rvmrelocmap.h"
2 #include "rmem.h"
3
4 rvm_relocmap_t *rvm_relocmap_create()
5 {
6         rvm_relocmap_t *relocmap;
7
8         relocmap = (rvm_relocmap_t*)r_zmalloc(sizeof(*relocmap));
9         if (!relocmap)
10                 return NULL;
11         relocmap->records = r_array_create(sizeof(rvm_relocrecord_t));
12         return relocmap;
13 }
14
15
16 void rvm_relocmap_destroy(rvm_relocmap_t *relocmap)
17 {
18         r_object_destroy((robject_t*)relocmap->records);
19         r_free(relocmap);
20 }
21
22
23 void rvm_relocmap_clear(rvm_relocmap_t *relocmap)
24 {
25         r_array_setlength(relocmap->records, 0);
26 }
27
28
29 rlong rvm_relocmap_add(rvm_relocmap_t *relocmap, rvm_reloctype_t type, rulong offset, rulong label)
30 {
31         rvm_relocrecord_t record;
32         record.type = type;
33         record.offset = offset;
34         record.label = label;
35
36         return r_array_add(relocmap->records, &record);
37 }
38
39
40 rvm_relocrecord_t *rvm_relocmap_get(rvm_relocmap_t *relocmap, rulong index)
41 {
42         if (index >= r_array_length(relocmap->records))
43                 return NULL;
44         return (rvm_relocrecord_t *)r_array_slot(relocmap->records, index);
45 }
46
47
48 rulong rvm_relocmap_length(rvm_relocmap_t *relocmap)
49 {
50         return r_array_length(relocmap->records);
51 }
52
53
54 rint rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code, rvm_codelabel_t **err)
55 {
56         rlong index;
57         rvm_relocrecord_t *reloc;
58         rword value;
59
60         for (index = 0; index < r_array_length(relocmap->records); index++) {
61                 reloc = rvm_relocmap_get(relocmap, index);
62                 value = rvm_codemap_resolve(codemap, reloc->label, err);
63                 if (value == (rword)-1)
64                         return -1;
65                 if (reloc->type == RVM_RELOC_BRANCH) {
66                         code[reloc->offset].data.v.w = RVM_BYTE2CODE_OFFSET(value - (rword)&code[reloc->offset]);
67                 } else if (reloc->type == RVM_RELOC_JUMP) {
68                         code[reloc->offset].data.v.w = value - RVM_CODE2BYTE_OFFSET(1);
69                 } else if (reloc->type == RVM_RELOC_STRING) {
70                         code[reloc->offset].data.v.w = value;
71                         code[reloc->offset].data.size = r_strlen((rchar*)value);
72                 } else if (reloc->type == RVM_RELOC_BLOB) {
73                         code[reloc->offset].data.v.w = value;
74                 } else {
75                         code[reloc->offset].data.v.w = value;
76                 }
77         }
78         return 0;
79 }