[Scummvm-cvs-logs] SF.net SVN: scummvm:[50942] scummvm/branches/gsoc2010-plugins/backends/ platform/ds/arm9/source

toneman1138 at users.sourceforge.net toneman1138 at users.sourceforge.net
Fri Jul 16 22:44:11 CEST 2010


Revision: 50942
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50942&view=rev
Author:   toneman1138
Date:     2010-07-16 20:44:11 +0000 (Fri, 16 Jul 2010)

Log Message:
-----------
put in initial relocations for R_ARM_ABS32, R_ARM_THM_CALL and R_ARM_V4BX

Modified Paths:
--------------
    scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/dsloader.cpp
    scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/elf32.h

Modified: scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/dsloader.cpp
===================================================================
--- scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/dsloader.cpp	2010-07-16 20:00:16 UTC (rev 50941)
+++ scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/dsloader.cpp	2010-07-16 20:44:11 UTC (rev 50942)
@@ -27,7 +27,6 @@
 
 #include <string.h>
 #include <stdarg.h>
-#include <stdarg.h>
 #include <stdio.h>
 #include <malloc.h>
 #include <unistd.h>
@@ -35,6 +34,7 @@
 
 //#include "backends/fs/stdiostream.h"
 #include "backends/fs/ds/ds-fs.h"
+#include "dsmain.h"
 
 #include "backends/platform/ds/arm9/source/dsloader.h"
 
@@ -92,24 +92,74 @@
 	// Treat each relocation entry. Loop over all of them
 	int cnt = size / sizeof(*rel);
 
-	DBG("# of relocation entries is %d.\n", cnt);
+	DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment);
 
-	// TODO: Loop over relocation entries
+	int a = 0;
+	unsigned int relocation = 0;
+
 	for (int i = 0; i < cnt; i++) {
 
-	    //Elf32_Sym *sym = ???;
+		Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info));
 
-		//void *target = ???;
+		unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset);
 
-		/*switch (REL_TYPE()) {*/
-		//case ??? :
-			//TODO: Cases for each relocation type.
-			//break;
-	//	default:
-			//seterror("Unknown relocation type %d.", ?? ?);
+		unsigned int origTarget = *target;	// Save for debugging
+
+		//DBG("%d, ", REL_TYPE(rel[i].r_info));
+
+		switch (REL_TYPE(rel[i].r_info)) {
+
+		case R_ARM_ABS32:
+			if (sym->st_shndx < SHN_LOPROC) {			// Only shift for plugin section.
+				a = *target;							// Get full 32 bits of addend
+				relocation = a + (Elf32_Addr)_segment;			   // Shift by main offset
+
+				/*TODO:
+				 * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) {
+				 * 	relocation |= 1;
+				 * }
+				 */
+
+				*target = relocation;
+
+				DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target);
+			}
+			break;
+
+		case R_ARM_THM_CALL:
+
+			if (sym->st_shndx < SHN_LOPROC) {			// Only shift for plugin section.
+				a = *target & 0x00000fff;				// Get the correct bits for addend:
+				a += ((*target & 0x0fff0000) >> 4);		// Bits 0-11 of the first half-word encode the 12 most significant bits of the branch offset,
+														// bits 0-11 of the next half-word encode the 12 least significant bits.
+				a = (a << 8) >> 8;						// sign-extend
+				a = a << 1;								// branch offset is in units of half-bytes
+
+				relocation = a + (Elf32_Addr)_segment;	// Shift by main offset
+
+				/*TODO:
+				 * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) {
+				 * 	relocation |= 1;
+				 * }
+				 */
+
+				relocation -= rel[i].r_offset;
+
+				*target = relocation;
+
+				DBG("R_ARM_THM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target);
+			}
+			break;
+
+		case R_ARM_V4BX:
+			DBG("R_ARM_V4BX: No relocation calculation necessary\n");
+			break;
+
+		default:
+			seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info));
 			free(rel);
 			return false;
-	//	}
+		}
 
 	}
 
@@ -400,7 +450,8 @@
 
 	//DLFile->finalize();
 
-	//TODO?: flush data cache
+	//flush data cache
+	DC_FlushAll();
 
 	ctors_start = symbol("___plugin_ctors");
 	ctors_end = symbol("___plugin_ctors_end");
@@ -444,9 +495,9 @@
 	Elf32_Sym *s = (Elf32_Sym *)_symtab;
 	for (int c = _symbol_cnt; c--; s++)
 
-		//TODO: Figure out which symbols should be detected here
-		if ((s->st_info >> 4 == 1 || s->st_info >> 4 == 2) &&
-		        _strtab[s->st_name] == '_' && !strcmp(name, _strtab + s->st_name + 1)) {
+		// We can only import symbols that are global or weak in the plugin
+		if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) &&
+		       !strcmp(name, _strtab + s->st_name)) {
 
 			// We found the symbol
 			DBG("=> %p\n", (void*)s->st_value);

Modified: scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/elf32.h
===================================================================
--- scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/elf32.h	2010-07-16 20:00:16 UTC (rev 50941)
+++ scummvm/branches/gsoc2010-plugins/backends/platform/ds/arm9/source/elf32.h	2010-07-16 20:44:11 UTC (rev 50942)
@@ -174,18 +174,13 @@
 } Elf32_Rel;
 
 // Access macros for the relocation info
-#define REL_TYPE(x)	((unsigned char) (x))	/* Extract relocation type */
+#define REL_TYPE(x)		((unsigned char) (x))	/* Extract relocation type */
 #define REL_INDEX(x)	((x)>>8)		/* Extract relocation index into symbol table */
 
 // ARM relocation types
 #define R_ARM_NONE			0
-#define R_ARM_PC24			1
 #define R_ARM_ABS32			2
-#define R_ARM_COPY			20
-#define R_ARM_GLOB_DAT			21
-#define R_ARM_JUMP_SLOT			22
-#define R_ARM_BASE_PREL			25
-#define R_ARM_GOT_BREL			26
-#define R_ARM_PLT32			27
+#define R_ARM_THM_CALL      10
+#define R_ARM_V4BX 			40
 
 #endif /* BACKENDS_ELF_H */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list