/* ....[@@@..[@@@..............[@.................. 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@van.ml.org ------------------------------------------------------------------------------ asmobjfile.cc */ #include <string.h> #include "config.h" #include "io.h" #include "asmobjfile.h" #include "llist.h" #define MEM_DELTA 100 int AsmObjFile::readFrom( StaticInput & in ) { asmobjheader head; constants_def.clr(); // HEADER in.read( &head, sizeof(asmobjheader) ); if ( strncmp(head.magic, ASMOBJ_MAGIC, 4 ) ) { in.error( "Bad magic number.\n\r"); return 1; } allocMemBlock(head.code_length); constants.allocMemBlock(head.consts_length); // EXEC CODE in.read( getMem(), head.code_length * sizeof(memorycell) ); setOffset( head.code_length ); // CONST TABLE constants_def.readFrom(in); // RELOCATION TABLE relocation_table.readFrom(in); // CONSTS in.read(constants.getMem(), head.consts_length); constants.setOffset( head.consts_length ); return 0; } char emptybuf[] = "\0\0\0\0\0\0"; int AsmObjFile::writeTo( Output & out ) const { asmobjheader head; // HEADER strncpy( head.magic, ASMOBJ_MAGIC, 4); head.code_length = getUsedSize(); head.consts_length = constants.getUsedSize(); out.write( &head, sizeof(asmobjheader) ); // CODE PART out.write(getConstMem(), getUsedBytesize()); // CONST DEF TABLE constants_def.writeTo( out ); // RELOCATION TABLE relocation_table.writeTo( out ); // CONSTS out.write(constants.getConstMem(), constants.getUsedBytesize() ); return 0; } int AsmObjFile::addConstant( vmtype type, const void * src_ptr, int size ) { asmobjconst oconst; int i; if ( (type == VMT_IMPORT_INTERFACE) || (type == VMT_IMPORT_FUN ) || (type == VMT_IMPORT_STATIC) || (type == VMT_CLASS_TYPE) ) { if ( (i = importLookup( type, (const char*)src_ptr) ) > 0) { // Cout << "Reduced import constant for " << (const char*)src_ptr <<endl; return i; } } oconst.type = type; oconst.offset = constants.getOffset(); constants.putStruct( src_ptr, size ); constants_def.add( oconst ); return (constants_def.length() - 1); } int AsmObjFile::importLookup( vmtype type, const char * name ) { int i,size; size = constants_def.length(); for ( i=0; i < size; i++ ) { if ( constants_def[i].type == type ) if ( !strcmp( name, constants.getMem() + constants_def[i].offset ) ) return i; } return -1; } /* * we have unsigned 16-bit constants numbers in object files * it is one 16-bit numberspace for all types of constants * after loading to mud it grows to 16-bit space for every main type of * reference - normal, mudasm fun, interface fun, static */ bool AsmObjFile::canLink( AsmObjFile & linkee ) { if ( (constants_def.length() + linkee.constants_def.length()) > 64000 ) return false; return true; } void AsmObjFile::link( AsmObjFile & linkee ) { int i,size,tmp; int code_offset; int consts_count; asmobjconst oconst; vmfilefun vmff; int * reloc_now = new int[linkee.constants_def.length()]; char * cptr; code_offset = getOffset(); consts_count = constants_def.length(); // copy code block canCarryMore( linkee.getUsedSize() ); memcpy( getPtr(), linkee.getMem(), linkee.getUsedBytesize() ); movePtr( linkee.getUsedSize() ); // copy and update both constants definitions and constants themselves size = linkee.constants_def.length(); for ( i=0; i < size; i++ ) { oconst = linkee.constants_def[i]; switch ( oconst.type ) { case VMT_CONST_STRING: case VMT_IMPORT_FUN: case VMT_IMPORT_INTERFACE: case VMT_IMPORT_STATIC: case VMT_CLASS_TYPE: case VMT_IMPORT_FUN_OR_INTERFACE: cptr = linkee.constants.getMem() + oconst.offset; reloc_now[i] = addConstant( oconst.type, cptr, strlen(cptr) + 1); break; case VMT_FIELD_DATA: cptr = linkee.constants.getMem() + oconst.offset; tmp = strlen( cptr ); tmp += strlen( &cptr[tmp+1] ); reloc_now[i] = addConstant( oconst.type, cptr, tmp + 2); break; case VMT_EXPORT_FUN: vmff = *((vmfilefun*)linkee.constants.getStruct(oconst.offset)); vmff.start += code_offset; vmff.end += code_offset; vmff.name = reloc_now[vmff.name]; reloc_now[i] = addConstant( oconst.type, &vmff, sizeof(vmfilefun)); break; default: Cout << "Unknown type of asmobjfile constant" <<endl; break; } } // copy and update relocation table // also update references in code size = linkee.relocation_table.length(); for ( i=0; i < size; i++ ) { tmp = linkee.relocation_table[i] + code_offset; mem[tmp].s.u.number = reloc_now[mem[tmp].s.u.number]; relocation_table.add(tmp); } delete [] reloc_now; }