Output
The annotation ``default:'' indicates the default value
the function returns if nothing in the object that
sassy
assembled affected that particular value. For example, if no align
forms were given in any data
directives, (sassy-data-align <sassy-output>)
returns the default value 4
.
7.1 Record-types
The names of the interfaces for the following data types are conventional. That is, for each of the following types, name is the indicated name of the type (the name in the heading), getter is any getter procedure listed, and
the constructor procedure is
make-
namethe predicate procedure is name
?
the setter procedures are getter
-set!
7.1.1 sassy-output
-- procedure: sassy-symbol-table sassy-output -> hash-table
default: an empty hash-table
The hash-table contains one entry for each of the symbols present in the object thatsassy
assembled. The keys of the hash-table are Scheme symbols. The values are records of type sassy-symbol.-- procedure: sassy-reloc-list sassy-output -> list
default:
'()
The list contains all the relocations thatsassy
recorded. Each relocation is a record of type sassy-reloc.-- procedure: sassy-entry-point sassy-output -> symbol
default:
#f
The symbol indicates the main entry point of the program.-- procedure: sassy-data-stack sassy-output -> pushdown-stack
-- procedure: sassy-text-stack sassy-output -> pushdown-stackdefault: an empty pushdown-stack
The pushdown-stacks contain the contents (bytes, represented as positive integers) of their respective sections. Wherever appropriate, byte-representations of numerical arguments and data are in little-endian order.-- procedure: sassy-heap-size sassy-output -> integer
default:
0
The integer is the total size of the heap, in bytes.-- procedure: sassy-text-org sassy-output -> integer
default:
0
The integer is the absolute address at which the text section should be loaded.For the following, if no
align
forms were designated for the appropriate section, or no alignments greater than the default value were designated, the default value is present. Otherwise the largest value that was specified for the appropriate section is present. In all cases, the integers present will be a positive power of 2, and indicate the alignment requirements, in bytes, of the particular section.-- procedure: sassy-heap-align sassy-output -> integer
-- procedure: sassy-data-align sassy-output -> integerdefault:
4
-- procedure: sassy-text-align sassy-output -> integer
default:
16
7.1.2 sassy-symbol
-- procedure: sassy-symbol-name sassy-symbol -> symbol
default: symbol
The symbol is the name of the symbol or label.-- procedure: sassy-symbol-scope sassy-symbol -> scope
default:
'local
The scope is either'local
,'import
, or'export
. (In the following, ``object'' means object-file, module, unit of compilation, etc.)A scope of
'local
is meant to denote a symbol declared in the current object that other objects will not link to.A scope of
'import
is meant to denote a symbol declared in another object that the current object will link to. (Other assemblers use a term like ``extern'' for these.)A scope of
'export
is meant to denote a symbol declared in the current object that other objects will link to. (Other assemblers refer to these as, for instance ``global''.)
The meaning of ``declared'' in regards to these can be fuzzy. For instance, when writing ELF shared objects, one exports the symbol
_GLOBAL_OFFSET_TABLE_
, even though that symbol is never assigned a location in the Sassy program itself. Instead the linkerld
``fully declares'' it.-- procedure: sassy-symbol-section sassy-symbol -> section
-- procedure: sassy-symbol-offset sassy-symbol -> integer
-- procedure: sassy-symbol-size sassy-symbol -> integerdefault:
#f
If any of these are#f
, then they all are#f
. This means that the symbol was never declared (assigned a location) in the object. This happens, for instance, when youimport
a symbol.The section is either
'text
,'data
, or'heap
, and indicates the section in which the symbol was defined.The offset indicates the offset in bytes from the base of the symbol's section to the symbol's definition.
The size indicates the size in bytes of the items encapsulated by the symbol's definition.
-- procedure: sassy-symbol-unres sassy-symbol -> list
default:
'()
The list is a list of functions used internally by Sassy to perform backpatching. You may safely ignore (the contents of) this field.7.1.3 sassy-reloc
-- procedure: sassy-reloc-name sassy-reloc -> symbol
default:
#f
This returns the name of the label, or ``target'' that this relocation refers to. If this value is#f
, the relocation is ``anonymous''. Usages of$win
,$lose
,$eip
, andlocals
may cause this. As well, the second argument in a custom relocation affects this value.-- procedure: sassy-reloc-section sassy-reloc -> section
default: the section
This is the section in which to apply the relocation ('text
or'data
).-- procedure: sassy-reloc-offset sassy-reloc -> integer)
default:
0
This is the offset from the base of the section, in bytes, of the relocation's field (i.e. the address at which to apply the relocation).-- procedure: sassy-reloc-type sassy-reloc -> symbol
default: all relocations have a type
The type of a relocation is a symbol that should be used to instruct the output module how to compute the final value in the relocation's field. By default, Sassy utilizes two types:'abs
relocations are meant to denote those whose final value in their field should be:(+ <the load address of the target's section> <the target's offset into it's section>)
'rel
relocations are meant to denote those whose final value in their field is some relative offset from the address of the relocation's field. Sassy generates these for normal usages of branch instructions, and the value present is the distance to the target from the address immediately following the relocation's field.
Or the type may be one specified by a usage of a custom relocation, and will be output module-specific. For instance, when targeting the included ELF output module, one can write
(reloc plt foo)
, which means that the type of the relocation will be'plt
, and that the ELF output module should make an entry in the object-file's relocation table of typeR_386_PLT32
.-- procedure: sassy-reloc-patcher sassy-reloc -> procedure
default: always present
The procedure is a procedure of one argument, an integer. When applied, the procedure does two things - it changes the value of the relocation's field in the appropriate push-stack (or its list) to be the little-endian byte representation of the integer, and it updates the reloc-value field of the relocation's record with the integer.-- procedure: sassy-reloc-value sassy-reloc -> integer
default:
0
The value is the integer representation of the field's current value. It is automatically updated by the application of the relocation's patcher function. The third argument in a custom relocation is added to the value otherwise present.-- procedure: sassy-reloc-width sassy-reloc -> integer
default:
.4
The width is the width, in bytes, of the relocation field. Currently, since Sassy only records dword-sized relocations, this value is always 47.2 Additional procedures for sassy-output
The following are extra procedures for accessing sassy-output. They are external to the record-type definition of sassy-output.
-- procedure: sassy-data-list sassy-output -> list-of-bytes
-- procedure: sassy-text-list sassy-output -> list-of-bytesdefault:
'()
Returns the actual list-of-bytes that comprise the exact contents of the text or data sections. The bytes are expressed as positive integers, and wherever appropriate, numerical arguments and data are in little-endian order.-- procedure: sassy-text-size sassy-output -> integer
-- procedure: sassy-data-size sassy-output -> integerdefault:
0
The integer indicates the total size in bytes of the contents of the text or data sections.-- procedure: sassy-symbol-exists? sassy-output symbol -> varies
If symbol is present in sassy-output, its record (of type sassy-symbol) in the symbol table is returned. Otherwise
#f
is returned.7.3 push-stacks
Push-stacks are wrappers around Scheme lists that create stack-like objects that normally can only grow. They can not be popped (but their state may be saved and restored). Push-stacks are built for speed but BEWARE! Pushing a list onto a push-stack calls set-cdr! either on the stack or the list, so don't push quoted (literal) lists onto a push-stack or infinite loops may eventually occur!2
As well, mutating a list after it has been pushed on to a push-stack will mutate the stack as well. This is on purpose, since pushing onto a push-stack returns the pointer to the pushed item in the stack. By saving that pointer (a list) you can mutate the contents of a push-stack as fast as you can mutate a vector, even if the push-stack gets appended! to another.
Sassy uses push-stacks for its sequence-type accumulators (the data section and text section) because they provide:
linear time accumulation of items (like a vector)
constant time access to the contents for mutation (like a vector)
dynamic growth in size with basically zero overhead (unlike a vector)
constant time splicing of sequences together (unlike a vector)
-- procedure: make-pushdown-stack -> push-stack
-- procedure: make-pushup-stack -> push-stackThese return an empty push-stack.
Make-pushdown-stack
returns a push-stack that grows upwards. New items are added to its last tail.Make-pushup-stack
returns a push-stack that grows downwards. New items are added to its head.-- procedure: push-stack-empty? push-stack -> boolean
-- procedure: push-stack-push push-stack object -> pointer
Pushes object on to the push-stack. The object may be anything except an improper list. If the object is a proper list, the list is spliced to the push-stack's head or last tail, depending on the growth direction of the push-stack. If the object is the empty-list, nothing is pushed. The pointer returned is the pair that contains the first item of object in the push-stack.
-- procedure: push-stack-pointer push-stack -> pointer
The pointer is the pair that is the head or last tail of the push-stack, depending on the push-stack's direction.
-- procedure: push-stack-items push-stack -> list
Returns the list of items in the push-stack.
-- procedure: push-stack-patch push-stack pointer object
Replaces items in push-stack starting at pointer with object, which may be anything except an improper list. If object is a proper list, as many items are replaced as the number of items in the list, with items in the list. Otherwise, the object replaces one item.
-- procedure: push-stack-push->patcher push-stack object -> procedure
Pushes object on to the push-stack and returns a procedure of one argument, that when applied, replaces the object in the push-stack with its argument. That is:
(let ((ptr (push-stack-push push-stack object))) (lambda (new-object) (push-stack-patch push-stack ptr new-object)))
-- procedure: push-stack-save push-stack -> thunk
Encapsulates the state of push-stack in thunk. Applying thunk restores the push-stack to the saved state. After thunk is applied any pointers to objects pushed after a save and before the restore will no longer point in to the push-stack.
-- procedure: push-stack-direction push-stack -> direction
Returns a symbol indicating the direction of growth of the push-stack. If push-stack was created by
make-pushdown-stack
, then'up
is returned. Otherwise'down
is returned.-- procedure: push-stack-size push-stack -> integer
Returns the number of single items in push-stack.
-- procedure: push-stack-append! push-stack1 push-stack2
Effectively appends! the contents of push-stack2 to the last tail of push-stack1, regardless of the growth direction of each push-stack. It is an error to append! the same push-stacks more than once, in any order.
-- procedure: push-stack-align push-stack align fill [offset]
Pushes fill, which may be anything except a pair, on to push-stack as many times as necessary such that the following is true:
(zero? (modulo (push-stack-size push-stack) align))
If the optional offset is provided, than instead the following formula is used:
(zero? (modulo (+ offset (push-stack-size push-stack)) align))
7.4 Utilities
The following are useful for displaying information.
-- procedure: sassy-hexdump list-of-bytes
Displays the list-of-bytes in the ``canonical'' format, just as if using
hexdump -C
on Unix. Useful for viewing the results returned by the proceduressassy-text-list
orsassy-data-list
.-- procedure: sassy-print-symbols sassy-output
-- procedure: sassy-print-relocs sassy-outputThese procedures display formatted listings of all the information for each symbol or relocation in sassy-output. If the value in a field is
#f
, these procedures display the string``#<undefined>''
.2 I mention this because some Schemes are apparently lax about the mutation of parts of literal lists.