mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
add ability to disassemble ELF images
* module/scripts/disassemble.scm (disassemble): Update to work with RTl (and only RTL, as that's the future). * module/system/vm/debug.scm (for-each-elf-symbol): New public interface. (debug-context-from-image): New helper. (find-debug-context): Use the helper. * module/system/vm/disassembler.scm (disassemble-image): New public interface.
This commit is contained in:
parent
c96933fd54
commit
610295ec9d
3 changed files with 55 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
||||||
;;; Disassemble --- Disassemble .go files into something human-readable
|
;;; Disassemble --- Disassemble .go files into something human-readable
|
||||||
|
|
||||||
;; Copyright 2005, 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
|
;; Copyright 2005, 2008, 2009, 2011, 2012, 2013 Free Software Foundation, Inc.
|
||||||
;;
|
;;
|
||||||
;; This program is free software; you can redistribute it and/or
|
;; This program is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public License
|
;; modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -22,12 +22,14 @@
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; Usage: disassemble [ARGS]
|
;; Usage: disassemble FILE...
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (scripts disassemble)
|
(define-module (scripts disassemble)
|
||||||
#:use-module (system vm objcode)
|
#:use-module (system vm objcode)
|
||||||
|
#:use-module (system vm program)
|
||||||
|
#:use-module (system vm disassembler)
|
||||||
#:use-module ((language assembly disassemble)
|
#:use-module ((language assembly disassemble)
|
||||||
#:renamer (symbol-prefix-proc 'asm:))
|
#:renamer (symbol-prefix-proc 'asm:))
|
||||||
#:export (disassemble))
|
#:export (disassemble))
|
||||||
|
@ -36,7 +38,9 @@
|
||||||
|
|
||||||
(define (disassemble . files)
|
(define (disassemble . files)
|
||||||
(for-each (lambda (file)
|
(for-each (lambda (file)
|
||||||
(asm:disassemble (load-thunk-from-file file)))
|
(let* ((thunk (load-thunk-from-file file))
|
||||||
|
(elf (find-mapped-elf-image (rtl-program-code thunk))))
|
||||||
|
(disassemble-image elf)))
|
||||||
files))
|
files))
|
||||||
|
|
||||||
(define main disassemble)
|
(define main disassemble)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#:use-module (srfi srfi-9)
|
#:use-module (srfi srfi-9)
|
||||||
#:export (debug-context-image
|
#:export (debug-context-image
|
||||||
debug-context-base
|
debug-context-base
|
||||||
|
debug-context-text-base
|
||||||
|
|
||||||
program-debug-info-name
|
program-debug-info-name
|
||||||
program-debug-info-context
|
program-debug-info-context
|
||||||
|
@ -52,6 +53,8 @@
|
||||||
arity-has-keyword-args?
|
arity-has-keyword-args?
|
||||||
arity-is-case-lambda?
|
arity-is-case-lambda?
|
||||||
|
|
||||||
|
debug-context-from-image
|
||||||
|
for-each-elf-symbol
|
||||||
find-debug-context
|
find-debug-context
|
||||||
find-program-debug-info
|
find-program-debug-info
|
||||||
arity-arguments-alist
|
arity-arguments-alist
|
||||||
|
@ -79,6 +82,19 @@
|
||||||
@var{context}."
|
@var{context}."
|
||||||
(elf-bytes (debug-context-elf context)))
|
(elf-bytes (debug-context-elf context)))
|
||||||
|
|
||||||
|
(define (for-each-elf-symbol context proc)
|
||||||
|
"Call @var{proc} on each symbol in the symbol table of @var{context}."
|
||||||
|
(let ((elf (debug-context-elf context)))
|
||||||
|
(cond
|
||||||
|
((elf-section-by-name elf ".symtab")
|
||||||
|
=> (lambda (symtab)
|
||||||
|
(let ((len (elf-symbol-table-len symtab))
|
||||||
|
(strtab (elf-section elf (elf-section-link symtab))))
|
||||||
|
(let lp ((n 0))
|
||||||
|
(when (< n len)
|
||||||
|
(proc (elf-symbol-table-ref elf symtab n strtab))
|
||||||
|
(lp (1+ n))))))))))
|
||||||
|
|
||||||
;;; A program debug info (PDI) is a handle on debugging meta-data for a
|
;;; A program debug info (PDI) is a handle on debugging meta-data for a
|
||||||
;;; particular program.
|
;;; particular program.
|
||||||
;;;
|
;;;
|
||||||
|
@ -117,17 +133,20 @@ offset from the beginning of the ELF image in 32-bit units."
|
||||||
(debug-context-text-base (program-debug-info-context pdi)))
|
(debug-context-text-base (program-debug-info-context pdi)))
|
||||||
4))
|
4))
|
||||||
|
|
||||||
(define (find-debug-context addr)
|
(define (debug-context-from-image bv)
|
||||||
"Find and return the debugging context corresponding to the ELF image
|
"Build a debugging context corresponding to a given ELF image."
|
||||||
containing the address @var{addr}. @var{addr} is an integer."
|
(let* ((elf (parse-elf bv))
|
||||||
(let* ((bv (find-mapped-elf-image addr))
|
|
||||||
(elf (parse-elf bv))
|
|
||||||
(base (pointer-address (bytevector->pointer (elf-bytes elf))))
|
(base (pointer-address (bytevector->pointer (elf-bytes elf))))
|
||||||
(text-base (elf-section-offset
|
(text-base (elf-section-offset
|
||||||
(or (elf-section-by-name elf ".rtl-text")
|
(or (elf-section-by-name elf ".rtl-text")
|
||||||
(error "ELF object has no text section")))))
|
(error "ELF object has no text section")))))
|
||||||
(make-debug-context elf base text-base)))
|
(make-debug-context elf base text-base)))
|
||||||
|
|
||||||
|
(define (find-debug-context addr)
|
||||||
|
"Find and return the debugging context corresponding to the ELF image
|
||||||
|
containing the address @var{addr}. @var{addr} is an integer."
|
||||||
|
(debug-context-from-image (find-mapped-elf-image addr)))
|
||||||
|
|
||||||
(define (find-elf-symbol elf text-offset)
|
(define (find-elf-symbol elf text-offset)
|
||||||
"Search the symbol table of @var{elf} for the ELF symbol containing
|
"Search the symbol table of @var{elf} for the ELF symbol containing
|
||||||
@var{text-offset}. @var{text-offset} is a byte offset in the text
|
@var{text-offset}. @var{text-offset} is a byte offset in the text
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
#:use-module (ice-9 vlist)
|
#:use-module (ice-9 vlist)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-4)
|
#:use-module (srfi srfi-4)
|
||||||
#:export (disassemble-program))
|
#:export (disassemble-program
|
||||||
|
disassemble-image))
|
||||||
|
|
||||||
(define-syntax-rule (u32-ref buf n)
|
(define-syntax-rule (u32-ref buf n)
|
||||||
(bytevector-u32-native-ref buf (* n 4)))
|
(bytevector-u32-native-ref buf (* n 4)))
|
||||||
|
@ -334,3 +335,25 @@ address of that offset."
|
||||||
(else
|
(else
|
||||||
(format port "Debugging information unavailable.~%")))
|
(format port "Debugging information unavailable.~%")))
|
||||||
(values))
|
(values))
|
||||||
|
|
||||||
|
(define* (disassemble-image bv #:optional (port (current-output-port)))
|
||||||
|
(let* ((ctx (debug-context-from-image bv))
|
||||||
|
(base (debug-context-text-base ctx)))
|
||||||
|
(for-each-elf-symbol
|
||||||
|
ctx
|
||||||
|
(lambda (sym)
|
||||||
|
(let ((name (elf-symbol-name sym))
|
||||||
|
(value (elf-symbol-value sym))
|
||||||
|
(size (elf-symbol-size sym)))
|
||||||
|
(format port "Disassembly of ~A at #x~X:\n\n"
|
||||||
|
(if (and (string? name) (not (string-null? name)))
|
||||||
|
name
|
||||||
|
"<unnamed function>")
|
||||||
|
(+ base value))
|
||||||
|
(disassemble-buffer port
|
||||||
|
bv
|
||||||
|
(/ (+ base value) 4)
|
||||||
|
(/ (+ base value size) 4)
|
||||||
|
ctx)
|
||||||
|
(display "\n\n" port)))))
|
||||||
|
(values))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue