Skip to content

Commit 495e963

Browse files
committed
[mips] Fixing PR for r5900: final pass over code before merge
1 parent cf0852e commit 495e963

File tree

5 files changed

+1367
-1792
lines changed

5 files changed

+1367
-1792
lines changed

arch/mips/arch_mips.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ using namespace std;
1919
#define snprintf _snprintf
2020
#endif
2121

22+
#define E_MIPS_MACH_5900 0x00920000
23+
2224
uint32_t bswap32(uint32_t x)
2325
{
2426
return ((x << 24) & 0xff000000 ) |
@@ -102,7 +104,7 @@ enum ElfMipsRelocationType : uint32_t
102104

103105
// This range is reserved for vendor specific relocations.
104106
R_MIPS_LOVENDOR = 100,
105-
R_MIPS_VCALLMS = 119, // MIPS R5900 (Emotion Engine) specific relocation for the Vector Unit (VU) micromode call instruction
107+
R_MIPS_VCALLMS = 119, // MIPS R5900-specific relocation for the Vector Unit (VU) micromode call instruction
106108
R_MIPS64_COPY = 125,
107109
R_MIPS_COPY = 126,
108110
R_MIPS_JUMP_SLOT = 127,
@@ -540,7 +542,7 @@ class MipsArchitecture: public Architecture
540542
{
541543
InstructionInfo instrInfo;
542544
LowLevelILLabel trueCode, falseCode;
543-
auto registerSize = [=](const InstructionOperand& op) -> size_t const
545+
auto registerSize = [this](const InstructionOperand& op) -> size_t const
544546
{
545547
return get_register_width(Reg(op.reg), m_version);
546548
};
@@ -1779,7 +1781,7 @@ class MipsArchitecture: public Architecture
17791781
};
17801782

17811783
if (m_version == MIPS_R5900) {
1782-
// TODO: R5900 has 128-bit wide GPRs, $lo and $hi are 128-bit, and $lo1 and $hi1 are the upper 64 bits of $lo and $hi
1784+
// Note: R5900 has 128-bit wide GPRs, $lo and $hi are 128-bit, and $lo1 and $hi1 are the upper 64 bits of $lo and $hi
17831785
uint32_t r5900_registers[] = {
17841786
R5900_SA,
17851787
REG_LO1, REG_HI1,
@@ -3595,6 +3597,8 @@ class MipsElfRelocationHandler: public RelocationHandler
35953597
case R_MIPS_LO16:
35963598
case R_MIPS_CALL16:
35973599
case R_MIPS_GOT16:
3600+
case R_MIPS_HIGHER:
3601+
case R_MIPS_HIGHEST:
35983602
result = BN_NOCOERCE_EXTERN_PTR;
35993603
break;
36003604
default:
@@ -3644,6 +3648,9 @@ static Ref<Platform> ElfFlagsRecognize(BinaryView* view, Metadata* metadata)
36443648
case 0x8e: // EF_MIPS_MACH_OCTEON3
36453649
LogInfo("ELF flags 0x%08" PRIx64 " machine variant 0x%02x: using cavium architecture", flagsValue, machineVariant);
36463650
return Platform::GetByName("linux-cnmips64");
3651+
case 0x92: // E_MIPS_MACH_5900
3652+
LogInfo("ELF flags 0x%08" PRIx64 " machine variant 0x%02x: using R5900 architecture", flagsValue, machineVariant);
3653+
return Platform::GetByName("r5900l");
36473654
default:
36483655
return nullptr;
36493656
}
@@ -3673,12 +3680,13 @@ extern "C"
36733680
Architecture* mips64eb = new MipsArchitecture("mips64", MIPS_64, BigEndian, 64);
36743681
Architecture* cnmips64eb = new MipsArchitecture("cavium-mips64", MIPS_64, BigEndian, 64, DECOMPOSE_FLAGS_CAVIUM);
36753682
Architecture* r5900l = new MipsArchitecture("r5900l", MIPS_R5900, LittleEndian, 32);
3676-
Architecture* r5900b = new MipsArchitecture("r5900b", MIPS_R5900, BigEndian, 32);
3683+
// R5900 should only be Little-Endian, so until someone complains, I'm leaving the Big-Endian variant disabled.
3684+
// Architecture* r5900b = new MipsArchitecture("r5900b", MIPS_R5900, BigEndian, 32);
36773685

36783686
Architecture::Register(mipsel);
36793687
Architecture::Register(mipseb);
36803688
Architecture::Register(r5900l);
3681-
Architecture::Register(r5900b);
3689+
// Architecture::Register(r5900b);
36823690
Architecture::Register(mips3);
36833691
Architecture::Register(mips3el);
36843692
Architecture::Register(mips64el);
@@ -3692,7 +3700,7 @@ extern "C"
36923700
MipsN64CallingConvention* n64BE = new MipsN64CallingConvention(mips64eb);
36933701
MipsN64CallingConvention* n64BEc = new MipsN64CallingConvention(cnmips64eb);
36943702
MipsPS2CallingConvention* ps2LE = new MipsPS2CallingConvention(r5900l);
3695-
MipsPS2CallingConvention* ps2BE = new MipsPS2CallingConvention(r5900b);
3703+
// MipsPS2CallingConvention* ps2BE = new MipsPS2CallingConvention(r5900b);
36963704

36973705
mipseb->RegisterCallingConvention(o32BE);
36983706
mipseb->SetDefaultCallingConvention(o32BE);
@@ -3710,26 +3718,26 @@ extern "C"
37103718
cnmips64eb->SetDefaultCallingConvention(n64BEc);
37113719
r5900l->RegisterCallingConvention(ps2LE);
37123720
r5900l->SetDefaultCallingConvention(ps2LE);
3713-
r5900b->RegisterCallingConvention(ps2BE);
3714-
r5900b->SetDefaultCallingConvention(ps2BE);
3721+
// r5900b->RegisterCallingConvention(ps2BE);
3722+
// r5900b->SetDefaultCallingConvention(ps2BE);
37153723

37163724
MipsLinuxSyscallCallingConvention* linuxSyscallBE = new MipsLinuxSyscallCallingConvention(mipseb);
37173725
MipsLinuxSyscallCallingConvention* linuxSyscallLE = new MipsLinuxSyscallCallingConvention(mipsel);
37183726
mipseb->RegisterCallingConvention(linuxSyscallBE);
37193727
mipsel->RegisterCallingConvention(linuxSyscallLE);
37203728
MipsLinuxSyscallCallingConvention* linuxSyscallBE3 = new MipsLinuxSyscallCallingConvention(mips3);
37213729
MipsLinuxSyscallCallingConvention* linuxSyscallLE3 = new MipsLinuxSyscallCallingConvention(mips3el);
3722-
mips3->RegisterCallingConvention(linuxSyscallBE);
3723-
mips3el->RegisterCallingConvention(linuxSyscallLE);
3730+
mips3->RegisterCallingConvention(linuxSyscallBE3);
3731+
mips3el->RegisterCallingConvention(linuxSyscallLE3);
37243732
MipsLinuxSyscallCallingConvention* linuxSyscallr5900LE = new MipsLinuxSyscallCallingConvention(r5900l);
3725-
MipsLinuxSyscallCallingConvention* linuxSyscallr5900BE = new MipsLinuxSyscallCallingConvention(r5900b);
3733+
// MipsLinuxSyscallCallingConvention* linuxSyscallr5900BE = new MipsLinuxSyscallCallingConvention(r5900b);
37263734
r5900l->RegisterCallingConvention(linuxSyscallr5900LE);
3727-
r5900b->RegisterCallingConvention(linuxSyscallr5900BE);
3735+
// r5900b->RegisterCallingConvention(linuxSyscallr5900BE);
37283736

37293737
mipsel->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mipsel));
37303738
mipseb->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mipseb));
37313739
r5900l->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(r5900l));
3732-
r5900b->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(r5900b));
3740+
// r5900b->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(r5900b));
37333741
mips3->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips3));
37343742
mips3el->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips3el));
37353743
mips64el->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips64el));
@@ -3749,7 +3757,7 @@ extern "C"
37493757
mips64eb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
37503758
mips64el->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
37513759
r5900l->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
3752-
r5900b->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
3760+
// r5900b->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
37533761
cnmips64eb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
37543762

37553763
// Register the architectures with the binary format parsers so that they know when to use
@@ -3772,6 +3780,7 @@ extern "C"
37723780
{
37733781
elf->RegisterPlatformRecognizer(ARCH_ID_MIPS64, LittleEndian, ElfFlagsRecognize);
37743782
elf->RegisterPlatformRecognizer(ARCH_ID_MIPS64, BigEndian, ElfFlagsRecognize);
3783+
elf->RegisterPlatformRecognizer(ARCH_ID_MIPS32, LittleEndian, ElfFlagsRecognize); // R5900
37753784
}
37763785

37773786
BinaryViewType::RegisterArchitecture("PE", 0x166, LittleEndian, mipsel);

0 commit comments

Comments
 (0)