Support IBM AIX on POWER (#6677)
commitd568c0b28d0f9f22380d7d8cb1f3fece9bb35780
authorCalvin <calvin@cmpct.info>
Mon, 5 Feb 2018 16:17:20 +0000 (5 12:17 -0400)
committerBernhard Urban <bernhard.urban@xamarin.com>
Mon, 5 Feb 2018 16:17:20 +0000 (5 17:17 +0100)
treea1e9e7b2c4845e5942883d247b5e33ba0bf29f48
parent8fca785bcb63797012ac03e416d375701e6984a9
Support IBM AIX on POWER (#6677)

* Get autotools scripts for Mono and Boehm to recognize i

PASE is most similar to AIX, and perhaps I assume other commercial
Unices, as well as PowerPC Linux, so grab variables from them as
needed.

With this, we get glib failing to build due to missing mkdtemp.

* Use better cpp definition to grab more of what we want

* Fix random and 64-bit file offset support

* Set TARGET on IBM i on POWER

* Add hack to gfile-unix.c to work around flawed AIX header

From comment:

/* HACK: the preprocessor will not give us mkdtemp no matter
   what and Mono (for good reason) does
   "-Werror-implicit-function-declaration" so we error out;
   instead declare mkdtemp here; the linker will find mkdtemp
   anwyays. libuv has had similar issues, but they just ignore
   the compiler warning instead of failing on it.

   See: github.com/libuv/libuv/pull/740 */

* Work around missing definition on AIX/PASE

* Fix conflicting definition from due too AIX headers

* Initial work to get JIT working on AIX

* uncertain about NIP; is IAR the right register? need review from
  PPC asm people

* needs calling convention work; AIX does NOT use ELF

* Fix lack of casting on sigcontext macros, fix errnos for AIX

* AIX doesn't distinguish between ENOTEMPTY and EEXIST without a
  define. Handle this case with a conditional cpp directive..

* When ctx is a void pointer, dereferencing as a struct will fail.
  Handle this case with a cast.

* Handle regular AIX as well as PASE

* Implement stack boundaries check for AIX, volume info func

* vol info should be like other Unix, just needs to bridge ifdef

* highly uncertain for the bounds checking, needs further review

* Fix typo in mono/utils/mono-threads-aix.c

* In boehm-gc.c, don't use pthread_getattr_np on AIX even if available

It's not available on IBM i, and even if available, toolchains for AIX
may "helpfully" swap out system headers with variants that remove
functions like pthread_getattr_np.

* Don't use "-export-dynamic" on non-GNU ld

IBM ld considers "-e" to be a flag for setting the entry point.
Detect non-GNU ld, and offer equivalents when possible.

The makefile in mini had to be changed as a result due to
hardcoded flags.

* Use pthread-stop-world.c on AIX

Remove an ifdef that gated this off to AIX. It seems the old AIX
specific files shouldn't be used, and that the changelog for libgc
says pthread should work fine on AIX instead; yet it was blocked.
Restore this, as it compiles and seems to let mono-boehm link fine.

* AIX workarounds for some of support dir

* fstab on AIX is there, but defines a struct more like other
  platforms' checklist struct.

* AIX, like macOS and some BSDs, doesn't define some serial types.

* psignal is another victim of GNU; even then it isn't in PASE
  headers anyways

* More support workarounds for AIX headers

* Replacement function body for syslog2 on vsyslog-less platforms

AIX lacks vsyslog; detect in autoconf and act appropriately.

* Final support hacks for AIX

* Fix problematic stack management on AIX

this gets us past ifdefs, after much handwringing

* get the right end of the stack; r1/stack pointer is on the wrong
  end and ustk is just plain broken

* AIX doesn't seem to like the semantics of the mmap call valloc
  does here; either we're allocating into an area we shouldn't be
  or we're not passing the right flags. Until then, learn to live
  without the stack guard?

* Disable Boehm GC on AIX

Focus on getting SGen working, and avoid legacy debugging nonsense

* Remove AIX ifdef-undef and replace with s/hz/uhz

* Don't use sigaltstack on AIX due to bugginess with guard sections

The valloc call on AIX has issues after issuing mprotect; don't do
do it. I believe it fails because we aren't issuing the right
flags on AIX, or because we're allocating inside of an already
allocated area.

* Perform a 64-bit build on AIX

We still crash at the same place, but probably for the best that
we switch to 64-bit. (Maybe we could make it configurable?)

* Fix func descriptor ifdef, add initial (likely wrong) defs for AIX

* AIX doesn't define __powerpc64__ or __ppc64__ when compiling as
  64-bit. Use an alternate ifdef, and shuffle around that ifdef
  anyways, as it could lead to wrong results on other platforms
  too.

* AIX likely needs special definitions, especially on 32-bit. The
  calling convention is closest to PPC64BE Linux, but not exactly.

* Fix stack size on AIX

Ruby dealt with this before: https://github.com/ruby/ruby/commit/a2594be783c727c6034308f5294333752c3845bb

* Set up initial PPC hwcap for AIX, fix ftnptr ifdefs, tweak AIX defs

* Fix hwcap to use better values on PPC AIX

Still needs more adjustment though

* Fix alignment issue on AIX, tweak mini-ppc values just a bit more

* On AIX, doubles are always aligned by 4 if they're in structs.
  Since we need to have them aligned by 8 on 64-bit, this is bad,
  so change the type on AIX.

* We can use this definition on AIX

Now we can bootstrap Mono!

* Shuffle MonoArray ifdef per suggestion of @vargaz

* Fix System.Decimal division on big endian systems

Before, we got non-sensical overflow on things like
`(Decimal)Int32.MaxValue / 1000`; now they get the same value,
comparing this POWER6 running AIX to my server's output running
OpenBSD/amd64.

* Fix dynamically linked build of Mono on AIX

nm wasn't seeing 64-bit symbools as it defaults to 32-bit mode,
also never try to use GNU nm

* Fix PPC64 define in mono-config

Interestingly, there was an AIX define already present, and that
definition is present in AIX's passed includes, so continue to use
it.

* Don't use __thread even if detected on AIX

tl;dr: The assembler gets angry with __thread and minimal-toc, and
changing options to replace minimal-toc causes linker issues; this
TLS option isn't important anyways if we have pthread instead,
like before when we were using Perzl's old GCC without __thread.

* Get lib.a(lib.o) type archives working with P/Invoke for AIX

AIX libraries are very, very strange compared to other Unices.

I'm not entirely sure if this is correct or optimal; it may need
to special case further. For now, it's enough to get gacutil
up and running.

Some resources I found useful for this charade:
<http://stromberg.dnsalias.org/~dstromberg/AIX-shared-libs.html>

Also set libc and libintl to their proper values.

* Scheduling priority hack for i

PASE doesn't accept anything other than SCHED_OTHER, and the funcs
for getting min/max don't work either. AIX suffers, but only a
little bit.

* Final polish on request

Remove Boehm changes if we don't use Boehm, tweak some defines,
remove some externs, tweak autoconf file

* Be aware of ERESTART, on OSes that use it

Instead of EINTR/EAGAIN, AIX uses ERESTART. Handle this, so things
like xsp are less chatty when performing async IO.
28 files changed:
configure.ac
mono/eglib/gfile-unix.c
mono/metadata/decimal-ms.c
mono/metadata/mono-config.c
mono/metadata/object-internals.h
mono/metadata/threadpool-io.c
mono/metadata/threads.c
mono/metadata/w32error-unix.c
mono/metadata/w32file-unix.c
mono/mini/Makefile.am.in
mono/mini/mini-ppc.c
mono/mini/mini-ppc.h
mono/mini/mini-runtime.c
mono/utils/Makefile.am
mono/utils/mono-dl-posix.c
mono/utils/mono-hwcap-ppc.c
mono/utils/mono-machine.h
mono/utils/mono-mmap.c
mono/utils/mono-proclib.c
mono/utils/mono-sigcontext.h
mono/utils/mono-threads-aix.c [new file with mode: 0644]
support/fstab.c
support/serial.c
support/signal.c
support/sys-statvfs.c
support/syslog.c
support/time.c
support/unistd.c