This patch implements the behaviour of the SECTIONS linker script directive,
used to define a custom mapping between input and output sections. Not all
sections constructs are currently supported, but only the ones that do not
use wildcard matching to define section names and that does not sort or use
any other special feature. This patch also adds support for the evaluation of
linker scripts expressions when used to define a new address for an output
section. I added a LIT test as a practical example of which sections
directives are currently supported.
The strategy employed here to change the layout of the output file based on
the linker script file was based on a suggestion by Shankar and involves
using "rule ids".
We start by assigning each linker script "rule" (a mapping between input and
output section) a "rule id" in an incremental fashion: the first rules have
the lowest ids. Afterwards, in the ELF reader, when creating ELF defined atoms,
I check from which input file and input section this file came from, try to
match a linker script rule against it and assign it a "rule id". When done
reading, we should have a "rule id" for each atom, which is essentially a
different "ordinal" number, but crafted in terms of what the linker script
thinks the order should be.
In terms of high-level changes, I created a new class "script::Sema" that owns
all linker script ASTs and the logic for linker script semantics as well.
ELFLinkingContext owns a single copy of Sema, which will be used throughout
the object file reading process (to assign rule ids to atoms) and writing
process (to layout sections as proposed by the linker script).
Other high-level change is that the writer no longer uses a "const" copy of
the linking context. This happens because linker script expressions must be
calculated *while* calculating final virtual addresses, which is a very late
step in object file writing. While calculating these expressions, we need to
update the linker script symbol table (inside the semantics object), and, thus,
we are "modifying our context" as we prepare to write the file.