@@ -179,27 +179,24 @@ static const char* GetRelocationString(ElfMipsRelocationType rel)
179179class MipsArchitecture : public Architecture
180180{
181181protected:
182+ bool m_userWarnedAboutDelaySlots = false ;
183+ MipsVersion m_version;
182184 size_t m_bits;
183185 BNEndianness m_endian;
184- MipsVersion version_overwrite;
185186 uint32_t m_decomposeFlags;
186187
187188 virtual bool Disassemble (const uint8_t * data, uint64_t addr, size_t maxLen, Instruction& result)
188189 {
189- MipsVersion version = version_overwrite;
190-
191190 memset (&result, 0 , sizeof (result));
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 )
191+ if (mips_decompose ((uint32_t *)data, maxLen, &result, m_bits == 64 ? MIPS_64 : MIPS_32, addr, m_endian, m_decomposeFlags) != 0 )
198192 return false ;
199193 return true ;
200194 }
201195
202- virtual size_t GetAddressSize () const override { return m_bits / 8 ; }
196+ virtual size_t GetAddressSize () const override
197+ {
198+ return m_bits / 8 ;
199+ }
203200
204201 size_t InstructionHasBranchDelay (const Instruction& instr)
205202 {
@@ -407,8 +404,8 @@ class MipsArchitecture: public Architecture
407404 }
408405
409406public:
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)
407+ MipsArchitecture (const std::string& name, MipsVersion version, BNEndianness endian, size_t bits, uint32_t decomposeFlags = 0 )
408+ : Architecture(name), m_version(version ), m_bits(bits ), m_endian(endian ), m_decomposeFlags(decomposeFlags)
412409 {
413410 Ref<Settings> settings = Settings::Instance ();
414411 uint32_t flag_pseudo_ops = settings->Get <bool >(" arch.mips.disassembly.pseudoOps" ) ? DECOMPOSE_FLAGS_PSEUDO_OP : 0 ;
@@ -508,7 +505,16 @@ class MipsArchitecture: public Architecture
508505 {
509506 if (len < 8 )
510507 {
511- LogWarn (" Can not lift instruction with delay slot @ 0x%08" PRIx64, addr);
508+ if (!m_userWarnedAboutDelaySlots)
509+ {
510+
511+ LogWarn (" Can not lift instruction with delay slot @ 0x%08" PRIx64 " \n "
512+ " Any future delay slot errors will be printed as debug logs\n "
513+ " and can be viewed by setting the log capture level to debug." , addr);
514+ m_userWarnedAboutDelaySlots = true ;
515+ }
516+ else
517+ LogDebug (" Can not lift instruction with delay slot @ 0x%08" PRIx64, addr);
512518 return false ;
513519 }
514520
@@ -847,15 +853,18 @@ class MipsArchitecture: public Architecture
847853 break ;
848854 case MEM_IMM:
849855 result.emplace_back (BeginMemoryOperandToken, " " );
850- if (imm < -9 )
851- snprintf (operand, sizeof (operand), " -%#x" , -imm);
852- else if (imm < 0 )
853- snprintf (operand, sizeof (operand), " -%d" , -imm);
854- else if (imm < 10 )
855- snprintf (operand, sizeof (operand), " %d" , imm);
856- else
857- snprintf (operand, sizeof (operand), " %#x" , imm);
858- result.emplace_back (IntegerToken, operand, imm);
856+ if (imm != 0 )
857+ {
858+ if (imm < -9 )
859+ snprintf (operand, sizeof (operand), " -%#x" , -imm);
860+ else if (imm < 0 )
861+ snprintf (operand, sizeof (operand), " -%d" , -imm);
862+ else if (imm < 10 )
863+ snprintf (operand, sizeof (operand), " %d" , imm);
864+ else
865+ snprintf (operand, sizeof (operand), " %#x" , imm);
866+ result.emplace_back (IntegerToken, operand, imm);
867+ }
859868 if (instr.operands [i].reg == REG_ZERO)
860869 break ;
861870 result.emplace_back (BraceToken, " (" );
@@ -3018,7 +3027,14 @@ class MipsElfRelocationHandler: public RelocationHandler
30183027 uint32_t inst2 = *(uint32_t *)(cur->relocationDataCache );
30193028 Instruction instruction;
30203029 memset (&instruction, 0 , sizeof (instruction));
3021- if (mips_decompose (&inst2, sizeof (uint32_t ), &instruction, arch->GetAddressSize () == 8 ? MIPS_64 : MIPS_32, cur->address , arch->GetEndianness (), DECOMPOSE_FLAGS_PSEUDO_OP))
3030+
3031+ MipsVersion version;
3032+ if (arch->GetName ().substr (0 , 5 ) == " r5900" )
3033+ version = MIPS_R5900;
3034+ else
3035+ version = arch->GetAddressSize () == 8 ? MIPS_64 : MIPS_32;
3036+
3037+ if (mips_decompose (&inst2, sizeof (uint32_t ), &instruction, version, cur->address , arch->GetEndianness (), DECOMPOSE_FLAGS_PSEUDO_OP))
30223038 break ;
30233039
30243040 int32_t immediate = swap (inst2) & 0xffff ;
@@ -3195,8 +3211,6 @@ class MipsElfRelocationHandler: public RelocationHandler
31953211 case R_MIPS_LO16:
31963212 case R_MIPS_CALL16:
31973213 case R_MIPS_GOT16:
3198- case R_MIPS_HIGHER:
3199- case R_MIPS_HIGHEST:
32003214 result = BN_NOCOERCE_EXTERN_PTR;
32013215 break ;
32023216 default :
@@ -3267,16 +3281,20 @@ extern "C"
32673281 {
32683282 InitMipsSettings ();
32693283
3270- Architecture* mipseb = new MipsArchitecture (" mips32" , BigEndian, 32 , MIPS_32);
3271- Architecture* mipsel = new MipsArchitecture (" mipsel32" , LittleEndian, 32 , MIPS_32);
3272- Architecture* mips3 = new MipsArchitecture (" mips3" , BigEndian, 32 , MIPS_3);
3273- Architecture* mips3el = new MipsArchitecture (" mipsel3" , LittleEndian, 32 , MIPS_3);
3274- Architecture* mips64el = new MipsArchitecture (" mipsel64" , LittleEndian, 64 , MIPS_64);
3275- Architecture* mips64eb = new MipsArchitecture (" mips64" , BigEndian, 64 , MIPS_64);
3276- Architecture* cnmips64eb = new MipsArchitecture (" cavium-mips64" , BigEndian, 64 , MIPS_64, DECOMPOSE_FLAGS_CAVIUM);
3284+ Architecture* mipsel = new MipsArchitecture (" mipsel32" , MIPS_32, LittleEndian, 32 );
3285+ Architecture* mipseb = new MipsArchitecture (" mips32" , MIPS_32, BigEndian, 32 );
3286+ Architecture* mips3 = new MipsArchitecture (" mips3" , MIPS_3, BigEndian, 32 );
3287+ Architecture* mips3el = new MipsArchitecture (" mipsel3" , MIPS_3, LittleEndian, 32 );
3288+ Architecture* mips64el = new MipsArchitecture (" mipsel64" , MIPS_64, LittleEndian, 64 );
3289+ Architecture* mips64eb = new MipsArchitecture (" mips64" , MIPS_64, BigEndian, 64 );
3290+ Architecture* cnmips64eb = new MipsArchitecture (" cavium-mips64" , MIPS_64, BigEndian, 64 , DECOMPOSE_FLAGS_CAVIUM);
3291+ Architecture* r5900l = new MipsArchitecture (" r5900l" , MIPS_R5900, LittleEndian, 32 );
3292+ Architecture* r5900b = new MipsArchitecture (" r5900b" , MIPS_R5900, BigEndian, 32 );
32773293
3278- Architecture::Register (mipseb);
32793294 Architecture::Register (mipsel);
3295+ Architecture::Register (mipseb);
3296+ Architecture::Register (r5900l);
3297+ Architecture::Register (r5900b);
32803298 Architecture::Register (mips3);
32813299 Architecture::Register (mips3el);
32823300 Architecture::Register (mips64el);
@@ -3294,44 +3312,58 @@ extern "C"
32943312 mipseb->SetDefaultCallingConvention (o32BE);
32953313 mipsel->RegisterCallingConvention (o32LE);
32963314 mipsel->SetDefaultCallingConvention (o32LE);
3315+ r5900l->RegisterCallingConvention (o32LE);
3316+ r5900l->SetDefaultCallingConvention (o32LE);
3317+ r5900b->RegisterCallingConvention (o32BE);
3318+ r5900b->SetDefaultCallingConvention (o32BE);
32973319 mips3->RegisterCallingConvention (o32BE);
32983320 mips3->SetDefaultCallingConvention (o32BE);
3299- mips3 ->RegisterCallingConvention (o32LE);
3300- mips3 ->SetDefaultCallingConvention (o32LE);
3321+ mips3el ->RegisterCallingConvention (o32LE);
3322+ mips3el ->SetDefaultCallingConvention (o32LE);
33013323 mips64el->RegisterCallingConvention (n64LE);
33023324 mips64el->SetDefaultCallingConvention (n64LE);
33033325 mips64eb->RegisterCallingConvention (n64BE);
33043326 mips64eb->SetDefaultCallingConvention (n64BE);
33053327 cnmips64eb->RegisterCallingConvention (n64BEc);
33063328 cnmips64eb->SetDefaultCallingConvention (n64BEc);
33073329
3308- MipsLinuxSyscallCallingConvention* linuxSyscallLE = new MipsLinuxSyscallCallingConvention (mipsel);
33093330 MipsLinuxSyscallCallingConvention* linuxSyscallBE = new MipsLinuxSyscallCallingConvention (mipseb);
3331+ MipsLinuxSyscallCallingConvention* linuxSyscallLE = new MipsLinuxSyscallCallingConvention (mipsel);
33103332 mipseb->RegisterCallingConvention (linuxSyscallBE);
33113333 mipsel->RegisterCallingConvention (linuxSyscallLE);
3334+ MipsLinuxSyscallCallingConvention* linuxSyscallBE3 = new MipsLinuxSyscallCallingConvention (mips3);
3335+ MipsLinuxSyscallCallingConvention* linuxSyscallLE3 = new MipsLinuxSyscallCallingConvention (mips3el);
33123336 mips3->RegisterCallingConvention (linuxSyscallBE);
33133337 mips3el->RegisterCallingConvention (linuxSyscallLE);
3338+ MipsLinuxSyscallCallingConvention* linuxSyscallr5900LE = new MipsLinuxSyscallCallingConvention (r5900l);
3339+ MipsLinuxSyscallCallingConvention* linuxSyscallr5900BE = new MipsLinuxSyscallCallingConvention (r5900b);
3340+ r5900l->RegisterCallingConvention (linuxSyscallr5900LE);
3341+ r5900b->RegisterCallingConvention (linuxSyscallr5900BE);
33143342
3315- mipseb->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mipseb));
33163343 mipsel->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mipsel));
3344+ mipseb->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mipseb));
3345+ r5900l->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (r5900l));
3346+ r5900b->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (r5900b));
33173347 mips3->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mips3));
33183348 mips3el->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mips3el));
33193349 mips64el->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mips64el));
33203350 mips64eb->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (mips64eb));
33213351 cnmips64eb->RegisterCallingConvention (new MipsLinuxRtlResolveCallingConvention (cnmips64eb));
33223352
33233353 /* function recognizers */
3324- mipseb->RegisterFunctionRecognizer (new MipsImportedFunctionRecognizer ());
33253354 mipsel->RegisterFunctionRecognizer (new MipsImportedFunctionRecognizer ());
3355+ mipseb->RegisterFunctionRecognizer (new MipsImportedFunctionRecognizer ());
33263356 mips3->RegisterFunctionRecognizer (new MipsImportedFunctionRecognizer ());
33273357 mips3el->RegisterFunctionRecognizer (new MipsImportedFunctionRecognizer ());
33283358
33293359 mipseb->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
33303360 mipsel->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
33313361 mips3->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
33323362 mips3el->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
3333- mips64el->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
33343363 mips64eb->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
3364+ mips64el->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
3365+ r5900l->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
3366+ r5900b->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
33353367 cnmips64eb->RegisterRelocationHandler (" ELF" , new MipsElfRelocationHandler ());
33363368
33373369 // Register the architectures with the binary format parsers so that they know when to use
0 commit comments