The compiler used to build Illumos needs to have several features not present in mainline GCC, and several other properties which GCC otherwise lacks.

Below is an attempt to sketch out

The majority of these changes were made by Codesourcery LLC under contract to Sun Microsystems, further changes were made by Sun itself.

Changes applicable to code generation

The following options affect code generation, and are not in any upstream version of GCC (they're not particularly useful in the general sense).

amd64 -msave-args

The amd64 ABI states that the first 6 integer-sized arguments are passed in registers, with the rest spilled to the stack. This makes it particularly difficult to find arguments without fairly full debugger support for something like DWARF (which would have its own complications).

Instead of this, GCC was modified to push the register-passed arguments onto the stack at the frame pointer (before the callee-saved registers) in the function prologue, and mdb was modified such that, when debugging the kernel (why this was not done for userland is unknown) we pattern-match the instruction prologue attempting to discover this modified prologue, and, if we discover it, we pull the arguments from there.

Without these changes, getting at function arguments from mdb is incredibly tedious and context specific (and is not guaranteed to be possible).


The SPARC specification states that the memory operands of ldd and std must be 8-byte aligned. GCC generates code that uses ldd and std to load and store 64bit integers, presuming them to be suitably aligned as the ABI requires this. Some of our code does not align 64bit integers to the ABI requirement and thus requires that all integers be stored/loaded with pairs of st orld instructions instead. This option causes that to happen, similar to Sun C's -xmemalign=4


Direct system calls on SPARC systems pass the first 6 word-sized arguments in registers, according to the normal ABI calling conventions.  Thus, when a 32bit process makes a system call to a 64bit kernel, negative arguments are twos complement in the width of the 32bit v7 register, not the 64bit v9 register the kernel sees.  This, in effect, makes any integer argument from a 32bit process implicitly signed.  This option causes GCC to emit code which does any promotion of function arguments in the callee rather than the caller, to account for this and allow direct 32bit calls to continue to function (at the cost of some pessimization).  This is also how Studio, and GCC prior to 4.2 would have generated the code.


For observability reasons, it is important that local functions follow the ABI-specified calling conventions, regardless of the compilers opinions about performance.  This prevents the use of the GCC 'local' i386 convention, where arguments are passed in registers.

General changes

Support for cmn_err format specifiers

cmn_err(9F) has a variety of format specifiers not present in the normal printf family of functions, we'd like format-string checking of them.

#pragma redefine_extname should itself be macro expanded

We use #pragma redefine_extname with parameters which are themselves pre-processor macro expansions, GCC needs to be told that macro expansion should be performed.

We expect #pragma weak to be applied regardless of scoping

This change appears to be present upstream in recent GCC.

Allow #pragma align to be used after a variable is declared

GCC mandates that #pragma align precede any declaration, Sun C does not. It is easier to make the compilers agree on semantics.

Parameters to #pragma align need to be macro expanded

GCC does not macro-expand #pragma align, Sun C does. It is easier to make the compilers agree on semantics.