Last active
September 15, 2015 01:50
-
-
Save stassats/796da6ad2665582f5956 to your computer and use it in GitHub Desktop.
cold-core disassembly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defconstant +core-magic+ (logior (ash (char-code #\S) 24) | |
(ash (char-code #\B) 16) | |
(ash (char-code #\C) 8) | |
(char-code #\L))) | |
(defconstant +build-id-core-entry-type-code+ 3860) | |
(defconstant +new-directory-core-entry-type-code+ 3861) | |
(defconstant +initial-fun-core-entry-type-code+ 3863) | |
(defconstant +page-table-core-entry-type-code+ 3880) | |
(defconstant +end-core-entry-type-code+ 3840) | |
(defconstant +dynamic-core-space-id+ 1) | |
(defconstant +static-core-space-id+ 2) | |
(defconstant +read-only-core-space-id+ 3) | |
(defconstant +deflated-core-space-id-flag+ 4) | |
(defconstant +backend-page-words+ (/ 4096 8)) | |
(defstruct entry | |
identifier | |
nwords | |
data-page | |
address | |
page-count) | |
(defun read-entry (stream) | |
(make-entry :identifier (read-byte stream) | |
:nwords (read-byte stream) | |
:data-page (read-byte stream) | |
:address (* (read-byte stream) +backend-page-words+) | |
:page-count (read-byte stream))) | |
(defun get-ds (stream) | |
(read-byte stream) ;; size | |
(loop repeat 3 | |
for entry = (read-entry stream) | |
when (= (entry-identifier entry) | |
+dynamic-core-space-id+) | |
return entry)) | |
(defun find-initial-function (stream) | |
(assert (= (read-byte stream) +core-magic+)) | |
(let ((fun-start) | |
(ds)) | |
(loop for value = (read-byte stream) | |
until (= value +end-core-entry-type-code+) | |
do | |
(case value | |
(#.+new-directory-core-entry-type-code+ | |
(setf ds (get-ds stream))) | |
(#.+initial-fun-core-entry-type-code+ | |
(read-byte stream) ;; length | |
(setf fun-start (read-byte stream))))) | |
(let ((start (+ (* +backend-page-words+ (1+ (entry-data-page ds))) | |
(- (/ (- fun-start sb-vm:fun-pointer-lowtag) 8) | |
(entry-address ds))))) | |
(file-position stream start) | |
(let ((code-offset (ash (read-byte stream) -8))) | |
(file-position stream (1+ (- start code-offset))) | |
(values (+ start sb-vm:simple-fun-code-offset) | |
(- (ash (read-byte stream) (- (+ 3 sb-vm::n-fixnum-tag-bits))) | |
sb-vm:simple-fun-code-offset) | |
(+ (- fun-start sb-vm:fun-pointer-lowtag) | |
(* sb-vm:simple-fun-code-offset 8))))))) | |
(defun copy-init-fun (core) | |
(with-open-file (in core :element-type '(unsigned-byte 64)) | |
(multiple-value-bind (start count memory-fun-start) | |
(find-initial-function in) | |
(with-open-file (out "/tmp/dis" :direction :output | |
:if-exists :supersede | |
:element-type '(unsigned-byte 64)) | |
(file-position in start) | |
(loop repeat count | |
do (write-byte (read-byte in) out))) | |
memory-fun-start))) | |
(defun disassemble-core (core) | |
(let ((offset (copy-init-fun core))) | |
(sb-ext:run-program "objdump" (list "-m" "aarch64" "-b" "binary" "-D" "/tmp/dis" | |
"--dwarf-start=0" ;; suppreses some superflous output | |
(format nil "--adjust-vma=~a" offset)) | |
:search t | |
:output *standard-output*))) | |
#+() | |
(sb-ext:save-lisp-and-die "core-disas" | |
:toplevel | |
(lambda () | |
(unwind-protect | |
(let ((arg (cadr sb-ext:*posix-argv*))) | |
(disassemble-core arg)) | |
(sb-ext:exit))) | |
:executable t | |
:compression t) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment