Seite 1 von 3

Disassembler für MIPS-CPUs

Verfasst: Fr 9. Dez 2005, 18:23
von Acade
Damit dieses Thema auch im neuen Board schon mal seinen Aufhänger hat und "suchbar" wird, hier ein paar Links und Keywords dazu:

Original-Thread (nur als "Archiv", bitte nicht weiter dort schreiben):
http://board.topfield.de/viewtopic.php?t=17711

Webpage mit Download und Minimaldoku:
http://acade.au7.de/disasmips.htm

Suchbegriffe, die auf diesen Thread und die obigen Links führen sollen:
Memory-Dump, gcc Object-File, Map-File, HTML-Output, Memory-Referenzen, Symbolische Adressen, ...

Viel Spaß mit disasmips im neuen Board!

Ciao,
Acade

Verfasst: Mo 19. Dez 2005, 12:08
von Harvey
Deine Suchbegriffe führen leider zu keinem Ergebnis.

Ich schätze mal, die Bindestriche sind der Knackpunkt.

Verfasst: Mo 19. Dez 2005, 22:14
von Acade
Danke für den Tip, Harvey. Tja, dann gibt's da also etwas, was man an vB oder den hiesigen Einstellungen noch verbessern kann, unter phpBB geht sowas nämlich (hab's gerade am alten Brett ausprobiert). Du kennst Dich doch eh damit aus, kannst ja Strizzi auch noch einen Tip dazu geben ;)

Ciao,
Acade


Aber sicherheitshalber als vorläufiger Workaround:
Memory Dump, gcc Object File, Map File, HTML Output, Memory Referenzen
MemoryDump, gcc ObjectFile, MapFile, HTMLOutput, MemoryReferenzen

Verfasst: Mo 9. Jan 2006, 17:01
von Strizzi
Hi,

schaut so aus, wie wenn ein Bindestrich als Minus identifiziert wird und somit ein Wildcard ist. Wildcard abzustellen macht aber auch keinen Sinn.

Verfasst: Di 10. Jan 2006, 20:02
von Acade
Hm, wenn der Suchstring ein Minus enthält und dieses als Wildcard interpretiert wird, müsste doch aber ein identischer Zielstring im Beitrag auch gematcht werden, oder? Tut's aber nicht :-((
Egal, ist jetzt auch nicht so wichtig ...

Ciao,
Acade

Verfasst: Di 10. Jan 2006, 20:33
von Strizzi
Hi,
probier bitte noch einmal.

Verfasst: Di 10. Jan 2006, 20:59
von Acade
Na wunderbar, geht doch!

Danke,
Acade

Was hast'n jetzt geändert ;-) ?

Verfasst: Sa 21. Jan 2006, 18:11
von Harvey
Die MIPS-CPU macht mich fertig.

Ich kann ja damit leben, daß grundsätzlich noch der auf einem Sprungbefehl folgende Befehl ausgeführt wird, aber wieso steht dahinter oftmals noch ein zweiter, der augenscheinlich nie ausgeführt wird?

Beispiel (was die Funktion macht weiss ich nicht):

Code: Alles auswählen

     0r	001cc154:    3c0f81b2	lui	$t7,0x81b2		
     4r	001cc158:    25ef5bd4	addiu	$t7,23508=0x5bd4	# 81b25bd4
     8r	001cc15c:    01e47821	addu	$t7,$a0			
     cr	001cc160:    91ef0000	lbu	$t7,0($t7)		
    10r	001cc164:    0004c040	sll	$t8,$a0,1		
    14r	001cc168:    3c1981b2	lui	$t9,0x81b2		
    18r	001cc16c:    000f2c00	sll	$a1,$t7,16		
    1cr	001cc170:    8784a012	lh	$a0,-24558($gp)		
    20r	001cc174:    273965de	addiu	$t9,26078=0x65de	# 81b265de
    24r	001cc178:    00052c03	sra	$a1,16			
    28r	001cc17c:    0338c821	addu	$t9,$t8			
    2cr	001cc180:    00a4082a	slt	$at,$a1,$a0		
    30r	001cc184:    10200008	beq	$at,0,54r		
    34r	001cc188:    97230000	lhu	$v1,0($t9)		
    38r	001cc18c:    00852023	subu	$a0,$a1			
    3cr	001cc190:    a784a012	sh	$a0,-24558($gp)		
    40r	001cc194:    9798a010	lhu	$t8,-24560($gp)		
    44r	001cc198:    00837804	sllv	$t7,$v1,$a0		
    48r	001cc19c:    030fc025	or	$t8,$t7			
    4cr	001cc1a0:    1000002e	beq	0,0,108r		
    50r	001cc1a4:    a798a010	sh	$t8,-24560($gp)		
    54r	001cc1a8:    8f999fdc	lw	$t9,-24612($gp)		
    58r	001cc1ac:    8f989fe0	lw	$t8,-24608($gp)		
    5cr	001cc1b0:    0338082b	sltu	$at,$t9,$t8		
    60r	001cc1b4:    10200027	beq	$at,0,100r		
    64r	001cc1b8:    00001025	move	$v0,0			
    68r	001cc1bc:    00a4c823	subu	$t9,$a1,$a0		
    6cr	001cc1c0:    00192400	sll	$a0,$t9,16		
    70r	001cc1c4:    00042403	sra	$a0,16			
    74r	001cc1c8:    978fa010	lhu	$t7,-24560($gp)		
    78r	001cc1cc:    8f859fd8	lw	$a1,-24616($gp)		
    7cr	001cc1d0:    00837007	srav	$t6,$v1,$a0		
    80r	001cc1d4:    01ee7825	or	$t7,$t6			
    84r	001cc1d8:    a0af0000	sb	$t7,0($a1)		
    88r	001cc1dc:    24a50001	addiu	$a1,1			
    8cr	001cc1e0:    af859fd8	sw	$a1,-24616($gp)		
    90r	001cc1e4:    8f989fdc	lw	$t8,-24612($gp)		
    94r	001cc1e8:    28810008	slti	$at,$a0,8		
    98r	001cc1ec:    27020001	addiu	$v0,$t8,1		
    9cr	001cc1f0:    10200005	beq	$at,0,b4r		
    a0r	001cc1f4:    af829fdc	sw	$v0,-24612($gp)		
    a4r	001cc1f8:    24190008	move	$t9,8			
    a8r	001cc1fc:    0324c823	subu	$t9,$a0			
    acr	001cc200:    1000000f	beq	0,0,ecr			
    b0r	001cc204:    a799a012	sh	$t9,-24558($gp)		
    b4r	001cc208:    8f999fe0	lw	$t9,-24608($gp)		
    b8r	001cc20c:    0059082b	sltu	$at,$v0,$t9		
    bcr	001cc210:    50200010	beql	$at,0,100r		
    c0r	001cc214:    00001025	move	$v0,0			
    c4r	001cc218:    2499fff8	addiu	$t9,$a0,-8=0xfff8	
    c8r	001cc21c:    240e0010	move	$t6,16=0x0010		
    ccr	001cc220:    0323c807	srav	$t9,$v1,$t9		
    d0r	001cc224:    24b80001	addiu	$t8,$a1,1		
    d4r	001cc228:    244f0001	addiu	$t7,$v0,1		
    d8r	001cc22c:    01c47023	subu	$t6,$a0			
    dcr	001cc230:    a0b90000	sb	$t9,0($a1)		
    e0r	001cc234:    af989fd8	sw	$t8,-24616($gp)		
    e4r	001cc238:    af8f9fdc	sw	$t7,-24612($gp)		
    e8r	001cc23c:    a78ea012	sh	$t6,-24558($gp)		
    ecr	001cc240:    9799a012	lhu	$t9,-24558($gp)		
    f0r	001cc244:    0323c804	sllv	$t9,$v1,$t9		
    f4r	001cc248:    10000004	beq	0,0,108r		
    f8r	001cc24c:    a799a010	sh	$t9,-24560($gp)		
    fcr	001cc250:    00001025	move	$v0,0			
   100r	001cc254:    03e00008	jr	$ra			
   104r	001cc258:    00000000	nop				
   108r	001cc25c:    03e00008	jr	$ra			
   10ar	001cc260:    24020001	move	$v0,1			
Stein des Anstosses ist die Zeile fcr. Es wird zwar 100r angesprungen, aber niemals fcr. Ich sehe einfach nicht, wie in $v0 eine 0 zurückgegeben werden soll.

Übrigens hat dein Dissassembler (wahrscheinlich aus diesem Grund) aus 104r und 108r eine eigene Funktion gemacht.

Verfasst: Sa 21. Jan 2006, 20:11
von Acade
Hi Harvey,

habe die Stelle im Code gefunden. Der move-Befehl wird tatsächlich nicht angesprungen, das ist toter Code. Der kann von schlechten Compileroptionen kommen, z.B. bei "if (0 != 0) return (0); else return (1);".

Leider kann kein Disassembler ohne Zusatzinfos (z.B. C-Prolog/-Epilog) den Beginn einer neuen Funktion zuverlässig erkennen, daher behilft sich disasmips mit dem vermutlichen Ende einer Funktion, dem "jr $ra"-Befehl. Und der kann beim verwendeten Compiler bzw. dessen Einstellungen auch mitten in einer Funktion vorkommen. Das ist also unvermeidlich.

Kleiner Tip: Du kannst übrigens durch Weglassen der -r-Option von disasmips die absoluten Zieladressen sehen und damit nach Sprungbefehlen auch außerhalb einer durch frühzeitigen "jr $ra"-Befehl beendeten Funktion suchen. Damit kannst Du sicherstellen, daß ein Befehl nicht doch noch von "außerhalb" der Funktion angesprungen wird.

Viel Spaß mit disasmips,
Acade

Edit: 0 wird in $v0 über die Befehle bcr/c0r zurückgegeben, aber das ist Dir ja sicher klar.
Und nicht aus 104r/108r wird eine eigene Funktion, sondern aus 108r/10ar.

Verfasst: Fr 23. Jun 2006, 21:03
von Harvey
Nabbent.

Läge es in der Peripherie der possibalen Globalitäten, die Beschränkung von 100 Zeichen/Zeile aufzuheben oder sagen wir zu verdoppeln?

Alldiweil ich versuche grade, zu übergebenen Variablen im C++-Style zu kommentieren, und das haut absolut nicht hin.

Danke.

Verfasst: Do 29. Jun 2006, 14:57
von Acade
Dein Begehren wurde erhört :cool:

Ciao,
Acade

Verfasst: Do 29. Jun 2006, 15:10
von FireBird
Rituale braucht der Mensch: Erster! :D

Danke.

Verfasst: Do 29. Jun 2006, 17:33
von Harvey
Dankeschön. :)

Verfasst: Do 29. Jun 2006, 18:14
von Aldarin
Obwohl ich noch blutiger WAA (WiederAsmAnfänger) bin, auch ein kleines Dankeschön von mir :o

Gruß
Aldarin

Verfasst: Do 29. Jun 2006, 23:32
von Acade
Und von mir immer gerne schöne Grüße nach Austria! :hello:

Servus,
Acade

Erkennung von Beginn / Ende von Funktionen

Verfasst: Fr 8. Sep 2006, 23:22
von Acade
Hi,

es gibt eine erhebliche Verbesserung in disasmips, was die Erkennung von Beginn und Ende von Funktionen anbelangt (wichtig für die Angabe von Relativadressen innerhalb von Funktionen und die Aufspaltung des HTML-Outputs in Files an Funktionsgrenzen).

Bisher galt (s. o.):
"Leider kann kein Disassembler ohne Zusatzinfos (z.B. C-Prolog/-Epilog) den Beginn einer neuen Funktion zuverlässig erkennen, daher behilft sich disasmips mit dem vermutlichen Ende einer Funktion, dem "jr $ra"-Befehl. Und der kann beim verwendeten Compiler bzw. dessen Einstellungen auch mitten in einer Funktion vorkommen."
(D.h., die Funktion kann nach einem jr-Befehl auch noch lustig weitergehen.)

Ok, ist richtig und gilt auch weiterhin. Aber: Wenn eine Funktion nach einem jr-Befehl noch weitergeht, muß man irgendwie dorthin kommen können, und das passiert mit (beliebig gearteten) Branch-Befehlen. Also muß man sich nur die Zieladressen aller Branchbefehle einer Funktion ansehen, um zu wissen, wann diese Funktion frühestens zu Ende sein kann und welche jr-Befehle noch mitten in der Funktion liegen müssen. D.h., man kann auf dem Weg zum Funktionsende (das man noch gar nicht kennt) das früheste Funktionsende immer wieder hinausschieben, wenn wieder ein Branchbefehl mit Zieladresse _nach_ dem bisherigen frühesten Ende auftaucht. Auf diese Weise _muß_ man das korrekte Funktionsende finden, sonst hätte der Compiler Code generiert, den man nicht erreichen kann oder es gäbe Branches, die über eine Funktion hinausspringen.

Diese Erkenntnisse habe ich jetzt in disasmips implementiert (Option -F {len}) und als Schutz vor ("falschen") Branch-Befehlen in Datenbereichen, die das früheste Ende der nächsten Funktion auf St.-Nimmerlein verschieben könnten, reicht eine Begrenzung der Reichweite von Branches auf {len} Befehle (default 500, in der Topf-FW voll ausreichend).

Viel Spaß mit der neuen Version von disasmips (Link s.u.)!

Ciao,
Acade

PS: Auf der Webseite ist jetzt auch ein Link zur Benachrichtigung per Email, wenn es eine neue Version gibt, bitte nutzen!

AW: Disassembler für MIPS-CPUs

Verfasst: Sa 9. Sep 2006, 13:19
von Harvey
Sei bedankt.


Falls Du mal Langeweile haben solltest: Hast Du noch eine Idee, Daten mitten in einer Funktion etwas schicker aufzubereiten (relative Adresse)?

Wenn diese Daten vorhanden sind dann sind das (immer?) Sprungtabellen kurz nach einem jr $at .

Ist aber nicht so wichtig.

AW: Disassembler für MIPS-CPUs

Verfasst: Di 12. Sep 2006, 21:56
von Acade
[quote=""Harvey""]
Hast Du noch eine Idee, Daten mitten in einer Funktion etwas schicker aufzubereiten (relative Adresse)?

Wenn diese Daten vorhanden sind dann sind das (immer?) Sprungtabellen kurz nach einem jr $at .
[/quote]

Beispiel? (Ist - Soll)

AW: Disassembler für MIPS-CPUs

Verfasst: Mi 13. Sep 2006, 09:26
von Harvey
ist

Code: Alles auswählen

    64r	80005320:    3c018000	lui	$at,0x8000		
    68r	80005324:    24215338	addiu	$at,21304=0x5338	# 80005338 -> 8000589c -> 32d90001
    6cr	80005328:    00380821	addu	$at,$t8			
    70r	8000532c:    8c210000	lw	$at,0($at)		
    74r	80005330:    00200008	jr	$at			
    78r	80005334:    00000000	nop				
    7cr	80005338:    8000589c	lb	0,22684(0)		
    80r	8000533c:    8000557c	lb	0,21884(0)		
    84r	80005340:    80005538	lb	0,21816(0)		
    88r	80005344:    80005378	lb	0,21368(0)		
    8cr	80005348:    80005514	lb	0,21780(0)		
    90r	8000534c:    800053e4	lb	0,21476(0)		
    94r	80005350:    80005418	lb	0,21528(0)		
    98r	80005354:    800054f0	lb	0,21744(0)		
    9cr	80005358:    80005444	lb	0,21572(0)		
    a0r	8000535c:    800054a8	lb	0,21672(0)		
    a4r	80005360:    800057f0	lb	0,22512(0)		
    a8r	80005364:    80005800	lb	0,22528(0)		
    acr	80005368:    80005788	lb	0,22408(0)		
    b0r	8000536c:    80005820	lb	0,22560(0)		
    b4r	80005370:    80005830	lb	0,22576(0)		
    b8r	80005374:    80005858	lb	0,22616(0)		
    bcr	80005378:    24040032	move	$a0,50=0x0032		
    c0r	8000537c:    0c000499	jal	0x80001264		# sysprocSwitchTask
    c4r	80005380:    00000000	nop				
    c8r	80005384:    8fb80034	lw	$t8,52($sp)		
soll vielleicht so?

Code: Alles auswählen

    64r	80005320:    3c018000	lui	$at,0x8000		
    68r	80005324:    24215338	addiu	$at,21304=0x5338	# 80005338 -> 8000589c -> 32d90001
    6cr	80005328:    00380821	addu	$at,$t8			
    70r	8000532c:    8c210000	lw	$at,0($at)		
    74r	80005330:    00200008	jr	$at			
    78r	80005334:    00000000	nop				
    7cr	80005338:    8000589c	lb	0,22684(0)		#5e0r
    80r	8000533c:    8000557c	lb	0,21884(0)		#2c0r
    84r	80005340:    80005538	lb	0,21816(0)		usw.
Wenn das zu aufwändig ist lass es.

AW: Disassembler für MIPS-CPUs

Verfasst: Mi 20. Sep 2006, 00:14
von Acade
Hi Harvey,

naja, aufwendig wäre es schon auch, aber kannst Du nicht einfach per Mapfile zu Beginn der Sprungtabelle auf "data representation" umschalten (und am Ende wieder zurück auf Code), etwa so (im Mapfile):

Code: Alles auswählen

80005338    @jmptable5338
80005378    continue5378
Dann hast Du die Sprungadressen immerhin in absoluter Form. Die relativen Adressen sind sowieso nur für die Branchbefehle eine Erleichterung ...

Ciao,
Acade