DragonLace.Net
Home of the GNAT AUX and future DRACO Ada compilers.

GCC 4.7 has been available for quite some time. In fact, GCC 4.7.1 was released in mid-June. Originally GNAT AUX was intended to follow the latest trunk, and when that was discovered to be problematic, it was intended to follow the latest release of the latest major branch.

Now even that approach is problematic. For pkgsrc, DragonFly uses GNAT AUX as their way of building DragonFly world and kernel with a GCC 4.6 compiler. For FreeBSD, the GNATDROID cross compilers (and possibly other cross compilers in the future) are based on it. Furthermore, the GNAT AUX port/package are based on individual language tarballs which GCC discontinued after 4.6, so the entire makefile would have to be reworked again to use one monolithic tarball.

An additional problem is GNAT AUX installs at ${LOCALBASE} which means several libraries and binaries would conflict with other GCC-based ports installed there.

To address all these problems, a new compiler package, lang/gcc-aux, was created. It is based on GCC 4.7.1 and installs at ${LOCALBASE}/gcc-aux to avoid file conflicts. It is intended to migrate to GCC 4.8 in the future, so like GNAT AUX, it has a date as a version (currently 20120614).

The pkgsrc make file system was altered to recognize USE_LANGUAGES+= ada. This means that it is no longer required to specify a certain compiler for Ada-based packages. All the Ada packages, including Florist, were updated update to build with lang/gcc-aux instead of lang/gnat_aux.

At the same time, GPRBUILD was updated to version GPL 2012 and Florist was updated from version 3.15p to version GPL 2012. Future updates to xmlada, gtkada, and GPS are coming soon to pkgsrc.

These updates are not yet available for FreeBSD.

Posted Wed Jul 11 07:42:49 2012

The following issue is probably not widely known so I'll explain what it was, what platforms it affected, and how it was solved.

The problem was that you couldn't build GCC to support both Ada and C/C++ with long double support perfectly on x86 FreeBSD and x86 DragonFly platforms. You had to choose which language you wanted to provide correct precision: Ada or C/C++. You couldn't have both correct on these platforms.

The reason is that FreeBSD's floating point unit on the i386 platform rounds long doubles down to 53-bit mantissas. GCC knows that FreeBSD does this on its x386 platform and compensates for it. There is a macro for the GCC configuration files called TARGET_96_ROUND_53_LONG_DOUBLE. The default value for this macro is zero (false), but for x86 FreeBSD (and by inheritance, x86 DragonFly), this value must be true. If you build GCC on x86 FreeBSD with this macro set to zero, the results of run time long double calculations (e.g. add, subtract, square root) will be different than expected.

Unfortunately, if you build GCC on x86 FreeBSD with this macro set to 1 (true), then GNAT will fails some precision tests. As long as the builder doesn't build GCC with both GNAT and C++, he could tailor TARGET_96_ROUND_53_LONG_DOUBLE to one language.

Over time, people asked GNAT-AUX and it's successor GCC-AUX to support more than Ada. Currently they support C++, Fortran, and Objective-C as well as the base C language. It was tailored to Ada, so long double calculations with these compilers were suspect. How could it be fixed? The same backend was common to both compiler front ends, presented as libbackend.a during the build.

The solution was to first isolate the source file that initializes the FPU. That file is insn-modes.c, which is generated. During the build, that file is now duplicated and edited to produce insn-modes-ada.c, which ignores the value of TARGET_96_ROUND_53_LONG_DOUBLE (the same as if it were set to false). The object file from this source file is now keep out of the libbackend.a library, but passed along separately to each language front end. The Ada front end gets passed the insn-modes-ada.o object file instead.

That's how the new GCC-AUX compiler (based on gcc-4.7.1) maintains precision quality with both GNAT and the C++ front-end simultaneously. This fix is already available in PKGSRC, and soon I hope to submit a new lang/gcc-aux port for FreeBSD. I'll also publish a comprehensive set of testsuite results that cover all languages and several Operating System / CPU combinations (e.g NetBSD, FreeBSD, DragonFly, OpenSolaris with x86 and x86_64 CPUs).

Posted Sun Jul 15 14:53:57 2012

To fix Ada tasking in FreeBSD 9.0, you have to fix and rebuild the thread library.

Before you start, make sure you have the FreeBSD 9.0 source at /usr/src. If you didn't install it with FreeBSD, you can find src.txz on the install disk. Alternatively, you can download the 89MB file directly from FreeBSD Just extract it in the root directory as it starts with /usr.

  1. Obtain the patch from DragonLace
  2. Apply the patch to /usr/src/lib/libthr/thread/thr_setscheduleparam.c
  3. cd /usr/src/lib/libthr

  4. make depend

  5. make

  6. make install

Now Ada tasking should function correctly on FreeBSD 9.0. This has already been fixed for the upcoming FreeBSD 9.1.

Posted Thu Jul 26 04:32:09 2012

Quite a few months ago, I discovered that Ada tasking was broken on FreeBSD 9.0. Whenever a task would exit, the system would respond with "thread exits with resources held!" I noticed there was a new panic assertion in the thread library, so my first inclination was that GNAT was misbehaving on all POSIX machines, but only FreeBSD was detecting it. I was a little annoyed that new check actually caused a regression. Since I detected this on the GCC 4.6-based GNAT-Aux, the Adacore folks told me to check GCC 4.7 before they'd take it further. Fair enough.

After porting GCC 4.7 to FreeBSD (it's a new port called lang/gcc-aux), I confirmed that tasking was still broken. After more prodding by Adacore, I also confirmed that the same panic check did not break tasking in DragonFly. Oh Uh, this looks like a FreeBSD problem, not a GNAT bug. Sure enough, it was a bug in FreeBSD 9.0. It's been fixed now, so tasking will work on gnat-aux and gcc-aux on FreeBSD 9.1. A follow-up post will describe how to fix and rebuild the FreeBSD 9.0 thread library.

A second problem was discovered with the AMD64 platform (i386 platform is unaffected). All the stack-check and dereference tests would fail on gnat-aux and gcc-aux on FreeBSD 9.0 AMD64. It turns out that in order to support non-executable stacks (an option only available on AMD64), the signal trampoline had to be moved from just prior to the PS_STRINGS location to a shared page. This caused the end-of-stack detection in the FreeBSD unwind code to fail. A signal trampoline pattern match similar to what is done for NetBSD had to be created for FreeBSD 9.0 AMD. This fix will be included in the first port of gcc-aux.

Posted Thu Jul 26 04:32:09 2012
Last edited Fri May 24 16:28:01 2013
© 2010 John Marino | design elements by styleshout | artwork by Arturo Aguirre