From 10076ec033564ea80ca40490a77607912755bba3 Mon Sep 17 00:00:00 2001 From: uyjulian Date: Mon, 15 Aug 2022 00:51:07 -0500 Subject: [PATCH] Changes to use unpatched binutils for linking IRX --- Defs.make | 2 +- iop/Makefile | 18 ++++- iop/Rules.make | 21 ++++-- iop/Rules.release | 2 +- iop/kernel/include/irx.h | 16 +++-- iop/startup/Makefile | 20 ++++++ iop/startup/src/linkfile | 109 ++++++++++++++++++++++++++++++ samples/Makefile.iopglobal_sample | 19 ++++-- samples/Makefile.pref_sample | 2 +- 9 files changed, 190 insertions(+), 19 deletions(-) create mode 100644 iop/startup/Makefile create mode 100644 iop/startup/src/linkfile diff --git a/Defs.make b/Defs.make index 9a840b0204c5..b7f005b9d55e 100644 --- a/Defs.make +++ b/Defs.make @@ -29,7 +29,7 @@ EE_RANLIB ?= $(EE_TOOL_PREFIX)ranlib # Defintions for the IOP toolchain. # -IOP_TOOL_PREFIX ?= mipsel-ps2-irx- +IOP_TOOL_PREFIX ?= mipsel-ps2-elf- IOP_CC ?= $(IOP_TOOL_PREFIX)gcc IOP_AS ?= $(IOP_TOOL_PREFIX)as IOP_LD ?= $(IOP_TOOL_PREFIX)ld diff --git a/iop/Makefile b/iop/Makefile index 7cdefa517589..f69ede92d121 100644 --- a/iop/Makefile +++ b/iop/Makefile @@ -6,7 +6,23 @@ # Licenced under Academic Free License version 2.0 # Review ps2sdk README & LICENSE files for further details. -SUBDIRS = kernel dev9 fs hdd sound tcpip usb system debug memorycard network iLink cdvd sio dvrp +SUBDIRS = \ + cdvd \ + debug \ + dev9 \ + dvrp \ + fs \ + hdd \ + iLink \ + kernel \ + memorycard \ + network \ + sio \ + sound \ + startup \ + system \ + tcpip \ + usb include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/Rules.make diff --git a/iop/Rules.make b/iop/Rules.make index 971b4b8f822b..7e9ccc4c8d80 100644 --- a/iop/Rules.make +++ b/iop/Rules.make @@ -37,7 +37,7 @@ ifeq ($(DEBUG),1) IOP_CFLAGS += -DDEBUG endif # Linker flags -IOP_LDFLAGS := -nostdlib -s $(IOP_LDFLAGS) +IOP_LDFLAGS := -Wl,--gpsize=0 -Wl,-G0 -Wl,--nmagic -Wl,--orphan-handling=error -Wl,--discard-all -Wl,--gc-sections -Wl,--emit-relocs -nostdlib -Wl,--no-relax $(IOP_LDFLAGS) # Additional C compiler flags for GCC >=v5.3.0 # -msoft-float is to "remind" GCC/Binutils that the soft-float ABI is to be used. This is due to a bug, which @@ -66,8 +66,15 @@ endif # Assembler flags IOP_ASFLAGS := $(ASFLAGS_TARGET) -EL -G0 $(IOP_ASFLAGS) +# Default link file +ifeq ($(IOP_LINKFILE),) +IOP_LINKFILE := $(PS2SDKSRC)/iop/startup/src/linkfile +endif + IOP_OBJS := $(IOP_OBJS:%=$(IOP_OBJS_DIR)%) +IOP_BIN_ELF := $(IOP_BIN:.irx=.notiopmod.elf) + # Externally defined variables: IOP_BIN, IOP_OBJS, IOP_LIB # These macros can be used to simplify certain build rules. @@ -90,6 +97,9 @@ $(IOP_OBJS_DIR)%.o: $(IOP_SRC_DIR)%.s .INTERMEDIATE: $(IOP_OBJS_DIR)build-imports.c $(IOP_OBJS_DIR)build-exports.c +$(PS2SDKSRC)/tools/ps2-irxgen/bin/ps2-irxgen: $(PS2SDKSRC)/tools/ps2-irxgen + $(MAKEREC) $< + # Rules to build imports.lst. $(IOP_OBJS_DIR)build-imports.c: $(IOP_SRC_DIR)imports.lst $(DIR_GUARD) @@ -110,10 +120,13 @@ $(IOP_OBJS_DIR)exports.o: $(IOP_OBJS_DIR)build-exports.c $(DIR_GUARD) $(IOP_C_COMPILE) $(IOP_IETABLE_CFLAGS) -c $< -o $@ -$(IOP_BIN): $(IOP_OBJS) +$(IOP_BIN_ELF): $(IOP_OBJS) $(DIR_GUARD) - $(IOP_C_COMPILE) $(IOP_OPTFLAGS) -o $(IOP_BIN) $(IOP_OBJS) $(IOP_LDFLAGS) $(IOP_LIBS) + $(IOP_C_COMPILE) -T$(IOP_LINKFILE) $(IOP_OPTFLAGS) -o $@ $(IOP_OBJS) $(IOP_LDFLAGS) $(IOP_LIBS) + +$(IOP_BIN): $(IOP_BIN_ELF) $(PS2SDKSRC)/tools/ps2-irxgen/bin/ps2-irxgen + $(PS2SDKSRC)/tools/ps2-irxgen/bin/ps2-irxgen $< $@ $(IOP_LIB): $(IOP_OBJS) $(DIR_GUARD) - $(IOP_AR) cru $(IOP_LIB) $(IOP_OBJS) + $(IOP_AR) cru $@ $(IOP_OBJS) diff --git a/iop/Rules.release b/iop/Rules.release index 268e42ca8032..b38faab9a954 100644 --- a/iop/Rules.release +++ b/iop/Rules.release @@ -11,7 +11,7 @@ # Creates the base iop directory structure in target directory. # -RELEASE_IOP_DIRS = iop/ iop/include/sys/ iop/irx/ iop/lib +RELEASE_IOP_DIRS = iop/ iop/include/sys/ iop/irx/ iop/lib iop/startup RELEASE_IOP_DIRS := $(RELEASE_IOP_DIRS:%=$(PS2SDK)/%) diff --git a/iop/kernel/include/irx.h b/iop/kernel/include/irx.h index 2e605df2b4c7..ec2aa53deac7 100644 --- a/iop/kernel/include/irx.h +++ b/iop/kernel/include/irx.h @@ -28,7 +28,9 @@ struct irx_id { #define IRX_ID(name, major, minor) \ struct irx_id _irx_id = { \ name, IRX_VER(major, minor) \ -}; +}; \ +const u16 _irx_version __attribute__((section(".iopmod"))) = IRX_VER(major, minor); \ +const char _irx_name[] __attribute__((aligned(1),section(".iopmod"))) = name; /* * Module imports @@ -57,20 +59,20 @@ struct irx_import_stub */ #define DECLARE_IMPORT_TABLE(modname, major, minor) \ static struct irx_import_table _imp_##modname \ - __attribute__((section(".text\n\t#"), unused))= { \ + __attribute__((section(".module.imports\n\t#"), unused))= { \ magic: IMPORT_MAGIC, version: IRX_VER(major, minor), \ name: #modname, }; #define STR(val) #val // .word 0x03e00008 == jr $ra (return immediately), this value will be patched later #define DECLARE_IMPORT(ord, name) \ - __asm__ (".section\t.text\n\t" \ + __asm__ (".section\t.module.imports\n\t" \ ".globl\t"#name"\n\t"#name":\n\t" \ ".word 0x03e00008\n\t" \ ".word "STR(0x24000000|ord)); #define END_IMPORT_TABLE \ - __asm__ (".section\t.text\n\t.word\t0, 0"); + __asm__ (".section\t.module.imports\n\t.word\t0, 0"); /* * Module exports @@ -94,13 +96,13 @@ struct irx_export_table { #define DECLARE_EXPORT_TABLE(modname, major, minor) \ struct irx_export_table _exp_##modname \ - __attribute__((section(".text\n\t#"), unused)) = { \ + __attribute__((section(".module.exports\n\t#"), unused)) = { \ magic: EXPORT_MAGIC, version: IRX_VER(major, minor), \ name: #modname, }; #define DECLARE_EXPORT(fptr) \ - __asm__ (".section\t.text\n\t.word\t"STR(fptr)); + __asm__ (".section\t.module.exports\n\t.word\t"STR(fptr)); -#define END_EXPORT_TABLE __asm__ (".section\t.text\n\t.word\t0"); +#define END_EXPORT_TABLE __asm__ (".section\t.module.exports\n\t.word\t0"); #endif /* __IRX_H__ */ diff --git a/iop/startup/Makefile b/iop/startup/Makefile new file mode 100644 index 000000000000..feeef6fc4736 --- /dev/null +++ b/iop/startup/Makefile @@ -0,0 +1,20 @@ +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. + +all: + +include $(PS2SDKSRC)/Defs.make +include $(PS2SDKSRC)/iop/Rules.make +include $(PS2SDKSRC)/iop/Rules.release + +clean: + +release: + $(ECHO) Installing $(IOP_SRC_DIR)linkfile into $(PS2SDK)/iop/startup + cp -f $(IOP_SRC_DIR)linkfile $(PS2SDK)/iop/startup + diff --git a/iop/startup/src/linkfile b/iop/startup/src/linkfile new file mode 100644 index 000000000000..9c27f218152d --- /dev/null +++ b/iop/startup/src/linkfile @@ -0,0 +1,109 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2022, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +# Linkfile script for iop-ld +*/ + +OUTPUT_FORMAT("elf32-littlemips") +SEARCH_DIR(""); +ENTRY(_start) +PHDRS +{ + irxhdr 0x70000080 FLAGS (PF_R); /* 0x70000080 -> PT_SCE_IOPMOD */ + defhdr PT_LOAD FLAGS (PF_X | PF_W | PF_R); +} +SECTIONS +{ + . = SIZEOF_HEADERS; + /* + * This is the .iopmod section for the IRX, it contains information that + * the IOP uses when loading the IRX. + * This section is placed in its own segment. + */ + .iopmod 0 (COPY) : ALIGN(4) { + /* + * The linker will replace this first LONG with a pointer to _irx_id + * if the symbol has been defined. + */ + LONG (DEFINED(_irx_id) ? ABSOLUTE(_irx_id) : 0xffffffff) ; + LONG (ABSOLUTE(_start)) ; + LONG (_gp) ; + LONG (SIZEOF(.text)) ; + LONG (SIZEOF(.data)) ; + LONG (SIZEOF(.bss)) ; + /* + * The linker will put a SHORT here with the version of the IRX + * (or zero if there is no version). + */ + /* + * The linker will put a null terminated string here containing the + * name of the IRX (or an empty string if the name is not known). + */ + KEEP (* ( .iopmod )) ; + FILL(0x00000000); + } :irxhdr = 0 + + .text 0 : ALIGN(16) { + CREATE_OBJECT_SYMBOLS + PROVIDE (_ftext = .) ; + KEEP (* ( .module.imports )) ; + * ( .text ) + * ( .text.* ) + * ( .init ) + * ( .fini ) + KEEP (* ( .module.exports )) ; + PROVIDE (_etext = .) ; + } :defhdr = 0 + + .rodata : ALIGN(16) { + * ( .rdata ) + * ( .rodata ) + * ( .rodata1 ) + * ( .rodata.* ) + } :defhdr = 0 + + .data : ALIGN(16) { + * ( .data ) + * ( .data1 ) + * ( .data.* ) + CONSTRUCTORS + } :defhdr = 0 + + .bss : ALIGN(16) { + * ( .bss ) + * ( .bss.* ) + * ( COMMON ) + . = ALIGN(4) ; + } :defhdr + _gp = ALIGN(16) ; + + /* + * These are the stuff that we don't want to be put in an IRX. + */ + /DISCARD/ : { + * ( .MIPS.abiflags ) + * ( .comment ) + * ( .debug_* ) + * ( .gnu.attributes ) + * ( .mdebug.* ) + * ( .reginfo ) + * ( .symtab ) + * ( .strtab ) + * ( .shstrtab ) + /* + * This must go because it confuses the IOP kernel (treated as a reloc section). + */ + * ( .pdr ) + /* + * Until I can figure out if there's a better way to rid ourselves of + * .rel.dyn this will have to do. - MRB + */ + * ( .rel.dyn ) + } +} diff --git a/samples/Makefile.iopglobal_sample b/samples/Makefile.iopglobal_sample index ccf40b4d3ab8..5736b427465c 100644 --- a/samples/Makefile.iopglobal_sample +++ b/samples/Makefile.iopglobal_sample @@ -35,7 +35,7 @@ IOP_WARNFLAGS ?= -Wall # for finer-grained control over what goes into each IRX. IOP_CFLAGS := -D_IOP -fno-builtin -G0 $(IOP_OPTFLAGS) $(IOP_WARNFLAGS) $(IOP_INCS) $(IOP_CFLAGS) # linker flags -IOP_LDFLAGS := -nostdlib -s $(IOP_LDFLAGS) +IOP_LDFLAGS := -Wl,--gpsize=0 -Wl,-G0 -Wl,--nmagic -Wl,--orphan-handling=error -Wl,--discard-all -Wl,--gc-sections -Wl,--emit-relocs -nostdlib -Wl,--no-relax $(IOP_LDFLAGS) # Additional C compiler flags for GCC >=v5.3.0 # -msoft-float is to "remind" GCC/Binutils that the soft-float ABI is to be used. This is due to a bug, which @@ -64,8 +64,15 @@ endif # Assembler flags IOP_ASFLAGS := $(ASFLAGS_TARGET) -EL -G0 $(IOP_ASFLAGS) +# Default link file +ifeq ($(IOP_LINKFILE),) +IOP_LINKFILE := $(PS2SDK)/iop/startup/linkfile +endif + IOP_OBJS := $(IOP_OBJS:%=$(IOP_OBJS_DIR)%) +IOP_BIN_ELF := $(IOP_BIN:.irx=.notiopmod.elf) + # Externally defined variables: IOP_BIN, IOP_OBJS, IOP_LIB # These macros can be used to simplify certain build rules. @@ -107,10 +114,14 @@ $(IOP_OBJS_DIR)exports.o: $(IOP_OBJS_DIR)build-exports.c $(DIR_GUARD) $(IOP_C_COMPILE) $(IOP_IETABLE_CFLAGS) -c $< -o $@ -$(IOP_BIN): $(IOP_OBJS) +$(IOP_BIN_ELF): $(IOP_OBJS) + $(DIR_GUARD) + $(IOP_C_COMPILE) -T$(IOP_LINKFILE) $(IOP_OPTFLAGS) -o $@ $(IOP_OBJS) $(IOP_LDFLAGS) $(IOP_LIBS) + +$(IOP_BIN): $(IOP_BIN_ELF) $(DIR_GUARD) - $(IOP_C_COMPILE) $(IOP_OPTFLAGS) -o $(IOP_BIN) $(IOP_OBJS) $(IOP_LDFLAGS) $(IOP_LIBS) + ps2-irxgen $< $@ $(IOP_LIB): $(IOP_OBJS) $(DIR_GUARD) - $(IOP_AR) cru $(IOP_LIB) $(IOP_OBJS) + $(IOP_AR) cru $@ $(IOP_OBJS) diff --git a/samples/Makefile.pref_sample b/samples/Makefile.pref_sample index b4648f711193..63d6a5711221 100644 --- a/samples/Makefile.pref_sample +++ b/samples/Makefile.pref_sample @@ -29,7 +29,7 @@ EE_RANLIB ?= $(EE_TOOL_PREFIX)ranlib # Defintions for the IOP toolchain. # -IOP_TOOL_PREFIX ?= mipsel-ps2-irx- +IOP_TOOL_PREFIX ?= mipsel-ps2-elf- IOP_CC ?= $(IOP_TOOL_PREFIX)gcc IOP_AS ?= $(IOP_TOOL_PREFIX)as IOP_LD ?= $(IOP_TOOL_PREFIX)ld