X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=mark.c;h=3b3bd3ada80dd969415089218b95f5b0b59e6e5d;hp=d3b827aede1bc00a44dae7080aebaeafa6ce47e5;hb=062214e62031c26d372edc2e68473ebb64f6a506;hpb=49cce96fba11282e4244187f15be418d5ae5bb8d diff --git a/mark.c b/mark.c index d3b827a..3b3bd3a 100644 --- a/mark.c +++ b/mark.c @@ -9,20 +9,24 @@ #include "mark.h" #include "error.h" #include "object.h" -#include "risca.h" +#include "riscasm.h" + MCHUNK * firstmch; // First mark chunk MCHUNK * curmch; // Current mark chunk PTR markptr; // Deposit point in current mark chunk LONG mcalloc; // #bytes alloc'd to current mark chunk LONG mcused; // #bytes used in current mark chunk -WORD curfrom; // Current "from" section +uint16_t curfrom; // Current "from" section + + +//#define DEBUG_IMAGE_MARKING // // Initialize Marker // -void init_mark(void) +void InitMark(void) { firstmch = curmch = NULL; mcalloc = mcused = 0; @@ -37,8 +41,8 @@ void stopmark(void) { if (curmch) { - *markptr.wp = MCHEND; // Mark end of block - curmch->mcused = mcused; // Update #used in mark block + *markptr.wp = MCHEND; // Mark end of block + curmch->mcused = mcused; // Update #used in mark block } } @@ -46,36 +50,40 @@ void stopmark(void) // // Mark a word or longword relocatable // -int rmark(int from, LONG loc, int to, int size, SYM * symbol) +int rmark(uint16_t from, uint32_t loc, uint16_t to, uint16_t size, SYM * symbol) { - WORD w; +#ifdef DEBUG_IMAGE_MARKING +printf("rmark: from=%i, loc=$%X, to=$%X, size=$%x, symbol=$%X\n", from, loc, to, size, symbol); +if (symbol) + printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname); +#endif if ((mcalloc - mcused) < MIN_MARK_MEM) amark(); - w = (WORD)(size | to); + uint16_t flags = (size | to); if (from != curfrom) - w |= MCHFROM; + flags |= MCHFROM; if (symbol != NULL) - w |= MSYMBOL; + flags |= MSYMBOL; mcused += sizeof(WORD) + sizeof(LONG); - *markptr.wp++ = w; + *markptr.wp++ = flags; *markptr.lp++ = loc; - if (w & MCHFROM) + if (flags & MCHFROM) { - *markptr.wp++ = (WORD)from; - curfrom = (WORD)from; + curfrom = from; + *markptr.wp++ = from; mcused += sizeof(WORD); } - if (w & MSYMBOL) + if (flags & MSYMBOL) { *markptr.sy++ = symbol; - mcused += sizeof(LONG); + mcused += sizeof(SYM *); } *markptr.wp = 0x0000; @@ -89,18 +97,19 @@ int rmark(int from, LONG loc, int to, int size, SYM * symbol) // int amark(void) { - MCHUNK * p; +// MCHUNK * p; // Alloc mark block header (and data) and set it up. // p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR); - p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR); + MCHUNK * p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR); p->mcnext = NULL; p->mcalloc = MARK_ALLOC_INCR; p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK)); if (curmch) - { // Link onto previous chunk - *markptr.wp++ = MCHEND; // Mark end of block + { + // Link onto previous chunk + *markptr.wp++ = MCHEND; // Mark end of block curmch->mcused = mcused; curmch->mcnext = p; } @@ -108,7 +117,7 @@ int amark(void) if (!firstmch) firstmch = p; - curmch = p; // Setup global vars + curmch = p; // Setup global vars markptr = p->mcptr; mcalloc = MARK_ALLOC_INCR; mcused = 0; @@ -120,53 +129,60 @@ int amark(void) // // Make mark image for BSD .o file // -LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) +uint32_t bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) { - MCHUNK * mch; // Mark chunk - PTR p; // Source point from within mark chunk - WORD from; // Section fixups are currently FROM - WORD w; // A word (temp) - LONG loc; // Location (temp) - SYM * symbol; // Symbols (temp) - char * wp; // Pointer into raw relocation info - char * dp; // Deposit point for RELMOD info - LONG diff; // Difference to relocate (RELMOD) - LONG raddr, rflag = 0; // BSD relocation address and flags - LONG rsize; // Relocation size - int validsegment = 0; // Valid segment being processed - - rsize = 0; // Initialise relocation size + MCHUNK * mch; // Mark chunk + PTR p; // Source point from within mark chunk + uint16_t from; // Section fixups are currently FROM + uint16_t w; // A word (temp) + uint32_t loc; // Location (temp) + SYM * symbol; // Symbols (temp) + uint8_t * wp; // Pointer into raw relocation info + uint8_t * dp; // Deposit point for RELMOD info + uint32_t diff; // Difference to relocate (RELMOD) + uint32_t raddr, rflag = 0; // BSD relocation address and flags + uint32_t rsize; // Relocation size + int validsegment = 0; // Valid segment being processed + +#ifdef DEBUG_IMAGE_MARKING +printf("bsdmarkimg():\n"); +#endif + // Initialise relocation size + rsize = 0; chptr = mp; - from = 0; - for(mch = firstmch; mch != NULL; mch = mch->mcnext) + + for(mch=firstmch; mch!=NULL; mch=mch->mcnext) { for(p=mch->mcptr;;) { - w = *p.wp++; // Next mark entry + w = *p.wp++; // Next mark entry if (w & MCHEND) - break; // End of mark chunk + break; // End of mark chunk // Get mark record symbol = NULL; - loc = *p.lp++; // Mark location + loc = *p.lp++; // Mark location if (w & MCHFROM) - { // Maybe change "from" section + { + // Maybe change "from" section from = *p.wp++; if (obj_format == BSD) { if (reqseg == TEXT) - { // Requested segment is TEXT + { + // Requested segment is TEXT if (from == TEXT) validsegment = 1; else validsegment = 0; } else - { // Requested segment is DATA + { + // Requested segment is DATA if (from == DATA) validsegment = 1; else @@ -175,23 +191,34 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) } } - if (w & MSYMBOL) // Maybe includes a symbol + if (w & MSYMBOL) // Maybe includes a symbol symbol = *p.sy++; if (obj_format == BSD) { - raddr = loc; // Set relocation address + raddr = loc; // Set relocation address if (validsegment) - D_long(raddr); // Write relocation address +#ifdef DEBUG_IMAGE_MARKING +{ +printf(" validsegment: raddr = $%08X\n", raddr); +#endif + D_long(raddr); // Write relocation address +#ifdef DEBUG_IMAGE_MARKING +} +#endif if (w & MPCREL) - rflag = 0x000000A0; // PC-relative fixup + rflag = 0x000000A0; // PC-relative fixup else - rflag = 0x00000040; // Absolute fixup + rflag = 0x00000040; // Absolute fixup +// This flag tells the linker to WORD swap the LONG when doing the fixup. if (w & MMOVEI) +//{ +//printf("bsdmarkimg: ORing $01 to rflag (MMOVEI) [symbol=%s]...\n", symbol->sname); rflag |= 0x00000001; +//} } // Compute mark position in relocation information; @@ -199,23 +226,32 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) if (from == DATA) loc += tsize; - wp = (char *)(mp + loc); + wp = (uint8_t *)(mp + loc); if (symbol) { // Deposit external reference if (obj_format == BSD) { - rflag |= 0x00000010; // Set external reloc flag bit - rflag |= (symbol->senv << 8); // Put symbol index in flags + rflag |= 0x00000010; // Set external reloc flag bit + rflag |= (symbol->senv << 8); // Put symbol index in flags +// Looks like this is completely unnecessary (considering it does the wrong thing!) +#if 0 if (symbol->sattre & RISCSYM) +{ +printf("bsdmarkimg: ORing $01 to rflag (RISCSYM) [symbol=%s]...\n", symbol->sname); rflag |= 0x00000001; +} +#endif if (validsegment) { - D_long(rflag); // Write relocation flags - rsize += 8; // Increment relocation size +#ifdef DEBUG_IMAGE_MARKING +printf(" validsegment(2): rflag = $%08X\n", rflag); +#endif + D_long(rflag); // Write relocation flags + rsize += 8; // Increment relocation size } } } @@ -223,7 +259,10 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) { if (obj_format == BSD) { - w &= TDB; // Set reloc flags to segment +#ifdef DEBUG_IMAGE_MARKING +printf(" w = $%04X\n", w); +#endif + w &= TDB; // Set reloc flags to segment switch (w) { @@ -234,8 +273,11 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) if (validsegment) { - D_long(rflag); // Write relocation flags - rsize += 8; // Increment relocation size +#ifdef DEBUG_IMAGE_MARKING +printf(" validsegment(3): rflag = $%08X\n", rflag); +#endif + D_long(rflag); // Write relocation flags + rsize += 8; // Increment relocation size } w &= TDB; @@ -250,6 +292,9 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) diff |= ((LONG)(*dp++ & 0xFF)) << 8; diff |= (LONG)(*dp & 0xFF); DEBUG printf("diff=%ux ==> ", diff); +#ifdef DEBUG_IMAGE_MARKING +printf(" validsegment(4): diff = $%08X --> ", diff); +#endif if (rflag & 0x01) diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000); @@ -268,6 +313,9 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) *dp++ = (char)(diff >> 8); *dp = (char)diff; DEBUG printf("%ux\n", diff); +#ifdef DEBUG_IMAGE_MARKING +printf("$%08X\n", diff); +#endif } } } @@ -277,7 +325,14 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) // Return relocation size if (obj_format == BSD) +#ifdef DEBUG_IMAGE_MARKING +{ +printf(" rsize = $%X\n", rsize); +#endif return rsize; +#ifdef DEBUG_IMAGE_MARKING +} +#endif return siz; }