This page will be less well-organized than some of the others here; it's a
dumping ground for any useful techniques or info I pick up that ought to be
shared, but that either don't deserve extensive writeups, or just haven't
received them yet.
Unlike the earlier models, the 4000 is based on VxWorks and uses multiple
modules in standard MIPS_BE ELF file formats. The
GNU binutils
include useful tools for making sense of these files. Download, configure
with something like
./configure --prefix=/home/jtl/apps/binutils-2.11.2-mips --program-prefix=mips --target=mips-wrs-vxworks
, make, and make install, and you're well
on your way.
ptv.bin
, the primary program in previous
versions, now appears to be the lowest-level of software, providing services traditionally associated with operating systems. This may be primarily VxWorks code, rather than ReplayTV-specific.; There are multiple .out
modules and a
CougLib.o
library; all of these are in the
Platform/Plymouth/Modules
directory under the sys directory
(which will be either sys1
or sys2
; 411 ZONE
will show which is being
used). The ReplayTV GUI system, the UI built on top of it, and much of the rest, is in the IAppShell.out
module.
I started off with something like:
#!/bin/sh
file=$1
base=`basename $file .out`
base=`basename $base .o`
base=`basename $base .bin`
strings - $file > $base.strings
mipsobjdump -s -j .data $file > $base.data
mipsobjdump -s -j .rodata $file > $base.rodata
mipsobjdump -C -r $file > $base.reloc
mipsobjdump -C -d -mmips4650 $file > $base.dis
merge-disasm-reloc $base.dis $base.reloc > $file.combined
(the current version of the real one is a bit fancier than that)
merge-disasm-reloc.pl adds
relocation records for the .text
segment to the disassmebly of
the segment (that doesn't
work for ptv.bin
, which is linked statically and has no
relocation records).
For each module, you end up with a .strings
file, containing
just the strings in the file; useful for grepping to find particular text;
.rodata
, a hexdump of the read-only data segment;
.data
; a hexdump of the initialized modifiable data segment;
.reloc
, the relocations -- relocations for the text
segment have been merged into the combined file, but there are possibly
relocations for the data and rodata segments as well; .dis
, the
raw disassembly; and .combined
, disassembly + relocation. Most
of your disassembly time will be spent with combined files.
The MIPS32 architecture and instruction set references can be downloaded
(after registration) from mips.com.
Most of the intra-module interfaces seem to be handled via C++ vtables.
Some classes are fairly traditional types, with multiple objects of the class;
many others seem to have just one instance used globally (or possibly just
lots of static functions). A call to a member function through a vtable looks
something like:
; s0 is a pointer to an object; in this case, an IRPlatform *
; first, get a pointer to the vtable; there doesn't seem to be a rule-of-thumb
; for knowing where in the object it is.
26d4: 8e020000 lw v0,0(s0)
; get an offset into the object to use for 'self'. Every case I've looked at,
; this is 0; I expect this is for multiple inheritance support.
26d8: 844400b0 lh a0,176(v0)
; get a pointer to the function itself.
26dc: 8c4200b4 lw v0,180(v0)
; add the object offset to the pointer we already have; this has to go into
; a0; all the other pointers involved are optional, but usual
26e0: 02042021 addu a0,s0,a0
; make the actual call
26e4: 0040f809 jalr v0 ; IRPLatform_mmb_176(sp + 32)
; remember that the instruction after the call itself is executed before
; the call; in this case, the first non-self argument is set here
26e8: 27a50020 addiu a1,sp,32
The notation I've been using is "Object_mmb_number", where number is the
offset in the vtable to the object offset (the offset to the function pointer
(180 in this case) or the C-style index (176/8 = 22 in this case) would make
more sense -- I started using this notation before I fully understood what was happening).
Most (all) classes are split between interface and implementation classes;
calling functions get a pointer to an IRPlatform
object, for
example, which is actually implemented by an IRPlatformImpl
object.
Checking the ptv.sym
file, we see that the IRPlatformImpl?
virtual table is at 0xffffffff80163120
. Adding 180 to that, we
get 0xffffffff801631d4
; looking at ptv.rodata
, we
find at 0x801631d4
(what happened to the leading
0xffffffff00000000
? The MIPS IV architecture is 64-bits extended from an older 32-bit architecture very cleanly; it basically has a full 32-bit subset hidden cleanly inside with no mode bits. For reasons too involved to go into here (see Run, Mips, Run or write me if you're really interested) 32-bit constants when loaded into 64-bit registers always sign extend, and the entire top half of the 32-bit address space (which for other reasons is the only half normally used on an embedded system) is replicated in a teeny tiny bit of the 64-bit address space -- so, address 0xffffffff801631d4
is the same as address 0x801631d4
. As a side note: I haven't seen any use of the full register width; 64 bit quantities are always split between two registers) the address 0x8002c3c0
. Going back to
ptv.combined
, we find
IRPlatformImpl::GetBootState(RBootState? &)
at that address; in
this case, we got somewhat lucky - functions called through vtables may not
have visible names.
- Why are many-but-not-all of the rodata references in IAppShell? off by 0x10000?
Update: Solved! daddiu
, despite being 'unsigned', sign-extends its arguments, so anything
in the upper-half of a 64k chunk will have a high-bit section 1 higher than
I'd thought; so, how much have I gotten wrong, not knowing that? (and not
knowing that offset(base) addressing is signed)
- What's up with the non-disassmbleable instructions? Is this a non-standard MIPS processor with some additional custom instructions?
0x72251802
looks like mul v1,s1,a1
and 0x70641802
looks like mul v1,v1,a0
.
Update: Solved! They're MIPS32/MIPS4650 instructions, which aren't covered
by the MIPS IV instruction set document I've been using, and weren't
disassmebled because the ELF header claimed these are MIPS4000 files, not
MIPS32/MIPS4650.
- Why are the romLed, romPrintString, and other rom* functions such garbage? They're called, they must work, right? but they don't disassemble at all.
Updated: Solved! The symbol table marked them as objects, not functions,
so the disassembler didn't even try - they must be assembly objects rather
than C/C++, which makes sense. Using "-D" instead of "-d" fixes that.
more later
-- ToddLarason - 09 Mar 2002
The __ctype values the Replay uses:
- isalnum 07
- isalpha 03
- isascii ff
- iscntrl a0
- isdigit 04
- isgraph 17
- islower 02
- isprint 5f
- ispunct 10
- isspace 28
- isupper 01
- isxdigit 40
-- ToddLarason - 28 Mar 2002
to disassemble a straight memory dump: mipsobjdump -D -EB -m mips -b binary
-- ToddLarason - 29 Jun 2002
Revision r1.8 - 14 Jul 2003 - 18:54 GMT - TWikiGuest Parents: WebHome
|
Copyright © 2001 by the contributing authors.
All material on this collaboration tool is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.
|
|