Skip to content

Commit

Permalink
Implement follows_segment
Browse files Browse the repository at this point in the history
Fixes #43
  • Loading branch information
AngheloAlf committed Feb 28, 2024
1 parent 0714aa0 commit cda0176
Show file tree
Hide file tree
Showing 4 changed files with 269 additions and 2 deletions.
2 changes: 2 additions & 0 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ impl LinkerWriter<'_> {
} else {
if let Some(fixed_vram) = segment.fixed_vram {
line += &format!(" 0x{:08X}", fixed_vram);
} else if let Some(follows_segment) = &segment.follows_segment {
line += &format!(" {}", &style.segment_vram_end(follows_segment));
}

line += &format!(" : AT({})", style.segment_rom_start(&segment.name));
Expand Down
23 changes: 21 additions & 2 deletions slinky/src/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ pub struct Segment {
/// List of files corresponding to this segment
pub files: Vec<FileInfo>,

/// If not None then forces the segment to have a fixed vram address instead of following the previous segment
/// If not None then forces the segment to have a fixed vram address instead of following the previous segment.
/// Not compatible with `follows_segment`.
pub fixed_vram: Option<u32>,

/// If not None then forces the segment's vram address to be after the specified segment instead of following the previous one.
/// Not compatible with `fixed_vram`.
pub follows_segment: Option<String>,

// The default value of the following members come from Settings
pub alloc_sections: Vec<String>,
pub noload_sections: Vec<String>,
Expand All @@ -39,6 +44,8 @@ pub(crate) struct SegmentSerial {

pub fixed_vram: AbsentNullable<u32>,

pub follows_segment: AbsentNullable<String>,

// The default of the following come from Options
#[serde(default)]
pub alloc_sections: AbsentNullable<Vec<String>>,
Expand Down Expand Up @@ -79,6 +86,17 @@ impl SegmentSerial {
.fixed_vram
.get_optional_nullable("fixed_vram", || None)?;

let follows_segment = self
.follows_segment
.get_optional_nullable("follows_segment", || None)?;

if fixed_vram.is_some() && follows_segment.is_some() {
return Err(SlinkyError::InvalidFieldCombo {
field1: "fixed_vram".to_string(),
field2: "follows_segment".to_string(),
});
}

let alloc_sections = self
.alloc_sections
.get_non_null("alloc_sections", || settings.alloc_sections.clone())?;
Expand All @@ -101,9 +119,10 @@ impl SegmentSerial {
Ok(Segment {
name,
files,
fixed_vram,
follows_segment,
alloc_sections,
noload_sections,
fixed_vram,
subalign,
wildcard_sections,
fill_value,
Expand Down
19 changes: 19 additions & 0 deletions tests/input_files/follow_segment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
settings:
base_path: build

segments:
- name: boot
files:
- { path: src/main/boot_main.o }
- { path: src/libultra.o } # yes a single file, deal with it

- name: kanji
files:
- { path: src/kanji/kanji.o }

- name: main
follows_segment: boot
files:
- { path: src/main/main.o }
- { path: src/main/dmadata.o }
- { path: asm/main/util.o }
227 changes: 227 additions & 0 deletions tests/linker_scripts/follow_segment.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
SECTIONS
{
__romPos = 0x0;

boot_ROM_START = __romPos;
boot_VRAM = ADDR(.boot);
boot_alloc_VRAM = .;
.boot : AT(boot_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
boot_TEXT_START = .;
build/src/main/boot_main.o(.text*);
build/src/libultra.o(.text*);
boot_TEXT_END = .;
boot_TEXT_SIZE = ABSOLUTE(boot_TEXT_END - boot_TEXT_START);

boot_DATA_START = .;
build/src/main/boot_main.o(.data*);
build/src/libultra.o(.data*);
boot_DATA_END = .;
boot_DATA_SIZE = ABSOLUTE(boot_DATA_END - boot_DATA_START);

boot_RODATA_START = .;
build/src/main/boot_main.o(.rodata*);
build/src/libultra.o(.rodata*);
boot_RODATA_END = .;
boot_RODATA_SIZE = ABSOLUTE(boot_RODATA_END - boot_RODATA_START);

boot_SDATA_START = .;
build/src/main/boot_main.o(.sdata*);
build/src/libultra.o(.sdata*);
boot_SDATA_END = .;
boot_SDATA_SIZE = ABSOLUTE(boot_SDATA_END - boot_SDATA_START);
}
boot_alloc_VRAM_END = .;
boot_alloc_VRAM_SIZE = ABSOLUTE(boot_alloc_VRAM_END - boot_alloc_VRAM);

boot_noload_VRAM = .;
.boot.noload (NOLOAD) : SUBALIGN(16)
{
FILL(0x00000000);
boot_SBSS_START = .;
build/src/main/boot_main.o(.sbss*);
build/src/libultra.o(.sbss*);
boot_SBSS_END = .;
boot_SBSS_SIZE = ABSOLUTE(boot_SBSS_END - boot_SBSS_START);

boot_SCOMMON_START = .;
build/src/main/boot_main.o(.scommon*);
build/src/libultra.o(.scommon*);
boot_SCOMMON_END = .;
boot_SCOMMON_SIZE = ABSOLUTE(boot_SCOMMON_END - boot_SCOMMON_START);

boot_BSS_START = .;
build/src/main/boot_main.o(.bss*);
build/src/libultra.o(.bss*);
boot_BSS_END = .;
boot_BSS_SIZE = ABSOLUTE(boot_BSS_END - boot_BSS_START);

bootCOMMON_START = .;
build/src/main/boot_main.o(COMMON*);
build/src/libultra.o(COMMON*);
bootCOMMON_END = .;
bootCOMMON_SIZE = ABSOLUTE(bootCOMMON_END - bootCOMMON_START);
}
boot_noload_VRAM_END = .;
boot_noload_VRAM_SIZE = ABSOLUTE(boot_noload_VRAM_END - boot_noload_VRAM);
boot_VRAM_END = .;
boot_VRAM_SIZE = ABSOLUTE(boot_VRAM_END - boot_VRAM);
__romPos += SIZEOF(.boot);
boot_ROM_END = __romPos;
boot_ROM_SIZE = ABSOLUTE(boot_ROM_END - boot_ROM_START);

kanji_ROM_START = __romPos;
kanji_VRAM = ADDR(.kanji);
kanji_alloc_VRAM = .;
.kanji : AT(kanji_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
kanji_TEXT_START = .;
build/src/kanji/kanji.o(.text*);
kanji_TEXT_END = .;
kanji_TEXT_SIZE = ABSOLUTE(kanji_TEXT_END - kanji_TEXT_START);

kanji_DATA_START = .;
build/src/kanji/kanji.o(.data*);
kanji_DATA_END = .;
kanji_DATA_SIZE = ABSOLUTE(kanji_DATA_END - kanji_DATA_START);

kanji_RODATA_START = .;
build/src/kanji/kanji.o(.rodata*);
kanji_RODATA_END = .;
kanji_RODATA_SIZE = ABSOLUTE(kanji_RODATA_END - kanji_RODATA_START);

kanji_SDATA_START = .;
build/src/kanji/kanji.o(.sdata*);
kanji_SDATA_END = .;
kanji_SDATA_SIZE = ABSOLUTE(kanji_SDATA_END - kanji_SDATA_START);
}
kanji_alloc_VRAM_END = .;
kanji_alloc_VRAM_SIZE = ABSOLUTE(kanji_alloc_VRAM_END - kanji_alloc_VRAM);

kanji_noload_VRAM = .;
.kanji.noload (NOLOAD) : SUBALIGN(16)
{
FILL(0x00000000);
kanji_SBSS_START = .;
build/src/kanji/kanji.o(.sbss*);
kanji_SBSS_END = .;
kanji_SBSS_SIZE = ABSOLUTE(kanji_SBSS_END - kanji_SBSS_START);

kanji_SCOMMON_START = .;
build/src/kanji/kanji.o(.scommon*);
kanji_SCOMMON_END = .;
kanji_SCOMMON_SIZE = ABSOLUTE(kanji_SCOMMON_END - kanji_SCOMMON_START);

kanji_BSS_START = .;
build/src/kanji/kanji.o(.bss*);
kanji_BSS_END = .;
kanji_BSS_SIZE = ABSOLUTE(kanji_BSS_END - kanji_BSS_START);

kanjiCOMMON_START = .;
build/src/kanji/kanji.o(COMMON*);
kanjiCOMMON_END = .;
kanjiCOMMON_SIZE = ABSOLUTE(kanjiCOMMON_END - kanjiCOMMON_START);
}
kanji_noload_VRAM_END = .;
kanji_noload_VRAM_SIZE = ABSOLUTE(kanji_noload_VRAM_END - kanji_noload_VRAM);
kanji_VRAM_END = .;
kanji_VRAM_SIZE = ABSOLUTE(kanji_VRAM_END - kanji_VRAM);
__romPos += SIZEOF(.kanji);
kanji_ROM_END = __romPos;
kanji_ROM_SIZE = ABSOLUTE(kanji_ROM_END - kanji_ROM_START);

main_ROM_START = __romPos;
main_VRAM = ADDR(.main);
main_alloc_VRAM = .;
.main boot_VRAM_END : AT(main_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
main_TEXT_START = .;
build/src/main/main.o(.text*);
build/src/main/dmadata.o(.text*);
build/asm/main/util.o(.text*);
main_TEXT_END = .;
main_TEXT_SIZE = ABSOLUTE(main_TEXT_END - main_TEXT_START);

main_DATA_START = .;
build/src/main/main.o(.data*);
build/src/main/dmadata.o(.data*);
build/asm/main/util.o(.data*);
main_DATA_END = .;
main_DATA_SIZE = ABSOLUTE(main_DATA_END - main_DATA_START);

main_RODATA_START = .;
build/src/main/main.o(.rodata*);
build/src/main/dmadata.o(.rodata*);
build/asm/main/util.o(.rodata*);
main_RODATA_END = .;
main_RODATA_SIZE = ABSOLUTE(main_RODATA_END - main_RODATA_START);

main_SDATA_START = .;
build/src/main/main.o(.sdata*);
build/src/main/dmadata.o(.sdata*);
build/asm/main/util.o(.sdata*);
main_SDATA_END = .;
main_SDATA_SIZE = ABSOLUTE(main_SDATA_END - main_SDATA_START);
}
main_alloc_VRAM_END = .;
main_alloc_VRAM_SIZE = ABSOLUTE(main_alloc_VRAM_END - main_alloc_VRAM);

main_noload_VRAM = .;
.main.noload (NOLOAD) : SUBALIGN(16)
{
FILL(0x00000000);
main_SBSS_START = .;
build/src/main/main.o(.sbss*);
build/src/main/dmadata.o(.sbss*);
build/asm/main/util.o(.sbss*);
main_SBSS_END = .;
main_SBSS_SIZE = ABSOLUTE(main_SBSS_END - main_SBSS_START);

main_SCOMMON_START = .;
build/src/main/main.o(.scommon*);
build/src/main/dmadata.o(.scommon*);
build/asm/main/util.o(.scommon*);
main_SCOMMON_END = .;
main_SCOMMON_SIZE = ABSOLUTE(main_SCOMMON_END - main_SCOMMON_START);

main_BSS_START = .;
build/src/main/main.o(.bss*);
build/src/main/dmadata.o(.bss*);
build/asm/main/util.o(.bss*);
main_BSS_END = .;
main_BSS_SIZE = ABSOLUTE(main_BSS_END - main_BSS_START);

mainCOMMON_START = .;
build/src/main/main.o(COMMON*);
build/src/main/dmadata.o(COMMON*);
build/asm/main/util.o(COMMON*);
mainCOMMON_END = .;
mainCOMMON_SIZE = ABSOLUTE(mainCOMMON_END - mainCOMMON_START);
}
main_noload_VRAM_END = .;
main_noload_VRAM_SIZE = ABSOLUTE(main_noload_VRAM_END - main_noload_VRAM);
main_VRAM_END = .;
main_VRAM_SIZE = ABSOLUTE(main_VRAM_END - main_VRAM);
__romPos += SIZEOF(.main);
main_ROM_END = __romPos;
main_ROM_SIZE = ABSOLUTE(main_ROM_END - main_ROM_START);

.shstrtab 0 :
{
*(.shstrtab);
}

/DISCARD/ :
{
*(.reginfo);
*(.MIPS.abiflags);
*(.MIPS.options);
*(.note.gnu.build-id);
*(.interp);
*(.eh_frame);
*(*);
}
}

0 comments on commit cda0176

Please sign in to comment.