linker: Formatting

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-01-18 17:03:57 +01:00
parent a16218e1d5
commit cc1340190e
8 changed files with 499 additions and 405 deletions
+165 -111
View File
@@ -1,137 +1,172 @@
#include "std.hpp"
#include "linker.hpp"
#include "image_util.hpp"
#include "std.hpp"
using namespace std;
class BBModule : public Module{
public:
class BBModule : public Module {
public:
BBModule();
BBModule( istream &in );
BBModule(istream& in);
~BBModule();
void *link( Module *libs );
bool createExe( const char *exe_file,const char *dll_file );
void* link(Module* libs);
bool createExe(const char* exe_file, const char* dll_file);
int getPC();
void emit( int byte );
void emitw( int word );
void emitd( int dword );
void emitx( void *mem,int sz );
bool addSymbol( const char *sym,int pc );
bool addReloc( const char *dest_sym,int pc,bool pcrel );
void emit(int byte);
void emitw(int word);
void emitd(int dword);
void emitx(void* mem, int sz);
bool addSymbol(const char* sym, int pc);
bool addReloc(const char* dest_sym, int pc, bool pcrel);
bool findSymbol( const char *sym,int *pc );
bool findSymbol(const char* sym, int* pc);
private:
char *data;
int data_sz,pc;
bool linked;
private:
char* data;
int data_sz, pc;
bool linked;
map<string,int> symbols;
map<int,string> rel_relocs,abs_relocs;
map<string, int> symbols;
map<int, string> rel_relocs, abs_relocs;
bool findSym( const string &t,Module *libs,int *n ){
if( findSymbol( t.c_str(),n ) ) return true;
if( libs->findSymbol( t.c_str(),n ) ) return true;
string err="Symbol '"+t+"' not found";
MessageBox( GetDesktopWindow(),err.c_str(),"Blitz Linker Error",MB_TOPMOST|MB_SETFOREGROUND );
bool findSym(const string& t, Module* libs, int* n)
{
if (findSymbol(t.c_str(), n))
return true;
if (libs->findSymbol(t.c_str(), n))
return true;
string err = "Symbol '" + t + "' not found";
MessageBox(GetDesktopWindow(), err.c_str(), "Blitz Linker Error", MB_TOPMOST | MB_SETFOREGROUND);
return false;
}
void ensure( int n ){
if( pc+n<=data_sz ) return;
data_sz=data_sz/2+data_sz;
if( data_sz<pc+n ) data_sz=pc+n;
char *old_data=data;
data=new char[data_sz];
memcpy( data,old_data,pc );
void ensure(int n)
{
if (pc + n <= data_sz)
return;
data_sz = data_sz / 2 + data_sz;
if (data_sz < pc + n)
data_sz = pc + n;
char* old_data = data;
data = new char[data_sz];
memcpy(data, old_data, pc);
delete old_data;
}
};
BBModule::BBModule():data(0),data_sz(0),pc(0),linked(false){
BBModule::BBModule() : data(0), data_sz(0), pc(0), linked(false) {}
BBModule::~BBModule()
{
if (linked)
VirtualFree(data, 0, MEM_RELEASE);
else
delete[] data;
}
BBModule::~BBModule(){
if( linked ) VirtualFree( data,0,MEM_RELEASE );
else delete[] data;
}
void* BBModule::link(Module* libs)
{
if (linked)
return data;
void *BBModule::link( Module *libs ){
int dest;
map<int, string>::iterator it;
if( linked ) return data;
int dest;
map<int,string>::iterator it;
char *p=(char*)VirtualAlloc( 0,pc,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE );
memcpy( p,data,pc );
char* p = (char*)VirtualAlloc(0, pc, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(p, data, pc);
delete[] data;
data=p;
data = p;
linked=true;
linked = true;
for( it=rel_relocs.begin();it!=rel_relocs.end();++it ){
if( !findSym( it->second,libs,&dest ) ) return 0;
int *p=(int*)(data+it->first);*p+=(dest-(int)p);
for (it = rel_relocs.begin(); it != rel_relocs.end(); ++it) {
if (!findSym(it->second, libs, &dest))
return 0;
int* p = (int*)(data + it->first);
*p += (dest - (int)p);
}
for( it=abs_relocs.begin();it!=abs_relocs.end();++it ){
if( !findSym( it->second,libs,&dest ) ) return 0;
int *p=(int*)(data+it->first);*p+=dest;
for (it = abs_relocs.begin(); it != abs_relocs.end(); ++it) {
if (!findSym(it->second, libs, &dest))
return 0;
int* p = (int*)(data + it->first);
*p += dest;
}
return data;
}
int BBModule::getPC(){
int BBModule::getPC()
{
return pc;
}
void BBModule::emit( int byte ){
ensure(1);data[pc++]=byte;
void BBModule::emit(int byte)
{
ensure(1);
data[pc++] = byte;
}
void BBModule::emitw( int word ){
ensure(2);*(short*)(data+pc)=word;pc+=2;
void BBModule::emitw(int word)
{
ensure(2);
*(short*)(data + pc) = word;
pc += 2;
}
void BBModule::emitd( int dword ){
ensure(4);*(int*)(data+pc)=dword;pc+=4;
void BBModule::emitd(int dword)
{
ensure(4);
*(int*)(data + pc) = dword;
pc += 4;
}
void BBModule::emitx( void *mem,int sz ){
ensure(sz);memcpy( data+pc,mem,sz );pc+=sz;
void BBModule::emitx(void* mem, int sz)
{
ensure(sz);
memcpy(data + pc, mem, sz);
pc += sz;
}
bool BBModule::addSymbol( const char *sym,int pc ){
bool BBModule::addSymbol(const char* sym, int pc)
{
string t(sym);
if( symbols.find( t )!=symbols.end() ) return false;
symbols[t]=pc;return true;
}
bool BBModule::addReloc( const char *dest_sym,int pc,bool pcrel ){
map<int,string> &rel=pcrel ? rel_relocs : abs_relocs;
if( rel.find( pc )!=rel.end() ) return false;
rel[pc]=string(dest_sym);return true;
}
bool BBModule::findSymbol( const char *sym,int *pc ){
string t=string(sym);
map<string,int>::iterator it=symbols.find( t );
if( it==symbols.end() ) return false;
*pc=it->second + (int)data;
if (symbols.find(t) != symbols.end())
return false;
symbols[t] = pc;
return true;
}
int Linker::version(){
bool BBModule::addReloc(const char* dest_sym, int pc, bool pcrel)
{
map<int, string>& rel = pcrel ? rel_relocs : abs_relocs;
if (rel.find(pc) != rel.end())
return false;
rel[pc] = string(dest_sym);
return true;
}
bool BBModule::findSymbol(const char* sym, int* pc)
{
string t = string(sym);
map<string, int>::iterator it = symbols.find(t);
if (it == symbols.end())
return false;
*pc = it->second + (int)data;
return true;
}
int Linker::version()
{
return VERSION;
}
bool Linker::canCreateExe(){
bool Linker::canCreateExe()
{
#ifdef DEMO
return false;
#else
@@ -139,34 +174,45 @@ bool Linker::canCreateExe(){
#endif
}
Module *Linker::createModule(){
Module* Linker::createModule()
{
return new BBModule();
}
void Linker::deleteModule( Module *mod ){
void Linker::deleteModule(Module* mod)
{
delete mod;
}
Linker *_cdecl linkerGetLinker(){
static Linker linker;return &linker;
Linker* _cdecl linkerGetLinker()
{
static Linker linker;
return &linker;
}
bool BBModule::createExe( const char *exe_file,const char *dll_file ){
bool BBModule::createExe(const char* exe_file, const char* dll_file)
{
#ifdef DEMO
return false;
#else
//find proc address of bbWinMain
HMODULE hmod=LoadLibrary( dll_file );if( !hmod ) return false;
int proc=(int)GetProcAddress( hmod,"_bbWinMain@0" );
int entry=proc-(int)hmod;FreeLibrary( hmod );if( !proc ) return false;
HMODULE hmod = LoadLibrary(dll_file);
if (!hmod)
return false;
int proc = (int)GetProcAddress(hmod, "_bbWinMain@0");
int entry = proc - (int)hmod;
FreeLibrary(hmod);
if (!proc)
return false;
if( !CopyFile( dll_file,exe_file,false ) ) return false;
if (!CopyFile(dll_file, exe_file, false))
return false;
if( !openImage( exe_file ) ) return false;
if (!openImage(exe_file))
return false;
makeExe( entry );
makeExe(entry);
//create module
//code size: code...
@@ -175,39 +221,47 @@ bool BBModule::createExe( const char *exe_file,const char *dll_file ){
//num_abss: name,val...
//
qstreambuf buf;
iostream out( &buf );
iostream out(&buf);
map<string,int>::iterator it;
map<int,string>::iterator rit;
map<string, int>::iterator it;
map<int, string>::iterator rit;
//write the code
int sz=pc;out.write( (char*)&sz,4 );out.write( data,pc );
int sz = pc;
out.write((char*)&sz, 4);
out.write(data, pc);
//write symbols
sz=symbols.size();out.write( (char*)&sz,4 );
for( it=symbols.begin();it!=symbols.end();++it ){
string t=it->first+'\0';
out.write( t.data(),t.size() );
sz=it->second;out.write( (char*)&sz,4 );
sz = symbols.size();
out.write((char*)&sz, 4);
for (it = symbols.begin(); it != symbols.end(); ++it) {
string t = it->first + '\0';
out.write(t.data(), t.size());
sz = it->second;
out.write((char*)&sz, 4);
}
//write relative relocs
sz=rel_relocs.size();out.write( (char*)&sz,4 );
for( rit=rel_relocs.begin();rit!=rel_relocs.end();++rit ){
string t=rit->second+'\0';
out.write( t.data(),t.size() );
sz=rit->first;out.write( (char*)&sz,4 );
sz = rel_relocs.size();
out.write((char*)&sz, 4);
for (rit = rel_relocs.begin(); rit != rel_relocs.end(); ++rit) {
string t = rit->second + '\0';
out.write(t.data(), t.size());
sz = rit->first;
out.write((char*)&sz, 4);
}
//write absolute relocs
sz=abs_relocs.size();out.write( (char*)&sz,4 );
for( rit=abs_relocs.begin();rit!=abs_relocs.end();++rit ){
string t=rit->second+'\0';
out.write( t.data(),t.size() );
sz=rit->first;out.write( (char*)&sz,4 );
sz = abs_relocs.size();
out.write((char*)&sz, 4);
for (rit = abs_relocs.begin(); rit != abs_relocs.end(); ++rit) {
string t = rit->second + '\0';
out.write(t.data(), t.size());
sz = rit->first;
out.write((char*)&sz, 4);
}
replaceRsrc( 10,1111,1033,buf.data(),buf.size() );
replaceRsrc(10, 1111, 1033, buf.data(), buf.size());
closeImage();