Use udis on x86
							parent
							
								
									51ee6be047
								
							
						
					
					
						commit
						cefdec0644
					
				| 
						 | 
					@ -3,11 +3,11 @@ USING: help.markup help.syntax sequences.private ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HELP: disassemble
 | 
					HELP: disassemble
 | 
				
			||||||
{ $values { "obj" "a word or a pair of addresses" } }
 | 
					{ $values { "obj" "a word or a pair of addresses" } }
 | 
				
			||||||
{ $description "Disassembles either a compiled word definition or an arbitrary memory range (in the case " { $snippet "obj" } " is a pair of integers) by attaching " { $snippet "gdb" } " to the Factor VM and capturing the output." }
 | 
					{ $description "Disassembles either a compiled word definition or an arbitrary memory range (in the case " { $snippet "obj" } " is a pair of integers)." }
 | 
				
			||||||
{ $notes "In some cases the Factor compiler emits data inline with code, which can confuse " { $snippet "gdb" } ". This occurs in words which call " { $link dispatch } ", where the jump table addresses are compiled inline. Also on the ARM architecture, various pointers are often compiled inline, and the preceeding instruction jumps over the inline pinter." } ;
 | 
					{ $notes "In some cases the Factor compiler emits data inline with code, which can confuse the disassembler. This occurs in words which call " { $link dispatch } ", where the jump table addresses are compiled inline." } ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARTICLE: "tools.disassembler" "Disassembling words"
 | 
					ARTICLE: "tools.disassembler" "Disassembling words"
 | 
				
			||||||
"The " { $vocab-link "tools.disassembler" } " vocabulary integrates Factor with the GNU debugger (" { $snippet "gdb" } ") for viewing the assembly code generated by the compiler. It can be used on both Unix and Windows as long as a working copy of " { $snippet "gdb" } " is installed and available in the " { $snippet "PATH" } "."
 | 
					"The " { $vocab-link "tools.disassembler" } " vocabulary provides support for disassembling compiled word definitions. It uses the " { $snippet "libudis86" } " library on x86-32 and x86-64, and " { $snippet "gdb" } " on PowerPC."
 | 
				
			||||||
{ $subsection disassemble } ;
 | 
					{ $subsection disassemble } ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ABOUT: "tools.disassembler"
 | 
					ABOUT: "tools.disassembler"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,43 +1,25 @@
 | 
				
			||||||
! Copyright (C) 2008 Slava Pestov, Jorge Acereda Macia.
 | 
					! Copyright (C) 2008 Slava Pestov.
 | 
				
			||||||
! See http://factorcode.org/license.txt for BSD license.
 | 
					! See http://factorcode.org/license.txt for BSD license.
 | 
				
			||||||
USING: io.files io words alien kernel math.parser alien.syntax
 | 
					USING: tr arrays sequences io words generic system combinators
 | 
				
			||||||
io.launcher system assocs arrays sequences namespaces make
 | 
					vocabs.loader ;
 | 
				
			||||||
qualified system math compiler.codegen.fixup
 | 
					 | 
				
			||||||
io.encodings.ascii accessors generic tr ;
 | 
					 | 
				
			||||||
IN: tools.disassembler
 | 
					IN: tools.disassembler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: in-file ( -- path ) "gdb-in.txt" temp-file ;
 | 
					GENERIC: disassemble ( obj -- )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: out-file ( -- path ) "gdb-out.txt" temp-file ;
 | 
					SYMBOL: disassembler-backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENERIC: make-disassemble-cmd ( obj -- )
 | 
					HOOK: disassemble* disassembler-backend ( from to -- lines )
 | 
				
			||||||
 | 
					 | 
				
			||||||
M: word make-disassemble-cmd
 | 
					 | 
				
			||||||
    word-xt code-format - 2array make-disassemble-cmd ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
M: pair make-disassemble-cmd
 | 
					 | 
				
			||||||
    in-file ascii [
 | 
					 | 
				
			||||||
        "attach " write
 | 
					 | 
				
			||||||
        current-process-handle number>string print
 | 
					 | 
				
			||||||
        "disassemble " write
 | 
					 | 
				
			||||||
        [ number>string write bl ] each
 | 
					 | 
				
			||||||
    ] with-file-writer ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
M: method-spec make-disassemble-cmd
 | 
					 | 
				
			||||||
    first2 method make-disassemble-cmd ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: gdb-binary ( -- string ) "gdb" ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: run-gdb ( -- lines )
 | 
					 | 
				
			||||||
    <process>
 | 
					 | 
				
			||||||
        +closed+ >>stdin
 | 
					 | 
				
			||||||
        out-file >>stdout
 | 
					 | 
				
			||||||
        [ gdb-binary , "-x" , in-file , "-batch" , ] { } make >>command
 | 
					 | 
				
			||||||
    try-process
 | 
					 | 
				
			||||||
    out-file ascii file-lines ;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
TR: tabs>spaces "\t" "\s" ;
 | 
					TR: tabs>spaces "\t" "\s" ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: disassemble ( obj -- )
 | 
					M: pair disassemble first2 disassemble* [ tabs>spaces print ] each ;
 | 
				
			||||||
    make-disassemble-cmd run-gdb
 | 
					
 | 
				
			||||||
    [ tabs>spaces ] map [ print ] each ;
 | 
					M: word disassemble word-xt 2array disassemble ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: method-spec disassemble first2 method disassemble ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cpu {
 | 
				
			||||||
 | 
					    { x86.32 [ "tools.disassembler.udis" ] }
 | 
				
			||||||
 | 
					    { x86.64 [ "tools.disassembler.udis" ] }
 | 
				
			||||||
 | 
					    { ppc [ "tools.disassembler.gdb" ] }
 | 
				
			||||||
 | 
					} case require
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					! Copyright (C) 2008 Slava Pestov, Jorge Acereda Macia.
 | 
				
			||||||
 | 
					! See http://factorcode.org/license.txt for BSD license.
 | 
				
			||||||
 | 
					USING: io.files io words alien kernel math.parser alien.syntax
 | 
				
			||||||
 | 
					io.launcher system assocs arrays sequences namespaces make
 | 
				
			||||||
 | 
					qualified system math io.encodings.ascii accessors
 | 
				
			||||||
 | 
					tools.disassembler ;
 | 
				
			||||||
 | 
					IN: tools.disassembler.gdb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SINGLETON: gdb-disassembler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: in-file ( -- path ) "gdb-in.txt" temp-file ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: out-file ( -- path ) "gdb-out.txt" temp-file ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: make-disassemble-cmd ( from to -- )
 | 
				
			||||||
 | 
					    in-file ascii [
 | 
				
			||||||
 | 
					        "attach " write
 | 
				
			||||||
 | 
					        current-process-handle number>string print
 | 
				
			||||||
 | 
					        "disassemble " write
 | 
				
			||||||
 | 
					        [ number>string write bl ] bi@
 | 
				
			||||||
 | 
					    ] with-file-writer ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: gdb-binary ( -- string ) "gdb" ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: run-gdb ( -- lines )
 | 
				
			||||||
 | 
					    <process>
 | 
				
			||||||
 | 
					        +closed+ >>stdin
 | 
				
			||||||
 | 
					        out-file >>stdout
 | 
				
			||||||
 | 
					        [ gdb-binary , "-x" , in-file , "-batch" , ] { } make >>command
 | 
				
			||||||
 | 
					    try-process
 | 
				
			||||||
 | 
					    out-file ascii file-lines ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: gdb-disassembler disassemble*
 | 
				
			||||||
 | 
					    make-disassemble-cmd run-gdb ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gdb-disassembler disassembler-backend set-global
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					unportable
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,91 @@
 | 
				
			||||||
 | 
					! Copyright (C) 2008 Slava Pestov, Jorge Acereda Macia.
 | 
				
			||||||
 | 
					! See http://factorcode.org/license.txt for BSD license.
 | 
				
			||||||
 | 
					USING: tools.disassembler namespaces combinators
 | 
				
			||||||
 | 
					alien alien.syntax alien.c-types lexer parser kernel
 | 
				
			||||||
 | 
					sequences layouts math math.parser system make fry arrays ;
 | 
				
			||||||
 | 
					IN: tools.disassembler.udis
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<< : & scan "c-library" get load-library dlsym parsed ; parsing >>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<<
 | 
				
			||||||
 | 
					"libudis86" {
 | 
				
			||||||
 | 
					    { [ os macosx? ] [ "libudis86.0.dylib" ] }
 | 
				
			||||||
 | 
					    { [ os unix? ] [ "libudis86.so.0" ] }
 | 
				
			||||||
 | 
					    { [ os winnt? ] [ "libudis86.dll" ] }
 | 
				
			||||||
 | 
					} cond "cdecl" add-library
 | 
				
			||||||
 | 
					>>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LIBRARY: libudis86
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TYPEDEF: char[592] ud
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FUNCTION: void ud_translate_intel ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_translate_att ( ud* u ) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: UD_SYN_INTEL    & ud_translate_intel ; inline
 | 
				
			||||||
 | 
					: UD_SYN_ATT      & ud_translate_att ; inline
 | 
				
			||||||
 | 
					: UD_EOI          -1 ; inline
 | 
				
			||||||
 | 
					: UD_INP_CACHE_SZ 32 ; inline
 | 
				
			||||||
 | 
					: UD_VENDOR_AMD   0 ; inline
 | 
				
			||||||
 | 
					: UD_VENDOR_INTEL 1 ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FUNCTION: void ud_init ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_set_mode ( ud* u, uint8_t mode ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_set_pc ( ud* u, ulonglong pc ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_set_input_buffer ( ud* u, uint8_t* offset, size_t size ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_set_vendor ( ud* u, uint vendor ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_set_syntax ( ud* u, void* syntax ) ;
 | 
				
			||||||
 | 
					FUNCTION: void ud_input_skip ( ud* u, size_t size ) ;
 | 
				
			||||||
 | 
					FUNCTION: int ud_input_end ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: uint ud_decode ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: uint ud_disassemble ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: char* ud_insn_asm ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: void* ud_insn_ptr ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: ulonglong ud_insn_off ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: char* ud_insn_hex ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: uint ud_insn_len ( ud* u ) ;
 | 
				
			||||||
 | 
					FUNCTION: char* ud_lookup_mnemonic ( int c ) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: <ud> ( -- ud )
 | 
				
			||||||
 | 
					    "ud" <c-object>
 | 
				
			||||||
 | 
					    dup ud_init
 | 
				
			||||||
 | 
					    dup cell-bits ud_set_mode
 | 
				
			||||||
 | 
					    dup UD_SYN_INTEL ud_set_syntax ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SINGLETON: udis-disassembler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: buf/len ( from to -- buf len ) [ drop <alien> ] [ swap - ] 2bi ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: format-disassembly ( lines -- lines' )
 | 
				
			||||||
 | 
					    dup [ second length ] map supremum
 | 
				
			||||||
 | 
					    '[
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [ first >hex cell 2 * CHAR: 0 pad-left % ": " % ]
 | 
				
			||||||
 | 
					            [ second _ CHAR: \s pad-right % "  " % ]
 | 
				
			||||||
 | 
					            [ third % ]
 | 
				
			||||||
 | 
					            tri
 | 
				
			||||||
 | 
					        ] "" make
 | 
				
			||||||
 | 
					    ] map ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: (disassemble) ( ud -- lines )
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        dup '[
 | 
				
			||||||
 | 
					            _ ud_disassemble 0 =
 | 
				
			||||||
 | 
					            [ f ] [
 | 
				
			||||||
 | 
					                _
 | 
				
			||||||
 | 
					                [ ud_insn_off ]
 | 
				
			||||||
 | 
					                [ ud_insn_hex ]
 | 
				
			||||||
 | 
					                [ ud_insn_asm ]
 | 
				
			||||||
 | 
					                tri 3array , t
 | 
				
			||||||
 | 
					            ] if
 | 
				
			||||||
 | 
					        ] loop
 | 
				
			||||||
 | 
					    ] { } make ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: udis-disassembler disassemble* ( from to -- buffer )
 | 
				
			||||||
 | 
					    [ <ud> ] 2dip {
 | 
				
			||||||
 | 
					        [ drop ud_set_pc ]
 | 
				
			||||||
 | 
					        [ buf/len ud_set_input_buffer ]
 | 
				
			||||||
 | 
					        [ 2drop (disassemble) format-disassembly ]
 | 
				
			||||||
 | 
					    } 3cleave ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					udis-disassembler disassembler-backend set-global
 | 
				
			||||||
		Loading…
	
		Reference in New Issue