Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translating RISC-V programs directly from ELF files. #1453

Merged
merged 108 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
bc8e5c1
Attempt to make vec_median a binary.
lvella May 22, 2024
2544ec3
Missing moved file.
lvella May 22, 2024
e750285
works
leonardoalt May 22, 2024
6050592
Starting implementation of instructions lifting.
lvella May 22, 2024
424115f
Refactoring instruction processor to be more generic.
lvella May 29, 2024
d362de7
Implementing more general jalr.
lvella May 29, 2024
6261fa8
Merge branch 'jalr-instruction' into HEAD
lvella May 29, 2024
2a0920a
Lifting sets of instructions into high level (pseudo)instructions.
lvella May 29, 2024
6879d74
Instruction lifting possibly done.
lvella May 30, 2024
5866a4b
Loading data and lifting references to text labels.
lvella May 30, 2024
69130e1
Relocation apparently working.
lvella May 31, 2024
d87c3dc
Merge remote-tracking branch 'origin/main' into elf-support
lvella May 31, 2024
c3c8842
Merge branch 'main' into elf-support
lvella Jun 3, 2024
d92987e
Refactoring powdr asm generator to make it source agnostic.
lvella Jun 4, 2024
3c71255
Make Label generic.
lvella Jun 5, 2024
bc53657
Setting the stack pointer.
lvella Jun 5, 2024
708dfee
Using a non-conflicting start function name.
lvella Jun 5, 2024
27872cd
Merge branch 'main' into split-code-gen
lvella Jun 6, 2024
856a128
Moving global declarations to asm_translate.
lvella Jun 6, 2024
adfc41d
Doing RISC-V initializations on runtime lib, with linker support.
lvella Jun 6, 2024
d04c23f
Modify RISC-V compilation to build binaries instead of libraries.
lvella Jun 4, 2024
7ce3446
Correctly finding all the assembly files.
lvella Jun 7, 2024
890f529
Linker settings for the ELF file to be usable.
lvella Jun 7, 2024
ce334a1
Relocation table test.
lvella Jun 7, 2024
42af5f7
Removing unrelated test.
lvella Jun 7, 2024
9f509a8
Fixing lint.
lvella Jun 7, 2024
bad34de
Updating comments.
lvella Jun 7, 2024
5c703da
Bumping version because the runtime changes are incompatible.
lvella Jun 7, 2024
531e8ee
Fixing lint.
lvella Jun 7, 2024
d138007
Addressing reviews.
lvella Jun 10, 2024
7280a0c
Merge remote-tracking branch 'origin/main' into split-code-gen
lvella Jun 10, 2024
f4309de
Merge branch 'split-code-gen' into rv-init-in-runtime
lvella Jun 10, 2024
d18ae3f
Merge branch 'rv-init-in-runtime' into build-to-executable
lvella Jun 10, 2024
5ab5959
Building rust into executable instead of library.
lvella Jun 10, 2024
18989e4
Fixing test and improving comments.
lvella Jun 10, 2024
e002fcf
Merge commit '7280a0c7701581620d39ca' into elf-support
lvella Jun 10, 2024
dbfadca
Merge commit 'f4309defa9aa017c1f90b5b' into elf-support
lvella Jun 10, 2024
6b516ed
Merge branch 'build-to-executable' into elf-support
lvella Jun 10, 2024
8c5a23b
Reverting useless change.
lvella Jun 10, 2024
71c5626
Fixing comments.
lvella Jun 11, 2024
bfad2ae
Addressing review.
lvella Jun 11, 2024
69ee478
Implementing args interface.
lvella Jun 11, 2024
66060e5
Complete and compiling, but not tested.
lvella Jun 11, 2024
9d54a16
Some fixes.
lvella Jun 11, 2024
d3f3375
Fixing regression.
lvella Jun 11, 2024
6126723
Running from end-to-end, but the result is wrong.
lvella Jun 12, 2024
d54b0e4
Loading labels from text, but relocation is broken.
lvella Jun 12, 2024
29e4744
Merge remote-tracking branch 'origin/main' into rv-init-in-runtime
lvella Jun 13, 2024
e423ddb
Merge branch 'rv-init-in-runtime' into build-to-executable
lvella Jun 13, 2024
75f1740
Fix comment.
lvella Jun 13, 2024
47fecb6
Comment and error message.
lvella Jun 13, 2024
2f78019
Apparently working on function pointer example.
lvella Jun 13, 2024
c6d171d
Best so far.
lvella Jun 13, 2024
e248978
Fixing LUI.
lvella Jun 13, 2024
691413f
Commenting back unsupported instructions section.
lvella Jun 13, 2024
9960886
vec-median working
lvella Jun 13, 2024
32e8425
Implementing static relocation, too
lvella Jun 14, 2024
8b2f7f7
Small fixes and reorg.
lvella Jun 14, 2024
0576d72
Using ELF pipeline for rust tests.
lvella Jun 14, 2024
26323ef
Deduplicating symbols.
lvella Jun 14, 2024
df9c45f
Found flaw in logic lifting LUI + ADDI.
lvella Jun 14, 2024
cbf840e
Doing two passes to decide wether to merge two instructions or not.
lvella Jun 14, 2024
1f567b6
Comments improvement.
lvella Jun 14, 2024
bccfd8a
Merge branch 'main' into build-to-executable
lvella Jun 14, 2024
144bd80
Merge branch 'build-to-executable' into elf-support
lvella Jun 14, 2024
5940340
Small changes.
lvella Jun 14, 2024
04a379f
Humoring lint.
lvella Jun 14, 2024
31f365c
More clippy.
lvella Jun 14, 2024
18cac28
Update riscv/src/lib.rs
lvella Jun 17, 2024
2b67195
Merge remote-tracking branch 'origin/main' into elf-support
lvella Jul 2, 2024
2d41b75
Trying to run tests on both paths.
lvella Jul 2, 2024
a2aa483
Failing if result is unexpected.
lvella Jul 2, 2024
70b62ad
Also running assembly tests from elf.
lvella Jul 2, 2024
861f66f
Fixing running assembly tests via ELF.
lvella Jul 2, 2024
55ab22e
Merge branch 'elf-support' of github.com:powdr-labs/powdr into elf-su…
lvella Jul 2, 2024
a5f01f6
Merge remote-tracking branch 'origin/main' into elf-support
lvella Jul 2, 2024
856ac0d
Fixing argument order of amoadd.w.
lvella Jul 2, 2024
ce6b66a
Fixing assembly compilation of tests.
lvella Jul 2, 2024
d81c9c6
Using GNU Assembler with LLVM Linker.
lvella Jul 3, 2024
357b77d
Supporting auipc followed by load or store.
lvella Jul 3, 2024
bcaeaab
Detecting assembler.
lvella Jul 3, 2024
b56814d
Fixing lrsc test.
lvella Jul 3, 2024
291ebf3
Fixed dynamic relocation test.
lvella Jul 3, 2024
87f7467
I tried as much as I could not to fork raki.
lvella Jul 3, 2024
95534ba
Fixing dynamic relocation test.
lvella Jul 3, 2024
640e996
Fixing dynamic relocation test even more.
lvella Jul 3, 2024
e40b8b1
Removing debug leftover.
lvella Jul 3, 2024
205a9cb
Adding partial rvc.S test.
lvella Jul 3, 2024
1c706e9
Added command line switch to use the ELF path.
lvella Jul 3, 2024
0d36343
Install the linker and assembler in the CI VM.
lvella Jul 3, 2024
1638f1a
Documenting TwoOrOneMapper.
lvella Jul 3, 2024
41d83cb
Documented a few functions.
lvella Jul 4, 2024
490ca7b
Small improvements.
lvella Jul 4, 2024
7691764
Better wording.
lvella Jul 4, 2024
d20a613
Update riscv/src/elf.rs
lvella Jul 5, 2024
ce69fea
Grammar fix.
lvella Jul 5, 2024
7c134f7
Update riscv/src/elf.rs
lvella Jul 5, 2024
750d569
Addressing lots of reviews.
lvella Jul 5, 2024
6be0212
Merge branch 'elf-support' of github.com:powdr-labs/powdr into elf-su…
lvella Jul 5, 2024
0c46213
Update riscv/src/elf.rs
lvella Jul 8, 2024
799aa23
More review addressing.
lvella Jul 8, 2024
c2743ed
Merge branch 'elf-support' of github.com:powdr-labs/powdr into elf-su…
lvella Jul 8, 2024
d753b58
Translating from assembly by default.
lvella Jul 8, 2024
d36cf75
Using `is_executable`.
lvella Jul 8, 2024
f2b8c34
Placing private below pub.
lvella Jul 8, 2024
cc0b5ed
Reverting itertools to 0.12.
lvella Jul 8, 2024
e3cce8f
Merge branch 'main' into elf-support
lvella Jul 8, 2024
42cf0cc
Update riscv/tests/instruction_tests/README.md
lvella Jul 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/pr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ jobs:
key: ${{ runner.os }}-pilcom-node-modules
- name: Install Rust toolchain 1.77 (with clippy and rustfmt)
run: rustup toolchain install 1.77-x86_64-unknown-linux-gnu && rustup component add clippy --toolchain 1.77-x86_64-unknown-linux-gnu && rustup component add rustfmt --toolchain 1.77-x86_64-unknown-linux-gnu
- name: Install test dependencies
run: sudo apt-get install -y binutils-riscv64-unknown-elf lld
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not riscv32?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no riscv32 in Ubuntu. You use the 64 for both.

- name: Install nightly
run: rustup toolchain install nightly-2024-02-01-x86_64-unknown-linux-gnu
- name: Install riscv target
Expand Down
6 changes: 2 additions & 4 deletions asm-utils/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ pub fn escape_label(l: &str) -> String {
l.replace('.', "_dot_").replace('/', "_slash_")
}

pub fn argument_to_escaped_symbol<R: Register, F: FunctionOpKind>(
x: &Argument<R, F>,
) -> Option<String> {
pub fn argument_to_symbol<R: Register, F: FunctionOpKind>(x: &Argument<R, F>) -> Option<&str> {
if let Argument::Expression(Expression::Symbol(symbol)) = x {
Some(escape_label(symbol))
Some(symbol)
} else {
None
}
Expand Down
99 changes: 92 additions & 7 deletions cli-rs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use powdr_pipeline::Pipeline;
use powdr_riscv_executor::ProfilerOptions;

use std::ffi::OsStr;
use std::io;
use std::{borrow::Cow, io::Write, path::Path};
use std::{fs, io};
use strum::{Display, EnumString, EnumVariantNames};

#[derive(Clone, EnumString, EnumVariantNames, Display)]
Expand Down Expand Up @@ -62,13 +62,17 @@ enum Commands {
#[arg(long)]
coprocessors: Option<String>,

/// Convert from the executable ELF file instead of the assembly.
#[arg(short, long)]
#[arg(default_value_t = false)]
elf: bool,

/// Run a long execution in chunks (Experimental and not sound!)
#[arg(short, long)]
#[arg(default_value_t = false)]
continuations: bool,
},
/// Compiles riscv assembly to powdr assembly and then to PIL
/// and generates fixed and witness columns.
/// Compiles riscv assembly to powdr assembly.
RiscvAsm {
/// Input files
#[arg(required = true)]
Expand All @@ -94,6 +98,32 @@ enum Commands {
#[arg(default_value_t = false)]
continuations: bool,
},
/// Translates a RISC-V statically linked executable to powdr assembly.
RiscvElf {
/// Input file
#[arg(required = true)]
file: String,

/// The field to use
#[arg(long)]
#[arg(default_value_t = FieldArgument::Gl)]
#[arg(value_parser = clap_enum_variants!(FieldArgument))]
field: FieldArgument,

/// Directory for output files.
#[arg(short, long)]
#[arg(default_value_t = String::from("."))]
output_directory: String,

/// Comma-separated list of coprocessors.
#[arg(long)]
coprocessors: Option<String>,

/// Run a long execution in chunks (Experimental and not sound!)
#[arg(short, long)]
#[arg(default_value_t = false)]
continuations: bool,
},
/// Executes a powdr-asm file with given inputs.
Execute {
/// input powdr-asm code compiled from Rust/RISCV
Expand Down Expand Up @@ -194,12 +224,14 @@ fn run_command(command: Commands) {
field,
output_directory,
coprocessors,
elf,
continuations,
} => {
call_with_field!(compile_rust::<field>(
&file,
Path::new(&output_directory),
coprocessors,
elf,
continuations
))
}
Expand All @@ -225,6 +257,20 @@ fn run_command(command: Commands) {
continuations
))
}
Commands::RiscvElf {
file,
field,
output_directory,
coprocessors,
continuations,
} => {
call_with_field!(compile_riscv_elf::<field>(
&file,
Path::new(&output_directory),
coprocessors,
continuations
))
}
Commands::Execute {
file,
field,
Expand Down Expand Up @@ -271,6 +317,7 @@ fn compile_rust<F: FieldElement>(
file_name: &str,
output_dir: &Path,
coprocessors: Option<String>,
via_elf: bool,
continuations: bool,
) -> Result<(), Vec<String>> {
let mut runtime = match coprocessors {
Expand All @@ -284,8 +331,15 @@ fn compile_rust<F: FieldElement>(
runtime = runtime.with_poseidon();
}

powdr_riscv::compile_rust::<F>(file_name, output_dir, true, &runtime, continuations)
.ok_or_else(|| vec!["could not compile rust".to_string()])?;
powdr_riscv::compile_rust::<F>(
file_name,
output_dir,
true,
&runtime,
via_elf,
continuations,
)
.ok_or_else(|| vec!["could not compile rust".to_string()])?;

Ok(())
}
Expand All @@ -305,9 +359,14 @@ fn compile_riscv_asm<F: FieldElement>(
None => powdr_riscv::Runtime::base(),
};

powdr_riscv::compile_riscv_asm::<F>(
powdr_riscv::compile_riscv_asm_bundle::<F>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is elf still the default compilation path here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no ELF path in this function, this only from assembly.

original_file_name,
file_names,
file_names
.map(|name| {
let contents = fs::read_to_string(&name).unwrap();
(name, contents)
})
.collect(),
output_dir,
true,
&runtime,
Expand All @@ -318,6 +377,32 @@ fn compile_riscv_asm<F: FieldElement>(
Ok(())
}

fn compile_riscv_elf<F: FieldElement>(
input_file: &str,
output_dir: &Path,
coprocessors: Option<String>,
continuations: bool,
) -> Result<(), Vec<String>> {
let runtime = match coprocessors {
Some(list) => {
powdr_riscv::Runtime::try_from(list.split(',').collect::<Vec<_>>().as_ref()).unwrap()
}
None => powdr_riscv::Runtime::base(),
};

powdr_riscv::compile_riscv_elf::<F>(
input_file,
Path::new(input_file),
output_dir,
true,
&runtime,
continuations,
)
.ok_or_else(|| vec!["could not translate RISC-V executable".to_string()])?;

Ok(())
}

#[allow(clippy::too_many_arguments)]
fn execute<F: FieldElement>(
file_name: &Path,
Expand Down
10 changes: 4 additions & 6 deletions riscv-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,21 @@ unsafe fn panic(panic: &PanicInfo<'_>) -> ! {
// 3. Tail call the main function (in powdr, the return address register is already
// set, so that returning from the entry point function will cause the execution
// to succeed).
// TODO: support Position Independent Executables (PIE) by using lla.
global_asm!(
r"
.global __runtime_start
.type __runtime_start, @function
__runtime_start:
.option push
.option norelax
#lla gp, __global_pointer$
lui gp, %hi(__global_pointer$)
addi gp, gp, %lo(__global_pointer$)
.option pop
#lla sp, __powdr_stack_start
lui sp, %hi(__powdr_stack_start)
addi sp, sp, %lo(__powdr_stack_start)
tail main
"
);

// TODO: ideally, the above code would use `la` instead of `lui` + `addi`, but
// for some reason rustc automatically expands it to `auipc %pcrel_hi(...)`
// + `addi %pcrel_lo(...)`, which our asm converter doesn't support on multiple
// levels. We can't use `li` either, because rustc doesn't like `li` with
// symbols.
4 changes: 4 additions & 0 deletions riscv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ powdr-pipeline.workspace = true
powdr-riscv-executor.workspace = true
powdr-riscv-syscalls.workspace = true

goblin = { version = "0.8" }
lazy_static = "1.4.0"
itertools = "0.13"
lalrpop-util = { version = "^0.19", features = ["lexer"] }
log = "0.4.17"
mktemp = "0.5.0"
num-traits = "0.2.15"
# Use the patched version of raki until the fix is merged.
# Fixes the name of "mulhsu" instruction.
raki = { git = "https://github.com/powdr-labs/raki.git", branch = "patch-1" }
pacheco marked this conversation as resolved.
Show resolved Hide resolved
leonardoalt marked this conversation as resolved.
Show resolved Hide resolved
serde_json = "1.0"
# This is only here to work around https://github.com/lalrpop/lalrpop/issues/750
# It should be removed once that workaround is no longer needed.
Expand Down
9 changes: 4 additions & 5 deletions riscv/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,16 @@ fn build_instruction_tests() {
.to_string()
.strip_suffix(".S")
{
println!("cargo:rerun-if-changed={generated_path}/{file_name}.S");
write!(
test_file,
r#"
r##"
#[test]
#[ignore = "Too slow"]
fn {file_name}() {{
run_instruction_test(include_str!("{test_file}"), "{file_name}");
run_instruction_test(Path::new(r#"{file}"#), r#"{file_name}"#);
}}
"#,
test_file = file.path().canonicalize().unwrap().display(),
"##,
file = file.path().to_str().unwrap(),
)
.unwrap();
}
Expand Down
Loading
Loading