Skip to content

Commit 840072d

Browse files
committed
[mips] Merging PR #6013: adding mips3 support
1 parent b4e75ef commit 840072d

File tree

3 files changed

+181
-50
lines changed

3 files changed

+181
-50
lines changed

arch/mips/arch_mips.cpp

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,25 @@ class MipsArchitecture: public Architecture
181181
protected:
182182
size_t m_bits;
183183
BNEndianness m_endian;
184+
MipsVersion version_overwrite;
184185
uint32_t m_decomposeFlags;
185186

186187
virtual bool Disassemble(const uint8_t* data, uint64_t addr, size_t maxLen, Instruction& result)
187188
{
189+
MipsVersion version = version_overwrite;
190+
188191
memset(&result, 0, sizeof(result));
189-
if (mips_decompose((uint32_t*)data, maxLen, &result, m_bits == 64 ? MIPS_64 : MIPS_32, addr, m_endian, m_decomposeFlags) != 0)
192+
if (m_bits == 64)
193+
{
194+
version = MIPS_64;
195+
}
196+
197+
if (mips_decompose((uint32_t*)data, maxLen, &result, version, addr, m_endian, m_decomposeFlags) != 0)
190198
return false;
191199
return true;
192200
}
193201

194-
virtual size_t GetAddressSize() const override
195-
{
196-
return m_bits / 8;
197-
}
202+
virtual size_t GetAddressSize() const override { return m_bits / 8; }
198203

199204
size_t InstructionHasBranchDelay(const Instruction& instr)
200205
{
@@ -402,8 +407,8 @@ class MipsArchitecture: public Architecture
402407
}
403408

404409
public:
405-
MipsArchitecture(const std::string& name, BNEndianness endian, size_t bits, uint32_t decomposeFlags = 0)
406-
: Architecture(name), m_bits(bits), m_endian(endian), m_decomposeFlags(decomposeFlags)
410+
MipsArchitecture(const std::string& name, BNEndianness endian, size_t bits, MipsVersion version_in, uint32_t decomposeFlags = 0)
411+
: Architecture(name), m_bits(bits), m_endian(endian), version_overwrite(version_in), m_decomposeFlags(decomposeFlags)
407412
{
408413
Ref<Settings> settings = Settings::Instance();
409414
uint32_t flag_pseudo_ops = settings->Get<bool>("arch.mips.disassembly.pseudoOps") ? DECOMPOSE_FLAGS_PSEUDO_OP : 0;
@@ -3258,14 +3263,18 @@ extern "C"
32583263
{
32593264
InitMipsSettings();
32603265

3261-
Architecture* mipsel = new MipsArchitecture("mipsel32", LittleEndian, 32);
3262-
Architecture* mipseb = new MipsArchitecture("mips32", BigEndian, 32);
3263-
Architecture* mips64el = new MipsArchitecture("mipsel64", LittleEndian, 64);
3264-
Architecture* mips64eb = new MipsArchitecture("mips64", BigEndian, 64);
3265-
Architecture* cnmips64eb = new MipsArchitecture("cavium-mips64", BigEndian, 64, DECOMPOSE_FLAGS_CAVIUM);
3266+
Architecture* mipseb = new MipsArchitecture("mips32", BigEndian, 32, MIPS_32);
3267+
Architecture* mipsel = new MipsArchitecture("mipsel32", LittleEndian, 32, MIPS_32);
3268+
Architecture* mips3 = new MipsArchitecture("mips3", BigEndian, 32, MIPS_3);
3269+
Architecture* mips3el = new MipsArchitecture("mipsel3", LittleEndian, 32, MIPS_3);
3270+
Architecture* mips64el = new MipsArchitecture("mipsel64", LittleEndian, 64, MIPS_64);
3271+
Architecture* mips64eb = new MipsArchitecture("mips64", BigEndian, 64, MIPS_64);
3272+
Architecture* cnmips64eb = new MipsArchitecture("cavium-mips64", BigEndian, 64, MIPS_64, DECOMPOSE_FLAGS_CAVIUM);
32663273

3267-
Architecture::Register(mipsel);
32683274
Architecture::Register(mipseb);
3275+
Architecture::Register(mipsel);
3276+
Architecture::Register(mips3);
3277+
Architecture::Register(mips3el);
32693278
Architecture::Register(mips64el);
32703279
Architecture::Register(mips64eb);
32713280
Architecture::Register(cnmips64eb);
@@ -3277,10 +3286,14 @@ extern "C"
32773286
MipsN64CallingConvention* n64BE = new MipsN64CallingConvention(mips64eb);
32783287
MipsN64CallingConvention* n64BEc = new MipsN64CallingConvention(cnmips64eb);
32793288

3280-
mipsel->RegisterCallingConvention(o32LE);
32813289
mipseb->RegisterCallingConvention(o32BE);
3282-
mipsel->SetDefaultCallingConvention(o32LE);
32833290
mipseb->SetDefaultCallingConvention(o32BE);
3291+
mipsel->RegisterCallingConvention(o32LE);
3292+
mipsel->SetDefaultCallingConvention(o32LE);
3293+
mips3->RegisterCallingConvention(o32BE);
3294+
mips3->SetDefaultCallingConvention(o32BE);
3295+
mips3->RegisterCallingConvention(o32LE);
3296+
mips3->SetDefaultCallingConvention(o32LE);
32843297
mips64el->RegisterCallingConvention(n64LE);
32853298
mips64el->SetDefaultCallingConvention(n64LE);
32863299
mips64eb->RegisterCallingConvention(n64BE);
@@ -3290,21 +3303,29 @@ extern "C"
32903303

32913304
MipsLinuxSyscallCallingConvention* linuxSyscallLE = new MipsLinuxSyscallCallingConvention(mipsel);
32923305
MipsLinuxSyscallCallingConvention* linuxSyscallBE = new MipsLinuxSyscallCallingConvention(mipseb);
3293-
mipsel->RegisterCallingConvention(linuxSyscallLE);
32943306
mipseb->RegisterCallingConvention(linuxSyscallBE);
3307+
mipsel->RegisterCallingConvention(linuxSyscallLE);
3308+
mips3->RegisterCallingConvention(linuxSyscallBE);
3309+
mips3el->RegisterCallingConvention(linuxSyscallLE);
32953310

3296-
mipsel->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mipsel));
32973311
mipseb->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mipseb));
3312+
mipsel->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mipsel));
3313+
mips3->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips3));
3314+
mips3el->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips3el));
32983315
mips64el->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips64el));
32993316
mips64eb->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips64eb));
33003317
cnmips64eb->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(cnmips64eb));
33013318

33023319
/* function recognizers */
3303-
mipsel->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
33043320
mipseb->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
3321+
mipsel->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
3322+
mips3->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
3323+
mips3el->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
33053324

3306-
mipsel->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
33073325
mipseb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
3326+
mipsel->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
3327+
mips3->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
3328+
mips3el->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
33083329
mips64el->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
33093330
mips64eb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
33103331
cnmips64eb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());

arch/mips/mips/test.c

Lines changed: 129 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ b mips_decompose
55
b mips_disassemble
66
*/
77

8+
#include <errno.h>
89
#include <stdio.h>
910
#include <stdint.h>
1011
#include <inttypes.h>
1112

1213
#include "mips.h"
1314

14-
int disassemble(uint32_t insword, uint64_t address, enum MipsVersion version, char *result)
15+
int disassemble(uint32_t insword, uint64_t address, MipsVersion version, int flags, char *result)
1516
{
1617
int rc;
1718
Instruction instr;
@@ -35,47 +36,146 @@ int disassemble(uint32_t insword, uint64_t address, enum MipsVersion version, ch
3536
}
3637

3738
#define ASSERT(X) \
38-
if(!(X)) { \
39+
do { if(!(X)) { \
3940
printf("failed assert() at %s:%d\n", __FILE__, __LINE__); \
4041
exit(-1); \
41-
}
42+
} } while(0)
43+
44+
45+
void usage(char** av)
46+
{
47+
printf("usage:\n");
48+
printf("\t%s [-mips32|-mips64|-mips1|-mips2|-mips3|-mips4|-cavium] [-a BASEADDR] [instruction_words]+\n", av[0]);
49+
printf("\t\tdisassemble for the given MIPS version (MIPS32 by default)\n");
50+
printf("\t\tBASEADDR must be an unsigned 32-bit integer in hexadecimal\n");
51+
printf("\t%s test\n", av[0]);
52+
printf("example:\n");
53+
printf("\t%s 0c1001dc 8ca40000 2c410020 10200013\n", av[0]);
54+
printf("\t%s test\n", av[0]);
55+
exit(-1);
56+
}
4257

4358
int main(int ac, char **av)
4459
{
4560
char instxt[4096];
61+
uint32_t insword = 0;
62+
uint64_t baseaddr = 0;
63+
int instindex = 1;
64+
int c = 0;
65+
int version = -1;
66+
int flags = 0;
67+
int result = 0;
4668

47-
if(ac == 1) {
48-
printf("usage:\n");
49-
printf("\t%s [<address>] <instruction_word>\n", av[0]);
50-
printf("\t%s <instruction_word>\n", av[0]);
51-
printf("\t%s test\n", av[0]);
52-
printf("examples:\n");
53-
printf("\t%s 0 14E00003\n", av[0]);
54-
printf("\t%s 00405A58 14E00003\n", av[0]);
55-
printf("\t%s test\n", av[0]);
56-
exit(-1);
69+
if (ac > 1) {
70+
if (!strcmp("-mips64", av[1]))
71+
version = MIPS_64;
72+
else if (!strcmp("-mips32", av[1]))
73+
version = MIPS_32;
74+
else if (!strcmp("-mips1", av[1]))
75+
version = MIPS_1;
76+
else if (!strcmp("-mips2", av[1]))
77+
version = MIPS_2;
78+
else if (!strcmp("-mips3", av[1]))
79+
version = MIPS_3;
80+
else if (!strcmp("-mips4", av[1]))
81+
version = MIPS_4;
82+
else if (!strcmp("-cavium", av[1]))
83+
{
84+
version = MIPS_64;
85+
flags = DECOMPOSE_FLAGS_CAVIUM;
86+
}
87+
else if (!strcmp("-a", av[1]))
88+
;
89+
else if (av[1][0] == '-')
90+
{
91+
usage(av);
92+
goto cleanup;
93+
}
94+
if (version != -1)
95+
{
96+
instindex++;
97+
}
5798
}
99+
if (version == -1)
100+
version = MIPS_32;
58101

59-
if(ac == 2 && !strcmp(av[1], "test")) {
60-
disassemble(0x14E00003, 0, MIPS_32, instxt);
61-
ASSERT(!strcmp(instxt, "bne\t$a3, $zero, 0x10"));
62-
disassemble(0x14E00003, 0x405a58, MIPS_32, instxt);
63-
ASSERT(!strcmp(instxt, "bne\t$a3, $zero, 0x405a68"));
102+
if (instindex < ac && !strcmp(av[instindex], "test"))
103+
{
104+
insword = 0x14E00003;
105+
baseaddr = 0;
106+
if (0 == disassemble(insword, baseaddr, version, flags, instxt))
107+
{
108+
printf("%08llX: %08X %s\n", baseaddr, insword, instxt);
109+
}
110+
else
111+
{
112+
printf("%08llX: %08X ??\n", baseaddr, insword);
113+
}
114+
// disassemble(0x14E00003, 0, version, flags, instxt);
115+
if (version < MIPS_32)
116+
ASSERT(!strcmp(instxt, "bne\t$a3, $zero, 0x10"));
117+
else
118+
ASSERT(!strcmp(instxt, "bnez\t$a3, 0x10"));
119+
baseaddr = 0x405a58;
120+
if (0 == disassemble(insword, baseaddr, version, flags, instxt))
121+
{
122+
printf("%08llX: %08X %s\n", baseaddr, insword, instxt);
123+
}
124+
else
125+
{
126+
printf("%08llX: %08X ??\n", baseaddr, insword);
127+
}
128+
// disassemble(0x14E00003, 4, version, flags, instxt);
129+
if (version < MIPS_32)
130+
ASSERT(!strcmp(instxt, "bne\t$a3, $zero, 0x405a68"));
131+
else
132+
ASSERT(!strcmp(instxt, "bnez\t$a3, 0x405a68"));
64133
exit(0);
65134
}
66135

67-
uint64_t address = 0;
68-
uint32_t insword = 0;
69-
if(ac == 2) {
70-
address = 0;
71-
insword = strtoul(av[1], NULL, 16);
72-
}
73-
else if(ac == 3) {
74-
address = strtoul(av[1], NULL, 16);
75-
insword = strtoul(av[2], NULL, 16);
136+
if (instindex < ac && !strcmp(av[instindex], "-a")) {
137+
if (ac <= ++instindex) {
138+
printf("ERROR: Missing argument for -a\n");
139+
usage(av);
140+
result = -1;
141+
goto cleanup;
142+
}
143+
errno = 0;
144+
char *endptr;
145+
char *addr = av[instindex];
146+
if (addr[0] == '0' && addr[1] == 'x')
147+
addr += 2;
148+
baseaddr = strtoul(addr, &endptr, 16);
149+
if (errno == EINVAL || errno == ERANGE || (addr[0] != '\0' && (*(void **) endptr) == addr)) {
150+
printf("ERROR: Invalid argument for -a: \"%s\"\n", av[instindex]);
151+
usage(av);
152+
result = -1;
153+
goto cleanup;
154+
}
155+
if (ac <= ++instindex) {
156+
usage(av);
157+
result = -1;
158+
goto cleanup;
159+
}
76160
}
77161

78-
if(0 == disassemble(insword, address, MIPS_32, instxt)) {
79-
printf("%08" PRIX64 ": %08X %s\n", address, insword, instxt);
162+
while (instindex < ac)
163+
{
164+
insword = strtoul(av[instindex], NULL, 16);
165+
166+
if (0 == disassemble(insword, baseaddr, version, flags, instxt))
167+
{
168+
printf("%08llX: %08X %s\n", baseaddr, insword, instxt);
169+
}
170+
else
171+
{
172+
printf("%08llX: %08X ??\n", baseaddr, insword);
173+
}
174+
175+
baseaddr += 4;
176+
instindex++;
80177
}
178+
179+
cleanup:
180+
return result;
81181
}

platform/linux/platform_linux.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,27 +352,37 @@ extern "C"
352352

353353
Ref<Architecture> mipsel = Architecture::GetByName("mipsel32");
354354
Ref<Architecture> mipseb = Architecture::GetByName("mips32");
355+
Ref<Architecture> mips3el = Architecture::GetByName("mipsel3");
356+
Ref<Architecture> mips3eb = Architecture::GetByName("mips3");
355357
Ref<Architecture> mips64eb = Architecture::GetByName("mips64");
356358
Ref<Architecture> cnmips64eb = Architecture::GetByName("cavium-mips64");
357-
if (mipsel && mipseb && mips64eb && cnmips64eb)
359+
if (mipsel && mipseb && mips64eb && cnmips64eb && mips3el && mips3eb)
358360
{
359-
Ref<Platform> platformLE, platformBE, platformBE64, platformBE64cn;
361+
Ref<Platform> platformLE, platformBE, platformBE64, platformBE64cn, platform3LE, platform3BE;
360362

361363
platformLE = new LinuxMipsPlatform(mipsel, "linux-mipsel");
362364
platformBE = new LinuxMipsPlatform(mipseb, "linux-mips");
365+
platform3LE = new LinuxMipsPlatform(mips3el, "linux-mipsel3");
366+
platform3BE = new LinuxMipsPlatform(mips3eb, "linux-mips3");
363367
platformBE64 = new LinuxMips64Platform(mips64eb, "linux-mips64");
364368
platformBE64cn = new LinuxMips64Platform(cnmips64eb, "linux-cnmips64");
365369
Platform::Register("linux", platformLE);
366370
Platform::Register("linux", platformBE);
371+
Platform::Register("linux", platform3LE);
372+
Platform::Register("linux", platform3BE);
367373
Platform::Register("linux", platformBE64);
368374
Platform::Register("linux", platformBE64cn);
369375
// Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one
370376
BinaryViewType::RegisterPlatform("ELF", 0, mipsel, platformLE);
371377
BinaryViewType::RegisterPlatform("ELF", 0, mipseb, platformBE);
378+
BinaryViewType::RegisterPlatform("ELF", 0, mips3el, platform3LE);
379+
BinaryViewType::RegisterPlatform("ELF", 0, mips3eb, platform3BE);
372380
BinaryViewType::RegisterPlatform("ELF", 0, mips64eb, platformBE64);
373381
BinaryViewType::RegisterPlatform("ELF", 0, cnmips64eb, platformBE64cn);
374382
BinaryViewType::RegisterPlatform("ELF", 3, mipsel, platformLE);
375383
BinaryViewType::RegisterPlatform("ELF", 3, mipseb, platformBE);
384+
BinaryViewType::RegisterPlatform("ELF", 3, mips3el, platform3LE);
385+
BinaryViewType::RegisterPlatform("ELF", 3, mips3eb, platform3BE);
376386
BinaryViewType::RegisterPlatform("ELF", 3, mips64eb, platformBE64);
377387
BinaryViewType::RegisterPlatform("ELF", 3, cnmips64eb, platformBE64cn);
378388
}

0 commit comments

Comments
 (0)