The top-level settings
attribute specifies many options to customize the
generated linker script. Note that many of these options can be customized per
segment too.
All the settings are optional. Unspecified options will use the default value for it. Note that using certain settings may require specifying other options as well.
- Settings
- Table of Contents
base_path
linker_symbols_style
hardcoded_gp_value
d_path
target_path
symbols_header_path
symbols_header_type
symbols_header_as_array
sections_allowlist
sections_allowlist_extra
sections_denylist
discard_wildcard_section
single_segment_mode
partial_scripts_folder
partial_build_segments_folder
alloc_sections
noload_sections
subalign
segment_start_align
segment_end_align
section_start_align
section_end_align
sections_start_alignment
sections_end_alignment
wildcard_sections
fill_value
sections_subgroups
All the emitted paths are relative to this path. Useful when all the files are
relative to the same directory, like a build
folder.
settings:
base_path: build/us
Any valid path.
Defaults to empty path.
The styling used for the automatically generated linker symbols.
These symbols correspond to the vram and rom address of the segments and the vram address of the sections of the corresponding segment.
To be precise, symbols are generated for the following:
- Segment's rom start, end and size.
- Segment's vram start, end and size.
- Segment's allocatable vram start, end and size.
- Segment's noload vram start, end and size.
- Section's vram start, end and size.
- File's linker offset.
- Vram's class's start, end and size.
settings:
linker_symbols_style: makerom
-
splat
: Produces SCREAMING_CASE symbols. Given a segment namedboot
:- Segment rom:
boot_ROM_START
,boot_ROM_END
andboot_ROM_SIZE
. - Segment vram:
boot_VRAM
,boot_VRAM_END
andboot_VRAM_SIZE
. - Segment allocatable:
boot_alloc_VRAM
,boot_alloc_VRAM_END
andboot_alloc_VRAM_SIZE
. - Segment noload:
boot_noload_VRAM
,boot_noload_VRAM_END
andboot_noload_VRAM_SIZE
. - Section vram (not limited to the foloowing examples):
.text
:boot_TEXT_START
,boot_TEXT_END
andboot_TEXT_SIZE
..data
:boot_DATA_START
,boot_DATA_END
andboot_DATA_SIZE
..bss
:boot_BSS_START
,boot_BSS_END
andboot_BSS_SIZE
.
- File
linker_offset_name
:{name}_OFFSET
. - Vram class:
{name}_VRAM_CLASS_START
,{name}_VRAM_CLASS_END
and{name}_VRAM_CLASS_SIZE
.
- Segment rom:
-
makerom
: Produces _camelCase symbols. Given a segment namedboot
:- Segment rom:
_bootSegmentRomStart
,_bootSegmentRomEnd
and_bootSegmentRomSize
. - Segment vram:
_bootSegmentStart
,_bootSegmentEnd
and_bootSegmentSize
. - Section vram (not limited to the foloowing examples):
.text
:_bootSegmentTextStart
,_bootSegmentTextEnd
and_bootSegmentTextSize
..data
:_bootSegmentDataStart
,_bootSegmentDataEnd
and_bootSegmentDataSize
..bss
:_bootSegmentBssStart
,_bootSegmentBssEnd
and_bootSegmentBssSize
.
- File
linker_offset_name
:_{name}Offset
. - Vram class:
_{name}VramClassStart
,_{name}VramClassEnd
and_{name}VramClassSize
.
- Segment rom:
splat
Emits a _gp
symbol with the specified value, essentially hardcoding the value.
_gp
is requiered for initializing the $gp
register.
This can be useful for decomp projects on the discovering step, but it would be problematic on shiftable builds.
It is strongly recommended to use the gp_info
field of
the corresponding segment instead of hardcoding the _gp
value, since this
will this value to shift properly when modifying the code of the builds.
Providing both gp_info
and a hardcoded_gp_value
is
not a valid combination and slinky will refuse to process the file.
settings:
hardcoded_gp_value: 0x800E4090
A positive integer or null
.
null
Output path for the .d
(dependencies) file.
A dependencies file consists on a file that lists required files to build a
given file. This kind of dependency files can be consumed by build systems like
make
or ninja
.
The generated .d
file will list all the paths listed by every segment as
required to build a given target_path
.
This file is generated only if d_path
is specified.
This option requires target_path
.
settings:
d_path: linker_scripts/game.d
target_path: build/game.elf
Non-empty path.
The path to the file that will result of linking, usually an .elf
file.
Currently only used by the d_path
setting.
settings:
d_path: linker_scripts/game.d
target_path: build/game.elf
Non-empty path.
Path to output a C header containing the generated linker symbols.
The symbols are declared as extern
and their type can be customized with
symbols_header_type
and
symbols_header_as_array
.
This file is generated only if symbols_header_path
is specified.
settings:
symbols_header_path: include/linker_symbols.h
Non-empty path.
The type used for every linker symbol on the generated header.
This option is ignored if symbols_header_path
was not
set.
settings:
symbols_header_path: include/linker_symbols.h
symbols_header_type: u32
Generates entries like:
extern u32 main_BSS_START[];
String
char
Allows customizing if the entries from the generated symbols header should be declared as arrays or not.
This option is ignored if symbols_header_path
was not
set.
settings:
symbols_header_path: include/linker_symbols.h
symbols_header_type: Addr
symbols_header_as_array: False
Generates entries like:
extern Addr main_BSS_START;
Boolean
True
A list of sections to that should be preserved during linking.
Usually used to avoid discarding debugging sections.
settings:
sections_allowlist: [.mdebug, .note, .comment]
List of strings.
[]
A list of sections to that should be preserved during linking.
This setting works the same as same as
sections_allowlist
. This option exists as a way to have
a default list of sections to be preserved that won't be overrided if the user
wants to specify their own allow list by setting sections_allowlist
.
These defaults exists because some linkers (like clang's lld
) complain if some
sections like .shstrtab
are not listed explicitly and a wildcard was used on
the /DISCARD/
section (see
discard_wildcard_section
), seemingly producing
lld
to discard those sections. So to avoid issues when wanting to use other
linkers we emit the section by default.
settings:
sections_allowlist_extra:
- .shstrtab
- .strtab
- .symtab
List of strings.
[.symtab, .strtab, .shstrtab]
List of sections to be discarded.
This option work independently from discard_wildcard_section
.
settings:
sections_denylist: [.reginfo, .got]
List of strings.
[.reginfo, .MIPS.abiflags, .MIPS.options, .note.gnu.build-id, .interp, .eh_frame]
Toggles emitting a discard section with a wildcard (*
) entry, essentially
discarding every section and file that is not explicitly listed on the linker
script.
This option work independently from sections_denylist
.
GNU LD docs for /DISCARD/
: https://sourceware.org/binutils/docs/ld/Output-Section-Discarding.html#index-_002fDISCARD_002f
settings:
discard_wildcard_section: False
Boolean.
True
Change linker script generation to be more similar to an standard linker script, removing the multi-segment handling logic that is used mainly for N64 projects.
With this mode active the emitted sections will correspond directly to
alloc_sections
and noload_sectionss
.
This requires the YAML document to have exactly 1 segment under the
[segments.md#segments](segments.md#segments)
section.
The segments.md#fixed_vram property is used to specify the vram for the first section, then the following sections' vram grow accordingly.
settings:
single_segment_mode: True
Boolean.
False
This setting is used when generating partial linker scripts for incremental linking, thus being ignored during normal linker script generation.
This field holds a path to a folder where the generated partial linker scripts will be written to.
Each partial script will be named like the segment's name with a .ld
file
extension. If dependency generation is enabled then dependency files will be
generated in this folder for each partial linker script, named like the
segment's name and .d
as the file extension.
settings:
partial_scripts_folder: linker_scripts/partial/
Non-empty path.
This setting is used when generating partial linker scripts for incremental linking, thus being ignored during normal linker script generation.
This field holds a path to a folder where each built partial segment will be
placed by the build system in use. Each built partial segment is expected to be
named after the corresponding segment and use a .o
file extension.
This path will be prefixed by the base_path
field during
generation the scripts generation.
settings:
base_path: build/us
partial_scripts_folder: segments/
The above example indicates the built partial segments will be in the
build/us/segments/
Non-empty path.
List of allocatable sections (the ones that take ROM space).
The sections from this list will be emitted for each file in the specified order.
This option can be overriden per segment, see segments.md#alloc_sections for more info.
settings:
alloc_sections: [.rodata, .text, .data]
List of strings.
[.text, .data, .rodata, .sdata]
List of noload sections (the ones that don't take ROM space).
The sections from this list will be emitted for each file in the specified order.
This option can be overriden per segment, see segments.md#noload_sections for more info.
settings:
noload_sections: [.bss]
List of strings.
[.sbss, .scommon, .bss, COMMON]
The value to use in the SUBALIGN
directives.
If the value is null
then disables using SUBALIGN
directives.
GNU LD docs for SUBALIGN
: https://sourceware.org/binutils/docs/ld/Forced-Input-Alignment.html#index-SUBALIGN_0028subsection_005falign_0029
This option can be overriden per segment, see segments.md#subalign for more info.
settings:
subalign: 4
Positive integers or null
.
null
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 for more info.
settings:
segment_start_align: 0x10
Positive integers or null
.
null
Force aligning the end 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_end_align for more info.
settings:
segment_end_align: 0x10
Positive integers or null
.
null
Force aligning the start of each section to the specified value.
If the value is null
then no alignment will be forced on the start of the
sections.
Note that this field and sections_start_alignment
does not override each other, meaning that if this field is non-null
and a
section is specified in sections_start_alignment
then both alignments will be applied to given section.
This option can be overriden per segment, see segments.md#section_start_align for more info.
settings:
section_start_align: 0x10
Positive integers or null
.
null
Force aligning the end of each section to the specified value.
If the value is null
then no alignment will be forced on the end of the
sections.
Note that this field and sections_end_alignment
does not override each other, meaning that if this field is non-null
and a
section is specified in sections_end_alignment
then both alignments will be applied to given section.
This option can be overriden per segment, see segments.md#section_end_align for more info.
settings:
section_end_align: 0x10
Positive integers or null
.
null
Allows to specify different alignments for the start of every section.
If a specific section is not pressent on this mapping then no alignment will be forced on the given section.
Note that this field and section_start_align
does not
override each other, meaning that if a section is specified in this field and
section_start_align
is non-null
then both alignments
will be applied to the section.
This option can be overriden per segment, see segments.md#sections_start_alignment for more info.
settings:
sections_start_alignment: { .text: 128, .rodata: 0x40, .sdata: 0x8 }
A mapping of strings as keys and positive numbers as values.
Empty mapping.
Allows to specify different alignments for the end of every section.
If a specific section is not pressent on this mapping then no alignment will be forced on the given section.
Note that this field and section_end_align
does not
override each other, meaning that if a section is specified in this field and
section_end_align
is non-null
then both alignments
will be applied to the section.
This option can be overriden per segment, see segments.md#sections_end_alignment for more info.
settings:
sections_end_alignment: { .text: 128, .rodata: 0x40, .sdata: 0x8 }
A mapping of strings as keys and positive numbers as values.
Empty mapping.
Toggles using wildcards (*
) as suffix in the emitted sections.
For example the .rodata
section would be emitted as .rodata*
if this option
is enabled.
This option can be overriden per segment, see segments.md#wildcard_sections for more info.
settings:
wildcard_sections: False
Boolean
True
Allows to specify the value of the FILL
statement emitted for every segment of
the linker script.
If the value is null
then no FILL
statements will be emitted.
GNU LD docs for FILL
: https://sourceware.org/binutils/docs/ld/Output-Section-Data.html#index-FILL_0028expression_0029
This option can be overriden per segment, see segments.md#fill_value for more info.
settings:
fill_value: 0xA1F
Which emits the following FILL
statement:
FILL(0x00000A1F);
Positive integers or null
.
0
Allows to specify one or multiple sections that should be emitted alongside another section for each file, instead of getting their own "proper" section.
This setting can be overriden per segment. See the
sections_subgroups
on the segments
document.
settings:
sections_subgroups: { .rodata: [.rdata], .text: [.ctor, .dtor] }
segments:
- name: boot
files:
- { path: boot_main.o }
- { path: utils.o }
The above example produces output like the following (stripped a bit for demostrative reasons):
/* -- SNIP -- */
boot_TEXT_START = .;
boot_main.o(.text*);
boot_main.o(.ctor*);
boot_main.o(.dtor*);
utils.o(.text*);
utils.o(.ctor*);
utils.o(.dtor*);
boot_TEXT_END = .;
boot_TEXT_SIZE = ABSOLUTE(boot_TEXT_END - boot_TEXT_START);
/* -- SNIP -- */
boot_RODATA_START = .;
boot_main.o(.rodata*);
boot_main.o(.rdata*);
utils.o(.rodata*);
utils.o(.rdata*);
boot_RODATA_END = .;
boot_RODATA_SIZE = ABSOLUTE(boot_RODATA_END - boot_RODATA_START);
/* -- SNIP -- */
Note how .ctor
and .dtor
sections are emitted alongside the .text
sections
and they are emitted within the TEXT
group. Same for .rdata
being emitted
alongside .rodata
sections.
A mapping of sections (strings) as keys and a list of sections (strings) as values.
Empty mapping.