Skip to content

Commit 811277a

Browse files
author
Noam Preil
committed
Emit KEXC relocation table with -fauto-relocation
1 parent 9cb7459 commit 811277a

File tree

1 file changed

+15
-38
lines changed

1 file changed

+15
-38
lines changed

linker/linker.c

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -96,37 +96,15 @@ void resolve_immediate_values(list_t *symbols, area_t *area, list_t *errors) {
9696
}
9797

9898
/* z80 only (and possibly ez80) */
99-
void auto_relocate_area(area_t *area, area_t *runtime) {
99+
void auto_relocate_area(area_t *area, area_t *relocation_table) {
100100
scas_log(L_DEBUG, "Performing automatic relocation for %s", area->name);
101-
uint8_t rst0x8 = 0xCF;
102-
for (unsigned int i = 0; i < area->late_immediates->length; ++i) {
101+
int i;
102+
for (i = 0; i < area->late_immediates->length; ++i) {
103103
late_immediate_t *imm = area->late_immediates->items[i];
104-
if (imm->type != IMM_TYPE_RELATIVE) {
105-
if (imm->base_address != imm->address) {
106-
/* Relocate this */
107-
scas_log(L_DEBUG, "Adding relocation instruction for immediate at 0x%08X (inserting at 0x%08X)", imm->address, imm->instruction_address);
108-
insert_in_area(area, &rst0x8, sizeof(uint8_t), imm->instruction_address);
109-
++imm->address;
110-
/* Move everything that comes after */
111-
for (unsigned k = 0; k < area->symbols->length; ++k) {
112-
symbol_t *sym = area->symbols->items[k];
113-
if (sym->type == SYMBOL_LABEL && sym->value > imm->instruction_address) {
114-
++sym->value;
115-
}
116-
}
117-
for (unsigned int j = 0; j < area->late_immediates->length; ++j) {
118-
late_immediate_t *_imm = area->late_immediates->items[j];
119-
if (_imm->base_address > imm->base_address) {
120-
++_imm->base_address;
121-
++_imm->instruction_address;
122-
++_imm->address;
123-
}
124-
}
125-
} else {
126-
/* Relocate this */
127-
uint16_t value = (uint16_t)(imm->address + area->final_address);
128-
append_to_area(runtime, (uint8_t*)&value, sizeof(uint16_t));
129-
}
104+
if (imm->type != IMM_TYPE_RELATIVE && imm->base_address != imm->address) {
105+
/* Relocate this */
106+
uint16_t value = (uint16_t)(imm->address + area->final_address);
107+
append_to_area(relocation_table, (uint8_t*)&value, sizeof(uint16_t));
130108
}
131109
}
132110
}
@@ -154,19 +132,18 @@ void link_objects(FILE *output, list_t *objects, linker_settings_t *settings) {
154132
list_t *symbols = create_list(); // TODO: Use a hash table
155133

156134
/* Create a new area for relocatable references */
157-
area_t *runtime = NULL;
135+
area_t *relocation_table;
158136
if (settings->automatic_relocation) {
159-
const char *sym_name = "__scas_relocatable_data";
160-
runtime = create_area("__scas_relocatable");
137+
relocation_table = create_area("__scas_relocation_table");
161138
symbol_t *sym = malloc(sizeof(symbol_t));
162139
sym->type = SYMBOL_LABEL;
163-
sym->name = strdup(sym_name);
140+
sym->name = strdup("__scas_relocation_table");
164141
sym->value = 0;
165142
sym->defined_address = 0;
166143
sym->exported = 0;
167-
list_add(runtime->symbols, sym);
144+
list_add(relocation_table->symbols, sym);
168145
object_t *o = create_object();
169-
list_add(o->areas, runtime);
146+
list_add(o->areas, relocation_table);
170147
list_add(objects, o);
171148
}
172149

@@ -178,7 +155,7 @@ void link_objects(FILE *output, list_t *objects, linker_settings_t *settings) {
178155

179156
area_t *final = create_area("FINAL");
180157

181-
runtime = get_area_by_name(merged, "__scas_relocatable");
158+
relocation_table = get_area_by_name(merged, "__scas_relocation_table");
182159

183160
scas_log(L_INFO, "Assigning final address for all areas");
184161
if (scas_runtime.options.remove_unused_functions) {
@@ -189,11 +166,11 @@ void link_objects(FILE *output, list_t *objects, linker_settings_t *settings) {
189166
area_t *area = merged->areas->items[i];
190167
relocate_area(area, address, false);
191168
if (settings->automatic_relocation) {
192-
if (area == runtime) {
169+
if (area == relocation_table) {
193170
uint16_t null_ptr = 0;
194171
append_to_area(area, (uint8_t *)&null_ptr, sizeof(uint16_t));
195172
} else {
196-
auto_relocate_area(area, runtime);
173+
auto_relocate_area(area, relocation_table);
197174
}
198175
}
199176
address += area->data_length;

0 commit comments

Comments
 (0)