Skip to content
This repository has been archived by the owner on Nov 28, 2023. It is now read-only.

Commit

Permalink
build.rs now adapts link.x for the target arch
Browse files Browse the repository at this point in the history
  • Loading branch information
romancardenas committed Nov 8, 2023
1 parent 28b916d commit b0ef2f8
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 196 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Removed bors in favor of GitHub Merge Queue
- `start_trap_rust` is now marked as `unsafe`
- Implement `r0` as inline assembly
- Use `${ARCH_WIDTH}` in `link.x.in` to adapt to different archs

## [v0.11.0] - 2023-01-18

Expand Down
29 changes: 19 additions & 10 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
// NOTE: Adapted from cortex-m/build.rs

use riscv_target::Target;
use std::env;
use std::fs;
use std::path::PathBuf;
use std::{env, fs, io, path::PathBuf};

fn add_linker_script(arch_width: u32) -> io::Result<()> {
// Read the file to a string and replace all occurrences of ${ARCH_WIDTH} with the arch width
let mut content = fs::read_to_string("link.x.in")?;
content = content.replace("${ARCH_WIDTH}", &arch_width.to_string());

fn add_linker_script(bytes: &[u8]) {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

// Put the linker script somewhere the linker can find it
fs::write(out_dir.join("link.x"), bytes).unwrap();
fs::write(out_dir.join("link.x"), content)?;
println!("cargo:rustc-link-search={}", out_dir.display());
println!("cargo:rerun-if-changed=link.x");

Ok(())
}

fn main() {
Expand All @@ -22,19 +26,24 @@ fn main() {
if target.starts_with("riscv") {
println!("cargo:rustc-cfg=riscv");
let target = Target::from_target_str(&target);
match target.bits {

// generate the linker script
let arch_width = match target.bits {
32 => {
println!("cargo:rustc-cfg=riscv32");
add_linker_script(include_bytes!("link-rv32.x"));
4
}
64 => {
println!("cargo:rustc-cfg=riscv64");
add_linker_script(include_bytes!("link-rv64.x"));
8
}
_ => panic!("Unsupported bit width"),
}
};
add_linker_script(arch_width).unwrap();

// expose the ISA extensions
if target.has_extension('m') {
println!("cargo:rustc-cfg=riscvm"); // we can expose extensions this way
println!("cargo:rustc-cfg=riscvm");
}
}
}
174 changes: 0 additions & 174 deletions link-rv64.x

This file was deleted.

48 changes: 36 additions & 12 deletions link-rv32.x → link.x.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/* # Developer notes

- Symbols that start with a double underscore (__) are considered "private"

- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
static mut _heap_size }`).

- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
symbol if not dropped if it appears in or near the front of the linker arguments and "it's not
needed" by any of the preceding objects (linker arguments)

- `PROVIDE` is used to provide default values that can be overridden by a user linker script

- In this linker script, you may find symbols that look like `${...}` (e.g., `${ARCH_WIDTH}`).
These are wildcards used by the `build.rs` script to adapt to different target particularities.
Check `build.rs` for more details about these symbols.

- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
the LMA of .data are all `${ARCH_WIDTH}`-byte aligned. These alignments are assumed by the RAM
initialization routine. There's also a second benefit: `${ARCH_WIDTH}`-byte aligned boundaries
means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
*/

PROVIDE(_stext = ORIGIN(REGION_TEXT));
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
PROVIDE(_max_hart_id = 0);
Expand Down Expand Up @@ -72,23 +96,23 @@ SECTIONS
. = ALIGN(4);
} > REGION_RODATA

.data : ALIGN(4)
.data : ALIGN(${ARCH_WIDTH})
{
_sidata = LOADADDR(.data);
_sdata = .;
/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = . + 0x800);
*(.sdata .sdata.* .sdata2 .sdata2.*);
*(.data .data.*);
. = ALIGN(4);
. = ALIGN(${ARCH_WIDTH});
_edata = .;
} > REGION_DATA AT > REGION_RODATA

.bss (NOLOAD) : ALIGN(4)
.bss (NOLOAD) : ALIGN(${ARCH_WIDTH})
{
_sbss = .;
*(.sbss .sbss.* .bss .bss.*);
. = ALIGN(4);
. = ALIGN(${ARCH_WIDTH});
_ebss = .;
} > REGION_BSS

Expand Down Expand Up @@ -129,8 +153,8 @@ ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");

ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
ASSERT(ORIGIN(REGION_DATA) % ${ARCH_WIDTH} == 0, "
ERROR(riscv-rt): the start of the REGION_DATA must be ${ARCH_WIDTH}-byte aligned");

ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
Expand All @@ -144,14 +168,14 @@ ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
ASSERT(_stext % 4 == 0, "
ERROR(riscv-rt): `_stext` must be 4-byte aligned");

ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
BUG(riscv-rt): .data is not 4-byte aligned");
ASSERT(_sdata % ${ARCH_WIDTH} == 0 && _edata % ${ARCH_WIDTH} == 0, "
BUG(riscv-rt): .data is not ${ARCH_WIDTH}-byte aligned");

ASSERT(_sidata % 4 == 0, "
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
ASSERT(_sidata % ${ARCH_WIDTH} == 0, "
BUG(riscv-rt): the LMA of .data is not ${ARCH_WIDTH}-byte aligned");

ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
BUG(riscv-rt): .bss is not 4-byte aligned");
ASSERT(_sbss % ${ARCH_WIDTH} == 0 && _ebss % ${ARCH_WIDTH} == 0, "
BUG(riscv-rt): .bss is not ${ARCH_WIDTH}-byte aligned");

ASSERT(_sheap % 4 == 0, "
BUG(riscv-rt): start of .heap is not 4-byte aligned");
Expand Down

0 comments on commit b0ef2f8

Please sign in to comment.