Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix building kernel #63

Merged
merged 21 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ image: archlinux
packages:
- make
- cmake
- mkrom
- patchrom
- genkfs
- mktiupgrade
- valgrind
sources:
- https://github.com/knightos/scas
- https://github.com/knightos/kernel
environment:
project: scas
tasks:
Expand All @@ -13,3 +19,8 @@ tasks:
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
cd ../../kernel
# Temporary: use scas PR
git checkout scas
mkdir bin/TI84pSE -p
make AS="valgrind --track-origins=yes --leak-check=full --error-exitcode=1 ../scas/build/scas"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ test/
build/
.lvimrc
tables/z80.c
.ccls
.ccls-cache
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 2.8.5)

project(scas C)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=700")
set(CMAKE_C_FLAGS_DEVEL "-Werror -g -Og")

if(WIN32)
set(CMAKE_C_FLAGS "-Wl,--allow-multiple-definition")
Expand Down
26 changes: 19 additions & 7 deletions assembler/assembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,18 @@ int try_expand_macro(struct assembler_state *state, char **line) {
if (strstr(*line, "macro") == *line + 1) { // Cannot expand macros while defining them
return 0;
}
if (strstr(*line, "undefine") == *line + 1) { // Should not expand while removing
return 0;
}
if (strstr(*line, "ifdef") == *line + 1) { // Should not expand when testing for existence
return 0;
}
// Shouldn't expand macros in equates
if ((**line == '.' || **line == '#')) {
if (code_strstr(*line, ".equ") || code_strchr(*line, '=')) {
return 0;
}
}
int i;
for (i = 0; i < state->macros->length; i++) {
macro_t *macro = state->macros->items[i];
Expand Down Expand Up @@ -326,7 +335,7 @@ int try_add_label(struct assembler_state *state, char **line) {

/* Add label */
symbol_t *sym = malloc(sizeof(symbol_t));
sym->exported = 1; /* TODO: Support explicit export */
sym->exported = !scas_runtime.options.explicit_export;
sym->type = SYMBOL_LABEL;
sym->value = state->PC + scas_runtime.options.origin;
sym->defined_address = state->current_area->data_length;
Expand Down Expand Up @@ -433,7 +442,14 @@ int try_match_instruction(struct assembler_state *state, char **_line) {
transform_local_labels(expression, state->last_global_label);
const char *file_name = stack_peek(state->file_name_stack);
transform_relative_labels(expression, state->last_relative_label, file_name);
symbol_t sym_pc = {
.type = SYMBOL_LABEL,
.value = state->PC,
.name = "$"
};
list_add(state->equates, &sym_pc);
result = evaluate_expression(expression, state->equates, &error, &symbol);
state->equates->length -= 1;
if (error == EXPRESSION_BAD_SYMBOL) {
if (scas_runtime.options.explicit_import && strcmp(symbol, "$") != 0) {
unresolved_symbol_t *unresolved_sym = malloc(sizeof(unresolved_symbol_t));
Expand Down Expand Up @@ -605,8 +621,8 @@ object_t *assemble(FILE *file, const char *file_name, assembler_settings_t *sett
try_empty_line,
try_parse_inside_macro,
try_split_line,
try_expand_macro,
try_add_label,
try_expand_macro,
try_handle_directive,
try_match_instruction,
};
Expand Down Expand Up @@ -707,11 +723,7 @@ object_t *assemble(FILE *file, const char *file_name, assembler_settings_t *sett
macro_free(macro);
}
list_free(state.macros);
for (int i = 0; i < state.equates->length; i += 1) {
symbol_t *sym = (symbol_t*)state.equates->items[i];
free(sym->name);
free(sym);
}
// Equates are also added to an area's symbols list, so they're cleaned up there
list_free(state.equates);
stack_free(state.source_map_stack);
free(state.instruction_buffer);
Expand Down
33 changes: 30 additions & 3 deletions assembler/directives.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ int handle_block(struct assembler_state *state, char **argv, int argc) {

if (error == EXPRESSION_BAD_SYMBOL) {
ERROR(ERROR_UNKNOWN_SYMBOL, state->column, symbol);
free_expression(expression);
return 1;
}

Expand All @@ -167,6 +168,8 @@ int handle_block(struct assembler_state *state, char **argv, int argc) {
result = 0;
}
}
free(buffer);
free_expression(expression);
return 1;
}

Expand Down Expand Up @@ -433,6 +436,8 @@ int handle_undef(struct assembler_state *state, char **argv, int argc) {
return 1;
}

scas_log(L_DEBUG, "Looking for %s", argv[0]);

int i;
for (i = 0; i < state->macros->length; i++) {
macro_t *m = state->macros->items[i];
Expand Down Expand Up @@ -610,11 +615,20 @@ static void printf_putc(char c) {
putchar(c);
}

int handle_printf(struct assembler_state *state, char **argv, int argc) {
int handle_echo(struct assembler_state *state, char **argv, int argc) {
if (argc == 0) {
ERROR(ERROR_INVALID_DIRECTIVE, state->column, "echo expects 1+ arguments");
return 1;
}
(void)argv;
return 1;
}

int handle_printf(struct assembler_state *state, char **argv, int argc) {
if (argc == 0) {
ERROR(ERROR_INVALID_DIRECTIVE, state->column, "printf expects 1+ arguments");
return 1;
}
int len = strlen(argv[0]);
if (argv[0][0] != '"' || argv[0][len - 1] != '"') {
ERROR(ERROR_INVALID_DIRECTIVE, state->column, "unterminated string");
Expand Down Expand Up @@ -737,8 +751,19 @@ int handle_equ(struct assembler_state *state, char **argv, int argc) {
ERROR_NO_ARG(ERROR_INVALID_SYNTAX, state->column);
return 1;
} else {
transform_local_labels(expression, state->last_global_label);
int len = state->equates->length;
for (int i = 0; i < state->current_area->symbols->length; i += 1) {
list_add(state->equates, state->current_area->symbols->items[i]);
}
symbol_t sym_pc = {
.type = SYMBOL_LABEL,
.value = state->PC,
.name = "$"
};
list_add(state->equates, &sym_pc);
result = evaluate_expression(expression, state->equates, &error, &symbol);
free_expression(expression);
state->equates->length = len;
}
if (error == EXPRESSION_BAD_SYMBOL) {
ERROR(ERROR_UNKNOWN_SYMBOL, state->column, symbol);
Expand All @@ -752,8 +777,10 @@ int handle_equ(struct assembler_state *state, char **argv, int argc) {
sym->value = result;
sym->exported = 0;
list_add(state->equates, sym);
list_add(state->current_area->symbols, sym);
scas_log(L_DEBUG, "Added equate '%s' with value 0x%08X", sym->name, sym->value);
}
free_expression(expression);
return 1;
}

Expand Down Expand Up @@ -1277,7 +1304,7 @@ struct directive directives[] = {
{ "dl", handle_dl, DELIM_COMMAS },
{ "ds", handle_block, DELIM_COMMAS },
{ "dw", handle_dw, DELIM_COMMAS },
//{ "echo", handle_echo, DELIM_COMMAS | DELIM_WHITESPACE },
{ "echo", handle_echo, DELIM_COMMAS | DELIM_WHITESPACE },
{ "elif", handle_elseif, 0 },
{ "else", handle_else, 0 },
{ "elseif", handle_elseif, 0 },
Expand Down
21 changes: 15 additions & 6 deletions common/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "list.h"
#include "log.h"
#include "objects.h"
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
Expand Down Expand Up @@ -101,15 +102,14 @@ void add_warning(list_t *warnings, int code, size_t line_number,
void add_error_from_map(list_t *errors, int code, list_t *maps, uint64_t address, ...) {
source_map_t *map;
source_map_entry_t *entry;
int found = 0;
int i;
for (i = 0; i < maps->length; ++i) {
bool found = false;
for (int i = 0; i < maps->length; ++i) {
map = maps->items[i];
int j;
for (j = 0; j < map->entries->length; ++j) {
entry = map->entries->items[j];
if (address >= entry->address && address < entry->address + entry->length) {
found = 1;
found = true;
break;
}
}
Expand All @@ -135,16 +135,25 @@ void add_error_from_map(list_t *errors, int code, list_t *maps, uint64_t address
va_end(args);

error->message = buf;
scas_log(L_ERROR, "Added error '%s' at:", buf);
if (found) {
error->line_number = entry->line_number;
error->file_name = strdup(map->file_name);
error->line = strdup(entry->source_code);
for (int i = 0; i < maps->length; ++i) {
map = maps->items[i];
for (int j = 0; j < map->entries->length; ++j) {
entry = map->entries->items[j];
if (address >= entry->address && address < entry->address + entry->length) {
scas_log(L_ERROR, "\t%s:%d:%d", map->file_name,
entry->line_number, error->column);
}
}
}
} else {
error->line_number = 0;
error->file_name = NULL;
error->line = NULL;
}
list_add(errors, error);
scas_log(L_ERROR, "Added error '%s' at %s:%d:%d", buf, error->file_name,
error->line_number, error->column);
}
7 changes: 4 additions & 3 deletions common/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ void list_insert(list_t *list, int index, void *item) {

void list_del(list_t *list, int index) {
list->length--;
memmove(&list->items[index], &list->items[index + 1], sizeof(void*) * (list->length - index));
if (index != list->length) {
memmove(&list->items[index], &list->items[index + 1], sizeof(void*) * (list->length - index));
}
}

void list_cat(list_t *list, list_t *source) {
int i;
for (i = 0; i < source->length; ++i) {
for (int i = 0; i < source->length; ++i) {
list_add(list, source->items[i]);
}
}
Expand Down
1 change: 1 addition & 0 deletions include/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct assembler_state {

object_t *assemble(FILE *file, const char *file_name, assembler_settings_t *settings);
void transform_local_labels(tokenized_expression_t *expression, const char *last_global_label);
void transform_relative_labels(tokenized_expression_t *expression, int last_relative_label, const char *const file_name);
void macro_free(macro_t *macro);

#endif
21 changes: 17 additions & 4 deletions linker/linker.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,8 @@ void link_objects(FILE *output, list_t *objects, linker_settings_t *settings) {
if (scas_runtime.options.remove_unused_functions) {
remove_unused_functions(merged);
}
int i;
uint64_t address = 0;
for (i = 0; i < merged->areas->length; ++i) {
for (int i = 0; i < merged->areas->length; ++i) {
area_t *area = merged->areas->items[i];
relocate_area(area, address, false);
if (settings->automatic_relocation) {
Expand All @@ -206,11 +205,11 @@ void link_objects(FILE *output, list_t *objects, linker_settings_t *settings) {
}
address += area->data_length;
}
for (i = 0; i < merged->areas->length; ++i) {
for (int i = 0; i < merged->areas->length; ++i) {
area_t *area = merged->areas->items[i];
gather_symbols(symbols, area, settings);
}
for (i = 0; i < merged->areas->length; ++i) {
for (int i = 0; i < merged->areas->length; ++i) {
area_t *area = merged->areas->items[i];
scas_log(L_INFO, "Linking area %s", area->name);
if (scas_runtime.options.origin) {
Expand All @@ -222,6 +221,20 @@ void link_objects(FILE *output, list_t *objects, linker_settings_t *settings) {
}
settings->write_output(output, final->data, (int)final->data_length);
scas_log(L_DEBUG, "Final binary written: %d bytes", ftell(output));

if (scas_runtime.symbol_file) {
scas_log(L_DEBUG, "Generating symbol file '%s'", scas_runtime.symbol_file);
FILE *symfile = fopen(scas_runtime.symbol_file, "w");
for (int i = 0; i < symbols->length; i++) {
symbol_t *symbol = symbols->items[i];
if (symbol->type == SYMBOL_LABEL && symbol->exported && !strchr(symbol->name, '@')) {
fprintf(symfile, ".equ %s 0x%lX\n", symbol->name, symbol->value);
}
}
fflush(symfile);
fclose(symfile);
}

object_free(merged);
area_free(final);
list_free(symbols);
Expand Down
1 change: 1 addition & 0 deletions scas/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ int main(int argc, char **argv) {
}
fclose(out);
}

if (errors->length != 0) {
int i;
for (i = 0; i < errors->length; ++i) {
Expand Down