diff options
author | Tony Puccinelli | 2010-07-28 23:17:39 +0000 |
---|---|---|
committer | Tony Puccinelli | 2010-07-28 23:17:39 +0000 |
commit | 145d8899dfb3bd0b7af88c812a2696c9da094cbf (patch) | |
tree | 99b5e836b0ff8f8a04b55fe8ab95d8edec04cd5a /backends/plugins | |
parent | 9d236ac4d040cacdebd4e12e15a73279acfaf8f0 (diff) | |
download | scummvm-rg350-145d8899dfb3bd0b7af88c812a2696c9da094cbf.tar.gz scummvm-rg350-145d8899dfb3bd0b7af88c812a2696c9da094cbf.tar.bz2 scummvm-rg350-145d8899dfb3bd0b7af88c812a2696c9da094cbf.zip |
added some comments to shorts-segment-manager, moved main engine linker script for ps2 into the plugins folder as it is only used when dynamic plugins are enabled
svn-id: r51447
Diffstat (limited to 'backends/plugins')
-rw-r--r-- | backends/plugins/arm-relocs.cpp | 2 | ||||
-rw-r--r-- | backends/plugins/ps2/main_prog.ld | 99 | ||||
-rw-r--r-- | backends/plugins/shorts-segment-manager.cpp | 4 | ||||
-rw-r--r-- | backends/plugins/shorts-segment-manager.h | 8 |
4 files changed, 110 insertions, 3 deletions
diff --git a/backends/plugins/arm-relocs.cpp b/backends/plugins/arm-relocs.cpp index b00fb42f4a..8ceccfb7e8 100644 --- a/backends/plugins/arm-relocs.cpp +++ b/backends/plugins/arm-relocs.cpp @@ -115,7 +115,7 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset *target = relocation; DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - DBG("Make sure --target1-abs is a flag to LD.\n"); + DBG("Make sure --target1-abs is a flag to LD!\n"); } break; diff --git a/backends/plugins/ps2/main_prog.ld b/backends/plugins/ps2/main_prog.ld new file mode 100644 index 0000000000..9dba69c50e --- /dev/null +++ b/backends/plugins/ps2/main_prog.ld @@ -0,0 +1,99 @@ +ENTRY(_start); + +SECTIONS { + .text 0x00100000: { + _ftext = . ; + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + KEEP(*(.init)) + KEEP(*(.fini)) + QUAD(0) + } + + PROVIDE(_etext = .); + PROVIDE(etext = .); + + .reginfo : { *(.reginfo) } + + /* Global/static constructors and deconstructors. */ + .ctors ALIGN(16): { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors ALIGN(16): { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + + /* Static data. */ + .rodata ALIGN(128): { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + + .data ALIGN(128): { + _fdata = . ; + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + + .rdata ALIGN(128): { *(.rdata) } + .gcc_except_table ALIGN(128): { *(.gcc_except_table) } + + _gp = ALIGN(128) + 0x7ff0; + .lit4 ALIGN(128): { *(.lit4) } + .lit8 ALIGN(128): { *(.lit8) } + + .sdata ALIGN(128): { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s*) + } + + _edata = .; + PROVIDE(edata = .); + + /* Uninitialized data. */ + .sbss ALIGN(128) : { + _fbss = . ; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb*) + *(.scommon) + } + + /*This "plugin hole" is so the plugins can all have global small data + in the same place.*/ + __plugin_hole_start = .; + . = _gp + 0x7ff0; + __plugin_hole_end = .; + + COMMON : + { + *(COMMON) + } + . = ALIGN(128); + + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + } + _end_bss = .; + + _end = . ; + PROVIDE(end = .); + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); +} diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index eb2ab2d953..25962c504d 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -42,8 +42,8 @@ extern char _gp[]; // Value of gp register DECLARE_SINGLETON(ShortSegmentManager); // For singleton ShortSegmentManager::ShortSegmentManager() { - _shortsStart = &__plugin_hole_start ; - _shortsEnd = &__plugin_hole_end; + _shortsStart = &__plugin_hole_start ; //shorts segment begins at the plugin hole we made when linking + _shortsEnd = &__plugin_hole_end; //and ends at the end of that hole. } ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index 02f5221e8d..54a13d88e1 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -32,6 +32,12 @@ #define ShortsMan ShortSegmentManager::instance() +/** + * Manages the segments of small data put in the gp-relative area for MIPS processors, + * and lets these segments be handled differently in the ELF loader. + * Since there's no true dynamic linker to change the GP register between plugins and the main engine, + * custom linker scripts ensure the GP-area is in the same place for both. + */ class ShortSegmentManager : public Common::Singleton<ShortSegmentManager> { private: char *_shortsStart; @@ -41,6 +47,8 @@ public: char *getShortsStart() { return _shortsStart; } + + // Returns whether or not an absolute address is in the GP-relative section. bool inGeneralSegment(char *addr) { return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); } |