Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to use unpatched binutils for linking IRX #253

Merged
merged 2 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Defs.make
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 17 additions & 1 deletion iop/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 17 additions & 4 deletions iop/Rules.make
Original file line number Diff line number Diff line change
Expand Up @@ -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,-z,max-page-size=128 -Wl,--no-relax $(IOP_LDFLAGS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain all these flags and why the are needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--gpsize=0
Set the maximum size of objects to be optimized using the GP register to size. This is only meaningful for object file formats such as MIPS ELF that support putting large and small objects into different sections. This is ignored for other object file formats.

-G0
Set the maximum size of objects to be optimized using the GP register to size. This is only meaningful for object file formats such as MIPS ELF that support putting large and small objects into different sections. This is ignored for other object file formats.

--nmagic
Turn off page alignment of sections, and disable linking against shared libraries. If the output format supports Unix style magic numbers, mark the output as "NMAGIC".

--orphan-handling=error
Control how orphan sections are handled. An orphan section is one not specifically mentioned in a linker script.
The linker will exit with an error if any orphan section is found.

--discard-all
Delete all local symbols.

--gc-sections
Enable garbage collection of unused input sections. It is ignored on targets that do not support this option. The default behaviour (of not performing this garbage collection) can be restored by specifying --no-gc-sections on the command line. Note that garbage collection for COFF and PE format targets is supported, but the implementation is currently considered to be experimental.
--gc-sections decides which input sections are used by examining symbols and relocations. The section containing the entry symbol and all sections containing symbols undefined on the command-line will be kept, as will sections containing symbols referenced by dynamic objects. Note that when building shared libraries, the linker must assume that any visible symbol is referenced. Once this initial set of sections has been determined, the linker recursively marks as used any section referenced by their relocations. See --entry, --undefined, and --gc-keep-exported.

This option can be set when doing a partial link (enabled with option -r). In this case the root of symbols kept must be explicitly specified either by one of the options --entry, --undefined, or --gc-keep-exported or by a "ENTRY" command in the linker script.

As a GNU extension, ELF input sections marked with the "SHF_GNU_RETAIN" flag will not be garbage collected.

--emit-relocs
Leave relocation sections and contents in fully linked executables. Post link analysis and optimization tools may need this information in order to perform correct modifications of executables. This results in larger executables.
This option is currently only supported on ELF platforms.

-z,max-page-size=128
The recognized keywords are:
Set the maximum memory page size supported to 128.

--no-relax
An option with machine dependent effects. This option is only supported on a few targets.
On some platforms the --relax option performs target specific, global optimizations that become possible when the linker resolves addressing in the program, such as relaxing address modes, synthesizing new instructions, selecting shorter version of current instructions, and combining constant values.

On some platforms these link time global optimizations may make symbolic debugging of the resulting executable impossible. This is known to be the case for the Matsushita MN10200 and MN10300 family of processors.

On platforms where the feature is supported, the option --no-relax will disable it.

On platforms where the feature is not supported, both --relax and --no-relax are accepted, but ignored.


# 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
Expand Down Expand Up @@ -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.
Expand All @@ -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)
Expand All @@ -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)
2 changes: 1 addition & 1 deletion iop/Rules.release
Original file line number Diff line number Diff line change
Expand Up @@ -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)/%)


Expand Down
16 changes: 9 additions & 7 deletions iop/kernel/include/irx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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__ */
20 changes: 20 additions & 0 deletions iop/startup/Makefile
Original file line number Diff line number Diff line change
@@ -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

109 changes: 109 additions & 0 deletions iop/startup/src/linkfile
Original file line number Diff line number Diff line change
@@ -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 )
}
}
19 changes: 15 additions & 4 deletions samples/Makefile.iopglobal_sample
Original file line number Diff line number Diff line change
Expand Up @@ -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,-z,max-page-size=128 -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
2 changes: 1 addition & 1 deletion samples/Makefile.pref_sample
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.

SUBDIRS = bin2s bin2c bin2o adpenc ps2adpcm \
SUBDIRS = \
adpenc \
bin2c \
bin2o \
bin2s \
ps2-irxgen \
ps2adpcm \
# gensymtab

include $(PS2SDKSRC)/Defs.make
Expand Down
14 changes: 14 additions & 0 deletions tools/ps2-irxgen/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ 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.

TOOLS_OBJS = ps2-irxgen.o

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/tools/Rules.bin.make
include $(PS2SDKSRC)/tools/Rules.make
include $(PS2SDKSRC)/tools/Rules.release
Loading