From 438c21a3c80898dcc8781b278321661b4622085f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 29 Oct 2017 00:17:34 +0100 Subject: [PATCH] ld: closer but not yet entirely correct --- Applications/MWC/cmd/asz80/TODO | 50 ++++++++++++++++++--------------- Applications/MWC/cmd/asz80/ld.c | 14 ++++----- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/Applications/MWC/cmd/asz80/TODO b/Applications/MWC/cmd/asz80/TODO index aa4dbdea..f528e665 100644 --- a/Applications/MWC/cmd/asz80/TODO +++ b/Applications/MWC/cmd/asz80/TODO @@ -1,11 +1,14 @@ -Add outraw outrab and use them so that we can generate relocations +DONE Add outraw outrab and use them so that we can generate relocations +DONE Check error cases (seg +seg , unknown + seg etc) +DONE Automatic symbols __code __data __bss __endcode __enddata __endbss - Need to add .code .equ and all the other .byte type stuff that is nice to have -- Check error cases (seg +seg , unknown + seg etc) -- Automatic symbols __code __data __bss __endcode __enddata __endbss -What are the right rules for segment v absolute +Check that JR works with symbols properly (require they are in the same .o maybe) + +DONE +Rules for segment v absolute seg - seg = absolute if same seg seg - seg = error if not @@ -18,27 +21,28 @@ What are the right rules for segment v absolute multiply/divide of segs -> disallow ? and require things like x / 2 - y / 2 is done as (x - y) / 2 ? -Proper error messaeges needed + +DONE Proper error messaeges needed later: need a syntax/operator for high/low byte of seg output is then segbyteh or segbytel and follows same rules as segment (what about mixing them ?) -- Proper output logic - - write an invalid header - - for each segment - - write segment (counting relocs) - - write reloc tab (or fold it in ?) - - write symbol table - - write debug table - - rewind and fix header +DONE - Proper output logic +DONE - write an invalid header +DONE - for each segment +DONE - write segment (counting relocs) +DONE - write reloc tab (or fold it in ?) +DONE - write symbol table +DONE - write debug table +DONE - rewind and fix header Relocation types -1. versus our segment base for this object module (usual) -2. versus other segment base for this module -3. versus unresolved symbol +DONE versus our segment base for this object module (usual) +DONE versus other segment base for this module +DONE versus unresolved symbol Need to support relocations for 16bit and also 8bit ZP. Do we need to extend the assembler to support relocations for high 8 / low 8 ? Probably not for Z80 @@ -48,17 +52,19 @@ but also to know if its address high/address low/address/absolute - add to a_type somehow ? link - read each module header that we include - load its symbols +DONE read each module header that we include +DONE load its symbols - compute base of each versus segment - compute base of segments (split I/D differs a bit etc) +DONE compute base of each versus segment +DONE compute base of segments (split I/D differs a bit etc) - resolve all symbols we can +DONE resolve all symbols we can - write out segments relocating and resolving +IP write out segments relocating and resolving Unresolved symbols allowed for -r scan each module header again copy all the debug symbols (relocating as we go) + + Libraries diff --git a/Applications/MWC/cmd/asz80/ld.c b/Applications/MWC/cmd/asz80/ld.c index 3f99044b..099e6129 100644 --- a/Applications/MWC/cmd/asz80/ld.c +++ b/Applications/MWC/cmd/asz80/ld.c @@ -332,6 +332,7 @@ static void set_segment_bases(void) /* base will be 0 for absolute */ if (s->definedby) s->value += s->definedby->base[seg]; + /* FIXME: check overflow */ s = s->next; } } @@ -437,14 +438,7 @@ void relocate_stream(struct object *o, FILE * op, FILE * ip) r = fgetc(ip); if (size == 2) r |= fgetc(ip) << 8; - /* Add the base of the relevant segment of the defining - object module - unless it's an absolute constant */ - if ((s->type & S_SEGMENT) != ABSOLUTE) - r += s->definedby->base[s->type & S_SEGMENT]; - /* Check it didn't overflow */ - if (r < base[s->type & S_SEGMENT]) - error("relocation exceeded"); - /* Add the offset from the segment base of the object to the + /* Add the offset from the output segment base to the symbol */ r += s->value; /* Check again */ @@ -452,8 +446,10 @@ void relocate_stream(struct object *o, FILE * op, FILE * ip) error("relocation exceeded"); /* If we are not fully resolving then turn this into a simple relocation */ - if (ldmode != LD_ABSOLUTE) + if (ldmode != LD_ABSOLUTE) { + fputc(REL_ESC, op); fputc(REL_SIMPLE | (s->type & S_SEGMENT) | (size - 1) << 4, op); + } fputc(r, op); if (size == 2) fputc(r >> 8, op); -- 2.34.1