RPA Toolkit
Modified the public API of rvm_relocmap_t to add support for multiple relocation...
[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_reloctarget_t target, rvm_reloctype_t type, rulong offset, rulong label)
30 {
31         rvm_relocrecord_t record;
32         record.target = target;
33         record.type = type;
34         record.offset = offset;
35         record.label = label;
36
37         return r_array_add(relocmap->records, &record);
38 }
39
40
41 rvm_relocrecord_t *rvm_relocmap_get(rvm_relocmap_t *relocmap, rulong index)
42 {
43         if (index >= r_array_length(relocmap->records))
44                 return NULL;
45         return (rvm_relocrecord_t *)r_array_slot(relocmap->records, index);
46 }
47
48
49 rulong rvm_relocmap_length(rvm_relocmap_t *relocmap)
50 {
51         return r_array_length(relocmap->records);
52 }
53
54
55 rint rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code, rvm_codelabel_t **err)
56 {
57         rlong index;
58         rvm_relocrecord_t *reloc;
59         rword value;
60
61         for (index = 0; index < r_array_length(relocmap->records); index++) {
62                 reloc = rvm_relocmap_get(relocmap, index);
63                 value = rvm_codemap_resolve(codemap, reloc->label, err);
64                 if (value == (rword)-1)
65                         return -1;
66                 if (reloc->target == RVM_RELOC_CODE) {
67                         if (reloc->type == RVM_RELOC_BRANCH) {
68                                 code[reloc->offset].data.v.w = RVM_BYTE2CODE_OFFSET(value - (rword)&code[reloc->offset]);
69                         } else if (reloc->type == RVM_RELOC_JUMP) {
70                                 code[reloc->offset].data.v.w = value - RVM_CODE2BYTE_OFFSET(1);
71                         } else if (reloc->type == RVM_RELOC_STRING) {
72                                 code[reloc->offset].data.v.w = value;
73                                 code[reloc->offset].data.size = r_strlen((rchar*)value);
74                         } else if (reloc->type == RVM_RELOC_BLOB) {
75                                 code[reloc->offset].data.v.w = value;
76                         } else {
77                                 code[reloc->offset].data.v.w = value;
78                         }
79                 } else if (reloc->target == RVM_RELOC_DATA){
80                         /*
81                          * TBD: No support for data relocation yet.
82                          */
83                 }
84         }
85         return 0;
86 }