Skip to content

Commit

Permalink
ld_align_segment_start (#373)
Browse files Browse the repository at this point in the history
* Implement ld_align_segment_start

* docs and changelog

* black
  • Loading branch information
AngheloAlf authored May 31, 2024
1 parent e3bf97d commit da07fcb
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### 0.24.3

* New yaml option: `ld_align_segment_start`
* Allows specifying an alignment for the start of all the segments.
* The alignment can be overriden or disabled per segment too.
* Add `visibility` attribute to symbols.
* Allows to specify if a symbol should be declared as `local`, `weak`, etc in the disassembly.
* `spimdisasm` 1.26.0 or above is now required
Expand Down
12 changes: 11 additions & 1 deletion docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,6 @@ This behavior can be customized per segment too. See [ld_fill_value](Segments.md

Defaults to 0.


### ld_bss_is_noload

Allows to control if `bss` sections (and derivatived sections) will be put on a `NOLOAD` segment on the generated linker script or not.
Expand All @@ -437,6 +436,17 @@ Applies to all `bss` (`sbss`, `common`, `scommon`, etc) sections.
Defaults to `True`, meaning `bss` sections will be put on `NOLOAD` segments.


### ld_align_segment_start

Specify that segments should be aligned before starting them.

This option specifies the desired alignment value, or `null` if no aligment should be imposed on the segment start.

This behavior can be customized per segment too. See [ld_align_segment_start](Segments.md#ld_align_segment_start) on the Segments section.

Defaults to `null`.


### ld_align_segment_vram_end

Allows to toggle aligning the `*_VRAM_END` linker symbol of each segment.
Expand Down
8 changes: 8 additions & 0 deletions docs/Segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,14 @@ If not set, then the global configuration is used. See [ld_fill_value](Configura

Defaults to the value of the global option.

### `ld_align_segment_start`

Specify the current segment should be aligned before starting it.

This option specifies the desired alignment value, or `null` if no aligment should be imposed on the segment start.

If not set, then the global configuration is used. See [ld_align_segment_start](Configuration.md#ld_align_segment_start) on the Configuration section.

### `subalign`

Sub-alignment (in bytes) of sections.
Expand Down
18 changes: 18 additions & 0 deletions src/splat/segtypes/linker_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ def add(self, segment: Segment, max_vram_syms: List[Tuple[str, List[Segment]]]):
any_noload = any_noload or entry.noload
prev_entry = entry.section_order_type

if segment.ld_align_segment_start:
self._write_symbol(
"__romPos", f"ALIGN(__romPos, 0x{segment.ld_align_segment_start:X})"
)
self._write_symbol(".", f"ALIGN(., 0x{segment.ld_align_segment_start:X})")

seg_rom_start = get_segment_rom_start(seg_name)
self._write_symbol(seg_rom_start, "__romPos")

Expand Down Expand Up @@ -305,6 +311,12 @@ def add_legacy(self, segment: Segment, entries: List[LinkerEntry]):
):
last_seen_sections[entry] = entry.section_order_type

if segment.ld_align_segment_start:
self._write_symbol(
"__romPos", f"ALIGN(__romPos, 0x{segment.ld_align_segment_start:X})"
)
self._write_symbol(".", f"ALIGN(., 0x{segment.ld_align_segment_start:X})")

seg_rom_start = get_segment_rom_start(seg_name)
self._write_symbol(seg_rom_start, "__romPos")

Expand Down Expand Up @@ -359,6 +371,12 @@ def add_referenced_partial_segment(
for sym, segs in max_vram_syms:
self.write_max_vram_end_sym(sym, segs)

if segment.ld_align_segment_start:
self._write_symbol(
"__romPos", f"ALIGN(__romPos, 0x{segment.ld_align_segment_start:X})"
)
self._write_symbol(".", f"ALIGN(., 0x{segment.ld_align_segment_start:X})")

seg_rom_start = get_segment_rom_start(seg_name)
self._write_symbol(seg_rom_start, "__romPos")

Expand Down
10 changes: 10 additions & 0 deletions src/splat/segtypes/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ def parse_ld_fill_value(
return yaml["ld_fill_value"]
return default

@staticmethod
def parse_ld_align_segment_start(yaml: Union[dict, list]) -> Optional[int]:
if isinstance(yaml, dict) and "ld_align_segment_start" in yaml:
return yaml["ld_align_segment_start"]
return options.opts.ld_align_segment_start

def __init__(
self,
rom_start: Optional[int],
Expand Down Expand Up @@ -288,6 +294,10 @@ def __init__(
yaml, options.opts.ld_fill_value
)

self.ld_align_segment_start: Optional[int] = self.parse_ld_align_segment_start(
yaml
)

# True if this segment was generated based on auto_all_sections
self.is_auto_all: bool = False

Expand Down
5 changes: 5 additions & 0 deletions src/splat/util/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class SplatOpts:
ld_fill_value: Optional[int]
# Allows to control if `bss` sections (and derivatived sections) will be put on a `NOLOAD` segment on the generated linker script or not.
ld_bss_is_noload: bool
# Aligns the start of the segment to the given value
ld_align_segment_start: Optional[int]
# Allows to toggle aligning the `*_VRAM_END` linker symbol for each segment.
ld_align_segment_vram_end: bool
# Allows to toggle aligning the `*_END` linker symbol for each section of each section.
Expand Down Expand Up @@ -448,6 +450,9 @@ def parse_endianness() -> Literal["big", "little"]:
ld_bss_is_noload=p.parse_opt(
"ld_bss_is_noload", bool, default_ld_bss_is_noload
),
ld_align_segment_start=p.parse_optional_opt_with_default(
"ld_align_segment_start", int, None
),
ld_align_segment_vram_end=p.parse_opt("ld_align_segment_vram_end", bool, True),
ld_align_section_vram_end=p.parse_opt("ld_align_section_vram_end", bool, True),
ld_generate_symbol_per_data_segment=p.parse_opt(
Expand Down

0 comments on commit da07fcb

Please sign in to comment.