Skip to content

Commit 38266df

Browse files
author
Noam Preil
committed
Fix backwards relative labels
1 parent cbf8b54 commit 38266df

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

assembler/assembler.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ void transform_local_labels(tokenized_expression_t *expression, const char *last
7272
}
7373
}
7474

75-
void transform_relative_labels(tokenized_expression_t *expression, int last_relative_label) {
76-
int i;
77-
for(i = 0; i < expression->tokens->length; i++) {
78-
fflush(stderr);
75+
void transform_relative_labels(tokenized_expression_t *expression, int last_relative_label, const char *const file_name) {
76+
for(int i = 0; i < expression->tokens->length; i++) {
7977
expression_token_t *token = expression->tokens->items[i];
8078
if (token->type != SYMBOL || strcmp(token->symbol, "_")) {
8179
continue;
@@ -85,17 +83,27 @@ void transform_relative_labels(tokenized_expression_t *expression, int last_rela
8583
int offset = get_relative_label_offset(expression, &j);
8684
int relative_label = offset + last_relative_label;
8785

88-
const char *fmtstring = "relative@%d";
86+
const char *fmtstring = "relative:%d@%s";
8987
int len = log10_u64(relative_label);
90-
const int size = strlen(fmtstring) - 2 + len + 1;
88+
const int size = strlen(fmtstring) - 2 + len - 2 + strlen(file_name) + 1;
9189
free(token->symbol);
9290
token->symbol = malloc(size);
93-
if (snprintf(token->symbol, size, fmtstring, relative_label) != size - 1) {
91+
if (snprintf(token->symbol, size, fmtstring, relative_label, file_name) != size - 1) {
9492
scas_log(L_ERROR, "UNREACHABLE");
9593
exit(1);
9694
}
9795

9896
scas_log(L_DEBUG, "Transformed relative label with offset %d to %s, %d - %d", offset, token->symbol, i, j);
97+
while (i + 1 < expression->tokens->length) {
98+
expression_token_t *next = expression->tokens->items[i + 1];
99+
if (next->type == OPERATOR && next->operator == 1) {
100+
free_expression_token(next);
101+
list_del(expression->tokens, i + 1);
102+
}
103+
else {
104+
break;
105+
}
106+
}
99107
}
100108
}
101109

@@ -344,15 +352,16 @@ int try_add_label(struct assembler_state *state, char **line) {
344352
scas_log(L_DEBUG, "Adding ASxxxx local label %s", sym->name);
345353
free(temp);
346354
} else if (strncmp("_", *line, i) == 0) {
347-
const char *fmtstring = "relative@%d";
355+
const char *file_name = stack_peek(state->file_name_stack);
356+
const char *fmtstring = "relative:%d@%s";
348357
int len = log10_u64(state->last_relative_label);
349-
const int size = strlen(fmtstring) - 2 + len + 1;
358+
const int size = strlen(fmtstring) - 2 + len - 2 + strlen(file_name) + 1;
350359
sym->name = malloc(size);
351360
if (!sym->name) {
352361
scas_log(L_ERROR, "OOM");
353362
exit(1);
354363
}
355-
if (snprintf(sym->name, size, fmtstring, state->last_relative_label++) != size - 1) {
364+
if (snprintf(sym->name, size, fmtstring, state->last_relative_label++, file_name) != size - 1) {
356365
scas_log(L_ERROR, "Unreachable.");
357366
exit(1);
358367
}
@@ -425,7 +434,8 @@ int try_match_instruction(struct assembler_state *state, char **_line) {
425434
state->line, state->column, stack_peek(state->file_name_stack));
426435
} else {
427436
transform_local_labels(expression, state->last_global_label);
428-
transform_relative_labels(expression, state->last_relative_label);
437+
const char *file_name = stack_peek(state->file_name_stack);
438+
transform_relative_labels(expression, state->last_relative_label, file_name);
429439
result = evaluate_expression(expression, state->equates, &error, &symbol);
430440
if (error == EXPRESSION_BAD_SYMBOL) {
431441
if (scas_runtime.options.explicit_import && strcmp(symbol, "$") != 0) {
@@ -437,7 +447,7 @@ int try_match_instruction(struct assembler_state *state, char **_line) {
437447
unresolved_sym->file_name = strdup(stack_peek(state->file_name_stack));
438448
list_add(state->object->unresolved, unresolved_sym);
439449
}
440-
scas_log(L_DEBUG, "Postponing evaluation of '%s' to linker", ref->value_provided);
450+
scas_log(L_DEBUG, "Postponing evaluation of '%s' to linker (type %d)", ref->value_provided, imm->type);
441451
late_immediate_t *late_imm = malloc(sizeof(late_immediate_t));
442452
late_imm->instruction_address = state->current_area->data_length;
443453
late_imm->base_address = state->PC + (match->instruction->width / 8);

include/assembler.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct assembler_state {
3030
list_t *errors;
3131
list_t *warnings;
3232
list_t *extra_lines;
33-
bool expanding_macro;
33+
bool expanding_macro;
3434
char *line;
3535
int column;
3636
instruction_set_t *instruction_set;
@@ -44,8 +44,8 @@ struct assembler_state {
4444
char *last_global_label;
4545
assembler_settings_t *settings;
4646
macro_t *most_recent_macro;
47-
bool auto_source_maps;
48-
uint64_t last_relative_label;
47+
bool auto_source_maps;
48+
uint64_t last_relative_label;
4949
};
5050

5151
object_t *assemble(FILE *file, const char *file_name, assembler_settings_t *settings);

linker/linker.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ void resolve_immediate_values(list_t *symbols, area_t *area, list_t *errors) {
5252
int error;
5353
char *symbol;
5454
uint64_t result = evaluate_expression(imm->expression, symbols, &error, &symbol);
55+
5556
list_del(symbols, symbols->length - 1); // Remove $
5657
if (error == EXPRESSION_BAD_SYMBOL) {
5758
scas_log(L_ERROR, "Unable to find symbol for expression");

0 commit comments

Comments
 (0)