Building 32-bit x86 executables on macOS 10.15 Catalina - macos

Right now I am dipping my toes in x86 asm, and am trying to build a simple program using the 32-bit IA-32. I understand macOS 10.15 Catalina dumped support for running 32-bit programs, but does this mean there is no way I can build them? What if I need to cross-compile for another system?
Here is what I am trying to do. Say I have
test.c:
int main() {
return 0;
}
I compile with clang test.c -m32, and get the following warning:
ld: warning: The i386 architecture is deprecated for macOS (remove from the Xcode build setting: ARCHS)
ld: warning: ignoring file /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libSystem.tbd, missing required architecture i386 in file /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libSystem.tbd
ld: dynamic main executables must link with libSystem.dylib for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
When I try with gcc-10 test.c -m32 (installed through brew), I get
/var/folders/pg/m7w7y_w94s32b23psmxmy7bh0000gn/T//ccwFWObO.s:5:2: error: instruction requires: Not 64-bit mode
pushl %ebp
^
/var/folders/pg/m7w7y_w94s32b23psmxmy7bh0000gn/T//ccwFWObO.s:12:2: error: instruction requires: Not 64-bit mode
popl %ebp
^
Am I completely stuck here? What would you recommend to get around this? Do I need to use another operating system (e.g., past version of macOS, ubuntu, FreeBSD, etc.) in order to build 32-bit executable? For what it's worth, I can produce an asm source file, calling either gcc-10 -S test.c -m32 or the same with clang. I just can't build (and likely run) the executable. All suggestions appreciated.

Related

MacOS assembly linker throws error while linking

I'm trying to compile and link an assembly file to an executable with NASM and the standard LD linker on my MacBook Air M1. I have no problems with getting the .o file, but if I want to link it with LD, it throws that error:
ld: file not found: elf_i386
Command:
ld -m elf_i386 -s -o hello hello.o
What do I have to change?
Those are options for GNU ld on x86 Linux. (Note the ELF part of the target object-file format, and the i386). MacOS uses the MachO object-file format, not ELF, and apparently their ld takes different options.
Also, MacOS hasn't supported 32-bit x86 for a few versions now, so an M1 mac with an AArch64 CPU definitely can't run 32-bit x86 executables natively.
So get an emulator for a 32-bit Linux environment if you want to follow a tutorial for that environment, or find a tutorial for AArch64 MacOS. Or possibly x86-64 MacOS which should still work transparently thanks to Rosetta, but make sure single-step debugging actually works. That's an essential part of a development environment for learning asm.
Assembly language is not portable at all, you need a tutorial for the OS, CPU-architecture, and mode (32-bit vs. 64-bit) that you're going to built in. Don't waste your time trying to port a tutorial at the same time you're learning the basics it's trying to teach. You'd have to already know both systems to know which parts of the code and build commands need to change.

GLIBC error: Cross-compiling ARMNN on x86_64 (Ubuntu18.04) for ARM Cortex A9(Debian 9)

I cross-compiled ARMNN for my ARM Cortex-A9 (Debian 9) device on my host system which is x86_64 (Ubuntu 18.04).
I have successfully built ARMNN and all it's dependencies without any errors, but when I try to run the sample mnist on Cortex-A9, it gives the following error:
duu#34d456-45433g:~/ML-examples/armnn-mnist$ make test
arm-linux-gnueabihf-g++ -O3 -std=c++14 -I/home/duu/armnn/armnn/include mnist_caffe.cpp -o mnist_caffe -L/home/duu/build -larmnn -larmnnCaffeParser
/home/admin/build/libarmnn.so: undefined reference to `exp2f#GLIBC_2.27'
/home/admin/build/libarmnn.so: undefined reference to `logf#GLIBC_2.27'
/home/admin/build/libarmnn.so: undefined reference to `log2f#GLIBC_2.27'
/home/admin/build/libarmnn.so: undefined reference to `powf#GLIBC_2.27'
/home/admin/build/libarmnn.so: undefined reference to `expf#GLIBC_2.27'
collect2: error: ld returned 1 exit status
Makefile:12: recipe for target 'mnist_caffe' failed
make: *** [mnist_caffe] Error 1
I figured later that the device should have the same compiler and same GLIBC package, both with same versions as the host on which the library was compiled.
I compiled ARMNN using gcc-6.4.0 and glibc-2.27 on the host and I have gcc-6.3.0 and glibc-2.24 on Cortex-A9 device.
I managed to match the GCC versions and solve the compiler error but I am not able to find matching versions of GLIBC on Ubuntu 18.04 and debian 9.
Is there any way to install a GLIBC version on either of the systems which is common for both of them?
P.S. : Any other method to solve this issue is highly appreciated.
Here is a list of the possible options I can think of right now:
run your application while having LD_LIBRARY_PATH pointing to a directory containing the arm glibc dynamic libraries(v2.27) copied from your x86_64 system - see this post.
Re-compile your application on your target system, if possible, if your target system can use NFS for example,
cross-compile a static version of your library/application, linking it using -static -static-libgcc -static-libstdc++ - see this post.
use arm-linux-musleabihf-cross or one of his friends for cross-compiling a static version of your library/application if this did not work with gcc/g++ and glibc.
run your application in a chrooted environment containing the arm dynamic libraries you linked your application with on the x86_64 system - see this post for more details,
install docker on your Cortex-A9 system, and build a minimal debian/ubuntu docker image that contain a version of debian/ubuntu using glibc 2.27, along with your library and application, and execute the application in a container.

How can I compile with LLVM/Clang to RISC-V target?

I want to compile a simple program "int main(){return 0;}" to RISC-V processor.
LLVM/Clang version is 9.0 and I want to run the compiled program with a RISC-V simulator like this https://github.com/riscv/riscv-tools
My problem is that I can't list the clang supported targets only the LLC-s whith these commands:
llc --version
llc -march=xxARCHTYPExx -mattr=help
And there is no any type of riscv processor listed.
So I tried to look the triple file: llvm-project\llvm\include\llvm\ADT\Triple.h
and try a command like: clang hello.c -target riscv32 -march=rv32imafd
But I get the following error:
error: unable to create target: 'No available targets are compatible
with triple "riscv32"'
Can somebody help me to how get a valid RISC-V target? I just simple can't compile the program but I know LLVM has a RISC-V support.
LLVM 9 release notes explicitly state that RISC-V support was promoted from experimental to official.
And indeed, on my Fedora 31 machine, the LLVM 9 Fedora package does support RISC-V:
$ llvm-objdump --version | grep riscv
riscv32 - 32-bit RISC-V
riscv64 - 64-bit RISC-V
Also, I can create RISC-V binary code with the LLVM toolchain:
$ clang --target=riscv64 -march=rv64gc rotate.s -c -o rotate.o
$ file rotate.o
rotate.o: ELF 64-bit LSB relocatable, UCB RISC-V, version 1 (SYSV), not stripped
Although it doesn't include a libc for RISC-V targets:
$ clang --target=riscv64 -march=rv64gc hello-world.c -o hello-world
hello-world.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^~~~~~~~~
1 error generated.
However, you don't really need one - you could directly call syscalls for your hello world, e.g.:
$ clang --target=riscv64 -march=rv64gc hello.s -c -o hello.o
$ ld.lld hello.o -o hello
$ spike --isa=RV64gc ~/local/riscv/pk/riscv64-unknown-elf/bin/pk ./hello
bbl loader
Hello World
I don't use clang for linking because it seems that I can't convince clang with -fuse-ld to use another linker besides /usr/bin/ld.

Compiling GitHub project runs gcc with -static option on Mac and fails, how do I get around that?

I want to compile the following project that's hosted on GitHub. I'm on MacOs High Sierra 10.13.5.
When I run make on the solver directory, it gives the following error after running gcc with the -static option:
g++ -o dapcstp src/bbnode.o src/bbtree.o src/bounds.o src/cputime.o
src/heur.o src/inst.o src/main.o src/options.o src/prep.o
src/procstatus.o src/sol.o src/stats.o src/timer.o src/util.o -static -
lboost_timer -lboost_system -lboost_chrono -lboost_program_options -
lboost_filesystem
ld: library not found for -lcrt0.o
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
make: *** [dapcstp] Error 1
In the answer to ld: library not found for -lcrt0.o on OSX 10.6 with gcc/clang -static flag it says the following:
This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.
Is there a way I could circumvent this limitation and compile the project correctly on Mac ?
Looking at the project, the -static option is superfluous and counterproductive (even on system where static linking is supported). You can just remove it.

Linker (ld) crashes on Mac OS X when compiling with debuginfo, but works fine without

I'm working on a snow leopard machine (10.6.5) and I'm hunting a bug in our C++ application. However, I can't build our app with g++ -O0 -g, because the linker crashes:
g++-4.0 -arch i386 -arch x86_64 ... -dynamic -bundle -o SOMELIB.dylib <SOME OBJECTS>...
collect2: ld terminated with signal 11 [Segmentation fault]
collect2: ld terminated with signal 11 [Segmentation fault]
I guess the two crashes are because there are two "-arch" flags.
I managed to get a core file, which said the crash occurs in
(gdb) bt
#0 0x000000010001a2eb in Linker::synthesizeDebugNotes ()
#1 0x0000000100024cc5 in Linker::collectDebugInfo ()
#2 0x0000000100028198 in Linker::link ()
#3 0x000000010002a9eb in main ()
With this hint, I removed '-g' from the compiler flags, and everything builds fine. Moreover, most of our stuff builds fine with '-g', but just two of the big modules (.dylibs) don't, so I'm left with no debuginfo for those. And, ironically, the bug lurks just there, in one of these dylibs.
The bug is most likely due to an uninitialized memory use, as it manifests rarely, and running the app under valgrind reveals that there are a few uninitialized memory refences, but because of the missing debuginfo, it just says it happens inside module XXX (the dylib I can't compile with "-g")
So, I tried to download the ld utility from Apple's open source website, but I found (just like that guy) that it won't build because of a missing dependency to a Mac-specific version of libunwind, which Apple won't give away. Thus I can't recompile the linker.
So the next question is - what should I do now? I really wanted to avoid contacting Mac support...
ld version is "ld64 97.17", XCode is 3.2.5, gcc is 4.0.1.
I really need some directions...

Resources