Workaround for bug 3560 - [GCCE] elf2e32 puts unresolved weak function symbols in data segment. GCC_SURGE
authorMike Kinghan <mikek@symbian.org>
Fri, 13 Aug 2010 14:17:31 +0100
branchGCC_SURGE
changeset 246 4a60358e2cbf
parent 241 973a4e3b29b5
child 267 9b718307b8ec
Workaround for bug 3560 - [GCCE] elf2e32 puts unresolved weak function symbols in data segment.
kernel/eka/euser/epoc/arm/uc_dll.cpp
kernel/eka/euser/epoc/arm/uc_exe.cpp
kernel/eka/kernel/arm/d_entry.cpp
--- a/kernel/eka/euser/epoc/arm/uc_dll.cpp	Fri Aug 06 10:53:45 2010 +0100
+++ b/kernel/eka/euser/epoc/arm/uc_dll.cpp	Fri Aug 13 14:17:31 2010 +0100
@@ -46,6 +46,24 @@
 
 #elif defined(__EABI__)
 
+#ifdef __GCCE__
+// Workaround for bug #3560, http://developer.symbian.org/bugs/show_bug.cgi?id=3560
+static int AddressIsInCodeSegment(void *addr)
+{
+	void * code_seg_base;
+	void * code_seg_limit;
+	asm(".extern Image$$ER_RO$$Base");
+	asm(".extern Image$$ER_RO$$Limit");
+	asm("code_seg_limit:");
+	asm(".word Image$$ER_RO$$Limit");
+	asm("code_seg_base:");
+	asm(".word Image$$ER_RO$$Base");
+	asm("ldr %[result], code_seg_base" : [result] "=r" (code_seg_base));
+	asm("ldr %[result], code_seg_limit" : [result] "=r" (code_seg_limit));
+	return addr >= code_seg_base && addr < code_seg_limit;		
+}
+#endif
+
 void __DLL_Export_Table__(void);
 void __cpp_initialize__aeabi_(void);
 __WEAK__ void run_static_dtors(void);
@@ -59,8 +77,15 @@
 		}
 	else if (aReason==KModuleEntryReasonProcessDetach)
 		{
+#if defined(__ARMCC__)
 		int call_static_dtors = (int)run_static_dtors;
 		if (call_static_dtors) run_static_dtors();
+#elif defined(__GCCE__)
+// Workaround for bug #3560, http://developer.symbian.org/bugs/show_bug.cgi?id=3560
+		if (AddressIsInCodeSegment((void *)run_static_dtors)) run_static_dtors();
+#else
+#error What compiler?
+#endif
 		return KErrNone;
 		}
 	return 0;
--- a/kernel/eka/euser/epoc/arm/uc_exe.cpp	Fri Aug 06 10:53:45 2010 +0100
+++ b/kernel/eka/euser/epoc/arm/uc_exe.cpp	Fri Aug 13 14:17:31 2010 +0100
@@ -74,13 +74,11 @@
 
 TInt CallThrdProcEntry(TInt (*aFn)(void*), void* aPtr, TInt aNotFirst);
 
-__WEAK__ void run_static_dtors(void);
+void run_static_dtors(void);
 
 void globalDestructorFunc()
 	{
-	int call_static_dtors = (int)run_static_dtors;
-	if (call_static_dtors)
-		run_static_dtors();
+	run_static_dtors();
 	}
 
 void RunThread(TBool aNotFirst, SThreadCreateInfo& aInfo)
--- a/kernel/eka/kernel/arm/d_entry.cpp	Fri Aug 06 10:53:45 2010 +0100
+++ b/kernel/eka/kernel/arm/d_entry.cpp	Fri Aug 13 14:17:31 2010 +0100
@@ -51,6 +51,24 @@
 
 #elif defined(__EABI__)
 
+#ifdef __GCCE__
+// Workaround for bug #3560, http://developer.symbian.org/bugs/show_bug.cgi?id=3560
+static int AddressIsInCodeSegment(void *addr)
+{
+	void * code_seg_base;
+	void * code_seg_limit;
+	asm(".extern Image$$ER_RO$$Base");
+	asm(".extern Image$$ER_RO$$Limit");
+	asm("code_seg_limit:");
+	asm(".word Image$$ER_RO$$Limit");
+	asm("code_seg_base:");
+	asm(".word Image$$ER_RO$$Base");
+	asm("ldr %[result], code_seg_base" : [result] "=r" (code_seg_base));
+	asm("ldr %[result], code_seg_limit" : [result] "=r" (code_seg_limit));
+	return addr >= code_seg_base && addr < code_seg_limit;		
+}
+#endif
+
 void __DLL_Export_Table__(void);
 void __cpp_initialize__aeabi_(void);
 __WEAK__ void run_static_dtors(void);
@@ -62,8 +80,15 @@
 	{
 	if (aReason==KModuleEntryReasonProcessDetach)
 		{
+#if defined(__ARMCC__)
 		int call_static_dtors = (int)run_static_dtors;
 		if (call_static_dtors) run_static_dtors();
+#elif defined(__GCCE__)
+// Workaround for bug #3560, http://developer.symbian.org/bugs/show_bug.cgi?id=3560
+		if (AddressIsInCodeSegment((void *)run_static_dtors)) run_static_dtors();
+#else
+#error What compiler?
+#endif
 		return KErrNone;
 		}
 	if (aReason==KModuleEntryReasonExtensionInit1 || aReason==KModuleEntryReasonProcessAttach)