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

Jca/relocation obsidian way #128

Merged
merged 3 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cargo-ledger/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-ledger"
version = "1.2.4"
version = "1.3.0"
authors = ["yhql"]
description = "Build and sideload Ledger Nano apps"
categories = ["development-tools::cargo-plugins"]
Expand Down
70 changes: 52 additions & 18 deletions cargo-ledger/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,64 @@ pub fn install_targets() {
let sysroot_cmd = std::str::from_utf8(&sysroot_cmd).unwrap().trim();

let target_files_url = Path::new(
"https://raw.githubusercontent.com/LedgerHQ/ledger-device-rust-sdk/cee5644d6c20ff97b13e79a30caca751b7b52ac8/ledger_device_sdk/",
"https://raw.githubusercontent.com/LedgerHQ/ledger-device-rust-sdk/a630c93398316cc56dcec6aceb0d424b626d150c/ledger_device_sdk/"
);
let sysroot = Path::new(sysroot_cmd).join("lib").join("rustlib");

// Retrieve each target file independently
// TODO: handle target.json modified upstream
for target in &["nanos", "nanox", "nanosplus"] {
let outfilepath = sysroot.join(target).join("target.json");
if !outfilepath.exists() {
let targetpath =
outfilepath.clone().into_os_string().into_string().unwrap();
println!("* Adding \x1b[1;32m{target}\x1b[0m in \x1b[1;33m{targetpath}\x1b[0m");

let target_url = target_files_url.join(format!("{target}.json"));
let cmd = Command::new("curl")
.arg(target_url)
.arg("-o")
.arg(outfilepath)
.arg("--create-dirs")
.output()
.expect("failed to execute 'curl'");
println!("{}", std::str::from_utf8(&cmd.stderr).unwrap());
} else {
println!("* {target} already installed");
}
let targetpath =
outfilepath.clone().into_os_string().into_string().unwrap();
println!("* Adding \x1b[1;32m{target}\x1b[0m in \x1b[1;33m{targetpath}\x1b[0m");

let target_url = target_files_url.join(format!("{target}.json"));
let cmd = Command::new("curl")
.arg(target_url)
.arg("-o")
.arg(outfilepath)
.arg("--create-dirs")
.output()
.expect("failed to execute 'curl'");
println!("{}", std::str::from_utf8(&cmd.stderr).unwrap());
}

yhql marked this conversation as resolved.
Show resolved Hide resolved
// Install link_wrap.sh script needed for relocation
println!("[ ] Install custom link script...");

/* Shall be put at the same place as rust-lld */
let custom_link_script = "link_wrap.sh";

let cmd = Command::new("find")
.arg(sysroot_cmd)
.arg("-name")
.arg("rust-lld")
.output()
.expect("failed to find rust-lld linker")
.stdout;

let rust_lld_path = std::str::from_utf8(&cmd).unwrap();
let end = rust_lld_path.rfind('/').unwrap();

let outfilepath =
sysroot.join(&rust_lld_path[..end]).join(custom_link_script);

/* Retrieve the linker script */
let target_url = target_files_url.join(custom_link_script);
Command::new("curl")
.arg(target_url)
.arg("-o")
.arg(&outfilepath)
.output()
.expect("failed to execute 'curl'");

println!("* Custom link script is {}", outfilepath.display());

/* Make the linker script executable */
Command::new("chmod")
.arg("+x")
.arg(outfilepath)
.output()
.expect("failed to execute chmod");
}
4 changes: 2 additions & 2 deletions ledger_device_sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ledger_device_sdk"
version = "1.4.3"
version = "1.5.0"
authors = ["yhql", "yogh333"]
edition = "2021"
license.workspace = true
Expand All @@ -15,7 +15,7 @@ ledger_device_sdk = { path = ".", features = ["speculos"] }
testmacro = { path = "../testmacro", version = "0.1.0"}

[dependencies]
ledger_secure_sdk_sys = {path = "../ledger_secure_sdk_sys", version = "1.1.0"}
ledger_secure_sdk_sys = {path = "../ledger_secure_sdk_sys", version = "1.2.0"}
include_gif = {path = "../include_gif", version = "1.0.1"}
num-traits = { version = "0.2.14", default_features = false }
rand_core = { version = "0.6.3", default_features = false }
Expand Down
87 changes: 77 additions & 10 deletions ledger_device_sdk/link.ld
Original file line number Diff line number Diff line change
@@ -1,43 +1,110 @@
PHDRS
{
flash0 PT_LOAD ;
data PT_LOAD ;
flash2 PT_LOAD ;
sram PT_LOAD ;

headers PT_PHDR PHDRS ;
}

SECTIONS
{
/* Code, read only, no relocations needed. */
.text :
{
_text = .;
/* Here begins flash. This symbol is used by the ideompotent `pic`
function as the lower bound of addressed to relocate. */
_nvram_start = .;

*(.boot*)
*(.text*)
*(.rodata*)
/* .rodata is moved out so we can update it */

. = ALIGN(PAGE_SIZE);
_etext = .;
} > FLASH
} > FLASH :flash0

.nvm_data : ALIGN(PAGE_SIZE)
/* Relocations, read only, no relocations aginst the relocations themselves
needed! */
_reloc_size = SIZEOF(.rel.rodata) + SIZEOF(.rel.data) + SIZEOF(.rel.nvm_data);
.rel_flash : ALIGN(PAGE_SIZE)
{
_relocs = .;

. += _reloc_size;
. = ALIGN(PAGE_SIZE);

_erelocs = .;

. = ALIGN(PAGE_SIZE);

/* After this section we have mutable flash. Must be a multiple of PAGE_SIZE from _nvram_start. */
_nvram_data = .;
*(.nvm_data*)
} > FLASH :flash0

/* Immutable globals, read only during app running proper, but
relocations are needed. (So not read-only completely.) */
.rodata : ALIGN(PAGE_SIZE)
{
/* Moved here from .text so we can permantly apply relocations to it with
nvm_write() */
. = ALIGN(PAGE_SIZE);
_envram_data = .;
_install_parameters = .;
_nvram_end = .;
} > FLASH
_rodata = .;
_rodata_src = .;
*(.rodata*)
. = ALIGN(PAGE_SIZE);
_erodata = .;
} > FLASH :flash0
_rodata_len = _erodata - _rodata;

/* Mutable Globals, writable, relocations are needed. */
.data : ALIGN(4)
{
_data = .;
*(vtable)
*(.data*)
. = ALIGN(PAGE_SIZE);
_edata = .;
} > SRAM
} > SRAM AT> FLASH :data =0xa4a4
_data_len = SIZEOF(.data);

ASSERT( (_edata - _data) <= 0, ".data section must be empty" )

/* Persistent data, read and written during app running proper,
relocations are also needed. */
.nvm_data : ALIGN(PAGE_SIZE)
{
*(.nvm_data*)

/* Store _nvram value during link_pass and use this to detect movement of
_nvram as compared to the previous app execution, and redo the relocations
if necessary */
. = ALIGN(4);
_nvram_prev_run = .;
LONG(ABSOLUTE(_nvram_start))

. = ALIGN(PAGE_SIZE);

/* After this section we no longer have Flash memory at all. */

/* This symbol is used by the mutable portion of flash calculations. */
_envram_data = .;
_install_parameters = .;
/* This symbol is used by the ideompotent `pic` function as the upper
bound of addressed to relocate. */
_nvram_end = .;
} > FLASH :flash2

_sidata_src = LOADADDR(.data);

.bss :
{
_bss = .;
*(.bss*)
_ebss = .;
_bss_len = ABSOLUTE(_ebss) - ABSOLUTE(_bss);

. = ALIGN(4);
app_stack_canary = .;
Expand All @@ -46,7 +113,7 @@ SECTIONS
. = _stack_validation + STACK_SIZE;
_stack = ABSOLUTE(END_STACK) - STACK_SIZE;
_estack = ABSOLUTE(END_STACK);
} > SRAM
} > SRAM :sram

.stack_sizes (INFO):
{
Expand Down
42 changes: 42 additions & 0 deletions ledger_device_sdk/link_wrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

set -eu

set -x

LD=${LD:-rust-lld}
# Needed because LLD gets behavior from argv[0]
LD=${LD/-ld/-lld}
${LD} "$@" --emit-relocs

echo RUST_LLD DONE

while [ $# -gt 0 -a "$1" != "-o" ];
do
shift;
done
OUT="$2"

echo OUT IS $OUT

# the relocations for the constants section are required
llvm-objcopy --dump-section .rel.rodata=$OUT-rodata-reloc $OUT /dev/null
# there might not _be_ nonempty .data or .nvm_data sections, so there might be no relocations for it; fail gracefully.
llvm-objcopy --dump-section .rel.data=$OUT-data-reloc $OUT /dev/null || true
llvm-objcopy --dump-section .rel.nvm_data=$OUT-nvm-reloc $OUT /dev/null || true
# Concatenate the relocation sections; this should still write $OUT-relocs even if $OUT-data-reloc doesn't exist.
cat $OUT-rodata-reloc $OUT-nvm-reloc $OUT-data-reloc > $OUT-relocs || true

reloc_allocated_size="$((0x$(llvm-nm $OUT | grep _reloc_size | cut -d' ' -f1)))"
reloc_real_size="$(stat -c %s $OUT-relocs)"
# Check that our relocations _actually_ fit.
if [ "$reloc_real_size" -gt "$reloc_allocated_size" ]
then
echo "Insufficient size for relocs; This is likely some bug in nanos_sdk's link.ld."
echo "Available size: " $reloc_allocated_size " Used size: " $reloc_real_size
exit 1
fi

truncate -s $reloc_allocated_size $OUT-relocs
# and write the relocs to their section in the flash image.
llvm-objcopy --update-section .rel_flash=$OUT-relocs $OUT
20 changes: 11 additions & 9 deletions ledger_device_sdk/nanos.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
"executables": true,
"features": "+strict-align",
"frame-pointer": "always",
"linker": "rust-lld",
"linker": "link_wrap.sh",
"linker-flavor": "ld.lld",
"llvm-target": "thumbv6m-none-eabi",
"panic-strategy": "abort",
"pre-link-args": {
"ld.lld": [
"-Tnanos_layout.ld",
"-Tlink.ld"
],
"ld": [
"-Tnanos_layout.ld",
"-Tlink.ld"
]
"ld.lld": [
"-Tnanos_layout.ld",
"-Tlink.ld",
"--emit-relocs"
],
"ld": [
"-Tnanos_layout.ld",
"-Tlink.ld",
"--emit-relocs"
]
},
"relocation-model": "ropi",
"singlethread": true,
Expand Down
18 changes: 9 additions & 9 deletions ledger_device_sdk/nanosplus.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
"emit-debug-gdb-scripts": false,
"executables": true,
"frame-pointer": "always",
"linker": "rust-lld",
"linker": "link_wrap.sh",
"linker-flavor": "ld.lld",
"llvm-target": "thumbv8m.main-none-eabi",
"max-atomic-width": 32,
"panic-strategy": "abort",
"pre-link-args": {
"ld.lld": [
"-Tnanosplus_layout.ld",
"-Tlink.ld"
],
"ld": [
"-Tnanosplus_layout.ld",
"-Tlink.ld"
]
"ld.lld": [
"-Tnanosplus_layout.ld",
"-Tlink.ld"
],
"ld": [
"-Tnanosplus_layout.ld",
"-Tlink.ld"
]
},
"relocation-model": "ropi-rwpi",
"singlethread": true,
Expand Down
Loading
Loading