/* ....[@@@..[@@@..............[@.................. MUD++ is a written from ....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and ....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++. ....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing ....[@......[@..[@@@@@..[@@@@@.................. development project. All ................................................ contributions are welcome. ....Copyright(C).1995.Melvin.Smith.............. Enjoy. ------------------------------------------------------------------------------ Melvin Smith (aka Fusion) msmith@hom.net MUD++ development mailing list mudpp-list@mailhost.net ------------------------------------------------------------------------------ asmlinker.cpp */ #include "string.h" #include "io.h" #include "asmlinker.h" #include "asmobjfile.h" // I use new/delete for files because it was done this way in previous // linker. When I'll be sure of design I'll change it to references // Todo: track all identical IMPORTS and reduce them to one // it will speed up the linker and reduce image size int AsmLinker::link( char * imagename, int count, char * names[] ) { char buf[ BUF ]; int i,j, size,tmp; int code_offset = 0; int consts_offset =0; int consts_number = 0; int relocs_number = 0; asmobjconst oconst; asmimageheader header; AsmObjFile * obj; Output * code; Output * const_defs; Output * consts; Output * reloc; Output * headerfile; vmfilefun vmff; sprintf( buf, "%s.code", imagename); code = new Output(buf); sprintf( buf, "%s.reloc", imagename); reloc = new Output(buf); sprintf( buf, "%s.const_def", imagename); const_defs = new Output(buf); sprintf( buf, "%s.consts", imagename); consts = new Output(buf); sprintf( buf, "%s.header", imagename); headerfile = new Output(buf); for ( i =0; i < count; i++ ) { StaticInput inf(names[i]); obj = new AsmObjFile(); obj->readFrom( inf ); // RELOCATION TABLE size = obj->relocation_table.length(); for ( j = 0; j < size; j++ ) { tmp = obj->relocation_table[j] + code_offset; reloc->write( &tmp, sizeof(int)); } // CODE PART size = obj->relocation_table.length(); for ( j = 0; j < size; j++ ) { obj->relocCell(obj->relocation_table[j], consts_number); } code->write( obj->getConstMem(), obj->getUsedBytesize() ); // CONSTANTS size = obj->constants_def.length(); for ( j=0; j< size; j++ ) { switch ( obj->constants_def[j].type ) { case VMT_CONST_STRING: case VMT_FUN_IMPORT: case VMT_INTERFACE_IMPORT: case VMT_STATIC_IMPORT: continue; case VMT_FUN_EXPORT: tmp = obj->constants_def[j].offset; vmff = *((vmfilefun*)obj->constants.getStruct(tmp)); vmff.start += code_offset; vmff.end += code_offset; vmff.name += consts_number; obj->constants.setStruct(tmp, &vmff, sizeof(vmfilefun)); continue; default: continue; } } consts->write( obj->constants.getConstMem(), obj->constants.getUsedBytesize() ); // CONSTANTS DEFINITIONS size = obj->constants_def.length(); for ( j=0; j < size; j++ ) { oconst = obj->constants_def[j]; oconst.offset += consts_offset; const_defs->write( &oconst, sizeof(asmobjconst) ); } consts_number += obj->constants_def.length(); relocs_number += obj->relocation_table.length(); code_offset += obj->getUsedSize(); consts_offset += obj->constants.getUsedSize(); delete obj; } delete code; delete consts; delete const_defs; delete reloc; header.code_length = code_offset; header.constants_length = consts_offset; header.relocs_count = relocs_number; header.constants_count = consts_number; headerfile->write( &header, sizeof(asmimageheader) ); delete headerfile; return 0; }