/* ---------------------------------------------------------------------- */ /* Copyright (C) 1991 by Natrlich! */ /* This file is copyrighted! */ /* Refer to the documentation for details. */ /* ---------------------------------------------------------------------- */ #define LINKER 1 #define WRITE_TABLE 0 #if WRITE_TABLE # include #endif #include "defines.h" #include "nasm.h" #include OSBIND #include "debug.h" #include "seg.h" #include "labels.h" #include "imm.h" #include "process.h" extern imm huge *hip; extern seg huge *h_seg, huge *l_seg; seg huge *f_seg; extern word r_end, r_start, rcode_off; #define xdeposit( x) deposit( x) #define xwdeposit( x) wdeposit( x) void def_label( s, val) char *s; word val; { label huge *q; if( ! (q = find_label( s))) { #if ! VERSION extern char *str_alloc(); s = strcpy( str_alloc( strlen( s) + 1), s); #endif enter_llabel( s, val, L_PC); /* Shouldn't really happen */ } else if( ! q->refs) nierror("Linker internal label twice defined"); else { q->val = val; /* Case: Label has refs, we got the value */ entrefer( q); } } static int countem( p, ourpage, type) register imm huge *p; word ourpage; int type; { register int i; register word tmp; for( i = 0; p; p = p->next) if( p->type == type && p->block != f_seg) { if( (tmp = p->offset + p->block->offset - rcode_off + r_start) >= r_end || (tmp & 0xFF00) > ourpage) break; i++; } return( i); } /* ---------------------------------------------------------- */ /* This dumps the immediate table down into the file write */ /* space. The flag tells us whether we are gonna be */ /* page-aligned or not (then we need plenty more info) */ /* ---------------------------------------------------------- */ #define MSB 1 #define LSB 0 void dump_imm( flag) int flag; { register imm huge *p = hip; register word i; word pages, ourpage, factor = (r_start & 0xFF) - rcode_off; #if WRITE_TABLE word aux, cnt; #endif f_seg = l_seg->next; def_label("|IMMTAB", __pc); /* incorporate .DS holes into index */ /* { register seg huge *p; register word plus = 0; for( p = h_seg; p != f_seg; p = p->next) { p->index += plus; if( p->type == S_DS) plus += p->size; } }*/ pages = ( ((r_end & 0xFF00) - (ourpage = r_start & 0xFF00)) >> 8) + 1; #if WRITE_TABLE printf( "%d pages total\n", pages); #endif xdeposit( pages); if( ! flag) { int ipages = pages; #if WRITE_TABLE printf( "LSB patch bytes:"); aux = r_start & 0xFF00; #endif while( ipages--) { i = countem( p, ourpage, LSB); xdeposit( i); #if WRITE_TABLE printf( "\n%4d bytes to patch\n", i); cnt = 0; #endif while( i--) { while( p->type) p = p->next; xdeposit( p->offset + p->block->offset + factor); #if WRITE_TABLE if( cnt++ == 8) { putchar('\n'); cnt = 0; } printf( " $%04X", __p[ -1] + ourpage); if( i && cnt != 8) putchar( ','); #endif p = p->next; } ourpage += 0x100; #if WRITE_TABLE putchar('\n'); #endif } p = hip; ourpage = r_start & 0xFF00; } #if WRITE_TABLE printf( "\n\nMSB patch bytes:"); #endif while( pages--) { i = countem( p, ourpage, MSB); xdeposit( i); #if WRITE_TABLE printf( "\n%4d bytes to patch\n", i); cnt = 0; #endif while( i--) { while( ! p->type) p = p->next; xdeposit( p->offset + p->block->offset + factor); #if WRITE_TABLE if( cnt++ == 3) { putchar('\n'); cnt = 1; } printf( " $%04X (LSB: $%02X)", __p[ -1] + ourpage, p->val & 0xFF); if( i && cnt != 3) putchar( ','); #endif if( ! flag) { xdeposit( p->val); } p = p->next; } ourpage += 0x100; #if WRITE_TABLE putchar('\n'); #endif } } void dump_reloc() { register seg huge *p = h_seg; def_label( "|RELTAB", __pc); for(;;) { if( p->type == S_DS) { xdeposit( S_SDATA); } else { xdeposit( p->type); while( p != l_seg && p->next->type == p->type) { p->next->size += p->size; p = p->next; } } xwdeposit( p->size); if( p == l_seg) { xdeposit( 128); /* dump EOP */ return; } p = p->next; } }