I'm working on OS-adaptations for an OS that would use x86-64 applications that are located above 4G, but not in the upper area. Binutils provide a function to be able to set the start of text to above 4G, but there are problems with GCC when using this memory model.

The first issue has to do with creating a cross-compiler that defaults to medium memory model using PIC. While there are switches to achieve this on command line (-mcmodel=medium -fpic), this is inconvinient since everything ported must be changed to add these switches, including libgcc and newlib. The cross-compiler instead should default to this memory model.

One possibility to achieve this is to add a new .h-file in the gcc/config/i386 directory. However, further inspection of the source indicates there is no macro that can be redefined to achieve this. One possibility is to add such a macro in gcc/config/i386.h, and implement it in gcc/config/i386.c.

Here is a simple patch to do this:

diff -u -r -N gcc-4.8-20121202/gcc/config/i386/i386.h gcc-work/gcc/config/i386/i386.h --- gcc-4.8-20121202/gcc/config/i386/i386.h 2012-11-23 17:02:10.000000000 +0100
+++ gcc-work/gcc/config/i386/i386.h 2012-12-08 12:17:40.000000000 +0100
@@ -86,6 +86,8 @@
#define TARGET_LP64 TARGET_ABI_64
#define TARGET_X32 TARGET_ABI_X32

+#define TARGET_MEDIUM_PIC   0
+
/* SSE4.1 defines round instructions */
#define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1
#define TARGET_ISA_ROUND ((ix86_isa_flags & OPTION_MASK_ISA_ROUND) != 0)

diff -u -r -N gcc-4.8-20121202/gcc/config/i386/i386.c gcc-work/gcc/config/i386/i386.c --- gcc-4.8-20121202/gcc/config/i386/i386.c 2012-12-02 00:43:52.000000000 +0100
+++ gcc-work/gcc/config/i386/i386.c 2012-12-11 21:43:48.000000000 +0100
@@ -3235,6 +3235,8 @@
  DLL, and is essentially just as efficient as direct addressing.  */
      if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
 ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
+      else if (TARGET_64BIT && TARGET_MEDIUM_PIC)
+    ix86_cmodel = CM_MEDIUM_PIC, flag_pic = 1;
      else if (TARGET_64BIT)
 ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
      else

It can be used like this:

+#undef TARGET_MEDIUM_PIC
+#define TARGET_MEDIUM_PIC 1

Next, with this issue fixed, there is still another problem in libgcc when using a cross-compiler compiled with this memory model:

../../gcc-work/libgcc/. -I../../../gcc-work/libgcc/../gcc -I../../../gcc-work/libgcc/../include -DHAVE_CC_TLS -o cpuinfo.o -MT cpuinfo.o -MD -MP -MF cpuinfo.dep -c ../../../gcc-work/libgcc/config/i386/cpuinfo.c -fvisibility=hidden -DHIDE_EXPORTS
In file included from ../../../gcc-work/libgcc/config/i386/cpuinfo.c:21:0:
../../../gcc-work/libgcc/config/i386/cpuinfo.c: In function 'get_available_features': ../../../gcc-work/libgcc/config/i386/cpuinfo.c:236:7: error: inconsistent operand constraints in an 'asm'
__cpuid_count (7, 0, eax, ebx, ecx, edx);
^
../../../gcc-work/libgcc/static-object.mk:17: recipe for target `cpuinfo.o' failed
make[1]: *** [cpuinfo.o] Error 1
make[1]: Lämnar katalogen "/usr/src/build-gcc-noheader/rdos/libgcc"
Makefile:10619: recipe for target `all-target-libgcc' failed
make: *** [all-target-libgcc] Error 2

My guess is that __cpuid_count uses 32-bit addressing when it should be using 64-bit addressing. I have no patch for this as I don't understand what is going on here well enough, but __cpuid_count is defined in gcc/config/i386/cpuid.h.

In order to be able to continue to test the medium memory model I'd need patches to be applied to fix these issues.

Regards,
Leif Ekblad
RDOS Development

Reply via email to