Permalink
Browse files

Merge pull request #131 from sp1187/elf

 Check machine and endianness field when linking ELF files
  • Loading branch information...
Kingcom committed Jan 14, 2018
2 parents e2610fe + 79aad35 commit ca73d71c8b2570f46c73af8c5cb60190b1a761a9
@@ -1,7 +1,7 @@
#include "stdafx.h"
#include "Arm.h"
#include "Core/Common.h"
#include "ArmRelocator.h"
#include "ArmElfRelocator.h"
#include "ArmParser.h"
#include "ArmExpressionFunctions.h"

@@ -66,9 +66,9 @@ void CArmArchitecture::NextSection()

}

IElfRelocator* CArmArchitecture::getElfRelocator()
std::unique_ptr<IElfRelocator> CArmArchitecture::getElfRelocator()
{
return new ArmElfRelocator(version != AARCH_GBA);
return std::unique_ptr<IElfRelocator>(new ArmElfRelocator(version != AARCH_GBA));
}

void CArmArchitecture::addPoolValue(ArmOpcodeCommand* command, int32_t value)
@@ -41,7 +41,7 @@ class CArmArchitecture: public CArchitecture
virtual void NextSection();
virtual void Pass2();
virtual void Revalidate();
virtual IElfRelocator* getElfRelocator();
virtual std::unique_ptr<IElfRelocator> getElfRelocator();
virtual Endianness getEndianness() { return version == AARCH_BIG ? Endianness::Big : Endianness::Little; };
void SetThumbMode(bool b) { thumb = b; };
bool GetThumbMode() { return thumb; };
@@ -1,5 +1,5 @@
#include "stdafx.h"
#include "ArmRelocator.h"
#include "ArmElfRelocator.h"
#include "Util/Util.h"
#include "Arm.h"
#include "Core/Common.h"
@@ -17,6 +17,11 @@ bool ArmElfRelocator::isDummyRelocationType(int type) const
return type == R_ARM_V4BX;
}

int ArmElfRelocator::expectedMachine() const
{
return EM_ARM;
}

/*
S = symbol address
T = 1 if symbol is a thumb mode function, 0 otherwise
@@ -16,9 +16,12 @@ class ArmElfRelocator: public IElfRelocator
{
public:
ArmElfRelocator(bool arm9): arm9(arm9) { };
virtual int expectedMachine() const;
virtual bool isDummyRelocationType(int type) const;

virtual bool relocateOpcode(int type, RelocationData& data);
virtual void setSymbolAddress(RelocationData& data, int64_t symbolAddress, int symbolType);

virtual CAssemblerCommand* generateCtorStub(std::vector<ElfRelocatorCtor>& ctors);
private:
bool arm9;
@@ -64,9 +64,9 @@ void CInvalidArchitecture::Revalidate()
Logger::printError(Logger::FatalError,L"No architecture specified");
}

IElfRelocator* CInvalidArchitecture::getElfRelocator()
std::unique_ptr<IElfRelocator> CInvalidArchitecture::getElfRelocator()
{
Logger::printError(Logger::FatalError,L"No architecture specified");
return NULL;
return nullptr;
}

@@ -2,8 +2,8 @@
#include "../Commands/CAssemblerCommand.h"
#include "../Core/ExpressionFunctions.h"
#include "../Core/FileManager.h"
#include "../Core/ELF/ElfRelocator.h"

class IElfRelocator;
class Tokenizer;
class Parser;

@@ -16,7 +16,7 @@ class CArchitecture
virtual void NextSection() = 0;
virtual void Pass2() = 0;
virtual void Revalidate() = 0;
virtual IElfRelocator* getElfRelocator() = 0;
virtual std::unique_ptr<IElfRelocator> getElfRelocator() = 0;
virtual Endianness getEndianness() = 0;
private:
const ExpressionFunctionMap emptyMap = {};
@@ -43,8 +43,8 @@ class CInvalidArchitecture: public CArchitecture
virtual void NextSection();
virtual void Pass2();
virtual void Revalidate();
virtual IElfRelocator* getElfRelocator();
virtual Endianness getEndianness() { return Endianness::Little; };
virtual std::unique_ptr<IElfRelocator> getElfRelocator();
virtual Endianness getEndianness() { return Endianness::Little; }
};

extern CInvalidArchitecture InvalidArchitecture;
@@ -1,104 +1,11 @@
#include "stdafx.h"
#include "Mips.h"
#include "MipsParser.h"
#include "Parser/Parser.h"
#include "MipsExpressionFunctions.h"
#include "MipsElfRelocator.h"

CMipsArchitecture Mips;

bool MipsElfRelocator::relocateOpcode(int type, RelocationData& data)
{
unsigned int p;

unsigned int op = data.opcode;
switch (type)
{
case R_MIPS_26: //j, jal
op = (op & 0xFC000000) | (((op&0x03FFFFFF)+(data.relocationBase>>2))&0x03FFFFFF);
break;
case R_MIPS_32:
op += (int) data.relocationBase;
break;
case R_MIPS_HI16:
p = (op & 0xFFFF) + (int) data.relocationBase;
op = (op&0xffff0000) | (((p >> 16) + ((p & 0x8000) != 0)) & 0xFFFF);
break;
case R_MIPS_LO16:
op = (op&0xffff0000) | (((op&0xffff)+data.relocationBase)&0xffff);
break;
default:
data.errorMessage = formatString(L"Unknown MIPS relocation type %d",type);
return false;
}

data.opcode = op;
return true;
}

void MipsElfRelocator::setSymbolAddress(RelocationData& data, int64_t symbolAddress, int symbolType)
{
data.symbolAddress = symbolAddress;
data.targetSymbolType = symbolType;
}

const wchar_t* mipsCtorTemplate = LR"(
addiu sp,-32
sw ra,0(sp)
sw s0,4(sp)
sw s1,8(sp)
sw s2,12(sp)
sw s3,16(sp)
li s0,%ctorTable%
li s1,%ctorTable%+%ctorTableSize%
%outerLoopLabel%:
lw s2,(s0)
lw s3,4(s0)
addiu s0,8
%innerLoopLabel%:
lw a0,(s2)
jalr a0
addiu s2,4h
bne s2,s3,%innerLoopLabel%
nop
bne s0,s1,%outerLoopLabel%
nop
lw ra,0(sp)
lw s0,4(sp)
lw s1,8(sp)
lw s2,12(sp)
lw s3,16(sp)
jr ra
addiu sp,32
%ctorTable%:
.word %ctorContent%
)";

CAssemblerCommand* MipsElfRelocator::generateCtorStub(std::vector<ElfRelocatorCtor>& ctors)
{
Parser parser;
if (ctors.size() != 0)
{
// create constructor table
std::wstring table;
for (size_t i = 0; i < ctors.size(); i++)
{
if (i != 0)
table += ',';
table += formatString(L"%s,%s+0x%08X",ctors[i].symbolName,ctors[i].symbolName,ctors[i].size);
}

return parser.parseTemplate(mipsCtorTemplate,{
{ L"%ctorTable%", Global.symbolTable.getUniqueLabelName() },
{ L"%ctorTableSize%", formatString(L"%d",ctors.size()*8) },
{ L"%outerLoopLabel%", Global.symbolTable.getUniqueLabelName() },
{ L"%innerLoopLabel%", Global.symbolTable.getUniqueLabelName() },
{ L"%ctorContent%", table },
});
} else {
return parser.parseTemplate(L"jr ra :: nop");
}
}

CMipsArchitecture::CMipsArchitecture()
{
FixLoadDelay = false;
@@ -145,14 +52,14 @@ void CMipsArchitecture::Revalidate()
DelaySlot = false;
}

IElfRelocator* CMipsArchitecture::getElfRelocator()
std::unique_ptr<IElfRelocator> CMipsArchitecture::getElfRelocator()
{
switch (Version)
{
case MARCH_PS2:
case MARCH_PSP:
case MARCH_N64:
return new MipsElfRelocator();
return std::unique_ptr<IElfRelocator>(new MipsElfRelocator());
case MARCH_PSX:
case MARCH_RSP:
default:
@@ -4,22 +4,6 @@

enum MipsArchType { MARCH_PSX = 0, MARCH_N64, MARCH_PS2, MARCH_PSP, MARCH_RSP, MARCH_INVALID };

enum {
R_MIPS_NONE,
R_MIPS_16,
R_MIPS_32,
R_MIPS_REL32,
R_MIPS_26,
R_MIPS_HI16,
R_MIPS_LO16,
R_MIPS_GPREL16,
R_MIPS_LITERAL,
R_MIPS_GOT16,
R_MIPS_PC16,
R_MIPS_CALL16,
R_MIPS_GPREL32
};

class CMipsArchitecture: public CArchitecture
{
public:
@@ -30,7 +14,7 @@ class CMipsArchitecture: public CArchitecture
virtual void NextSection();
virtual void Pass2() { return; };
virtual void Revalidate();
virtual IElfRelocator* getElfRelocator();
virtual std::unique_ptr<IElfRelocator> getElfRelocator();
virtual Endianness getEndianness()
{
return Version == MARCH_N64 || Version == MARCH_RSP ? Endianness::Big : Endianness::Little;
@@ -86,10 +70,3 @@ bool MipsGetPs2VectorRegister(const char* source, int& RetLen, MipsRegisterInfo&
int MipsGetFloatRegister(const char* source, int& RetLen);
bool MipsCheckImmediate(const char* Source, Expression& Dest, int& RetLen);

class MipsElfRelocator: public IElfRelocator
{
public:
virtual bool relocateOpcode(int type, RelocationData& data);
virtual void setSymbolAddress(RelocationData& data, int64_t symbolAddress, int symbolType);
virtual CAssemblerCommand* generateCtorStub(std::vector<ElfRelocatorCtor>& ctors);
};
@@ -270,7 +270,7 @@ DirectiveLoadMipsElf::DirectiveLoadMipsElf(const std::wstring& fileName)
if (file->load(this->inputName,this->inputName) == false)
{
delete file;
file = NULL;
file = nullptr;
return;
}

@@ -286,7 +286,7 @@ DirectiveLoadMipsElf::DirectiveLoadMipsElf(const std::wstring& inputName, const
if (file->load(this->inputName,this->outputName) == false)
{
delete file;
file = NULL;
file = nullptr;
return;
}

@@ -0,0 +1,101 @@
#include "stdafx.h"
#include "MipsElfRelocator.h"
#include "Parser/Parser.h"

int MipsElfRelocator::expectedMachine() const
{
return EM_MIPS;
}

bool MipsElfRelocator::relocateOpcode(int type, RelocationData& data)
{
unsigned int p;

unsigned int op = data.opcode;
switch (type)
{
case R_MIPS_26: //j, jal
op = (op & 0xFC000000) | (((op&0x03FFFFFF)+(data.relocationBase>>2))&0x03FFFFFF);
break;
case R_MIPS_32:
op += (int) data.relocationBase;
break;
case R_MIPS_HI16:
p = (op & 0xFFFF) + (int) data.relocationBase;
op = (op&0xffff0000) | (((p >> 16) + ((p & 0x8000) != 0)) & 0xFFFF);
break;
case R_MIPS_LO16:
op = (op&0xffff0000) | (((op&0xffff)+data.relocationBase)&0xffff);
break;
default:
data.errorMessage = formatString(L"Unknown MIPS relocation type %d",type);
return false;
}

data.opcode = op;
return true;
}

void MipsElfRelocator::setSymbolAddress(RelocationData& data, int64_t symbolAddress, int symbolType)
{
data.symbolAddress = symbolAddress;
data.targetSymbolType = symbolType;
}

const wchar_t* mipsCtorTemplate = LR"(
addiu sp,-32
sw ra,0(sp)
sw s0,4(sp)
sw s1,8(sp)
sw s2,12(sp)
sw s3,16(sp)
li s0,%ctorTable%
li s1,%ctorTable%+%ctorTableSize%
%outerLoopLabel%:
lw s2,(s0)
lw s3,4(s0)
addiu s0,8
%innerLoopLabel%:
lw a0,(s2)
jalr a0
addiu s2,4h
bne s2,s3,%innerLoopLabel%
nop
bne s0,s1,%outerLoopLabel%
nop
lw ra,0(sp)
lw s0,4(sp)
lw s1,8(sp)
lw s2,12(sp)
lw s3,16(sp)
jr ra
addiu sp,32
%ctorTable%:
.word %ctorContent%
)";

CAssemblerCommand* MipsElfRelocator::generateCtorStub(std::vector<ElfRelocatorCtor>& ctors)
{
Parser parser;
if (ctors.size() != 0)
{
// create constructor table
std::wstring table;
for (size_t i = 0; i < ctors.size(); i++)
{
if (i != 0)
table += ',';
table += formatString(L"%s,%s+0x%08X",ctors[i].symbolName,ctors[i].symbolName,ctors[i].size);
}

return parser.parseTemplate(mipsCtorTemplate,{
{ L"%ctorTable%", Global.symbolTable.getUniqueLabelName() },
{ L"%ctorTableSize%", formatString(L"%d",ctors.size()*8) },
{ L"%outerLoopLabel%", Global.symbolTable.getUniqueLabelName() },
{ L"%innerLoopLabel%", Global.symbolTable.getUniqueLabelName() },
{ L"%ctorContent%", table },
});
} else {
return parser.parseTemplate(L"jr ra :: nop");
}
}
Oops, something went wrong.

0 comments on commit ca73d71

Please sign in to comment.