From 978087b8db6483eebfe2f727ce82190faf39dd61 Mon Sep 17 00:00:00 2001 From: uyjulian Date: Mon, 14 Mar 2022 20:28:36 -0500 Subject: [PATCH] Changes to use unpatched binutils for linking IRX --- Defs.make | 2 +- iop/Makefile | 2 +- iop/Rules.make | 21 +++++- iop/Rules.release | 2 +- iop/kernel/include/irx.h | 4 +- iop/startup/Makefile | 20 +++++ iop/startup/src/linkfile | 117 ++++++++++++++++++++++++++++++ samples/Makefile.iopglobal_sample | 19 ++++- samples/Makefile.pref_sample | 2 +- 9 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 iop/startup/Makefile create mode 100644 iop/startup/src/linkfile diff --git a/Defs.make b/Defs.make index a9bc7406cd5d..4b51f37b4bb4 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..ac6f6aea3fb1 100644 --- a/iop/Makefile +++ b/iop/Makefile @@ -6,7 +6,7 @@ # 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 = kernel dev9 fs hdd sound tcpip usb system debug memorycard network iLink cdvd sio dvrp startup include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/Rules.make diff --git a/iop/Rules.make b/iop/Rules.make index 971b4b8f822b..9372ad8442db 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 := -nostdlib -s -Wl,-q -Wl,-n -Wl,--no-check-sections $(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=.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/elftypechanger/bin/elftypechanger: $(PS2SDKSRC)/tools/elftypechanger + $(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/elftypechanger/bin/elftypechanger + $(PS2SDKSRC)/tools/elftypechanger/bin/elftypechanger $< $@ FF80 $(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..fa930da3fe71 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 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..4d95b90793a2 --- /dev/null +++ b/iop/startup/src/linkfile @@ -0,0 +1,117 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ 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); + 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 (0xFF80) : ALIGN(4) { /* 0xFF80 -> LOPROC+0x80 */ + /* + * The linker will replace this first LONG with a pointer to _irx_id + * if the symbol has been defined. + */ + LONG (IOPMOD_INFO) ; + LONG (IOPMOD_ENTRY) ; + LONG (_gp) ; + LONG (IOPMOD_TEXT_SIZE) ; + LONG (IOPMOD_DATA_SIZE) ; + LONG (IOPMOD_BSS_SIZE) ; + /* + * 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). + */ + * ( .iopmod ); + FILL(0x00000000); + } :irxhdr + . = 0; + .text : ALIGN(16) { + PROVIDE (_ftext = .); + CREATE_OBJECT_SYMBOLS + * ( .text ) + * ( .text.* ) + * ( .init ) + * ( .fini ) + PROVIDE (_etext = .); + } :defhdr + . = . ; + .rodata : ALIGN(16) { + * ( .rdata ) + * ( .rodata ) + * ( .rodata1 ) + * ( .rodata.* ) + } :defhdr + .data : ALIGN(16) { + * ( .data ) + * ( .data1 ) + * ( .data.* ) + CONSTRUCTORS + } :defhdr + . = ALIGN(16) ; + _gp = . + 0x8000 ; + .sdata : ALIGN(16) { + * ( .lit8 ) + * ( .lit4 ) + * ( .sdata ) + * ( .sdata.* ) + } :defhdr + .sbss : ALIGN(16) { + * ( .sbss ) + * ( .scommon ) + } :defhdr + .bss : ALIGN(16) { + * ( .bss ) + * ( COMMON ) + . = ALIGN(4) ; + } :defhdr + PROVIDE(_end = .); + /* + * These are the stuff that we don't want to be put in an IRX. + */ + /DISCARD/ : { + * ( .MIPS.abiflags ) + * ( .gnu.attributes ) + * ( .comment ) + * ( .reginfo ) + * ( .mdebug.* ) + /* + * 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 ) + } +} + +IOPMOD_INFO = DEFINED(_irx_id) ? ABSOLUTE(_irx_id) : 0xffffffff; +IOPMOD_ENTRY = ABSOLUTE(_start); +IOPMOD_TEXT_SIZE = SIZEOF(.text); +IOPMOD_DATA_SIZE = SIZEOF(.data); +IOPMOD_BSS_SIZE = SIZEOF(.bss); diff --git a/samples/Makefile.iopglobal_sample b/samples/Makefile.iopglobal_sample index ccf40b4d3ab8..2cc009062f35 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 := -nostdlib -s -Wl,-q -Wl,-n -Wl,--no-check-sections $(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=.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) + elftypechanger $< $@ FF80 $(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 4850e43b13c7..cd091f69b702 100644 --- a/samples/Makefile.pref_sample +++ b/samples/Makefile.pref_sample @@ -21,7 +21,7 @@ EE_STRIP = $(EE_PREFIX)strip EE_ADDR2LINE = $(EE_PREFIX)addr2line EE_RANLIB = $(EE_PREFIX)ranlib -IOP_PREFIX ?= mipsel-ps2-irx- +IOP_PREFIX ?= mipsel-ps2-elf- IOP_CC = $(IOP_PREFIX)gcc IOP_AS = $(IOP_PREFIX)as IOP_LD = $(IOP_PREFIX)ld