Skip to content

Commit

Permalink
Add provide and hidden for symbol_assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
AngheloAlf committed Aug 11, 2024
1 parent 34c44dc commit d5c2e14
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 17 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add new top-level attribute for the file format: `symbol_assignments`.
- Allows to define symbols directly on the generated linker script.
- Symbols created this way can be defined with raw addresses, reference other
symbols or more complex expressions.
- If a symbol assignment is emitted or not can be controlled with the same
conditional inclussion/exclussion mechanism used by the custom options.
- These definitions can be wrapped in `PROVIDE`, `HIDDEN` or `PROVIDE_HIDDEN`.

## [0.2.5] - 2024-07-17

### Fixed
Expand Down
49 changes: 49 additions & 0 deletions docs/file_format/symbol_assignments.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ Every attribute listed is optional unless explicitly stated.
- [`value`](#value)
- [Example](#example-1)
- [Valid values](#valid-values-1)
- [`provide`](#provide)
- [Valid values](#valid-values-2)
- [Default value](#default-value)
- [`hidden`](#hidden)
- [Valid values](#valid-values-3)
- [Default value](#default-value-1)
- [`include_if_any`, `include_if_all`, `exclude_if_any` and `exclude_if_all`](#include_if_any-include_if_all-exclude_if_any-and-exclude_if_all)

## `name`
Expand Down Expand Up @@ -66,6 +72,49 @@ symbol_assignments:

Non empty string.

## `provide`

If `provide` is enabled for an entry then this symbol assignment will only be
applied if the given symbol is referenced but is not defined in any object
included in the link.

See GNU LD documentation for
[`PROVIDE`](https://sourceware.org/binutils/docs/ld/PROVIDE.html).

This option can be combined with [`hidden`](#hidden). For more info see the GNU
LD documentation for
[`PROVIDE_HIDDEN`](https://sourceware.org/binutils/docs/ld/PROVIDE_005fHIDDEN.html).

### Valid values

Bool.

### Default value

`False`

## `hidden`

Allows defining the symbol that will be hidden and won't be exported.

On a more technical sense, the binding of the generated symbol on the elf will
be marked as `LOCAL` instead of `GLOBAL.`

See GNU LD documentation for
[`HIDDEN`](https://sourceware.org/binutils/docs/ld/HIDDEN.html).

This option can be combined with [`provide`](#provide). For more info see the
GNU LD documentation for
[`PROVIDE_HIDDEN`](https://sourceware.org/binutils/docs/ld/PROVIDE_005fHIDDEN.html).

### Valid values

Bool.

### Default value

`False`

## `include_if_any`, `include_if_all`, `exclude_if_any` and `exclude_if_all`

These fields allow to conditionally include or exclude a given segment depending
Expand Down
24 changes: 14 additions & 10 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl<'a> LinkerWriter<'a> {

self.begin_symbol_assignments()?;

for undefined_sym in symbol_assignments {
self.add_undefined_sym(undefined_sym)?;
for symbol_assignment in symbol_assignments {
self.add_symbol_assignment(symbol_assignment)?;
}

self.end_symbol_assignments()?;
Expand Down Expand Up @@ -606,21 +606,25 @@ impl LinkerWriter<'_> {
Ok(())
}

pub(crate) fn add_undefined_sym(
pub(crate) fn add_symbol_assignment(
&mut self,
undefined_sym: &SymbolAssignment,
symbol_assignment: &SymbolAssignment,
) -> Result<(), SlinkyError> {
if !self.rs.should_emit_entry(
&undefined_sym.exclude_if_any,
&undefined_sym.exclude_if_all,
&undefined_sym.include_if_any,
&undefined_sym.include_if_all,
&symbol_assignment.exclude_if_any,
&symbol_assignment.exclude_if_all,
&symbol_assignment.include_if_any,
&symbol_assignment.include_if_all,
) {
return Ok(());
}

self.buffer
.write_symbol_assignment(&undefined_sym.name, &undefined_sym.value);
self.buffer.write_symbol_assignment(
&symbol_assignment.name,
&symbol_assignment.value,
symbol_assignment.provide,
symbol_assignment.hidden,
);

Ok(())
}
Expand Down
21 changes: 16 additions & 5 deletions slinky/src/script_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,26 @@ impl ScriptBuffer {
pub fn write_linker_symbol(&mut self, symbol: &str, value: &str) {
// TODO: check `symbol` is a valid C identifier

self.write_symbol_assignment(symbol, value);
self.write_symbol_assignment(symbol, value, false, false);

self.linker_symbols.insert(symbol.to_string());
}

pub fn write_symbol_assignment(&mut self, symbol: &str, value: &str) {
// TODO: check `symbol` is a valid C identifier

self.writeln(&format!("{} = {};", symbol, value));
pub fn write_symbol_assignment(
&mut self,
symbol: &str,
value: &str,
provide: bool,
hidden: bool,
) {
let line = match (provide, hidden) {
(true, true) => format!("PROVIDE_HIDDEN({} = {});", symbol, value),
(true, false) => format!("PROVIDE({} = {});", symbol, value),
(false, true) => format!("HIDDEN({} = {});", symbol, value),
(false, false) => format!("{} = {};", symbol, value),
};

self.writeln(&line);
}

pub fn align_symbol(&mut self, symbol: &str, align_value: u32) {
Expand Down
17 changes: 17 additions & 0 deletions slinky/src/symbol_assignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ pub struct SymbolAssignment {
/// Value or expression to assign to this symbol
pub value: String,

/// Signals if this assignment should be wrapped in a `PROVIDE` statement.
/// Can be used with `hidden`.
pub provide: bool,
/// Signals if this assignment should be wrapped in a `HIDDEN` statement.
/// Can be used with `provide`.
pub hidden: bool,

pub include_if_any: Vec<(String, String)>,
pub include_if_all: Vec<(String, String)>,
pub exclude_if_any: Vec<(String, String)>,
Expand All @@ -25,6 +32,11 @@ pub(crate) struct SymbolAssignmentSerial {
pub name: String,
pub value: String,

#[serde(default)]
pub provide: AbsentNullable<bool>,
#[serde(default)]
pub hidden: AbsentNullable<bool>,

#[serde(default)]
pub include_if_any: AbsentNullable<Vec<(String, String)>>,
#[serde(default)]
Expand All @@ -51,6 +63,9 @@ impl SymbolAssignmentSerial {
}
let value = self.value;

let provide = self.provide.get_non_null("provide", || false)?;
let hidden = self.hidden.get_non_null("hidden", || false)?;

let include_if_any = self
.include_if_any
.get_non_null("include_if_any", Vec::new)?;
Expand All @@ -67,6 +82,8 @@ impl SymbolAssignmentSerial {
Ok(SymbolAssignment {
name,
value,
provide,
hidden,
include_if_any,
include_if_all,
exclude_if_any,
Expand Down
4 changes: 3 additions & 1 deletion tests/partial_linking/undefined_syms.ld
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,6 @@ osVersion = 0x80000314;
osMemSize = 0x80000318;
osAppNMIBuffer = 0x8000031C;
dummy_test = 0x80801234;
_gp = boot_SCOMMON_START + 0x7FF0;
HIDDEN(_gp = boot_SCOMMON_START + 0x7FF0);
PROVIDE(provided_sym = 0x1234);
PROVIDE_HIDDEN(provided_and_hidden_sym = 0x1234);
10 changes: 10 additions & 0 deletions tests/partial_linking/undefined_syms.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,13 @@ symbol_assignments:

- name: _gp
value: boot_SCOMMON_START + 0x7FF0
hidden: True

- name: provided_sym
value: 0x1234
provide: True

- name: provided_and_hidden_sym
value: 0x1234
provide: True
hidden: True
4 changes: 3 additions & 1 deletion tests/test_cases/undefined_syms.ld
Original file line number Diff line number Diff line change
Expand Up @@ -313,4 +313,6 @@ osVersion = 0x80000314;
osMemSize = 0x80000318;
osAppNMIBuffer = 0x8000031C;
dummy_test = 0x80801234;
_gp = boot_SCOMMON_START + 0x7FF0;
HIDDEN(_gp = boot_SCOMMON_START + 0x7FF0);
PROVIDE(provided_sym = 0x1234);
PROVIDE_HIDDEN(provided_and_hidden_sym = 0x1234);
10 changes: 10 additions & 0 deletions tests/test_cases/undefined_syms.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,13 @@ symbol_assignments:

- name: _gp
value: boot_SCOMMON_START + 0x7FF0
hidden: True

- name: provided_sym
value: 0x1234
provide: True

- name: provided_and_hidden_sym
value: 0x1234
provide: True
hidden: True

0 comments on commit d5c2e14

Please sign in to comment.