2019-11-27 09:18:17 -05:00
|
|
|
|
// TAME linker library
|
|
|
|
|
//
|
2021-07-22 15:00:15 -04:00
|
|
|
|
// Copyright (C) 2014-2021 Ryan Specialty Group, LLC.
|
2020-03-06 11:05:18 -05:00
|
|
|
|
//
|
|
|
|
|
// This file is part of TAME.
|
2019-11-27 09:18:17 -05:00
|
|
|
|
//
|
|
|
|
|
// 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/>.
|
|
|
|
|
|
2020-02-26 11:26:15 -05:00
|
|
|
|
//! Combine [object files](crate::obj) into a final executable.
|
2019-12-10 00:33:53 -05:00
|
|
|
|
//!
|
2020-02-26 11:26:15 -05:00
|
|
|
|
//! It's user-facing binary is [`tameld`](../../tameld).
|
2019-12-10 00:33:53 -05:00
|
|
|
|
//!
|
2020-02-26 11:26:15 -05:00
|
|
|
|
//!
|
|
|
|
|
//! Background Information
|
|
|
|
|
//! ======================
|
|
|
|
|
//! A [linker][] is responsible for combining individually compiled
|
|
|
|
|
//! [object files](crate::obj) containing relocatable code into a final
|
|
|
|
|
//! executable.
|
|
|
|
|
//! This involves putting the compiled code fragments into the right order
|
|
|
|
|
//! and into the right place within the executable.
|
2019-12-10 00:33:53 -05:00
|
|
|
|
//!
|
|
|
|
|
//! [linker]: https://en.wikipedia.org/wiki/Linker_(computing)
|
|
|
|
|
//!
|
2020-02-26 11:26:15 -05:00
|
|
|
|
//! _See below for more information on why this linker currently produces
|
|
|
|
|
//! another intermediate format (`xmle`) rather than a final executable._
|
|
|
|
|
//!
|
|
|
|
|
//! The type of relocatable code depends on the _target_.
|
|
|
|
|
//! Currently, the only target is JavaScript.
|
|
|
|
|
//!
|
|
|
|
|
//!
|
|
|
|
|
//! Backwards-Compatibility With XSLT System
|
2019-12-10 00:33:53 -05:00
|
|
|
|
//! -------------------------------------
|
|
|
|
|
//! This linker is part of the TAMER (TAME in Rust) project,
|
|
|
|
|
//! which aims to incrementally rewrite TAME in Rust.
|
|
|
|
|
//! Consequently, it must be able to serve as a drop-in replacement for the
|
|
|
|
|
//! existing (XSLT) linker,
|
|
|
|
|
//! which takes as input `xmlo` files and produces as output an `xmle`
|
|
|
|
|
//! file.
|
|
|
|
|
//! *This is not efficient*,
|
|
|
|
|
//! and future versions will begin to migrate away from this strategy.
|
|
|
|
|
//!
|
|
|
|
|
//! The output `xmle` file can then be fed to a `standalone` command which
|
|
|
|
|
//! extracts the JavaScript fragment and places it into its own file.
|
|
|
|
|
//! Even when that is replaced
|
|
|
|
|
//! (when this just outputs a final JS file directly),
|
|
|
|
|
//! the `xmle` file is still needed for other purposes,
|
|
|
|
|
//! such as `summary` and `dote` generation.
|
|
|
|
|
//! Those too will eventually be linker targets.
|
2020-02-26 11:26:15 -05:00
|
|
|
|
//!
|
|
|
|
|
//!
|
|
|
|
|
//! Linking Process
|
|
|
|
|
//! ===============
|
|
|
|
|
//! The linker works in the following steps:
|
|
|
|
|
//!
|
|
|
|
|
//! 1. [Object files](crate::obj) are recursively read.
|
|
|
|
|
//! They are used in a streaming manner for the next step of the
|
|
|
|
|
//! process;
|
|
|
|
|
//! they do not persist in memory.
|
|
|
|
|
//! Only the required portions of the file are loaded.
|
|
|
|
|
//! See the [Legacy IR](crate::ir::legacyir) for more information.
|
|
|
|
|
//!
|
|
|
|
|
//! 2. This information is used to populate the [ASG].
|
|
|
|
|
//! Information is added to the graph as it is discovered during object
|
|
|
|
|
//! file loading,
|
|
|
|
|
//! so the graph initially contains edges to missing identifiers.
|
|
|
|
|
//! Expressions are _not_ added to the graph,
|
|
|
|
|
//! as they are not needed for linking.
|
|
|
|
|
//! Once all data are loaded,
|
|
|
|
|
//! the ASG contains relocatable code fragments for each identifier.
|
|
|
|
|
//!
|
|
|
|
|
//! 3. The ASG is [sorted topologically][topo-sort] so that dependencies
|
|
|
|
|
//! will be written to the executable file before identifiers that
|
|
|
|
|
//! depend on them.
|
|
|
|
|
//! Roots for the sort are specified by the return map.
|
|
|
|
|
//! _Identifiers that are not accessable from one of those roots will be
|
|
|
|
|
//! omitted from the executable output._
|
|
|
|
|
//!
|
|
|
|
|
//! 4. Relocatable code fragments are output into various sections in the
|
|
|
|
|
//! executable file.
|
|
|
|
|
//! This output file is currently `xmle`.
|
|
|
|
|
//! (**TODO**: Link to new `xmle` crate.)
|
|
|
|
|
//!
|
|
|
|
|
//! [ASG]: crate::ir::asg
|
|
|
|
|
//! [topo-sort]: https://en.wikipedia.org/wiki/Topological_sorting
|
|
|
|
|
//!
|
|
|
|
|
//! Steps 1 and 2 are performed at the same time:
|
|
|
|
|
//! object files are used to immediately populate the [ASG][].
|
|
|
|
|
//! Since the ASG contains only partial information,
|
|
|
|
|
//! it must perform other validations (such as extern resolution) during
|
|
|
|
|
//! this process;
|
|
|
|
|
//! see [crate::ir::asg] for more information.
|
|
|
|
|
//!
|
|
|
|
|
//! Because the topological sort only considered explicitly defined roots,
|
|
|
|
|
//! identifiers are only included in the final executable if they are
|
|
|
|
|
//! either a root or are a dependency of a root.
|
|
|
|
|
//! This makes it possible to create large reusable packages without
|
|
|
|
|
//! incurring a runtime cost for unused objects,
|
|
|
|
|
//! which is especially important since templates may expand into many
|
|
|
|
|
//! identifiers.
|
2019-12-10 00:33:53 -05:00
|
|
|
|
|
2021-09-28 14:52:31 -04:00
|
|
|
|
use crate::span::Span;
|
|
|
|
|
use crate::sym::st16;
|
|
|
|
|
|
2019-11-27 09:18:17 -05:00
|
|
|
|
pub mod poc;
|
2021-09-28 14:52:31 -04:00
|
|
|
|
|
|
|
|
|
/// Span denoting a general linker operation.
|
|
|
|
|
///
|
|
|
|
|
/// This span may be used when the source of a given object is the linker
|
|
|
|
|
/// and it is not possible to derive a more useful span.
|
|
|
|
|
pub const LSPAN: Span = Span::st_ctx(st16::CTX_LINKER);
|