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
(sassy-data-align <sassy-output>) returns the default value
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
the predicate procedure is name
the setter procedures are getter
default: an empty hash-table
The hash-table contains one entry for each of the symbols present in the object that
sassyassembled. The keys of the hash-table are Scheme symbols. The values are records of type sassy-symbol.
The list contains all the relocations that
sassyrecorded. Each relocation is a record of type sassy-reloc.
The symbol indicates the main entry point of the program.
default: 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.
The integer is the total size of the heap, in bytes.
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
The symbol is the name of the symbol or label.
The scope is either
'export. (In the following, “object” means object-file, module, unit of compilation, etc.)
A scope of
'localis meant to denote a symbol declared in the current object that other objects will not link to.
A scope of
'importis 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
'exportis 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 linker
ld“fully declares” it.
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 you
The section is either
'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.
The list is a list of functions used internally by Sassy to perform backpatching. You may safely ignore (the contents of) this field.
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
localsmay cause this. As well, the second argument in a custom relocation affects this value.
default: the section
This is the section in which to apply the relocation (
default: the section
Returns the name of the section (
'heap) in which the target of the relocation is defined.
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).
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:
'absrelocations 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>)
'relrelocations 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 type
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.
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.
The width is the width, in bytes, of the relocation field. Currently, since Sassy only records dword-sized relocations, this value is always 4
The following are extra procedures for accessing sassy-output. They are external to the record-type definition of sassy-output.
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.
The integer indicates the total size in bytes of the contents of the text or data sections.
If symbol is present in sassy-output, its record (of type sassy-symbol) in the symbol table is returned. Otherwise
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!1
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)
These return an empty push-stack.
Make-pushdown-stackreturns a push-stack that grows upwards. New items are added to its last tail.
Make-pushup-stackreturns a push-stack that grows downwards. New items are added to its head.
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.
The pointer is the pair that is the head or last tail of the push-stack, depending on the push-stack’s direction.
Returns the list of items in the push-stack.
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.
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)))
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.
Returns a symbol indicating the direction of growth of the push-stack. If push-stack was created by
'upis returned. Otherwise
Returns the number of single items in push-stack.
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.
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))
The following are useful for displaying information.
Displays the list-of-bytes in the “canonical” format, just as if using
hexdump -Con Unix. Useful for viewing the results returned by the procedures
These 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
1 I mention this because some Schemes are apparently lax about the mutation of parts of literal lists.