How to get 64-bit binaries from GHC for Snow Leopard? - haskell

I've recently upgraded my OS to Snow Leopard, which broke my GHC. I was able to fix it on one machine by adding flags for 32-bit compiles in /usr/bin/ghc (something like -optl -m32 -opta -m32 -optc -m32, gathered from here). Now I can't get it to produce 64-bit binaries for my other machine, which supports 64-bits. The 32-bit flags break, and removing them breaks as well. Any tips?
When I try to compile I get stuff like this:
/var/folders/az/az3Ef9shFZq6RajmTEBwu++++TI/-Tmp-//ghc8006_0/ghc8006_0.s:212:0:
32-bit absolute addressing is not supported for x86-64
/var/folders/az/az3Ef9shFZq6RajmTEBwu++++TI/-Tmp-//ghc8006_0/ghc8006_0.s:212:0:
cannot do signed 4 byte relocation
/var/folders/az/az3Ef9shFZq6RajmTEBwu++++TI/-Tmp-//ghc8006_0/ghc8006_0.s:215:0:
32-bit absolute addressing is not supported for x86-64
/var/folders/az/az3Ef9shFZq6RajmTEBwu++++TI/-Tmp-//ghc8006_0/ghc8006_0.s:215:0:
cannot do signed 4 byte relocation
Thanks!

64 bit Snow Leopard installers for the Haskell Platform are available, as of 2011.
http://hackage.haskell.org/platform/mac.html

My understanding is that at the moment ghc cannot generate correct 64 bit binaries under Snow Leopard. This appears to be in part because of a bug in its 64 bit link generation and in part because of a change in the native toolchain. The workaround you mention simply tells it to generate a 32 bit target and thus won't be part of any actual solution to your problem.

Related

How can I determine which rust target to compile to by looking at a windows computer?

I am compiling a rust application that will be statically linked and then placed on an external server. What settings, config, or table should I look up to find the correct compile target? For most modern windows server and computers, x86_64-pc-windows-msvc should work just fine, but I wanted to know if there was a more concrete way of figuring this out.
Here the rustup docs mention windows installation and considerations, but not how to figure out the target.
Try going to the system you are building for and run echo %PROCESSOR_ARCHITECTURE%. This will give us information about the CPU architecture that can help us decide.
According to the win32 documentation, it will be a value of AMD64, IA64, ARM64, or x86. Conveniently these line up with the available windows rust targets. I can find all of the rust targets by running rustup target list and looking for ones with windows in the name. Here is that output on my machine:
$ rustup target list | grep windows
aarch64-pc-windows-msvc
i586-pc-windows-msvc
i686-pc-windows-gnu
i686-pc-windows-msvc
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc
For the values of PROCESSOR_ARCHITECTURE, we can more or less approximate which is which by just googling them.
AMD64: This is just another name for x86_64 so we need to use either x86_64-pc-windows-msvc or x86_64-pc-windows-gnu.
IA64: ¯\(ツ)/¯ Rust is built on top of LLVM. IA64 has reached its end of life and not much hardware uses it so LLVM decided not to support this architecture. I think gcc probably does support it, but we're already out of luck when it comes to using Rust.
ARM64: This corresponds to the aarch64 architecture so we should use aarch64-pc-windows-msvc.
x86: This actually means we are running in 32bit mode so we need to choose either i686-pc-windows-msvc or i686-pc-windows-gnu.
As for i586-pc-windows-msvc, it refers to the older I5 Pentium architecture. It should be compatible with the newer i686 and x86_64 architectures, but may or may not be as performant. I would avoid it unless you are working with older hardware and need compatibility. I am also assuming it will not be compatible with windows 11 due to the new 64bit requirement.
As for the difference between msvc and gnu, you get to pick. I imagine msvc will be easier to work with, but I have not tried to use the gnu version.

C++ 64 Bit compiler, what does it output?

I have suddenly had a bout of confusion around Mingw-64 compilers and other compilers which are said to be 64-bit. Does this mean that the compiler is built to run on a 64 bit platform and compiles in 32-bit (this seems to be the case for all the Mingw-64 compilers I have found)? Or does it mean that it will actually copile and build 64 bit binaries.
I want to build 64 bit binaries on a 64-bit compiler and am a little confused as to whether I am actually getting 64-bit outputs despite installing a 64-bit compiler?
There are a number of versions of Ming-64 bit around, eg: tdm, ming-64.. their binary directory seems to contain wing-32 binary files?
A "64 bit compiler" will output 64 bit executables. It may or may not be 64 bit itself; MSVC++ for instance has a 64 bit compiler that's 32 bits itself.

Is all MIPS code on Linux supposed to be PIC?

In Linux on MIPS CPUs (MIPSEL32 to be precise), is it true that all userland SO's are supposed be position independent (PIC)? A cite from an authoritative source would be the the best.
How about Android?
My interest stems from this.
The situation with PIC code on Linux appears to be somewhat interesting. In the past (pre EGLIBC-2.9) all binaries on MIPS where supposed to be PIC (both applications and shared libraries). However, to reduce the size of applications, the ABI extension was developed to allow for non-PIC executables (but shared objects stay PIC, as before):
At this time we do not propose any change to the position-independent
addressing conventions used by shared objects. Similarly,
position-independent executables compiled with '-fpie' -- as required
for address space randomisation in "hardened" Linux distributions --
shall continue to use the existing psABI addressing and calling
mechanisms.
http://gcc.gnu.org/ml/gcc/2008-07/txt00000.txt
The wiki page on linux-mips.org stating that all binaries on MIPS must be PIC appears to be somewhat out of date, as both recent GCC and EGLIBC on Linux support non-PIC executables: http://www.linux-mips.org/wiki/PIC_code

Using x86 materials to learn assembly on a 64 bit OS?

I am teaching myself/reading up about assembly. Most of the books on assembly refer to x86- all the register names in the code begin with "e" and not "r" (as they would in x86-64). However, I use 64-bit Linux and I was wondering if these books have any value because they are not referring to x86-64.
So in short- is it really worth me using these resources to learn x86-64. Or reworded differently, besides the difference in register naming convention- are there any other differences between the two which could make learning from x86 materials difficult?
64 bit Linux allows running 32bit applications, so you still can create 32 bit applications on your computer. This way, the books and example 32 bit code are fully useful.
The only single problem you might have is if the assembly application dynamically link to some 32 bit shared library. In order to fix this you should install 32 bit compatibility layer.
The assembly programs that use only Linux system calls works fine without this layer, which is actually set of shared libraries compiled for 32 bit.
BTW, in my opinion, writing 32 bit code is still better if you want your programs to be useful for more people. There are still many 32 bit computers around and they will not disappear soon.
It's indeed a bit easier to learn assembly on 32bit since the calling conventions and stack management are simpler.
On 64bit you need to worry about ABI. Not only that but the conventions are not the same for every OSes. For instance, the ABI rules on Mac OS X are different than those on Windows (the registers are not the same and on Windows it only uses 4 registers).
You can compile your assembly code using -arch i386 with the assembler (as). With clang or gcc you can use -m32 (at least on Mac OS X, since I haven't used it on Linux proper). You won't be able to link modules that have different bitness (32bit vs 64bit).
Once you're ready to switch or compile your program for 64bit you will have to make sure that when you handle the stack you need to push 64bit words instead of 32bit ones but that kinda goes with saying.

How to recompile libc to use soft float?

Libc had to be upgraded (via apt-get) for a certain package. That package is no longer needed, and by upgrading libc through apt-get I cannot build certain other programs from source any more. I need to recompile libc to use soft float instead of hard float so I can once again compile the programs I need.
Right now I get a warning like so:
Warning: /usr/lib64/libc_nonshared.a(elf-init.oS) uses hard float, foobar uses soft float
...and running the compiled foobar will result in the error:
Floating point exception
The system itself is on a MIPS64 architecture. Before upgrading libc through apt-get, these programs compiled and ran successfully.
Recompiling libc is difficult. Your best bet is to find a precompiled 64 bit soft float libc online, or restore your original from backup. Take a look at the free CodeSourcery Lite MIPS toolchain, which includes many different libc versions.

Resources