Skip to content

Commit

Permalink
Implement segment_start_align
Browse files Browse the repository at this point in the history
Fixes #21
  • Loading branch information
AngheloAlf committed Feb 28, 2024
1 parent de04bde commit 7058bca
Show file tree
Hide file tree
Showing 13 changed files with 1,140 additions and 825 deletions.
30 changes: 29 additions & 1 deletion docs/file_format/segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,33 @@ Positive integers or `null`.

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

## `segment_start_align`

Force aligning the beginning of this specific segment to the specified value.

If the value is `null` then no alignment will be forced at the start of this
specific segment.

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

### Example

```yaml
segments:
- name: gameplay_keep
segment_start_align: 0x1000
```

### Valid values

Positive integers or `null`.

### Default value

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

## `section_end_align`

Force aligning the end of each section for this segment to the specified value.
Expand All @@ -178,7 +205,8 @@ Positive integers or `null`.

### Default value

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

## `wildcard_sections`

Expand Down
24 changes: 24 additions & 0 deletions docs/file_format/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,30 @@ Positive integers or `null`.

`0x10`

## `segment_start_align`

Force aligning the beginning of the segment to the specified value.

If the value is `null` then no alignment will be forced.

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

### Example

```yaml
settings:
segment_start_align: 0x10
```

### Valid values

Positive integers or `null`.

### Default value

`null`

## `section_end_align`

Force aligning the end of each section to the specified value.
Expand Down
15 changes: 13 additions & 2 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ impl<'a> LinkerWriter<'a> {
let main_seg_sym_end: String = style.segment_vram_end(&segment.name);
let main_seg_sym_size: String = style.segment_vram_size(&segment.name);

if let Some(segment_start_align) = segment.segment_start_align {
self.align_symbol("__romPos", segment_start_align);
self.align_symbol(".", segment_start_align);
}

self.write_symbol(&main_seg_rom_sym_start, "__romPos");
self.write_symbol(&main_seg_sym_start, &format!("ADDR({})", dotted_seg_name));

Expand All @@ -138,7 +143,6 @@ impl<'a> LinkerWriter<'a> {
);

self.writeln(&format!("__romPos += SIZEOF({});", dotted_seg_name));
// self.writeln(&format!("__romPos = ALIGN(__romPos, {});", ));
self.write_sym_end_size(
&main_seg_rom_sym_start,
&main_seg_rom_sym_end,
Expand Down Expand Up @@ -230,6 +234,13 @@ impl LinkerWriter<'_> {
self.linker_symbols.insert(value.to_string());
}

fn align_symbol(&mut self, symbol: &str, align_value: u32) {
self.writeln(&format!(
"{} = ALIGN({}, 0x{:X});",
symbol, symbol, align_value
));
}

fn write_sym_end_size(&mut self, start: &str, end: &str, size: &str, value: &str) {
self.write_symbol(end, value);

Expand Down Expand Up @@ -355,7 +366,7 @@ impl LinkerWriter<'_> {
self.emit_section(segment, section);

if let Some(section_end_align) = segment.section_end_align {
self.writeln(&format!(". = ALIGN(0x{:X})", section_end_align));
self.align_symbol(".", section_end_align);
}
self.write_sym_end_size(&section_start_sym, &section_end_sym, &section_size_sym, ".");

Expand Down
8 changes: 8 additions & 0 deletions slinky/src/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct Segment {
pub noload_sections: Vec<String>,

pub subalign: Option<u32>,
pub segment_start_align: Option<u32>,
pub section_end_align: Option<u32>,

pub wildcard_sections: bool,
Expand All @@ -56,6 +57,8 @@ pub(crate) struct SegmentSerial {
#[serde(default)]
pub subalign: AbsentNullable<u32>,
#[serde(default)]
pub segment_start_align: AbsentNullable<u32>,
#[serde(default)]
pub section_end_align: AbsentNullable<u32>,

#[serde(default)]
Expand Down Expand Up @@ -111,6 +114,10 @@ impl SegmentSerial {
.subalign
.get_optional_nullable("subalign", || settings.subalign)?;

let segment_start_align = self
.segment_start_align
.get_optional_nullable("segment_start_align", || settings.segment_start_align)?;

let section_end_align = self
.section_end_align
.get_optional_nullable("section_end_align", || settings.section_end_align)?;
Expand All @@ -131,6 +138,7 @@ impl SegmentSerial {
alloc_sections,
noload_sections,
subalign,
segment_start_align,
section_end_align,
wildcard_sections,
fill_value,
Expand Down
13 changes: 13 additions & 0 deletions slinky/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Settings {
pub noload_sections: Vec<String>,

pub subalign: Option<u32>,
pub segment_start_align: Option<u32>,
pub section_end_align: Option<u32>,

pub wildcard_sections: bool,
Expand Down Expand Up @@ -91,6 +92,10 @@ fn settings_default_subalign() -> Option<u32> {
Some(0x10)
}

fn settings_default_segment_start_align() -> Option<u32> {
None
}

fn settings_default_section_end_align() -> Option<u32> {
Some(0x10)
}
Expand Down Expand Up @@ -120,6 +125,7 @@ impl Default for Settings {
noload_sections: settings_default_noload_sections(),

subalign: settings_default_subalign(),
segment_start_align: settings_default_segment_start_align(),
section_end_align: settings_default_section_end_align(),

wildcard_sections: settings_default_wildcard_sections(),
Expand Down Expand Up @@ -158,6 +164,8 @@ pub(crate) struct SettingsSerial {
#[serde(default)]
pub subalign: AbsentNullable<u32>,
#[serde(default)]
pub segment_start_align: AbsentNullable<u32>,
#[serde(default)]
pub section_end_align: AbsentNullable<u32>,

#[serde(default)]
Expand Down Expand Up @@ -207,6 +215,10 @@ impl SettingsSerial {
.subalign
.get_optional_nullable("subalign", settings_default_subalign)?;

let segment_start_align = self
.segment_start_align
.get_optional_nullable("segment_start_align", settings_default_segment_start_align)?;

let section_end_align = self
.section_end_align
.get_optional_nullable("section_end_align", settings_default_section_end_align)?;
Expand All @@ -230,6 +242,7 @@ impl SettingsSerial {
alloc_sections,
noload_sections,
subalign,
segment_start_align,
section_end_align,
wildcard_sections,
fill_value,
Expand Down
20 changes: 19 additions & 1 deletion tests/input_files/makerom_zelda_like.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ settings:

segments:
- name: makerom
alloc_sections: [".data", ".text", ".rodata"]
fixed_vram: 0x80024C00
alloc_sections: [".data", ".text", ".rodata"]
files:
- { path: makerom/header.o }
- { path: makerom/ipl3.o }
Expand All @@ -15,3 +15,21 @@ segments:
- name: boot
files:
- { path: boot/boot_main.o }

- name: gameplay_keep
fixed_vram: 0x04000000
segment_start_align: 0x1000
files:
- { path: assets/objects/gameplay_keep/gameplay_keep.o }

- name: gameplay_dangeon_keep
fixed_vram: 0x05000000
segment_start_align: 0x1000
files:
- { path: assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.o }

- name: gameplay_dangeon_keep
fixed_vram: 0x05000000
segment_start_align: 0x1000
files:
- { path: assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.o }
16 changes: 8 additions & 8 deletions tests/linker_scripts/archives.ld
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.text*);
build/lib/libmus.a:lib_memory.o(.text*);
build/lib/libmus.a:aud_samples.o(.text*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_TEXT_END = .;
boot_TEXT_SIZE = ABSOLUTE(boot_TEXT_END - boot_TEXT_START);

Expand All @@ -36,7 +36,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.data*);
build/lib/libmus.a:lib_memory.o(.data*);
build/lib/libmus.a:aud_samples.o(.data*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_DATA_END = .;
boot_DATA_SIZE = ABSOLUTE(boot_DATA_END - boot_DATA_START);

Expand All @@ -52,7 +52,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.rodata*);
build/lib/libmus.a:lib_memory.o(.rodata*);
build/lib/libmus.a:aud_samples.o(.rodata*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_RODATA_END = .;
boot_RODATA_SIZE = ABSOLUTE(boot_RODATA_END - boot_RODATA_START);

Expand All @@ -68,7 +68,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.sdata*);
build/lib/libmus.a:lib_memory.o(.sdata*);
build/lib/libmus.a:aud_samples.o(.sdata*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_SDATA_END = .;
boot_SDATA_SIZE = ABSOLUTE(boot_SDATA_END - boot_SDATA_START);
}
Expand All @@ -91,7 +91,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.sbss*);
build/lib/libmus.a:lib_memory.o(.sbss*);
build/lib/libmus.a:aud_samples.o(.sbss*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_SBSS_END = .;
boot_SBSS_SIZE = ABSOLUTE(boot_SBSS_END - boot_SBSS_START);

Expand All @@ -107,7 +107,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.scommon*);
build/lib/libmus.a:lib_memory.o(.scommon*);
build/lib/libmus.a:aud_samples.o(.scommon*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_SCOMMON_END = .;
boot_SCOMMON_SIZE = ABSOLUTE(boot_SCOMMON_END - boot_SCOMMON_START);

Expand All @@ -123,7 +123,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(.bss*);
build/lib/libmus.a:lib_memory.o(.bss*);
build/lib/libmus.a:aud_samples.o(.bss*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
boot_BSS_END = .;
boot_BSS_SIZE = ABSOLUTE(boot_BSS_END - boot_BSS_START);

Expand All @@ -139,7 +139,7 @@ SECTIONS
build/lib/libmus.a:aud_thread.o(COMMON*);
build/lib/libmus.a:lib_memory.o(COMMON*);
build/lib/libmus.a:aud_samples.o(COMMON*);
. = ALIGN(0x10)
. = ALIGN(., 0x10);
bootCOMMON_END = .;
bootCOMMON_SIZE = ABSOLUTE(bootCOMMON_END - bootCOMMON_START);
}
Expand Down
Loading

0 comments on commit 7058bca

Please sign in to comment.