Linking¶
This chapter describes how linking objects before runtime works. Linking
functionality can be found in dlink.c
and dlink.h
.
Decision is a compiled language, and you compile individual sheets into their respective objects. Most of the time you will want to just run a sheet straight from the terminal. But sometimes, especially if the sheet is very big, it may be worth your while to compile the sheet into an object file to increase performance (since it doesn’t compile the program every time).
The fact that you can compile a sheet to an object file is the reason why
we need to link. Every time you load an object from an object file in memory,
it is very likely that it will not be places into the same memory address
every time. So, we will need to change where the instructions in the .text
section point to, and that is exactly what we do when linking.
Object Sections¶
Objects have 2 sections that are purely used for linking:
.lmeta
A list of
LinkMeta
, where eachLinkMeta
describes a thing like a variable, function, or string literal, and where you can find it (if it’s defined on the same sheet).
.link
A table of instruction indexes and which
LinkMeta
they link to.
Structures¶
LinkType
An enum which describes what kind of thing a link points to, whether it be a variable, function, or something else.
LinkMeta
A struct that describes a link. It includes a
LinkType
, and theconst char*
name of the item it is linking to. In the case of string literals, the name is the content of the literal. It also contains a genericvoid*
pointer that is designed to point to a struct that contains metadata for the object being linked to, i.e. aSheetVariable
orSheetFunction
. It also contains a genericchar*
pointer which serves different purposes depending on what theLinkType
is:
If it is a link to an item in the object’s own
.data
section, the pointer’s value is the starting index of the item in the.data
section.If it is a link to an item in the object’s own
.text
section, the pointer’s value is the starting index of the item in the.text
section.
LinkMetaList
A struct that is a list of
LinkMeta
.
Functions¶
-
LinkMeta
d_link_new_meta
(LinkType type, const char *name, void *meta) Create a new LinkMeta structure.
- Return
A new
LinkMeta
with the given parameters.- Parameters
type
: The type of object this link will point to.name
: The name of the object this link will point to.meta
: A pointer to the metadata of the object the link points to.
LinkMetaList
by itself has a few helper functions to help create it, free
it, and to manipulate it’s contents:
-
LinkMetaList
d_link_new_meta_list
() Create an empty LinkMetaList.
- Return
An empty LinkMetaList.
-
void
d_link_meta_list_push
(LinkMetaList *list, LinkMeta item) Add a LinkMeta item to a list.
- Parameters
list
: The list to push the item onto.item
: The item to push onto.
-
void
d_link_free_list
(LinkMetaList *list) Free a LinkMetaList object.
- Parameters
list
: The list to free.
-
void
d_link_replace_fimmediate
(char *ins, char *ptr) Change an instruction’s full immediate to point somewhere.
NOTE: If you don’t like the fact that you can’t run 32-bit Decision code on 64-bit machines and vice versa, blame it on this function.
- Parameters
ins
: A pointer to first byte of the instruction.ptr
: The memory address for the instruction to load.
This function is what actually changes the instructions in .text
to point
to the correct items. Since we use pointers to set links, the instructions
need to load either 32-bit or 64-bit addresses into a register. This is always
done with a PUSHF
combination.
-
void
d_link_self
(struct _sheet *sheet) Link a sheet’s properties from itself to itself and included sheets.
- Parameters
sheet
: The sheet to link.
Takes a compiled sheet, gets the information it needs to link from the
.lmeta
and .link
sections, and uses it to call
d_link_replace_fimmediate
to replace all of the instructions that need
linking.