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;