Skip to content

Commit

Permalink
Implement sections_start_alignment to allow aligning individual sec…
Browse files Browse the repository at this point in the history
…tions

Closes #66
  • Loading branch information
AngheloAlf committed Jul 12, 2024
1 parent 9af7dc7 commit adf6e79
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 20 deletions.
37 changes: 35 additions & 2 deletions docs/file_format/segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,18 @@ Every attribute listed is optional unless explicitly stated.
- [Example](#example-11)
- [Valid values](#valid-values-10)
- [Default value](#default-value-9)
- [`wildcard_sections`](#wildcard_sections)
- [`sections_start_alignment`](#sections_start_alignment)
- [Example](#example-12)
- [Valid values](#valid-values-11)
- [Default value](#default-value-10)
- [`fill_value`](#fill_value)
- [`wildcard_sections`](#wildcard_sections)
- [Example](#example-13)
- [Valid values](#valid-values-12)
- [Default value](#default-value-11)
- [`fill_value`](#fill_value)
- [Example](#example-14)
- [Valid values](#valid-values-13)
- [Default value](#default-value-12)

## `name`

Expand Down Expand Up @@ -383,6 +387,35 @@ Positive integers or `null`.
The value specified for
[settings.md#section_end_align](settings.md#section_end_align)

## `sections_start_alignment`

Allows to specify different alignments for the start of every section of this
specific segment.

If a specific section is not pressent on this mapping then no alignment will be
forced on the given section.

This option overrides the global setting, see
[settings.md#sections_start_alignment](settings.md#sections_start_alignment) for
more info.

### Example

```yaml
segments:
- name: main
section_start_alignment: { .text: 4, .rodata: 0x10, .data: 0x20 }
```

### Valid values

A mapping of strings as keys and positive numbers as values.

### Default value

The value specified for
[settings.md#sections_start_alignment](settings.md#sections_start_alignment)

## `wildcard_sections`

Toggles using wildcards (`*`) as suffix in the emitted sections for this
Expand Down
34 changes: 32 additions & 2 deletions docs/file_format/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,18 @@ as well.
- [Example](#example-19)
- [Valid values](#valid-values-19)
- [Default value](#default-value-14)
- [`wildcard_sections`](#wildcard_sections)
- [`sections_start_alignment`](#sections_start_alignment)
- [Example](#example-20)
- [Valid values](#valid-values-20)
- [Default value](#default-value-15)
- [`fill_value`](#fill_value)
- [`wildcard_sections`](#wildcard_sections)
- [Example](#example-21)
- [Valid values](#valid-values-21)
- [Default value](#default-value-16)
- [`fill_value`](#fill_value)
- [Example](#example-22)
- [Valid values](#valid-values-22)
- [Default value](#default-value-17)

## `base_path`

Expand Down Expand Up @@ -627,6 +631,32 @@ Positive integers or `null`.

`0x10`

## `sections_start_alignment`

Allows to specify different alignments for the start of every section.

If a specific section is not pressent on this mapping then no alignment will be
forced on the given section.

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

### Example

```yaml
settings:
section_start_alignment: { .text: 128, .rodata: 0x40, .sdata: 0x8 }
```

### Valid values

A mapping of strings as keys and positive numbers as values.

### Default value

Empty mapping.

## `wildcard_sections`

Toggles using wildcards (`*`) as suffix in the emitted sections.
Expand Down
8 changes: 7 additions & 1 deletion slinky/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,13 @@ impl Document {
Ok(new_path)
}

pub(crate) fn should_emit_entry(&self, exclude_if_any: &[(String, String)], exclude_if_all: &[(String, String)], include_if_any: &[(String, String)], include_if_all: &[(String, String)]) -> bool {
pub(crate) fn should_emit_entry(
&self,
exclude_if_any: &[(String, String)],
exclude_if_all: &[(String, String)],
include_if_any: &[(String, String)],
include_if_all: &[(String, String)],
) -> bool {
if exclude_if_any
.iter()
.any(|(key, value)| self.custom_options.get(key) == Some(value))
Expand Down
17 changes: 15 additions & 2 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ impl<'a> LinkerWriter<'a> {
}

pub fn add_segment(&mut self, segment: &Segment) -> Result<(), SlinkyError> {
if !self.d.should_emit_entry(&segment.exclude_if_any, &segment.exclude_if_all, &segment.include_if_any, &segment.include_if_all) {
if !self.d.should_emit_entry(
&segment.exclude_if_any,
&segment.exclude_if_all,
&segment.include_if_any,
&segment.include_if_all,
) {
return Ok(());
}

Expand Down Expand Up @@ -559,6 +564,9 @@ impl LinkerWriter<'_> {

let section_start_sym = style.segment_section_start(&segment.name, section);

if let Some(align_value) = segment.sections_start_alignment.get(section) {
self.buffer.align_symbol(".", *align_value);
}
self.buffer.write_symbol(&section_start_sym, ".");
}
}
Expand Down Expand Up @@ -624,7 +632,12 @@ impl LinkerWriter<'_> {
section: &str,
base_path: &Path,
) -> Result<(), SlinkyError> {
if !self.d.should_emit_entry(&file.exclude_if_any, &file.exclude_if_all, &file.include_if_any, &file.include_if_all) {
if !self.d.should_emit_entry(
&file.exclude_if_any,
&file.exclude_if_all,
&file.include_if_any,
&file.include_if_all,
) {
return Ok(());
}

Expand Down
34 changes: 22 additions & 12 deletions slinky/src/segment.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* SPDX-FileCopyrightText: © 2024 decompals */
/* SPDX-License-Identifier: MIT */

use std::path::PathBuf;
use std::{collections::HashMap, path::PathBuf};

use serde::Deserialize;

Expand Down Expand Up @@ -50,6 +50,7 @@ pub struct Segment {
pub subalign: Option<u32>,
pub segment_start_align: Option<u32>,
pub section_end_align: Option<u32>,
pub sections_start_alignment: HashMap<String, u32>,

pub wildcard_sections: bool,

Expand Down Expand Up @@ -98,6 +99,8 @@ pub(crate) struct SegmentSerial {
pub segment_start_align: AbsentNullable<u32>,
#[serde(default)]
pub section_end_align: AbsentNullable<u32>,
#[serde(default)]
pub sections_start_alignment: AbsentNullable<HashMap<String, u32>>,

#[serde(default)]
pub wildcard_sections: AbsentNullable<bool>,
Expand Down Expand Up @@ -187,17 +190,17 @@ impl SegmentSerial {
let dir = self.dir.get_non_null("dir", PathBuf::new)?;

let include_if_any = self
.include_if_any
.get_non_null("include_if_any", Vec::new)?;
let include_if_all = self
.include_if_all
.get_non_null("include_if_all", Vec::new)?;
let exclude_if_any = self
.exclude_if_any
.get_non_null("exclude_if_any", Vec::new)?;
let exclude_if_all = self
.exclude_if_all
.get_non_null("exclude_if_all", Vec::new)?;
.include_if_any
.get_non_null("include_if_any", Vec::new)?;
let include_if_all = self
.include_if_all
.get_non_null("include_if_all", Vec::new)?;
let exclude_if_any = self
.exclude_if_any
.get_non_null("exclude_if_any", Vec::new)?;
let exclude_if_all = self
.exclude_if_all
.get_non_null("exclude_if_all", Vec::new)?;

let alloc_sections = self
.alloc_sections
Expand All @@ -218,6 +221,12 @@ impl SegmentSerial {
.section_end_align
.get_optional_nullable("section_end_align", || settings.section_end_align)?;

let sections_start_alignment = self
.sections_start_alignment
.get_non_null("sections_start_alignment", || {
settings.sections_start_alignment.clone()
})?;

let wildcard_sections = self
.wildcard_sections
.get_non_null("wildcard_sections", || settings.wildcard_sections)?;
Expand All @@ -243,6 +252,7 @@ impl SegmentSerial {
subalign,
segment_start_align,
section_end_align,
sections_start_alignment,
wildcard_sections,
fill_value,
})
Expand Down
16 changes: 15 additions & 1 deletion slinky/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* SPDX-License-Identifier: MIT */

use serde::Deserialize;
use std::path::PathBuf;
use std::{collections::HashMap, path::PathBuf};

use crate::{
absent_nullable::AbsentNullable, linker_symbols_style::LinkerSymbolsStyle, SlinkyError,
Expand Down Expand Up @@ -39,6 +39,7 @@ pub struct Settings {
pub subalign: Option<u32>,
pub segment_start_align: Option<u32>,
pub section_end_align: Option<u32>,
pub sections_start_alignment: HashMap<String, u32>,

pub wildcard_sections: bool,

Expand Down Expand Up @@ -144,6 +145,10 @@ const fn settings_default_section_end_align() -> Option<u32> {
Some(0x10)
}

fn settings_default_sections_start_alignment() -> HashMap<String, u32> {
HashMap::new()
}

const fn settings_default_wildcard_sections() -> bool {
true
}
Expand Down Expand Up @@ -183,6 +188,7 @@ impl Default for Settings {
subalign: settings_default_subalign(),
segment_start_align: settings_default_segment_start_align(),
section_end_align: settings_default_section_end_align(),
sections_start_alignment: settings_default_sections_start_alignment(),

wildcard_sections: settings_default_wildcard_sections(),

Expand Down Expand Up @@ -243,6 +249,8 @@ pub(crate) struct SettingsSerial {
pub segment_start_align: AbsentNullable<u32>,
#[serde(default)]
pub section_end_align: AbsentNullable<u32>,
#[serde(default)]
pub sections_start_alignment: AbsentNullable<HashMap<String, u32>>,

#[serde(default)]
pub wildcard_sections: AbsentNullable<bool>,
Expand Down Expand Up @@ -337,6 +345,11 @@ impl SettingsSerial {
.section_end_align
.get_optional_nullable("section_end_align", settings_default_section_end_align)?;

let sections_start_alignment = self.sections_start_alignment.get_non_null(
"sections_start_alignment",
settings_default_sections_start_alignment,
)?;

let wildcard_sections = self
.wildcard_sections
.get_non_null("wildcard_sections", settings_default_wildcard_sections)?;
Expand Down Expand Up @@ -372,6 +385,7 @@ impl SettingsSerial {
subalign,
segment_start_align,
section_end_align,
sections_start_alignment,
wildcard_sections,
fill_value,
})
Expand Down
Loading

0 comments on commit adf6e79

Please sign in to comment.