From c83af881a44a0235faa469fc40d7bf1795cae46c Mon Sep 17 00:00:00 2001 From: Angie Date: Wed, 14 Aug 2024 12:53:04 -0400 Subject: [PATCH] Add support to specify the entrypoint Closes #54 --- CHANGELOG.md | 2 ++ docs/file_format/README.md | 13 +++++++++++++ slinky/src/document.rs | 6 ++++++ slinky/src/linker_writer.rs | 10 ++++++++++ slinky/src/partial_linker_writer.rs | 4 ++++ slinky/src/traits.rs | 4 ++++ tests/partial_linking/follow_segment.ld | 2 ++ tests/partial_linking/follow_segment.yaml | 2 ++ tests/test_cases/drmario64.ld | 2 ++ tests/test_cases/drmario64.yaml | 2 ++ 10 files changed, 47 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48cac4d..1a9d998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add way to define a non hardcoded `_gp` symbol for a given segment. - Used by defining the `gp_info` field on a segment. - Can't be combined with the global `hardcoded_gp_value`. +- Add new top-level attribute for the file format: `entry`. + - Specifies the entrypoint for the build. ### Changed diff --git a/docs/file_format/README.md b/docs/file_format/README.md index b2872f1..e8a1188 100644 --- a/docs/file_format/README.md +++ b/docs/file_format/README.md @@ -6,6 +6,19 @@ attribute. Other optional top-level attributes may be specified, like [vram_classes](vram_classes.md) or [symbol_assignments](symbol_assignments.md). Check their specific documents for in-deep explanations. +## Format itself + +The document is composed by the following top-level attributes: + +- [`settings`](settings.md). +- A list of [`vram_classes`](vram_classes.md). +- A list of [`segments`](segments.md). + - This list is required. +- `entry` + - A single optional string that specifies the entrypoint of the final build. +- A list of [`symbol_assignments`](symbol_assignments.md). +- A list of [`required_symbols`](required_symbols.md). + ## Example The following example corresponds to the diff --git a/slinky/src/document.rs b/slinky/src/document.rs index a965c88..3784551 100644 --- a/slinky/src/document.rs +++ b/slinky/src/document.rs @@ -20,6 +20,7 @@ pub struct Document { pub segments: Vec, + pub entry: Option, pub symbol_assignments: Vec, pub required_symbols: Vec, } @@ -59,6 +60,8 @@ pub(crate) struct DocumentSerial { pub segments: Vec, + #[serde(default)] + pub entry: AbsentNullable, #[serde(default)] pub symbol_assignments: AbsentNullable>, #[serde(default)] @@ -85,6 +88,8 @@ impl DocumentSerial { let segments = self.segments.unserialize(&settings)?; + let entry = self.entry.get_non_null_no_default("entry")?; + let symbol_assignments = self .symbol_assignments .get_non_null("symbol_assignments", Vec::new)? @@ -99,6 +104,7 @@ impl DocumentSerial { settings, vram_classes, segments, + entry, symbol_assignments, required_symbols, }) diff --git a/slinky/src/linker_writer.rs b/slinky/src/linker_writer.rs index 6c5d1d4..6e26658 100644 --- a/slinky/src/linker_writer.rs +++ b/slinky/src/linker_writer.rs @@ -94,6 +94,16 @@ impl ScriptImporter for LinkerWriter<'_> { Ok(()) } + fn add_entry(&mut self, entry: &str) -> Result<(), SlinkyError> { + if !self.buffer.is_empty() { + self.buffer.write_empty_line(); + } + + self.buffer.writeln(&format!("ENTRY({});", entry)); + + Ok(()) + } + fn add_all_symbol_assignments( &mut self, symbol_assignments: &[SymbolAssignment], diff --git a/slinky/src/partial_linker_writer.rs b/slinky/src/partial_linker_writer.rs index 6638111..d111515 100644 --- a/slinky/src/partial_linker_writer.rs +++ b/slinky/src/partial_linker_writer.rs @@ -75,6 +75,10 @@ impl ScriptImporter for PartialLinkerWriter<'_> { Ok(()) } + fn add_entry(&mut self, entry: &str) -> Result<(), SlinkyError> { + self.main_writer.add_entry(entry) + } + fn add_all_symbol_assignments( &mut self, symbol_assignments: &[SymbolAssignment], diff --git a/slinky/src/traits.rs b/slinky/src/traits.rs index c4749c3..81412f6 100644 --- a/slinky/src/traits.rs +++ b/slinky/src/traits.rs @@ -30,6 +30,7 @@ mod private { pub trait ScriptImporter: private::Sealed { fn add_all_segments(&mut self, segments: &[Segment]) -> Result<(), SlinkyError>; + fn add_entry(&mut self, entry: &str) -> Result<(), SlinkyError>; fn add_all_symbol_assignments( &mut self, symbol_assignments: &[SymbolAssignment], @@ -41,6 +42,9 @@ pub trait ScriptImporter: private::Sealed { fn add_whole_document(&mut self, document: &Document) -> Result<(), SlinkyError> { self.add_all_segments(&document.segments)?; + if let Some(entry) = &document.entry { + self.add_entry(entry)?; + } self.add_all_symbol_assignments(&document.symbol_assignments)?; self.add_all_required_symbols(&document.required_symbols)?; diff --git a/tests/partial_linking/follow_segment.ld b/tests/partial_linking/follow_segment.ld index c1d6aba..b80f768 100644 --- a/tests/partial_linking/follow_segment.ld +++ b/tests/partial_linking/follow_segment.ld @@ -346,3 +346,5 @@ SECTIONS *(*); } } + +ENTRY(ENTRYPOINT); diff --git a/tests/partial_linking/follow_segment.yaml b/tests/partial_linking/follow_segment.yaml index 67dbce0..5a1f9a0 100644 --- a/tests/partial_linking/follow_segment.yaml +++ b/tests/partial_linking/follow_segment.yaml @@ -43,3 +43,5 @@ segments: - { path: src/main/main.o } - { path: src/main/dmadata.o } - { path: asm/main/util.o } + +entry: ENTRYPOINT diff --git a/tests/test_cases/drmario64.ld b/tests/test_cases/drmario64.ld index 5f84e23..af5e115 100644 --- a/tests/test_cases/drmario64.ld +++ b/tests/test_cases/drmario64.ld @@ -8093,3 +8093,5 @@ SECTIONS *(*); } } + +ENTRY(entrypoint); diff --git a/tests/test_cases/drmario64.yaml b/tests/test_cases/drmario64.yaml index 73b567c..9230dae 100644 --- a/tests/test_cases/drmario64.yaml +++ b/tests/test_cases/drmario64.yaml @@ -781,3 +781,5 @@ segments: fixed_vram: 0x0 files: - { path: src/assets/tutorial/tutorial_kasa.o } + +entry: entrypoint