Hi,
This is a patch I made trying to solve an issue presented in Gentoo Hardened project. VirtualBox doesn't compile with gcc if PIC/PIE related options are activated. The problem is related to inline asm code trying to use ebx register for passing arguments, but PIC/PIE systems reserve this register for specific functions, so special treatment is required when PIC/PIE is defined (gcc refuses to compile such a code if you don't do it). This may need extensive testing, but it seems to work fine. Please, let me know any problem you encounter. The patch is under MIT license.

best regards,

Dariem


diff -rud VirtualBox-3.1.0_OSE_Orig/src/VBox/Devices/PC/Etherboot-src/arch/i386/core/pci_io.c VirtualBox-3.1.0_OSE/src/VBox/Devices/PC/Etherboot-src/arch/i386/core/pci_io.c
--- VirtualBox-3.1.0_OSE_Orig/src/VBox/Devices/PC/Etherboot-src/arch/i386/core/pci_io.c	2009-03-13 06:38:36.000000000 -0400
+++ VirtualBox-3.1.0_OSE/src/VBox/Devices/PC/Etherboot-src/arch/i386/core/pci_io.c	2010-01-27 04:39:46.000000000 -0500
@@ -112,13 +112,30 @@
 	unsigned long length;		/* %ecx */
 	unsigned long entry;		/* %edx */
 
-	__asm__(BIOS32_CALL
+	__asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl  %%ecx, %%ebx\n"
+#endif
+		BIOS32_CALL
+#if __PIC__
+		"movl %%ebx, %1\n"
+		"pop %%ebx\n"
+#endif
 		: "=a" (return_code),
+#if __PIC__
+		  "=m" (address),
+#else
 		  "=b" (address),
+#endif
 		  "=c" (length),
 		  "=d" (entry)
 		: "0" (service),
+#if __PIC__
+		  "2" (0),
+#else
 		  "1" (0),
+#endif
 		  "S" (bios32_entry));
 
 	switch (return_code) {
@@ -140,14 +157,26 @@
         unsigned long ret;
         unsigned long bx = (bus << 8) | device_fn;
 
-        __asm__(BIOS32_CALL
+        __asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl %3, %%ebx\n"
+#endif
+		BIOS32_CALL
                 "jc 1f\n\t"
                 "xor %%ah, %%ah\n"
+#if __PIC__
+		"pop %%ebx\n"
+#endif
                 "1:"
                 : "=c" (*value),
                   "=a" (ret)
                 : "1" (PCIBIOS_READ_CONFIG_BYTE),
+#if __PIC__
+		  "m" (bx),
+#else
                   "b" (bx),
+#endif
                   "D" ((long) where),
                   "S" (pcibios_entry));
         return (int) (ret & 0xff00) >> 8;
@@ -159,14 +188,26 @@
         unsigned long ret;
         unsigned long bx = (bus << 8) | device_fn;
 
-        __asm__(BIOS32_CALL
+        __asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl %3, %%ebx\n"
+#endif
+		BIOS32_CALL
                 "jc 1f\n\t"
                 "xor %%ah, %%ah\n"
+#if __PIC__
+		"pop %%ebx\n"
+#endif
                 "1:"
                 : "=c" (*value),
                   "=a" (ret)
                 : "1" (PCIBIOS_READ_CONFIG_WORD),
+#if __PIC__
+		  "m" (bx),
+#else
                   "b" (bx),
+#endif
                   "D" ((long) where),
                   "S" (pcibios_entry));
         return (int) (ret & 0xff00) >> 8;
@@ -178,14 +219,26 @@
         unsigned long ret;
         unsigned long bx = (bus << 8) | device_fn;
 
-        __asm__(BIOS32_CALL
+        __asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl %3, %%ebx\n"
+#endif
+		BIOS32_CALL
                 "jc 1f\n\t"
                 "xor %%ah, %%ah\n"
+#if __PIC__
+		"pop %%ebx\n"
+#endif
                 "1:"
                 : "=c" (*value),
                   "=a" (ret)
                 : "1" (PCIBIOS_READ_CONFIG_DWORD),
+#if __PIC__
+		  "m" (bx),
+#else
                   "b" (bx),
+#endif
                   "D" ((long) where),
                   "S" (pcibios_entry));
         return (int) (ret & 0xff00) >> 8;
@@ -197,14 +250,26 @@
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
 
-	__asm__(BIOS32_CALL
+	__asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl %3, %%ebx\n"
+#endif
+		BIOS32_CALL
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
+#if __PIC__
+		"pop %%ebx\n"
+#endif
 		"1:"
 		: "=a" (ret)
 		: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
 		  "c" (value),
-		  "b" (bx),
+#if __PIC__
+		  "m" (bx),
+#else
+                  "b" (bx),
+#endif
 		  "D" ((long) where),
 		  "S" (pcibios_entry));
 	return (int) (ret & 0xff00) >> 8;
@@ -216,14 +281,26 @@
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
 
-	__asm__(BIOS32_CALL
+	__asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl %3, %%ebx\n"
+#endif
+		BIOS32_CALL
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
+#if __PIC__
+		"pop %%ebx\n"
+#endif
 		"1:"
 		: "=a" (ret)
 		: "0" (PCIBIOS_WRITE_CONFIG_WORD),
 		  "c" (value),
-		  "b" (bx),
+#if __PIC__
+		  "m" (bx),
+#else
+                  "b" (bx),
+#endif
 		  "D" ((long) where),
 		  "S" (pcibios_entry));
 	return (int) (ret & 0xff00) >> 8;
@@ -235,14 +312,26 @@
 	unsigned long ret;
 	unsigned long bx = (bus << 8) | device_fn;
 
-	__asm__(BIOS32_CALL
+	__asm__(
+#if __PIC__
+		"pushl %%ebx\n"
+		"movl %3, %%ebx\n"
+#endif
+		BIOS32_CALL
 		"jc 1f\n\t"
 		"xor %%ah, %%ah\n"
+#if __PIC__
+		"pop %%ebx\n"
+#endif
 		"1:"
 		: "=a" (ret)
 		: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
 		  "c" (value),
-		  "b" (bx),
+#if __PIC__
+		  "m" (bx),
+#else
+                  "b" (bx),
+#endif
 		  "D" ((long) where),
 		  "S" (pcibios_entry));
 	return (int) (ret & 0xff00) >> 8;
@@ -257,17 +346,27 @@
 	int pack;
 
 	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
-		__asm__(BIOS32_CALL
+		__asm__(
+#if __PIC__
+			"pushl %%ebx\n"
+#endif
+			BIOS32_CALL
 			"jc 1f\n\t"
 			"xor %%ah, %%ah\n"
 			"1:\tshl $8, %%eax\n\t"
-			"movw %%bx, %%ax"
+			"movw %%bx, %%ax\n"
+#if __PIC__
+			"pop %%ebx\n"
+#endif
 			: "=d" (signature),
 			  "=a" (pack)
 			: "1" (PCIBIOS_PCI_BIOS_PRESENT),
 			  "S" (pcibios_entry)
+#if __PIC__
+			: "cx");
+#else
 			: "bx", "cx");
-
+#endif
 		present_status = (pack >> 16) & 0xff;
 		major_revision = (pack >> 8) & 0xff;
 		minor_revision = pack & 0xff;
_______________________________________________
vbox-dev mailing list
[email protected]
http://vbox.innotek.de/mailman/listinfo/vbox-dev

Reply via email to