mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Roc linker library base setup
This commit is contained in:
parent
d5058041b0
commit
c6217ebfdb
10 changed files with 151 additions and 0 deletions
19
Cargo.lock
generated
19
Cargo.lock
generated
|
@ -2219,6 +2219,16 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.7.2"
|
||||
|
@ -3296,6 +3306,15 @@ dependencies = [
|
|||
name = "roc_ident"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "roc_linker"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"clap 3.0.0-beta.1",
|
||||
"object 0.26.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roc_load"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -32,6 +32,7 @@ members = [
|
|||
"cli/cli_utils",
|
||||
"roc_std",
|
||||
"docs",
|
||||
"linker",
|
||||
]
|
||||
exclude = [ "ci/bench-runner" ]
|
||||
# Needed to be able to run `cargo run -p roc_cli --no-default-features` -
|
||||
|
|
24
linker/Cargo.toml
Normal file
24
linker/Cargo.toml
Normal file
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "roc_linker"
|
||||
version = "0.1.0"
|
||||
authors = ["The Roc Contributors"]
|
||||
license = "UPL-1.0"
|
||||
repository = "https://github.com/rtfeldman/roc"
|
||||
edition = "2018"
|
||||
description = "A surgical linker for Roc"
|
||||
|
||||
[lib]
|
||||
name = "roc_linker"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "link"
|
||||
path = "src/main.rs"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
# TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it
|
||||
clap = { git = "https://github.com/rtfeldman/clap", branch = "master" }
|
||||
object = { version = "0.26", features = ["read"] }
|
||||
bumpalo = { version = "3.6.1", features = ["collections"] }
|
31
linker/README.md
Normal file
31
linker/README.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
# The Roc Surgical Linker
|
||||
|
||||
This linker has the goal of being extremely slim lined and fast.
|
||||
It is focused on the scope of only linking platforms to Roc applications.
|
||||
This restriction enables ignoring most of linking.
|
||||
|
||||
## General Overview
|
||||
|
||||
This linker is run in 2 phases: preprocessing and surigical linking.
|
||||
|
||||
### Platform Preprocessor
|
||||
|
||||
1. Dynamically link the platform to a dummy Roc application dynamic library
|
||||
1. Create metadata related to Roc dynamically linked functions
|
||||
- Symbols that need to be redefined
|
||||
- Call locations that need to be modified for each symbol
|
||||
- Locations of special roc functions (roc_alloc, roc_dealloc, builtins, etc)
|
||||
1. Modify the main executable to no longer be dynamically link
|
||||
- Delete dependency on dynamic library
|
||||
- Remove symbols from the dynamic table (maybe add them to the regular table?)
|
||||
- Delete GOT and PLT entries
|
||||
- Remove relocations from the dynamic table
|
||||
- Add extra header information about new text and data section at end of file
|
||||
|
||||
### Surgical Linker
|
||||
|
||||
1. Copy over preprocessed platform as base
|
||||
1. Append text and data of application, noting offset
|
||||
- This could potentially have extra complication around section locations and updating the header
|
||||
1. Surgically update all call locations in the platform
|
||||
1. Surgically update call information in the application (also dealing with other relocations for builtins)
|
34
linker/src/lib.rs
Normal file
34
linker/src/lib.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use clap::{App, AppSettings, Arg};
|
||||
use std::io;
|
||||
|
||||
pub const CMD_PREPROCESS: &str = "preprocess";
|
||||
pub const CMD_SURGERY: &str = "surgery";
|
||||
pub const EXEC: &str = "EXEC";
|
||||
pub const SHARED_LIB: &str = "SHARED_LIB";
|
||||
|
||||
pub fn build_app<'a>() -> App<'a> {
|
||||
App::new("link")
|
||||
.about("Preprocesses a platform and surgically links it to an application.")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
App::new(CMD_PREPROCESS)
|
||||
.about("Preprocesses a dynamically linked platform to prepare for linking.")
|
||||
.arg(
|
||||
Arg::with_name(EXEC)
|
||||
.help("The dynamically link platform executable")
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(SHARED_LIB)
|
||||
.help("The dummy shared library representing the Roc application")
|
||||
.required(true),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
App::new(CMD_SURGERY).about("Links a preprocessed platform with a Roc application."),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn preprocess() -> io::Result<()> {
|
||||
panic!("sad");
|
||||
}
|
17
linker/src/main.rs
Normal file
17
linker/src/main.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use roc_linker::{build_app, preprocess, CMD_PREPROCESS, CMD_SURGERY};
|
||||
use std::io;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let matches = build_app().get_matches();
|
||||
|
||||
let exit_code = match matches.subcommand_name() {
|
||||
None => Ok::<i32, io::Error>(-1),
|
||||
Some(CMD_PREPROCESS) => {
|
||||
preprocess()?;
|
||||
Ok(0)
|
||||
}
|
||||
Some(CMD_SURGERY) => Ok(0),
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
std::process::exit(exit_code);
|
||||
}
|
1
linker/tests/.gitignore
vendored
Normal file
1
linker/tests/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.so
|
12
linker/tests/Makefile
Normal file
12
linker/tests/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
SHLIB_LDFLAGS = -shared -Wl,--allow-shlib-undefined
|
||||
|
||||
all: platform
|
||||
|
||||
platform: platform.c libapp.so
|
||||
$(CC) -O2 -fPIC -o $@ $^
|
||||
|
||||
libapp.so: app.c
|
||||
$(CC) -O2 -fPIC -shared -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f platform libapp.so
|
3
linker/tests/app.c
Normal file
3
linker/tests/app.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void app() { printf("Hello World from the application"); }
|
9
linker/tests/platform.c
Normal file
9
linker/tests/platform.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void app();
|
||||
|
||||
int main() {
|
||||
printf("Hello World from the platform");
|
||||
app();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue