..
    Decision
    Copyright (C) 2019-2020  Benjamin Beddows

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

.. _linking:

*******
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 each ``LinkMeta`` 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 the
    ``const 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
    generic ``void*`` pointer that is designed to point to a struct that
    contains metadata for the object being linked to, i.e. a ``SheetVariable``
    or ``SheetFunction``. It also contains a generic ``char*`` pointer which
    serves different purposes depending on what the ``LinkType`` 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
#########

.. doxygenfunction:: d_link_new_meta
   :no-link:

``LinkMetaList`` by itself has a few helper functions to help create it, free
it, and to manipulate it's contents:

.. doxygenfunction:: d_link_new_meta_list
   :no-link:

.. doxygenfunction:: d_link_meta_list_push
   :no-link:

.. doxygenfunction:: d_link_free_list
   :no-link:

.. doxygenfunction:: d_link_replace_fimmediate
   :no-link:

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.

.. doxygenfunction:: d_link_self
   :no-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.