mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-30 00:40:20 +02:00
* module/Makefile.am: Add language/sassy.scm. Probably EXTRA_DIST the dependant files, too. * module/language/sassy.scm: New file, the sassy loader. Sassy is originally R5RS code that loads a number of files. I've converted that toplevel file to be a Guile module that *includes* the subfiles, so that it all gets compiled together. It's a pretty bad hack though, because what I should be doing is including them relative to the sassy.scm source location, but we don't know that at expansion time. Something to fix. really bad hack in it so that it will compile correctly -- p * module/language/sassy/: All the sassy files and some changelog information. All of these files are LGPLv2.1+, so they can be included in Guile. * test-suite/standalone/sassy/tests/: Add the sassy unit tests. * test-suite/standalone/Makefile.am: * test-suite/standalone/test-sassy: Hook the sassy unit tests up to our test suite.
163 lines
5.5 KiB
Scheme
163 lines
5.5 KiB
Scheme
; flat-bin.scm - create bin files from Sassy's output
|
|
; Copyright (C) 2005 Jonathan Kraut
|
|
|
|
; This library is free software; you can redistribute it and/or
|
|
; modify it under the terms of the GNU Lesser General Public
|
|
; License as published by the Free Software Foundation; either
|
|
; version 2.1 of the License, or (at your option) any later version.
|
|
|
|
; This library is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
; Lesser General Public License for more details.
|
|
|
|
; You should have received a copy of the GNU Lesser General Public
|
|
; License along with this library; if not, write to the Free Software
|
|
; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
; Contact:
|
|
; Jonathan Kraut
|
|
; 4130 43 ST #C2
|
|
; Sunnyside, NY 11104
|
|
; jak76@columbia.edu
|
|
|
|
; see file COPYING in the top of Sassy's distribution directory
|
|
|
|
|
|
; module flat-bin
|
|
; import api
|
|
; export all
|
|
|
|
|
|
|
|
; This is a good demonstration of how to use the output API, and we
|
|
; should probably include it in chapter 7 of the docs.
|
|
|
|
; usage:
|
|
|
|
; procedure:
|
|
; (sassy-make-bin output-file sassy-output opts ...) => unspecified
|
|
|
|
; Combines the text and data sections of sassy-output and writes a
|
|
; flat binary file to output-file. If the file already exists it is
|
|
; deleted. Any (org) directive is taken into account, and relocations
|
|
; are performed on absolute references in the data section. The data
|
|
; segment is placed (and aligned properly) immediately after the text
|
|
; segment.
|
|
|
|
; opts can be none, one or both of the following quoted symbols:
|
|
|
|
; 'boot : Make the file be an x86 boot-sector. That is, zero-fill the
|
|
; remainder of the file to 510 bytes, and add the x86 boot-sector
|
|
; signature #x55aa to bytes 511 and 512.
|
|
|
|
; 'stats : Display some stats about the output.
|
|
|
|
|
|
|
|
(define (sassy-make-bin output-file sassy-output . opts)
|
|
|
|
(define boot-sector? (memq 'boot opts))
|
|
(define stats? (memq 'stats opts))
|
|
|
|
(define data? (not (zero? (sassy-data-size sassy-output))))
|
|
|
|
; Grap some info for printout stats later.
|
|
|
|
(define text-size (sassy-text-size sassy-output))
|
|
(define data-size (sassy-data-size sassy-output))
|
|
(define text-pad 0)
|
|
|
|
(define (display-stat . itms)
|
|
(for-each display itms)
|
|
(newline))
|
|
|
|
(define (needed-reloc? x)
|
|
(and (eq? 'abs (sassy-reloc-type x))
|
|
(let ((name (sassy-reloc-name x)))
|
|
(if name
|
|
(let ((symbol (sassy-symbol-exists? sassy-output name)))
|
|
(and (eq? 'data (sassy-symbol-section symbol))
|
|
(not (eq? 'import (sassy-symbol-scope symbol)))))
|
|
(eq? 'data (sassy-reloc-section x))))))
|
|
|
|
; Align the end of the text-section to the align of the data section.
|
|
; The data section will begin at this point in the file.
|
|
; (nop) is used as the filler.
|
|
|
|
(when data?
|
|
(push-stack-align (sassy-text-stack sassy-output)
|
|
(sassy-data-align sassy-output)
|
|
#x90))
|
|
|
|
(set! text-pad (- (sassy-text-size sassy-output) text-size))
|
|
|
|
; Since the text-section is going to be loaded at whatever the given
|
|
; (org) was, all absolute relocations in the text section that refer
|
|
; to other locations in the text section already have the offset of
|
|
; (org) added to them, so we don't have to apply relocations to
|
|
; those. And we don't need to relocate relative addresses in the
|
|
; text section (and relative relocations aren't allowed in the data
|
|
; section).
|
|
|
|
; So, we only need to relocate references to symbols defined in the data
|
|
; section, or anonymous relocs in the data section
|
|
|
|
; Also, we need to grab all those references both from the
|
|
; text-section _and_ the _data_ section
|
|
|
|
(when data?
|
|
(let ((data-relocs-to-do
|
|
(filter needed-reloc? (sassy-reloc-list sassy-output))))
|
|
|
|
; Now we get ready to apply the relocations taking into account the new
|
|
; end of the text-section (or beginning of the data-section).
|
|
|
|
; For each reloc-to-do, we're going to apply it's patcher
|
|
; to the the data-offset plus the value already there
|
|
|
|
(let* ((text-offset (sassy-text-org sassy-output))
|
|
(data-offset (+ text-offset (sassy-text-size sassy-output))))
|
|
(for-each (lambda (reloc)
|
|
((sassy-reloc-patcher reloc)
|
|
(+ data-offset (sassy-reloc-value reloc))))
|
|
data-relocs-to-do))
|
|
|
|
; Now all we have to to is append the data to the text, mark it as
|
|
; a boot sectior, and spit it out.
|
|
|
|
; The fastest way to tack a data section on to a text section is
|
|
; the following
|
|
; !!!!NOTE: This actually alters the text section (append!)
|
|
(push-stack-append! (sassy-text-stack sassy-output)
|
|
(sassy-data-stack sassy-output))))
|
|
|
|
(when boot-sector?
|
|
; sanity check
|
|
(if (> (sassy-text-size sassy-output) 510)
|
|
(error "segment too big for a boot sector")
|
|
(begin
|
|
; mark it as a boot sector
|
|
(push-stack-align (sassy-text-stack sassy-output) 510 0)
|
|
(push-stack-push (sassy-text-stack sassy-output)
|
|
(list #x55 #xaa)))))
|
|
|
|
; dump to file
|
|
(when (file-exists? output-file)
|
|
(delete-file output-file))
|
|
(with-output-to-file output-file
|
|
(lambda ()
|
|
(for-each write-byte (sassy-text-list sassy-output))))
|
|
|
|
(when stats?
|
|
(display-stat "Text size: " text-size " bytes")
|
|
(display-stat "Data size: " data-size " bytes")
|
|
(display-stat "Data align: "
|
|
(sassy-data-align sassy-output)
|
|
" byte boundary")
|
|
(display-stat
|
|
"Total size: "
|
|
(+ text-size data-size text-pad)
|
|
" bytes, with " text-pad " bytes of padding in the text section.")
|
|
(when boot-sector?
|
|
(display-stat "Made a boot sector"))))
|