diff --git a/link_1.5.0.patch b/link_1.5.0.patch new file mode 100644 index 0000000..53dae32 --- /dev/null +++ b/link_1.5.0.patch @@ -0,0 +1,307 @@ +diff --git a/gputils/gpstrip.c b/gputils/gpstrip.c +index dce5ddb..06b7d97 100644 +--- a/gputils/gpstrip.c ++++ b/gputils/gpstrip.c +@@ -92,7 +92,7 @@ _conditional_remove(gp_symbol_t *Symbol) + gp_message("removing symbol \"%s\"", Symbol->name); + } + +- gp_coffgen_del_symbol(state.object, Symbol); ++ gp_coffgen_del_symbol(state.object, Symbol, true); + } + } + +diff --git a/libgputils/gpcoffgen.c b/libgputils/gpcoffgen.c +index 8ebcf15..dc60348 100644 +--- a/libgputils/gpcoffgen.c ++++ b/libgputils/gpcoffgen.c +@@ -346,7 +346,7 @@ gp_coffgen_del_section_symbols(gp_object_t *Object, gp_section_t *Section) + list = list->next; + + if (symbol->section == Section) { +- gp_coffgen_del_symbol(Object, symbol); ++ gp_coffgen_del_symbol(Object, symbol, true); + } + } + } +@@ -732,8 +732,10 @@ gp_coffgen_move_reserve_symbol(gp_object_t *Object, gp_symbol_t *Symbol) + /* Delete the symbol from the object. */ + + gp_boolean +-gp_coffgen_del_symbol(gp_object_t *Object, gp_symbol_t *Symbol) ++gp_coffgen_del_symbol(gp_object_t *Object, gp_symbol_t *Symbol, gp_boolean Touch_number) + { ++ unsigned int n_deleted; ++ + if (Object->symbol_list.first == NULL) { + return false; + } +@@ -745,7 +747,13 @@ gp_coffgen_del_symbol(gp_object_t *Object, gp_symbol_t *Symbol) + } + + gp_list_node_remove(&Object->symbol_list, Symbol); +- Object->num_symbols -= 1 + gp_coffgen_free_symbol(Symbol); ++ ++ n_deleted = 1 + gp_coffgen_free_symbol(Symbol); ++ ++ if (Touch_number) { ++ Object->num_symbols -= n_deleted; ++ } ++ + return true; + } + +@@ -999,7 +1007,7 @@ _check_section_relocations(proc_class_t Class, gp_section_t *Section, unsigned i + if (sym_sect == NULL) { + /* This is an orphan symbol. */ + if (FlagIsClr(Behavior, RELOC_DISABLE_WARN)) { +- if (FlagIsSet(Behavior, RELOC_ENABLE_CINIT_WARN) || (strcmp(symbol->name, "_cinit") != 0)) { ++ if (FlagIsSet(Behavior, RELOC_ENABLE_CINIT_WARN) && (strcmp(symbol->name, "_cinit") != 0)) { + gp_warning("Relocation symbol \"%s\" [0x%0*X] has no section. (pass %u)", + symbol->name, Class->addr_digits, relocation->address, Pass); + } +diff --git a/libgputils/gpcoffgen.h b/libgputils/gpcoffgen.h +index ffb5b5c..41d3f89 100644 +--- a/libgputils/gpcoffgen.h ++++ b/libgputils/gpcoffgen.h +@@ -73,7 +73,7 @@ extern gp_symbol_t *gp_coffgen_add_symbol(gp_object_t *Object, const char *Name, + extern gp_aux_t *gp_coffgen_add_aux(gp_object_t *Object, gp_symbol_t *Symbol); + extern gp_aux_t *gp_coffgen_make_block_aux(gp_symbol_t *Symbol, unsigned int Num_auxsyms); + extern gp_symbol_t *gp_coffgen_move_reserve_symbol(gp_object_t *Object, gp_symbol_t *Symbol); +-extern gp_boolean gp_coffgen_del_symbol(gp_object_t *Object, gp_symbol_t *Symbol); ++extern gp_boolean gp_coffgen_del_symbol(gp_object_t *Object, gp_symbol_t *Symbol, gp_boolean Touch_number); + extern gp_symbol_t **gp_coffgen_make_symbol_array(const gp_object_t *Object, int (*Cmp)(const void *, const void *)); + extern const char *gp_coffgen_symbol_type_to_str(uint8_t Type); + extern const char *gp_coffgen_symbol_derived_type_to_str(uint32_t Type); +diff --git a/libgputils/gpcofflink.c b/libgputils/gpcofflink.c +index 7511c36..1283e63 100644 +--- a/libgputils/gpcofflink.c ++++ b/libgputils/gpcofflink.c +@@ -174,9 +174,12 @@ gp_cofflink_clean_table(gp_object_t *Object, symbol_table_t *Symbols) + const gp_coffsymbol_t *var; + const symbol_t *sym; + gp_symbol_t *next; ++ int num_clean_errors; + + gp_debug("Cleaning symbol table."); + ++ num_clean_errors = gp_real_num_errors(); ++ + /* point all relocations to the symbol definitions */ + section = Object->section_list.first; + while (section != NULL) { +@@ -186,13 +189,17 @@ gp_cofflink_clean_table(gp_object_t *Object, symbol_table_t *Symbols) + + if (gp_coffgen_is_external_symbol(symbol)) { + /* This is an external symbol defined elsewhere. */ +- sym = gp_sym_get_symbol(Symbols, symbol->name); +- assert(sym != NULL); +- var = (const gp_coffsymbol_t *)gp_sym_get_symbol_annotation(sym); +- assert(var != NULL); +- symbol = var->symbol; +- assert(symbol != NULL); +- relocation->symbol = symbol; ++ sym = gp_sym_get_symbol(Symbols, symbol->name); ++ if (sym == NULL) { ++ gp_error("Non-existent external symbol - \"%s\" - used in \"%s\" section.", symbol->name, section->name); ++ } ++ else { ++ var = (const gp_coffsymbol_t *)gp_sym_get_symbol_annotation(sym); ++ assert(!(var == NULL)); ++ symbol = var->symbol; ++ assert(!(symbol == NULL)); ++ relocation->symbol = symbol; ++ } + } + + relocation = relocation->next; +@@ -201,13 +208,17 @@ gp_cofflink_clean_table(gp_object_t *Object, symbol_table_t *Symbols) + section = section->next; + } + ++ if (gp_real_num_errors() > num_clean_errors) { ++ exit(1); ++ } ++ + symbol = Object->symbol_list.first; + while (symbol != NULL) { + next = symbol->next; + + if (gp_coffgen_is_external_symbol(symbol)) { + gp_debug(" removed symbol \"%s\"", symbol->name); +- gp_coffgen_del_symbol(Object, symbol); ++ gp_coffgen_del_symbol(Object, symbol, true); + } + + symbol = next; +@@ -265,7 +276,7 @@ gp_cofflink_combine_overlay(gp_object_t *Object, gp_boolean Remove_symbol) + + /* Remove the section symbol. */ + if (Remove_symbol) { +- gp_coffgen_del_symbol(Object, second->symbol); ++ gp_coffgen_del_symbol(Object, second->symbol, true); + } + + /* Update the symbol table */ +@@ -1570,6 +1581,7 @@ _patch_addr(gp_object_t *Object, gp_section_t *Section, const gp_reloc_t *Reloca + int bank; + int page; + gp_boolean write_data; ++ const insn_t *instruction; + + class = Object->class; + num_pages = gp_processor_num_pages(Object->processor); +@@ -1602,9 +1614,23 @@ _patch_addr(gp_object_t *Object, gp_section_t *Section, const gp_reloc_t *Reloca + data = class->reloc_goto(value); + break; + +- case RELOC_LOW: +- data = value & 0xff; ++ case RELOC_LOW: { ++ instruction = class->find_insn(class, current_value); ++ ++ if (instruction == NULL) { ++ gp_error("No instruction for %#x at %#x(%s/%s)", current_value, ++ byte_addr, Section->name, symbol->name); ++ return; ++ } ++ ++ if (instruction->class == INSN_CLASS_LIT8) { ++ data = value & 0xff; ++ } ++ else { ++ data = class->reloc_f(value); ++ } + break; ++ } + + case RELOC_HIGH: + data = class->reloc_high(FlagIsSet(symbol->section->flags, STYP_ROM_AREA), value); +diff --git a/libgputils/gpmessage.c b/libgputils/gpmessage.c +index 0a640eb..1573193 100644 +--- a/libgputils/gpmessage.c ++++ b/libgputils/gpmessage.c +@@ -34,14 +34,20 @@ int gp_num_errors = 0; + int gp_num_warnings = 0; + int gp_num_messages = 0; + ++static int _real_num_errors = 0; ++static int _real_num_warnings = 0; ++static int _real_num_messages = 0; ++ + /*------------------------------------------------------------------------------------------------*/ + + void +-gp_error(const char *Format, ...) ++gp_error(const char* Format, ...) + { + va_list args; + char buffer[BUFSIZ]; + ++ _real_num_errors++; ++ + if (gp_message_disable) { + return; + } +@@ -62,11 +68,13 @@ gp_error(const char *Format, ...) + /*------------------------------------------------------------------------------------------------*/ + + void +-gp_warning(const char *Format, ...) ++gp_warning(const char* Format, ...) + { + va_list args; + char buffer[BUFSIZ]; + ++ _real_num_warnings++; ++ + if (gp_message_disable) { + return; + } +@@ -87,11 +95,13 @@ gp_warning(const char *Format, ...) + /*------------------------------------------------------------------------------------------------*/ + + void +-gp_message(const char *Format, ...) ++gp_message(const char* Format, ...) + { + va_list args; + char buffer[BUFSIZ]; + ++ _real_num_messages++; ++ + if (gp_message_disable) { + return; + } +@@ -112,7 +122,7 @@ gp_message(const char *Format, ...) + /*------------------------------------------------------------------------------------------------*/ + + void +-gp_debug(const char *Format, ...) ++gp_debug(const char* Format, ...) + { + va_list args; + char buffer[BUFSIZ]; +@@ -131,3 +141,27 @@ gp_debug(const char *Format, ...) + + printf("debug: %s\n", buffer); + } ++ ++/*------------------------------------------------------------------------------------------------*/ ++ ++int ++gp_real_num_errors(void) ++{ ++ return _real_num_errors; ++} ++ ++/*------------------------------------------------------------------------------------------------*/ ++ ++int ++gp_real_num_warnings(void) ++{ ++ return _real_num_warnings; ++} ++ ++/*------------------------------------------------------------------------------------------------*/ ++ ++int ++gp_real_num_messages(void) ++{ ++ return _real_num_messages; ++} +diff --git a/libgputils/gpmessage.h b/libgputils/gpmessage.h +index d2f6ffa..2329f4c 100644 +--- a/libgputils/gpmessage.h ++++ b/libgputils/gpmessage.h +@@ -30,9 +30,13 @@ extern int gp_num_errors; + extern int gp_num_warnings; + extern int gp_num_messages; + +-extern void gp_error(const char *Format, ...); +-extern void gp_warning(const char *Format, ...); +-extern void gp_message(const char *Format, ...); +-extern void gp_debug(const char *Format, ...); ++extern void gp_error(const char* Format, ...); ++extern void gp_warning(const char* Format, ...); ++extern void gp_message(const char* Format, ...); ++extern void gp_debug(const char* Format, ...); ++ ++extern int gp_real_num_errors(void); ++extern int gp_real_num_warnings(void); ++extern int gp_real_num_messages(void); + + #endif +diff --git a/libgputils/gpreadobj.c b/libgputils/gpreadobj.c +index f1cc22d..57de3f0 100644 +--- a/libgputils/gpreadobj.c ++++ b/libgputils/gpreadobj.c +@@ -648,7 +648,7 @@ _clean_symbol_table(gp_object_t *Object) + for (i = 0; i < curr_symbol->aux_list.num_nodes; ++i) { + aux_symbol = next_symbol; + next_symbol = next_symbol->next; +- gp_coffgen_del_symbol(Object, aux_symbol); ++ gp_coffgen_del_symbol(Object, aux_symbol, false); + } + } + curr_symbol = curr_symbol->next;