Skip to content
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Add option to control emission of `noload` segment.

### Changed

- Include `.symtab` and `.strtab` in default value of `sections_allowlist_extra`
Expand All @@ -15,6 +17,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
explicitly on the linker script.
- Add `.got` to the default list of discarded sections.
- Simplify the formatting used for extra sections.
- `alloc_sections` and `noload_sections` sections now accept `null` values.
- This allows to avoid emitting those sections completely for a given segment
or globally.
- The main difference between using `null` and an empty list is `null` will
not produce linker symbol nor the section itself in the generated linker
script, while the empty list would generate the starting and ending linker
symbols and the section with no files.

## [0.3.0] - 2024-08-17

Expand Down
11 changes: 9 additions & 2 deletions docs/file_format/segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ segment.
The sections from this list will be emitted for each file in the specified
order.

A `null` value can be used to signal that no allocatable sections should be
emitted for this segment. Setting to `null` will avoid emitting linker symbols
for allocatable sections too.

This allows to override the global settings in case a specific segment has
an order different than the global one. See
[settings.md#alloc_sections](settings.md#alloc_sections) for more info.
Expand All @@ -308,7 +312,7 @@ settings:

### Valid values

List of strings.
List of strings or `null`.

### Default value

Expand All @@ -322,6 +326,9 @@ segment.
The sections from this list will be emitted for each file in the specified
order.

A `null` value can be used to signal that no noload sections should be emitted.
Setting to `null` will avoid emitting linker symbols for noload sections too.

This allows to override the global settings in case a specific segment has
an order different than the global one. See
[settings.md#noload_sections](settings.md#noload_sections) for more info.
Expand All @@ -335,7 +342,7 @@ settings:

### Valid values

List of strings.
List of strings or `null`.

### Default value

Expand Down
11 changes: 9 additions & 2 deletions docs/file_format/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,10 @@ List of allocatable sections (the ones that take ROM space).
The sections from this list will be emitted for each file in the specified
order.

A `null` value can be used to signal that no allocatable sections should be
emitted. Setting to `null` will avoid emitting linker symbols for allocatable
sections too.

This option can be overriden per segment, see
[segments.md#alloc_sections](segments.md#alloc_sections) for more info.

Expand All @@ -548,7 +552,7 @@ settings:

### Valid values

List of strings.
List of strings or `null`.

### Default value

Expand All @@ -561,6 +565,9 @@ List of noload sections (the ones that don't take ROM space).
The sections from this list will be emitted for each file in the specified
order.

A `null` value can be used to signal that no noload sections should be emitted.
Setting to `null` will avoid emitting linker symbols for noload sections too.

This option can be overriden per segment, see
[segments.md#noload_sections](segments.md#noload_sections) for more info.

Expand All @@ -573,7 +580,7 @@ settings:

### Valid values

List of strings.
List of strings or `null`.

### Default value

Expand Down
16 changes: 12 additions & 4 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,16 @@ impl LinkerWriter<'_> {
.write_linker_symbol(&main_seg_sym_start, &format!("ADDR(.{})", segment.name));

// Emit alloc segment
self.write_segment(segment, &segment.alloc_sections, false)?;
if let Some(alloc_sections) = &segment.alloc_sections {
self.write_segment(segment, alloc_sections, false)?;
}

self.buffer.write_empty_line();

// Emit noload segment
self.write_segment(segment, &segment.noload_sections, true)?;
if let Some(noload_sections) = &segment.noload_sections {
self.write_segment(segment, noload_sections, true)?;
}

self.buffer.write_empty_line();

Expand Down Expand Up @@ -612,12 +616,16 @@ impl LinkerWriter<'_> {
}

// Emit alloc segment
self.write_single_segment(segment, &segment.alloc_sections, false)?;
if let Some(alloc_sections) = &segment.alloc_sections {
self.write_single_segment(segment, alloc_sections, false)?;
}

self.buffer.write_empty_line();

// Emit noload segment
self.write_single_segment(segment, &segment.noload_sections, true)?;
if let Some(noload_sections) = &segment.noload_sections {
self.write_single_segment(segment, noload_sections, true)?;
}

self.buffer.write_empty_line();

Expand Down
14 changes: 8 additions & 6 deletions slinky/src/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
file_info::{FileInfo, FileInfoSerial},
gp_info::{GpInfo, GpInfoSerial},
traits::Serial,
EscapedPath, KeepSections, RuntimeSettings, Settings, SlinkyError,
utils, EscapedPath, KeepSections, RuntimeSettings, Settings, SlinkyError,
};

#[derive(PartialEq, Debug, Clone)]
Expand Down Expand Up @@ -48,8 +48,8 @@ pub struct Segment {
pub exclude_if_all: Vec<(String, String)>,

// The default value of the following members come from Settings
pub alloc_sections: Vec<String>,
pub noload_sections: Vec<String>,
pub alloc_sections: Option<Vec<String>>,
pub noload_sections: Option<Vec<String>>,

pub subalign: Option<u32>,
pub segment_start_align: Option<u32>,
Expand Down Expand Up @@ -293,13 +293,15 @@ impl Serial for SegmentSerial {

let alloc_sections = self
.alloc_sections
.get_non_null("alloc_sections", || settings.alloc_sections.clone())?;
.get_optional_nullable("alloc_sections", || settings.alloc_sections.clone())?;
let noload_sections = self
.noload_sections
.get_non_null("noload_sections", || settings.noload_sections.clone())?;
.get_optional_nullable("noload_sections", || settings.noload_sections.clone())?;

if let Some(gp) = &gp_info {
if !alloc_sections.contains(&gp.section) && !noload_sections.contains(&gp.section) {
if utils::is_none_or(alloc_sections.as_ref(), |s| !s.contains(&gp.section))
&& utils::is_none_or(noload_sections.as_ref(), |s| !s.contains(&gp.section))
{
return Err(SlinkyError::MissingSectionForSegment {
field_name: Cow::from("gp_info"),
section: Cow::from(gp_info.unwrap().section),
Expand Down
21 changes: 11 additions & 10 deletions slinky/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub struct Settings {
pub partial_build_segments_folder: Option<PathBuf>,

// Options passed down to each segment
pub alloc_sections: Vec<String>,
pub noload_sections: Vec<String>,
pub alloc_sections: Option<Vec<String>>,
pub noload_sections: Option<Vec<String>>,

pub subalign: Option<u32>,
pub segment_start_align: Option<u32>,
Expand Down Expand Up @@ -120,22 +120,22 @@ const fn settings_default_partial_build_segments_folder() -> Option<PathBuf> {
None
}

fn settings_default_alloc_sections() -> Vec<String> {
vec![
fn settings_default_alloc_sections() -> Option<Vec<String>> {
Some(vec![
".text".into(),
".data".into(),
".rodata".into(),
".sdata".into(),
]
])
}

fn settings_default_noload_sections() -> Vec<String> {
vec![
fn settings_default_noload_sections() -> Option<Vec<String>> {
Some(vec![
".sbss".into(),
".scommon".into(),
".bss".into(),
"COMMON".into(),
]
])
}

const fn settings_default_subalign() -> Option<u32> {
Expand Down Expand Up @@ -417,10 +417,10 @@ impl SettingsSerial {

let alloc_sections = self
.alloc_sections
.get_non_null("alloc_sections", settings_default_alloc_sections)?;
.get_optional_nullable("alloc_sections", settings_default_alloc_sections)?;
let noload_sections = self
.noload_sections
.get_non_null("noload_sections", settings_default_noload_sections)?;
.get_optional_nullable("noload_sections", settings_default_noload_sections)?;

let subalign = self
.subalign
Expand Down Expand Up @@ -488,6 +488,7 @@ impl SettingsSerial {

alloc_sections,
noload_sections,

subalign,
segment_start_align,
segment_end_align,
Expand Down
10 changes: 10 additions & 0 deletions slinky/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ pub(crate) fn create_file_and_parents(path: &Path) -> Result<File, SlinkyError>
}),
}
}

pub(crate) fn is_none_or<T, F>(val: Option<&T>, f: F) -> bool
where
F: FnOnce(&T) -> bool,
{
match val {
None => true,
Some(x) => f(x),
}
}
83 changes: 83 additions & 0 deletions tests/test_cases/null_sections.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#ifndef HEADER_SYMBOLS_H
#define HEADER_SYMBOLS_H

extern char boot_ROM_START[];
extern char boot_VRAM[];
extern char boot_alloc_VRAM[];
extern char boot_TEXT_START[];
extern char boot_TEXT_END[];
extern char boot_TEXT_SIZE[];
extern char boot_DATA_START[];
extern char boot_DATA_END[];
extern char boot_DATA_SIZE[];
extern char boot_RODATA_START[];
extern char boot_RODATA_END[];
extern char boot_RODATA_SIZE[];
extern char boot_SDATA_START[];
extern char boot_SDATA_END[];
extern char boot_SDATA_SIZE[];
extern char boot_alloc_VRAM_END[];
extern char boot_alloc_VRAM_SIZE[];
extern char boot_noload_VRAM[];
extern char boot_SBSS_START[];
extern char boot_SBSS_END[];
extern char boot_SBSS_SIZE[];
extern char boot_SCOMMON_START[];
extern char boot_SCOMMON_END[];
extern char boot_SCOMMON_SIZE[];
extern char boot_BSS_START[];
extern char boot_BSS_END[];
extern char boot_BSS_SIZE[];
extern char bootCOMMON_START[];
extern char bootCOMMON_END[];
extern char bootCOMMON_SIZE[];
extern char boot_noload_VRAM_END[];
extern char boot_noload_VRAM_SIZE[];
extern char boot_VRAM_END[];
extern char boot_VRAM_SIZE[];
extern char boot_ROM_END[];
extern char boot_ROM_SIZE[];
extern char buffers_ROM_START[];
extern char buffers_VRAM[];
extern char buffers_noload_VRAM[];
extern char buffers_SBSS_START[];
extern char buffers_SBSS_END[];
extern char buffers_SBSS_SIZE[];
extern char buffers_SCOMMON_START[];
extern char buffers_SCOMMON_END[];
extern char buffers_SCOMMON_SIZE[];
extern char buffers_BSS_START[];
extern char buffers_BSS_END[];
extern char buffers_BSS_SIZE[];
extern char buffersCOMMON_START[];
extern char buffersCOMMON_END[];
extern char buffersCOMMON_SIZE[];
extern char buffers_noload_VRAM_END[];
extern char buffers_noload_VRAM_SIZE[];
extern char buffers_VRAM_END[];
extern char buffers_VRAM_SIZE[];
extern char buffers_ROM_END[];
extern char buffers_ROM_SIZE[];
extern char assets_ROM_START[];
extern char assets_VRAM[];
extern char assets_alloc_VRAM[];
extern char assets_TEXT_START[];
extern char assets_TEXT_END[];
extern char assets_TEXT_SIZE[];
extern char assets_DATA_START[];
extern char assets_DATA_END[];
extern char assets_DATA_SIZE[];
extern char assets_RODATA_START[];
extern char assets_RODATA_END[];
extern char assets_RODATA_SIZE[];
extern char assets_SDATA_START[];
extern char assets_SDATA_END[];
extern char assets_SDATA_SIZE[];
extern char assets_alloc_VRAM_END[];
extern char assets_alloc_VRAM_SIZE[];
extern char assets_VRAM_END[];
extern char assets_VRAM_SIZE[];
extern char assets_ROM_END[];
extern char assets_ROM_SIZE[];

#endif
Loading