From ba30d38488575521a7c862d6836ea1fc56d23b89 Mon Sep 17 00:00:00 2001 From: John Connors Date: Tue, 25 Mar 2008 15:09:18 +0000 Subject: [PATCH] Sorted out section classification. --- elf-file.lisp | 77 ++++++++++++++++++++++++++--------------------------------- elf-rw.lisp | 9 +++---- elf-test.lisp | 7 ++++-- 3 files changed, 44 insertions(+), 49 deletions(-) diff --git a/elf-file.lisp b/elf-file.lisp index 0778b3a..8db72cb 100644 --- a/elf-file.lisp +++ b/elf-file.lisp @@ -68,7 +68,7 @@ (once-only (buffer) (with-gensyms (old-pos) `(let* - ((,old-pos (buffer-pos-of (buffered-data-of ,buffer)))) + ((,old-pos (buffer-pos-of ,buffer))) (setf (buffer-pos-of ,buffer) ,pos) (prog1 @@ -87,7 +87,6 @@ (defclass elf-section (buffered-data-mixin) ((header :accessor header-of :initform 0) - (elf-type :initform nil) (name :initform nil :accessor name-of)) (:documentation "Object that represents a generic elf section")) @@ -113,7 +112,7 @@ section-header-offset) ;; read in the section header (setf (header-of section) - (read-value 'elf32-section-header (buffered-data-of elf))) + (read-value 'elf32-section-header elf)) ;; grab the actual section itself now we know where it is via header (setf (buffered-data-of section) (subseq (buffered-data-of elf) @@ -149,31 +148,31 @@ "Given the section, return the type used to read an entry from it via read-value" (let ((section-entry-types - '((+SHT_NULL+ 'u8) - (+SHT_STRTAB+ . 'asciiz) - (+SHT_PROGBITS+ . 'u8) - (+SHT_NOTES+ 'asciiz) - (+SHT_SYMTAB+ 'elf-sym) - (+SHT_REL+ 'elf-rel) - (+SHT_RELA+ 'elf-rela)))) + (list (cons +SHT_NULL+ 'u8) + (cons +SHT_STRTAB+ 'asciiz) + (cons +SHT_PROGBITS+ 'u8) + (cons +SHT_NOTE+ 'asciiz) + (cons +SHT_SYMTAB+ 'elf-sym) + (cons +SHT_REL+ 'elf-rel) + (cons +SHT_RELA+ 'elf-rela)))) (or - (cdr (assoc (slot-value section 'elf-type) section-entry-types)) - +SHT_NULL+))) + (cdr (assoc (elf-type-of section) section-entry-types)) + 'u8))) (defmethod elf-entry-type-class-of ((section elf-section)) "Given the section, return the class that should be used to represent that section" (let ((section-entry-classes - '((+SHT_NULL+ 'elf-section) - (+SHT_STRTAB+ . 'elf-string-section) - (+SHT_PROGBITS+ . 'elf-section) - (+SHT_NOTES+ 'elf-string-section) - (+SHT_SYMTAB+ 'elf-symbol-section) - (+SHT_REL+ 'elf-relinfo-section) - (+SHT_RELA+ 'elf-relainfo-section)))) + (list (cons +SHT_NULL+ 'elf-section) + (cons +SHT_STRTAB+ 'elf-string-section) + (cons +SHT_PROGBITS+ 'elf-section) + (cons +SHT_NOTE+ 'elf-string-section) + (cons +SHT_SYMTAB+ 'elf-symbol-section) + (cons +SHT_REL+ 'elf-relinfo-section) + (cons +SHT_RELA+ 'elf-relainfo-section)))) (or - (cdr (assoc (slot-value section 'elf-type) section-entry-classes)) + (cdr (assoc (elf-type-of section) section-entry-classes)) 'elf-section))) @@ -181,7 +180,7 @@ "Given an index into a section calclate the offset it represents." (* index (entry-size-of section))) -(defmacro with-real-offset (real-offset-sym ( section index offset) &rest body) +(defmacro with-real-offset (real-offset-sym (section index offset) &rest body) "Use real-offset-sym to represent the actual offset represented by either index or offset into the section in body." (once-only (index) @@ -206,10 +205,10 @@ either index or offset into the section in body." (with-real-offset real-offset (section index offset) (buffered-data-excursion - ((buffered-data-of section) real-offset) + (section real-offset) (read-value (elf-entry-type-of section) - (buffered-data-of section))))) + section)))) ;; -- strings from string sections --------------------------------------------------- @@ -219,8 +218,8 @@ either index or offset into the section in body." ;; you can't index these (assert (and (integerp offset) (null index))) (buffered-data-excursion - ((buffered-data-of section) offset) - (read-value 'asciiz (buffered-data-of section)))) + (section offset) + (read-value 'asciiz section))) (defun make-entry-extractor (elf &key section-index) "Create and return a function to extract an entry from the given section." @@ -330,7 +329,7 @@ either index or offset into the section in body." (let ((string-section-index (e-shstrndx-of (header-of elf)))) (get-entry (aref (sections-of elf) string-section-index) - :offset (sh-name-of (aref (sections-of elf) index))))) + :offset (sh-name-of (header-of (aref (sections-of elf) index)))))) ;; actually read an elf file -------------------------------------------------------- @@ -339,18 +338,11 @@ either index or offset into the section in body." (defmethod initialize-instance :after ((elf elf-file) &key filepath) "Actually read an elf file and process the sections." (labels - ((read-file () - (format *debug-io* "Reading elf file data~%") - (setf (buffered-data-of elf) - (make-instance 'elf-file-data :filepath filepath))) - - (read-header () + ((read-header () "Read and set the elf file header" - (let - ((elf-data (buffered-data-of elf))) - (setf (buffer-pos-of elf-data) 0) - (setf (header-of elf) - (read-value 'elf-header elf-data)))) + (setf (buffer-pos-of elf) 0) + (setf (header-of elf) + (read-value 'elf-header elf))) ;; create n empty sections for each section in the elf file (create-sections (section-count) @@ -359,8 +351,8 @@ either index or offset into the section in body." for section-index from 0 below section-count do (let ((section (make-instance 'elf-section :elf elf :index section-index))) - (change-class section (elf-entry-type-class-of section)) - (vector-push-extend section (sections-of elf))))) + (change-class section (elf-entry-type-class-of section)) + (vector-push-extend section (sections-of elf))))) (set-section-names () (loop @@ -369,11 +361,10 @@ either index or offset into the section in body." (setf (name-of section) (elf-section-name elf section-index)))))) - + ;; defmethod read-elf file - (read-file) + (read-buffered-data elf :filepath filepath) (read-header) - (create-sections (e-shnum-of (header-of elf))) - (set-section-names))) + (create-sections (e-shnum-of (header-of elf))))) diff --git a/elf-rw.lisp b/elf-rw.lisp index 27b4bc2..d3f00fe 100644 --- a/elf-rw.lisp +++ b/elf-rw.lisp @@ -257,15 +257,16 @@ (+ pos advance)))) -(defmethod initialize-instance :after ((self buffered-data-mixin) &key filepath) +(defmethod read-buffered-data ((self buffered-data-mixin) &key filepath) + (format t "Reading buffered data from ~A ~%" filepath) (setf (buffered-data-of self) (read-file-to-usb8-array filepath))) -(defgeneric write-elf-file (data file) +(defgeneric write-buffered-data (data &key filepath) (:documentation "Write the buffered data to the elf file")) -(defmethod write-elf-file ((self buffered-data-mixin) file) - (write-usb8-array-to-file (buffered-data-of self) file)) +(defmethod write-buffered-data ((self buffered-data-mixin) &key filepath) + (write-usb8-array-to-file (buffered-data-of self) filepath)) (defgeneric read-value (type buffered-data-mixin &key &allow-other-keys) diff --git a/elf-test.lisp b/elf-test.lisp index 9796206..aa6119b 100644 --- a/elf-test.lisp +++ b/elf-test.lisp @@ -9,16 +9,19 @@ (make-instance 'elf-file :filepath (merge-pathnames #P"main.o"))) + (e-shstrndx-of (header-of *test-elf-file*)) -(format t "Elf file has ~D sections." (length (sections-of *elf-file*))) +(format t "Elf file has ~D sections." (length (sections-of *test-elf-file*))) (loop for section across (sections-of *test-elf-file*) - do (format t "Section type ~X ~A ~A is ~X bytes long~%" + do (format t "Section type ~X ~A ~A ~A (~A) is ~X bytes long~%" (sh-type-of (header-of section)) (type-of section) (elf-type-of section) + (elf-entry-type-class-of section) + (elf-entry-type-of section) (size-of section))) ;; test code -- 2.11.4.GIT