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

Fix flip-link, make SSP configurable #3203

Merged
merged 8 commits into from
Mar 5, 2025
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
2 changes: 2 additions & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Support for `rand_core` 0.9 (#3211)
- `ESP_HAL_CONFIG_STACK_GUARD_OFFSET` and `ESP_HAL_CONFIG_STACK_GUARD_VALUE` to configure Rust's [Stack smashing protection](https://doc.rust-lang.org/rustc/exploit-mitigations.html#stack-smashing-protection) (#3203)

### Changed

Expand All @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Detecting a UART overflow now clears the RX FIFO. (#3190)
- ESP32-S2: Fixed PSRAM initialization (#3196)
- ESP32: Fixed SPI3 QSPI signals (#3201)
- ESP32-C6/H2: The `flip_link` feature should no longer crash (#3203)

### Removed

Expand Down
78 changes: 73 additions & 5 deletions esp-hal/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
collections::HashMap,
env,
error::Error,
fs::{self, File},
Expand Down Expand Up @@ -122,6 +123,19 @@ fn main() -> Result<(), Box<dyn Error>> {
Some(Validator::Enumeration(
vec![String::from("quad"), String::from("octal")]
)),
),
// Rust's stack smashing protection configuration
(
"stack-guard-offset",
"The stack guard variable will be placed this many bytes from the stack's end.",
Value::Integer(4096),
None
),
(
"stack-guard-value",
"The value to be written to the stack guard variable.",
Value::Integer(0xDEED_BAAD),
None
)
], true);

Expand Down Expand Up @@ -166,19 +180,30 @@ fn main() -> Result<(), Box<dyn Error>> {
} else {
// RISC-V devices:

preprocess_file(&config_symbols, "ld/riscv/asserts.x", out.join("asserts.x"))?;
preprocess_file(&config_symbols, "ld/riscv/debug.x", out.join("debug.x"))?;
preprocess_file(
&config_symbols,
&cfg,
"ld/riscv/asserts.x",
out.join("asserts.x"),
)?;
preprocess_file(
&config_symbols,
&cfg,
"ld/riscv/debug.x",
out.join("debug.x"),
)?;
preprocess_file(
&config_symbols,
&cfg,
"ld/riscv/hal-defaults.x",
out.join("hal-defaults.x"),
)?;
}

// With the architecture-specific linker scripts taken care of, we can copy all
// remaining linker scripts which are common to all devices:
copy_dir_all(&config_symbols, "ld/sections", &out)?;
copy_dir_all(&config_symbols, format!("ld/{device_name}"), &out)?;
copy_dir_all(&config_symbols, &cfg, "ld/sections", &out)?;
copy_dir_all(&config_symbols, &cfg, format!("ld/{device_name}"), &out)?;

Ok(())
}
Expand All @@ -188,6 +213,7 @@ fn main() -> Result<(), Box<dyn Error>> {

fn copy_dir_all(
config_symbols: &[&str],
cfg: &HashMap<String, Value>,
src: impl AsRef<Path>,
dst: impl AsRef<Path>,
) -> std::io::Result<()> {
Expand All @@ -198,12 +224,14 @@ fn copy_dir_all(
if ty.is_dir() {
copy_dir_all(
config_symbols,
cfg,
entry.path(),
dst.as_ref().join(entry.file_name()),
)?;
} else {
preprocess_file(
config_symbols,
cfg,
entry.path(),
dst.as_ref().join(entry.file_name()),
)?;
Expand All @@ -215,17 +243,20 @@ fn copy_dir_all(
/// A naive pre-processor for linker scripts
fn preprocess_file(
config: &[&str],
cfg: &HashMap<String, Value>,
src: impl AsRef<Path>,
dst: impl AsRef<Path>,
) -> std::io::Result<()> {
println!("cargo:rerun-if-changed={}", src.as_ref().display());

let file = File::open(src)?;
let mut out_file = File::create(dst)?;

let mut take = Vec::new();
take.push(true);

for line in std::io::BufReader::new(file).lines() {
let line = line?;
let line = substitute_config(cfg, &line?);
let trimmed = line.trim();

if let Some(condition) = trimmed.strip_prefix("#IF ") {
Expand All @@ -252,6 +283,43 @@ fn preprocess_file(
Ok(())
}

fn substitute_config(cfg: &HashMap<String, Value>, line: &str) -> String {
let mut result = String::new();
let mut chars = line.chars().peekable();

while let Some(c) = chars.next() {
if c != '$' {
result.push(c);
continue;
}

let Some('{') = chars.peek() else {
result.push(c);
continue;
};
chars.next();

let mut key = String::new();
for c in chars.by_ref() {
if c == '}' {
break;
}
key.push(c);
}
match cfg
.get(&key)
.unwrap_or_else(|| panic!("missing config key: {key}"))
{
Value::Bool(true) => result.push('1'),
Value::Bool(false) => result.push('0'),
Value::Integer(value) => result.push_str(&value.to_string()),
Value::String(value) => result.push_str(value),
}
}

result
}

#[cfg(feature = "esp32")]
fn generate_memory_extras() -> Vec<u8> {
let reserve_dram = if cfg!(feature = "bluetooth") {
Expand Down
6 changes: 4 additions & 2 deletions esp-hal/ld/esp32/esp32.x
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ INCLUDE "fixups/rtc_fast_rwdata_dummy.x"
/* END ESP32 fixups */

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
SECTIONS {
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
}
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "rtc_slow.x"
Expand Down
6 changes: 4 additions & 2 deletions esp-hal/ld/esp32c2/esp32c2.x
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ PROVIDE(__global_pointer$ = _data_start + 0x800);
/* end of esp32c2 fixups */

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
SECTIONS {
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
}
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "stack.x"
INCLUDE "dram2.x"
Expand Down
6 changes: 4 additions & 2 deletions esp-hal/ld/esp32c3/esp32c3.x
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ PROVIDE(__global_pointer$ = _data_start + 0x800);
/* end of esp32c3 fixups */

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
SECTIONS {
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
}
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "stack.x"
Expand Down
17 changes: 12 additions & 5 deletions esp-hal/ld/esp32c6/esp32c6.x
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,17 @@ SECTIONS {
KEEP(*(.trap));
*(.trap.*);
} > RWTEXT

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
/* End of Shared sections */
}
INSERT BEFORE .rwtext;
#IF ESP_HAL_CONFIG_FLIP_LINK
/* INSERT BEFORE does not seem to work for the .stack section. Instead, we place every RAM
section after .stack if `flip_link` is enabled. */
INSERT AFTER .stack;
#ENDIF

SECTIONS {
/**
Expand All @@ -71,15 +80,13 @@ SECTIONS {
INSERT BEFORE .rodata;
/* end of esp32c6 fixups */

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
/* Shared sections #2 - ordering matters */
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "stack.x"
INCLUDE "dram2.x"
/* End of Shared sections */
/* End of Shared sections #2 */

INCLUDE "debug.x"

Expand Down
18 changes: 13 additions & 5 deletions esp-hal/ld/esp32h2/esp32h2.x
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,24 @@ PROVIDE(_start_trap = default_start_trap);
/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = _data_start + 0x800);


SECTIONS {
.trap : ALIGN(4)
{
KEEP(*(.trap));
*(.trap.*);
} > RWTEXT

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
/* End of Shared sections */
}
INSERT BEFORE .rwtext;
#IF ESP_HAL_CONFIG_FLIP_LINK
/* INSERT BEFORE does not seem to work for the .stack section. Instead, we place every RAM
section after .stack if `flip_link` is enabled. */
INSERT AFTER .stack;
#ENDIF

SECTIONS {
/**
Expand All @@ -64,15 +74,13 @@ SECTIONS {
}
INSERT BEFORE .rodata;

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
/* Shared sections #2 - ordering matters */
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "stack.x"
INCLUDE "dram2.x"
/* End of Shared sections */
/* End of Shared sections #2 */

INCLUDE "debug.x"

Expand Down
6 changes: 4 additions & 2 deletions esp-hal/ld/esp32s2/esp32s2.x
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ INCLUDE "fixups/rtc_fast_rwdata_dummy.x"
/* End of fixups for esp32s2 */

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
SECTIONS {
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
}
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "rtc_slow.x"
Expand Down
6 changes: 4 additions & 2 deletions esp-hal/ld/esp32s3/esp32s3.x
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ INCLUDE "fixups/rodata_dummy.x"
/* End of ESP32S3 fixups */

/* Shared sections - ordering matters */
INCLUDE "rwtext.x"
SECTIONS {
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
}
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "rtc_slow.x"
Expand Down
Loading
Loading