mirror of
https://github.com/devkitPro/buildscripts.git
synced 2026-04-24 14:59:35 -05:00
updated linkscripts
This commit is contained in:
parent
e005d43fff
commit
63952c3991
285
dkppc/crtls/gcbogc.ld
Normal file
285
dkppc/crtls/gcbogc.ld
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Linkscript for GC, automatically sets up DOL structures,
|
||||
* generate ELF file and use objdump, or generate binary
|
||||
* directly.
|
||||
*
|
||||
* PSUL doesn't seem to handle separate text and data sections correctly,
|
||||
* that is why the text and data sections are merged in the header.
|
||||
*
|
||||
* If you want to experiment, it should be quite obvious how to
|
||||
* change the header to list the data separately.
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
|
||||
OUTPUT_ARCH(powerpc:common);
|
||||
EXTERN(_start);
|
||||
ENTRY(_start);
|
||||
|
||||
base_address = 0x81300000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Program
|
||||
*/
|
||||
file_start = base_address;
|
||||
. = base_address;
|
||||
text_mem_start = .;
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP (*crt0.o(*.init))
|
||||
KEEP (*(.init))
|
||||
} = 0
|
||||
.plt : { *(.plt) }
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
|
||||
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
|
||||
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
|
||||
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
|
||||
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
|
||||
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
|
||||
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
|
||||
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
|
||||
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rela.got1 : { *(.rela.got1) }
|
||||
.rela.got2 : { *(.rela.got2) }
|
||||
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
|
||||
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
|
||||
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
|
||||
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }
|
||||
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
|
||||
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
|
||||
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
|
||||
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
|
||||
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
|
||||
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.stub)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
text_mem_size = . - text_mem_start;
|
||||
|
||||
data_mem_start = .;
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
|
||||
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||
could instead move the label definition inside the section, but
|
||||
the linker would then create the section even if it turns out to
|
||||
be empty, which isn't pretty. */
|
||||
. = ALIGN(32 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { *(.preinit_array) }
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array : { *(.init_array) }
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array : { *(.fini_array) }
|
||||
PROVIDE (__fini_array_end = .);
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.eh_frame : { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.fixup : { *(.fixup) }
|
||||
.got1 : { *(.got1) }
|
||||
.got2 : { *(.got2) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
data_mem_size = . - data_mem_start;
|
||||
.textlen = . - base_address;
|
||||
|
||||
bss_mem_start = .;
|
||||
.sbss :
|
||||
{
|
||||
__sbss_start = .;
|
||||
PROVIDE (__sbss_start = .);
|
||||
PROVIDE (___sbss_start = .);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
PROVIDE (__sbss_end = .);
|
||||
PROVIDE (___sbss_end = .);
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
__sbss_end = .;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .;
|
||||
PROVIDE (__bss_start = .);
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections. */
|
||||
|
||||
. = ALIGN(32);
|
||||
|
||||
PROVIDE (__bss_end = .);
|
||||
__bss_end = .;
|
||||
}
|
||||
|
||||
bss_mem_size = . - bss_mem_start;
|
||||
|
||||
/* calculate file addresses */
|
||||
text_file_start = text_mem_start - file_start;
|
||||
data_file_start = data_mem_start - file_start;
|
||||
bss_file_start = bss_mem_start - file_start;
|
||||
|
||||
_end = .;
|
||||
|
||||
PROVIDE(end = .);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
|
||||
__isIPL = 1;
|
||||
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8);
|
||||
__stack_end = (__bss_start + SIZEOF(.bss));
|
||||
__intrstack_addr = (__stack_addr + 0x4000);
|
||||
__intrstack_end = (__stack_addr);
|
||||
__ArenaLo = (0x80B00000);
|
||||
__ArenaHi = (0x81100000);
|
||||
__gxregs = (0x81700000);
|
||||
|
||||
PROVIDE(__isIPL = __isIPL);
|
||||
PROVIDE(__text_start = text_mem_start);
|
||||
PROVIDE(__text_fstart = text_file_start);
|
||||
PROVIDE(__data_start = data_mem_start);
|
||||
PROVIDE(__data_fstart = data_file_start);
|
||||
PROVIDE(__bss_start = bss_mem_start);
|
||||
PROVIDE(__bss_fstart = bss_file_start);
|
||||
PROVIDE(__stack_addr = __stack_addr);
|
||||
PROVIDE(__stack_end = __stack_end);
|
||||
PROVIDE(__intrstack_addr = __intrstack_addr);
|
||||
PROVIDE(__intrstack_end = __intrstack_end);
|
||||
PROVIDE(__ArenaLo = __ArenaLo);
|
||||
PROVIDE(__ArenaHi = __ArenaHi);
|
||||
PROVIDE(__gxregs = __gxregs);
|
||||
|
|
@ -1,483 +0,0 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
# crt0.s file for the GameCube V1.0 by Costis (costis@gbaemu.com)!
|
||||
#
|
||||
# some little modifications by Groepaz/Hitmen and WinterMute
|
||||
#
|
||||
# This is start-up code for initializing the GameCube system and hardware
|
||||
# before executing the actual user program code. It clears the GPR's,
|
||||
# initializes the FPR's, initializes the Data, Code, and L2 caches, clears
|
||||
# and initializes SPR's, and disables exceptions (interrupts).
|
||||
#
|
||||
# Have fun!!! Please e-mail any suggestions or bugs to costis@gbaemu.com.
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
.section ".init"
|
||||
|
||||
.globl _start
|
||||
.extern __bss_start, _end
|
||||
.extern __init, __fini
|
||||
.extern main
|
||||
|
||||
_start:
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Initialize the General Purpose Registers
|
||||
#---------------------------------------------------------------------------------
|
||||
bl InitGPRS
|
||||
#---------------------------------------------------------------------------------
|
||||
# Initialize the GameCube Hardware (Floating Point Registers, Caches, etc.)
|
||||
#---------------------------------------------------------------------------------
|
||||
bl InitHardware
|
||||
#---------------------------------------------------------------------------------
|
||||
# Initialize more cache aspects, clear a few SPR's, and disable interrupts.
|
||||
#---------------------------------------------------------------------------------
|
||||
bl SystemInit
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# clear the bss section
|
||||
#---------------------------------------------------------------------------------
|
||||
lis 3, __bss_start@h
|
||||
ori 3, 3, __bss_start@l
|
||||
li 4, 0
|
||||
lis 5, _end@h
|
||||
ori 5, 5, _end@l
|
||||
sub 5, 5, 3
|
||||
#subi 3, 3, 4
|
||||
mtctr 5
|
||||
BSSCLoop:
|
||||
#stwu 4, 4(3)
|
||||
stbu 4,0(3)
|
||||
bdnz BSSCLoop
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# push args for main() and generate first stackframe
|
||||
#---------------------------------------------------------------------------------
|
||||
addi 1,1,-4
|
||||
lis 0,0
|
||||
stw 0,0(1)
|
||||
stwu 1,-64(1)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Initialise global constructors!
|
||||
#---------------------------------------------------------------------------------
|
||||
bl __init
|
||||
#---------------------------------------------------------------------------------
|
||||
# Branch to the user code!
|
||||
#---------------------------------------------------------------------------------
|
||||
bl main
|
||||
#---------------------------------------------------------------------------------
|
||||
# global destructors!
|
||||
#---------------------------------------------------------------------------------
|
||||
bl __fini
|
||||
|
||||
|
||||
# call functions registered by atexit()
|
||||
# .globl _exit
|
||||
# bl exit
|
||||
#_exit:
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# if the main function returns, reset the gc
|
||||
#
|
||||
# notice that restarting the program may fail since the
|
||||
# .data section may have been changed by previous run.
|
||||
#---------------------------------------------------------------------------------
|
||||
# disable irqs
|
||||
#---------------------------------------------------------------------------------
|
||||
mfmsr 3
|
||||
rlwinm 4,3,0,17,15
|
||||
mtmsr 4
|
||||
extrwi 3,3,1,16
|
||||
#---------------------------------------------------------------------------------
|
||||
eloop:
|
||||
#---------------------------------------------------------------------------------
|
||||
# hot reset
|
||||
#---------------------------------------------------------------------------------
|
||||
lis 9,0xcc00
|
||||
li 0,0x00
|
||||
ori 9,9,0x3024
|
||||
stw 0,0x00(9)
|
||||
|
||||
b eloop # try again if we really come here :=P
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# General Purpose Register init
|
||||
#---------------------------------------------------------------------------------
|
||||
InitGPRS:
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear all of the GPR's to 0
|
||||
#---------------------------------------------------------------------------------
|
||||
li 0,0
|
||||
li 3,0
|
||||
li 4,0
|
||||
li 5,0
|
||||
li 6,0
|
||||
li 7,0
|
||||
li 8,0
|
||||
li 9,0
|
||||
li 10,0
|
||||
li 11,0
|
||||
li 12,0
|
||||
li 14,0
|
||||
li 15,0
|
||||
li 16,0
|
||||
li 17,0
|
||||
li 18,0
|
||||
li 19,0
|
||||
li 20,0
|
||||
li 21,0
|
||||
li 22,0
|
||||
li 23,0
|
||||
li 24,0
|
||||
li 25,0
|
||||
li 26,0
|
||||
li 27,0
|
||||
li 28,0
|
||||
li 29,0
|
||||
li 30,0
|
||||
li 31,0
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Set the Stack Pointer - set in linkscript
|
||||
#---------------------------------------------------------------------------------
|
||||
lis 1,__stack@h
|
||||
ori 1,1,__stack@l
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Set the Small Data 2 (Read Only) base register.
|
||||
#---------------------------------------------------------------------------------
|
||||
lis 2,_SDA2_BASE_@h
|
||||
ori 2,2,_SDA2_BASE_@l
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Set the Small Data (Read\Write) base register.
|
||||
#---------------------------------------------------------------------------------
|
||||
lis 13,_SDA_BASE_@h
|
||||
ori 13,13,_SDA_BASE_@l
|
||||
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Hardware Init
|
||||
#---------------------------------------------------------------------------------
|
||||
InitHardware:
|
||||
#---------------------------------------------------------------------------------
|
||||
mflr 31 # Store the link register in r31
|
||||
|
||||
bl PSInit # Initialize Paired Singles
|
||||
bl FPRInit # Initialize the FPR's
|
||||
bl CacheInit # Initialize the system caches
|
||||
|
||||
mtlr 31 # Retreive the link register from r31
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
PSInit:
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 920 # (HID2)
|
||||
oris 3, 3, 0xA000
|
||||
mtspr 920, 3 # (HID2)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Set the Instruction Cache invalidation bit in HID0
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3,1008
|
||||
ori 3,3,0x0800
|
||||
mtspr 1008,3
|
||||
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear various Special Purpose Registers
|
||||
#---------------------------------------------------------------------------------
|
||||
li 3,0
|
||||
mtspr 912,3
|
||||
mtspr 913,3
|
||||
mtspr 914,3
|
||||
mtspr 915,3
|
||||
mtspr 916,3
|
||||
mtspr 917,3
|
||||
mtspr 918,3
|
||||
mtspr 919,3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Return
|
||||
#---------------------------------------------------------------------------------
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
FPRInit:
|
||||
#---------------------------------------------------------------------------------
|
||||
# Enable the Floating Point Registers
|
||||
#---------------------------------------------------------------------------------
|
||||
mfmsr 3
|
||||
ori 3,3,0x2000
|
||||
mtmsr 3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear all of the FPR's to 0
|
||||
#---------------------------------------------------------------------------------
|
||||
lis 3, zfloat@h
|
||||
ori 3, 3, zfloat@l
|
||||
lfd 0, 0(3)
|
||||
fmr 1,0
|
||||
fmr 2,0
|
||||
fmr 3,0
|
||||
fmr 4,0
|
||||
fmr 5,0
|
||||
fmr 6,0
|
||||
fmr 7,0
|
||||
fmr 8,0
|
||||
fmr 9,0
|
||||
fmr 10,0
|
||||
fmr 11,0
|
||||
fmr 12,0
|
||||
fmr 13,0
|
||||
fmr 14,0
|
||||
fmr 15,0
|
||||
fmr 16,0
|
||||
fmr 17,0
|
||||
fmr 18,0
|
||||
fmr 19,0
|
||||
fmr 20,0
|
||||
fmr 21,0
|
||||
fmr 22,0
|
||||
fmr 23,0
|
||||
fmr 24,0
|
||||
fmr 25,0
|
||||
fmr 26,0
|
||||
fmr 27,0
|
||||
fmr 28,0
|
||||
fmr 29,0
|
||||
fmr 30,0
|
||||
fmr 31,0
|
||||
mtfsf 255,0
|
||||
|
||||
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
CacheInit:
|
||||
#---------------------------------------------------------------------------------
|
||||
mflr 0
|
||||
stw 0, 4(1)
|
||||
stwu 1, -16(1)
|
||||
stw 31, 12(1)
|
||||
stw 30, 8(1)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Check if the Instruction Cache has been enabled.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3,1008 # (HID0)
|
||||
rlwinm 0, 3, 0, 16, 16
|
||||
cmplwi 0, 0x0000
|
||||
bne ICEnabled
|
||||
|
||||
isync
|
||||
mfspr 3, 1008
|
||||
ori 3, 3, 0x8000
|
||||
mtspr 1008, 3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
ICEnabled:
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1008 # bl PPCMfhid0
|
||||
rlwinm 0, 3, 0, 17, 17
|
||||
cmplwi 0, 0x0000 # Check if the Data Cache has been enabled or not.
|
||||
bne DCEnabled
|
||||
|
||||
# If not, then enable it.
|
||||
sync
|
||||
mfspr 3, 1008
|
||||
ori 3, 3, 0x4000
|
||||
mtspr 1008, 3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
DCEnabled:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
mfspr 3, 1017 # (L2CR)
|
||||
clrrwi 0, 3, 31 # Clear all of the bits except 31
|
||||
cmplwi 0, 0x0000
|
||||
bne L2GISkip # Skip the L2 Global Cache Invalidation process
|
||||
# if it has already been done before.
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Store the current state of the MSR in r30
|
||||
#---------------------------------------------------------------------------------
|
||||
mfmsr 3
|
||||
mr 30,3
|
||||
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Enable Instruction and Data Address Translation
|
||||
#---------------------------------------------------------------------------------
|
||||
li 3, 48
|
||||
mtmsr 3
|
||||
|
||||
sync
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Disable the L2 Global Cache.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # (L2CR
|
||||
clrlwi 3, 3, 1
|
||||
mtspr 1017, 3 # (L2CR)
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Invalidate the L2 Global Cache.
|
||||
#---------------------------------------------------------------------------------
|
||||
bl L2GlobalInvalidate
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Restore the previous state of the MSR from r30
|
||||
#---------------------------------------------------------------------------------
|
||||
mr 3, 30
|
||||
mtmsr 3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Enable the L2 Global Cache
|
||||
# disable the L2 Data Only bit and the L2 Global Invalidate Bit.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # (L2CR)
|
||||
oris 0, 3, 0x8000
|
||||
rlwinm 3, 0, 0, 11, 9
|
||||
mtspr 1017, 3 # (L2CR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
L2GISkip:
|
||||
#---------------------------------------------------------------------------------
|
||||
# Restore the non-volatile registers to their previous values and return.
|
||||
#---------------------------------------------------------------------------------
|
||||
lwz 0, 20(1)
|
||||
lwz 31, 12(1)
|
||||
lwz 30, 8(1)
|
||||
addi 1, 1, 16
|
||||
mtlr 0
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
L2GlobalInvalidate:
|
||||
#---------------------------------------------------------------------------------
|
||||
mflr 0
|
||||
stw 0, 4(1)
|
||||
stwu 1, -16(1)
|
||||
stw 31, 12(1)
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Disable the L2 Cache.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # bl PPCMf1017
|
||||
clrlwi 3, 3, 1
|
||||
mtspr 1017, 3 # bl PPCMt1017
|
||||
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Initiate the L2 Cache Global Invalidation process.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # (L2CR)
|
||||
oris 3, 3, 0x0020
|
||||
mtspr 1017, 3 # (L2CR)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Wait until the L2 Cache Global Invalidation has been completed.
|
||||
#---------------------------------------------------------------------------------
|
||||
L2GICheckComplete:
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # (L2CR)
|
||||
clrlwi 0, 3, 31
|
||||
cmplwi 0, 0x0000
|
||||
bne L2GICheckComplete
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear the L2 Data Only bit and the L2 Global Invalidate Bit.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # (L2CR)
|
||||
rlwinm 3, 3, 0, 11, 9
|
||||
mtspr 1017, 3 # (L2CR)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Wait until the L2 Cache Global Invalidation status bit signifies that it is ready.
|
||||
#---------------------------------------------------------------------------------
|
||||
L2GDICheckComplete:
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1017 # (L2CR)
|
||||
clrlwi 0, 3, 31
|
||||
cmplwi 0, 0x0000
|
||||
bne L2GDICheckComplete
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Restore the non-volatile registers to their previous values and return.
|
||||
#---------------------------------------------------------------------------------
|
||||
lwz 0, 20(1)
|
||||
lwz 31, 12(1)
|
||||
addi 1, 1, 16
|
||||
mtlr 0
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
SystemInit:
|
||||
#---------------------------------------------------------------------------------
|
||||
mflr 0
|
||||
stw 0, 4(1)
|
||||
stwu 1, -0x18(1)
|
||||
stw 31, 0x14(1)
|
||||
stw 30, 0x10(1)
|
||||
stw 29, 0xC(1)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Disable interrupts!
|
||||
#---------------------------------------------------------------------------------
|
||||
mfmsr 3
|
||||
rlwinm 4,3,0,17,15
|
||||
mtmsr 4
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear various SPR's
|
||||
#---------------------------------------------------------------------------------
|
||||
li 3,0
|
||||
mtspr 952, 3
|
||||
mtspr 956, 3
|
||||
mtspr 953, 3
|
||||
mtspr 954, 3
|
||||
mtspr 957, 3
|
||||
mtspr 958, 3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Disable Speculative Bus Accesses to non-guarded space from both caches.
|
||||
#---------------------------------------------------------------------------------
|
||||
mfspr 3, 1008 # (HID0)
|
||||
ori 3, 3, 0x0200
|
||||
mtspr 1008, 3
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Set the Non-IEEE mode in the FPSCR
|
||||
#---------------------------------------------------------------------------------
|
||||
mtfsb1 29
|
||||
|
||||
mfspr 3,920 # (HID2)
|
||||
rlwinm 3, 3, 0, 2, 0
|
||||
mtspr 920,3 # (HID2)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Restore the non-volatile registers to their previous values and return.
|
||||
#---------------------------------------------------------------------------------
|
||||
lwz 0, 0x1C(1)
|
||||
lwz 31, 0x14(1)
|
||||
lwz 30, 0x10(1)
|
||||
lwz 29, 0xC(1)
|
||||
addi 1, 1, 0x18
|
||||
mtlr 0
|
||||
blr
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
zfloat:
|
||||
#---------------------------------------------------------------------------------
|
||||
.float 0
|
||||
.align 4
|
||||
|
|
@ -21,7 +21,7 @@ SECTIONS
|
|||
|
||||
/* DOL header (from TITANIK's GC docs) */
|
||||
/* default base address */
|
||||
. = 0x80003000;
|
||||
. = 0x80003000;
|
||||
.header :
|
||||
{
|
||||
file_start = .;
|
||||
|
|
@ -160,19 +160,21 @@ SECTIONS
|
|||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
text_mem_size = . - text_mem_start;
|
||||
|
||||
. = ALIGN(32);
|
||||
data_mem_start = .;
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
|
|
@ -200,6 +202,7 @@ SECTIONS
|
|||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.data1 : { *(.data1) }
|
||||
|
|
@ -234,6 +237,7 @@ SECTIONS
|
|||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.dtors :
|
||||
|
|
@ -242,6 +246,7 @@ SECTIONS
|
|||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
|
|
@ -257,13 +262,14 @@ SECTIONS
|
|||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
data_mem_size = . - data_mem_start;
|
||||
|
||||
. = ALIGN(32);
|
||||
bss_mem_start = .;
|
||||
.sbss :
|
||||
{
|
||||
|
|
@ -277,11 +283,10 @@ SECTIONS
|
|||
*(.scommon)
|
||||
PROVIDE (__sbss_end = .);
|
||||
PROVIDE (___sbss_end = .);
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
__sbss_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32);
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .;
|
||||
|
|
@ -301,7 +306,6 @@ SECTIONS
|
|||
__bss_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32);
|
||||
bss_mem_size = . - bss_mem_start;
|
||||
|
||||
/* calculate file addresses */
|
||||
|
|
@ -347,9 +351,10 @@ SECTIONS
|
|||
/* These must appear regardless of . */
|
||||
}
|
||||
|
||||
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x10000 + 7) & (-8);
|
||||
__isIPL = 0;
|
||||
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8);
|
||||
__stack_end = (__bss_start + SIZEOF(.bss));
|
||||
__intrstack_addr = (__stack_addr + 0x2000);
|
||||
__intrstack_addr = (__stack_addr + 0x4000);
|
||||
__intrstack_end = (__stack_addr);
|
||||
__ArenaLo = (__intrstack_addr + 31) & (-32);
|
||||
__ArenaHi = (0x81700000);
|
||||
|
|
@ -358,6 +363,7 @@ __gxregs = (__ArenaHi + 31) & (-32);
|
|||
/* for backward compatibility with old crt0 */
|
||||
PROVIDE (__stack = (0x81700000));
|
||||
|
||||
PROVIDE(__isIPL = __isIPL);
|
||||
PROVIDE(__text_start = text_mem_start);
|
||||
PROVIDE(__text_fstart = text_file_start);
|
||||
PROVIDE(__data_start = data_mem_start);
|
||||
|
|
|
|||
383
dkppc/crtls/rvl.ld
Normal file
383
dkppc/crtls/rvl.ld
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* Linkscript for GC, automatically sets up DOL structures,
|
||||
* generate ELF file and use objdump, or generate binary
|
||||
* directly.
|
||||
*
|
||||
* PSUL doesn't seem to handle separate text and data sections correctly,
|
||||
* that is why the text and data sections are merged in the header.
|
||||
*
|
||||
* If you want to experiment, it should be quite obvious how to
|
||||
* change the header to list the data separately.
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
|
||||
OUTPUT_ARCH(powerpc:common);
|
||||
EXTERN(_start);
|
||||
ENTRY(_start);
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* DOL header (from TITANIK's GC docs) */
|
||||
/* default base address */
|
||||
. = 0x80003f00;
|
||||
.header :
|
||||
{
|
||||
file_start = .;
|
||||
/* 0000-001B Text[0..6] sections File Positions */
|
||||
LONG(text_file_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 001C-0047 Data[0..10] sections File Positions */
|
||||
LONG(data_file_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 0048-0063 Text[0..6] sections Mem Address */
|
||||
LONG(text_mem_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 0064-008F Data[0..10] sections Mem Address */
|
||||
LONG(data_mem_start);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 0090-00AB Text[0..6] sections Sizes */
|
||||
LONG(text_mem_size);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 00AC-00D7 Data[0..10] sections Sizes */
|
||||
LONG(data_mem_size);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
LONG(0);
|
||||
|
||||
/* 00D8 BSS Mem address
|
||||
00DC BSS Size */
|
||||
LONG(bss_mem_start);
|
||||
LONG(bss_mem_size);
|
||||
|
||||
/* 00E0 Entry Point */
|
||||
LONG(ABSOLUTE(_start));
|
||||
}
|
||||
|
||||
/* Program */
|
||||
. = file_start + 0x100;
|
||||
text_mem_start = .;
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP (*crt0.o(*.init))
|
||||
KEEP (*(.init))
|
||||
} = 0
|
||||
.plt : { *(.plt) }
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
|
||||
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
|
||||
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
|
||||
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
|
||||
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
|
||||
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
|
||||
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
|
||||
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
|
||||
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rela.got1 : { *(.rela.got1) }
|
||||
.rela.got2 : { *(.rela.got2) }
|
||||
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
|
||||
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
|
||||
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
|
||||
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }
|
||||
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
|
||||
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
|
||||
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
|
||||
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
|
||||
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
|
||||
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.stub)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
text_mem_size = . - text_mem_start;
|
||||
|
||||
data_mem_start = .;
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
|
||||
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||
could instead move the label definition inside the section, but
|
||||
the linker would then create the section even if it turns out to
|
||||
be empty, which isn't pretty. */
|
||||
. = ALIGN(32 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { *(.preinit_array) }
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array : { *(.init_array) }
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array : { *(.fini_array) }
|
||||
PROVIDE (__fini_array_end = .);
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.data1 : { *(.data1) }
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.eh_frame : { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.fixup : { *(.fixup) }
|
||||
.got1 : { *(.got1) }
|
||||
.got2 : { *(.got2) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
|
||||
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
}
|
||||
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
data_mem_size = . - data_mem_start;
|
||||
|
||||
bss_mem_start = .;
|
||||
.sbss :
|
||||
{
|
||||
__sbss_start = .;
|
||||
PROVIDE (__sbss_start = .);
|
||||
PROVIDE (___sbss_start = .);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
PROVIDE (__sbss_end = .);
|
||||
PROVIDE (___sbss_end = .);
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
__sbss_end = .;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .;
|
||||
PROVIDE (__bss_start = .);
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections. */
|
||||
|
||||
. = ALIGN(32);
|
||||
|
||||
PROVIDE (__bss_end = .);
|
||||
__bss_end = .;
|
||||
}
|
||||
|
||||
bss_mem_size = . - bss_mem_start;
|
||||
|
||||
/* calculate file addresses */
|
||||
text_file_start = text_mem_start - file_start;
|
||||
data_file_start = data_mem_start - file_start;
|
||||
bss_file_start = bss_mem_start - file_start;
|
||||
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
|
||||
__isIPL = 0;
|
||||
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8);
|
||||
__stack_end = (__bss_start + SIZEOF(.bss));
|
||||
__intrstack_addr = (__stack_addr + 0x4000);
|
||||
__intrstack_end = (__stack_addr);
|
||||
__ArenaLo = (__intrstack_addr + 31) & (-32);
|
||||
__ArenaHi = (0x81700000);
|
||||
__ipcbufferLo = (__ArenaHi + 31) & (-32);
|
||||
__ipcbufferHi = (__ipcbufferLo + 0x20000 + 31) & (-32);
|
||||
__gxregs = (__ipcbufferHi + 31) & (-32);
|
||||
|
||||
/* for backward compatibility with old crt0 */
|
||||
PROVIDE (__stack = (0x81700000));
|
||||
|
||||
PROVIDE(__isIPL = __isIPL);
|
||||
PROVIDE(__text_start = text_mem_start);
|
||||
PROVIDE(__text_fstart = text_file_start);
|
||||
PROVIDE(__data_start = data_mem_start);
|
||||
PROVIDE(__data_fstart = data_file_start);
|
||||
PROVIDE(__bss_start = bss_mem_start);
|
||||
PROVIDE(__bss_fstart = bss_file_start);
|
||||
PROVIDE(__stack_addr = __stack_addr);
|
||||
PROVIDE(__stack_end = __stack_end);
|
||||
PROVIDE(__intrstack_addr = __intrstack_addr);
|
||||
PROVIDE(__intrstack_end = __intrstack_end);
|
||||
PROVIDE(__ArenaLo = __ArenaLo);
|
||||
PROVIDE(__ArenaHi = __ArenaHi);
|
||||
PROVIDE(__ipcbufferLo = __ipcbufferLo);
|
||||
PROVIDE(__ipcbufferHi = __ipcbufferHi);
|
||||
PROVIDE(__gxregs = __gxregs);
|
||||
284
dkppc/crtls/vgcogc.ld
Normal file
284
dkppc/crtls/vgcogc.ld
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* Linkscript for GC, automatically sets up DOL structures,
|
||||
* generate ELF file and use objdump, or generate binary
|
||||
* directly.
|
||||
*
|
||||
* PSUL doesn't seem to handle separate text and data sections correctly,
|
||||
* that is why the text and data sections are merged in the header.
|
||||
*
|
||||
* If you want to experiment, it should be quite obvious how to
|
||||
* change the header to list the data separately.
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
|
||||
OUTPUT_ARCH(powerpc:common);
|
||||
EXTERN(_start);
|
||||
ENTRY(_start);
|
||||
|
||||
base_address = 0x81320000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Program
|
||||
*/
|
||||
file_start = base_address;
|
||||
. = base_address;
|
||||
text_mem_start = .;
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP (*crt0.o(*.init))
|
||||
KEEP (*(.init))
|
||||
} = 0
|
||||
.plt : { *(.plt) }
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
|
||||
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
|
||||
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
|
||||
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
|
||||
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
|
||||
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
|
||||
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
|
||||
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
|
||||
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rela.got1 : { *(.rela.got1) }
|
||||
.rela.got2 : { *(.rela.got2) }
|
||||
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
|
||||
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
|
||||
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
|
||||
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }
|
||||
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
|
||||
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
|
||||
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
|
||||
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
|
||||
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
|
||||
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.stub)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} = 0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} = 0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
. = ALIGN(32);
|
||||
text_mem_size = . - text_mem_start;
|
||||
|
||||
. = ALIGN(32);
|
||||
data_mem_start = .;
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
|
||||
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||
could instead move the label definition inside the section, but
|
||||
the linker would then create the section even if it turns out to
|
||||
be empty, which isn't pretty. */
|
||||
. = ALIGN(32 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { *(.preinit_array) }
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array : { *(.init_array) }
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array : { *(.fini_array) }
|
||||
PROVIDE (__fini_array_end = .);
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.eh_frame : { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.fixup : { *(.fixup) }
|
||||
.got1 : { *(.got1) }
|
||||
.got2 : { *(.got2) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
. = ALIGN(32);
|
||||
data_mem_size = . - data_mem_start;
|
||||
.textlen = . - base_address;
|
||||
|
||||
. = ALIGN(32);
|
||||
bss_mem_start = .;
|
||||
.sbss :
|
||||
{
|
||||
__sbss_start = .;
|
||||
PROVIDE (__sbss_start = .);
|
||||
PROVIDE (___sbss_start = .);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
PROVIDE (__sbss_end = .);
|
||||
PROVIDE (___sbss_end = .);
|
||||
__sbss_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32);
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .;
|
||||
PROVIDE (__bss_start = .);
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections. */
|
||||
. = ALIGN(32);
|
||||
PROVIDE (__bss_end = .);
|
||||
__bss_end = .;
|
||||
}
|
||||
. = ALIGN(32);
|
||||
bss_mem_size = . - bss_mem_start;
|
||||
|
||||
/* calculate file addresses */
|
||||
text_file_start = text_mem_start - file_start;
|
||||
data_file_start = data_mem_start - file_start;
|
||||
bss_file_start = bss_mem_start - file_start;
|
||||
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
|
||||
__isIPL = 1;
|
||||
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x10000 + 7) & (-8);
|
||||
__stack_end = (__bss_start + SIZEOF(.bss));
|
||||
__intrstack_addr = (__stack_addr + 0x2000);
|
||||
__intrstack_end = (__stack_addr);
|
||||
__ArenaLo = (__intrstack_addr + 31) & (-32);
|
||||
__ArenaHi = (0x81700000);
|
||||
__gxregs = (__ArenaHi + 31) & (-32);
|
||||
|
||||
/* for backward compatibility with old crt0 */
|
||||
PROVIDE (__stack = (0x81700000));
|
||||
|
||||
PROVIDE(__isIPL = __isIPL);
|
||||
PROVIDE(__text_start = text_mem_start);
|
||||
PROVIDE(__text_fstart = text_file_start);
|
||||
PROVIDE(__data_start = data_mem_start);
|
||||
PROVIDE(__data_fstart = data_file_start);
|
||||
PROVIDE(__bss_start = bss_mem_start);
|
||||
PROVIDE(__bss_fstart = bss_file_start);
|
||||
PROVIDE(__stack_addr = __stack_addr);
|
||||
PROVIDE(__stack_end = __stack_end);
|
||||
PROVIDE(__intrstack_addr = __intrstack_addr);
|
||||
PROVIDE(__intrstack_end = __intrstack_end);
|
||||
PROVIDE(__ArenaLo = __ArenaLo);
|
||||
PROVIDE(__ArenaHi = __ArenaHi);
|
||||
PROVIDE(__gxregs = __gxregs);
|
||||
Loading…
Reference in New Issue
Block a user