Fat Mach-O Executable Multi-purpose? - executable

I am currently working with Mach-O Executables on my Mac and A question just came across me, Can a single Fat Mach-O Executable file have multiple purposes? Eg.
Could I Have a single Mach-O Executable File with a Fat Header specifying 2 Executables:
Executable 1 : This executable could be a Dynamic Library allowing Its code to be loaded in external applications.
and
Executable 2 : This executable could be an Executable allowing It to be independently launched through Terminal or as an Application.
I just want to know, could this be possible to have 2 Executables with completely different functions inside a single Mach-O Binary File?

Yes it is possible, but hardly useful. Before I get to why, here's how to create one:
Take this C file:
#ifdef __LP64__
int main(void)
#else
int derp(void)
#endif
{
return 123;
}
Compile it as a 64-bit executable and a 32-bit shared library:
gcc -o t t.c -Wall
gcc -m32 -o t.dylib -Wall t.c -shared
And smash them together:
lipo -create -output t.fat t t.dylib
Now, why is that supposed to be not useful?
Because you're limited to one binary per architecture, and you have little to no control over which slice is used.
In theory, you can have slices for all these architectures in the same fat binary:
i386
x86_64
x86_64h
armv6
armv6m
armv7
armv7s
armv7k
armv7m
arm64
So you could smash an executable, a dylib, a linker and a kernel extension into one fat binary, but you'd have a hard time getting anything useful out of it.
The biggest problem is that the OS chooses which slice to load. For executables, that will always be the closest match for the processor you're running on. For dylibs, dylinkers and kexts, it will first be determined whether the process they're gonna be loaded into is 32- or 64-bit, but once that distinction has been made, there too you will get the slice most closely matching your CPU's capabilities.
I imagine back on Mac OS X 10.5 you could've had a 64-bit binary bundled with a 32-bit kext that it could try and load. However, outside of that I cannot think of a use case for this.

Related

In my macOS project, I am doing the transition to arm64. Is it possible, in C/Objective-C to only define a symbol for one architecture? [duplicate]

I would like to write code depending on whether the target architecture is e.g. armv7, armv7s, or arm64.
The reason that I can't use sysctlbyname is that this would give me the underlying architecture at runtime, but when arm64 e.g. simulates armv7, sysctl (seemingly) still reports arm64.
Although this is not a 100% answer to the question, but may be useful:
When using clang, you can discern between 32 bit arm and 64 bit arm using:
__arm__ which is defined for 32bit arm, and 32bit arm only.
__aarch64__ which is defined for 64bit arm, and 64bit arm only.
clang --target=... -mcpu=... -E - -dM </dev/null will output all the pre-defined preprocessor macros (similar works for gcc, too)
I don't see single macro that provides the answer, but you can probably use some combination of __ARM_ARCH and defined(__ARM_ARCH_*).
__ARM_ARCH_ISA_A64 is predefined if it's target is arm64,
__ARM_ARCH_7S__ for armv7s,
__ARM_ARCH_7A__ for armv7.
Use: clang -arch arm64 -E -dM - < /dev/null which can output preprocess macro.

Arm v8 elf to mach-o

I have a program in C and Arm v8 assembly(inline assembly). I've compiled it to produce a 64 bit arm statically linked elf. I need to be able to run this on an iPhone, but its giving me an error 'Cannot execute binary file'. This is because I'm trying to run an elf and not a mach-o which is needed for the iPhone.
Is there any converter which can convert an arm v8 elf to mach-o?
Most of what I've seen are from x86 elf to mach-o
You should instead consider setting up your tool-chain, compiler as well as linker correctly. You need a cross-toolchain for that target exactly.
If you were using GNU tools consider this:
Recompile your cross-compiler as well as bin-utils with a configure command with the proper target option (GNU-triplet).
For iPhone this should be: ../configure --target=arm64-apple-darwin . . . . a.s.on
(RTFM about setting up a cross-compiler toolchain.)
Hope that helps. In any case the correct GNU-triplet will determine also the file-header.

Anyone use GMP on Xeon Phi?

I compiled GMP with icc and -mmic option, but can't install on MIC. How should I install?
I wrote a demo program, compiled with icc. It says can't find gmp.h.
How should I install GMP library on MIC and where to place gmp.h?
Build GMP with Intel Compiler:
cd /home/
wget https://gmplib.org/download/gmp/gmp-6.0.0.tar.bz2
tar -xf gmp-6.0.0.tar.bz2
rm -f gmp-6.0.0.tar.bz2
cd gmp-6.0.0
mkdir mic
cd mic
../configure CC=icc CFLAGS="-mmic" --host=x86_64 --disable-assembly --prefix /home/gmp-6.0.0/mic/
make
make install
Use the Intel Compiler with environment variables for mic development:
GMP_INCDIR=/home/gmp-6.0.0/mic/include
GMP_LIBDIR=/home/gmp-6.0.0/mic/lib
Though I don't have any expertize on Xeon Phi or even ICC if you are running on Unix-like environment, then you might to try to step through normal configure/make procedure on GMP sources pointing on ICC compiler instead of default GCC in order to build static and/or shared library along with generated gmp.h header, that you can then link with your application. You might want to see GMP documentation on that. Here are some advices, that I stepped to trying to compile it for NVIDIA CUDA:
Supply ./configure with CC and CFLAGS variables to point to desired compiler and its whatever options that you want
Be sure that there is no ABI incompability between your host and Xeon Phi device, especially between 32 and 64 bit architecture.
Consider adding --disable-assembly option to generate "pure-C" build (I am not familiar with Xeon Phi assembly and if/how it is compatibile with x86)
Don't forget to run make check (possibly with -j parameter) after you compiled GMP in order to check if tests are passing, it's very important step if you want use it for some professional purpose.
The library is installed in OS by make install command, for default under /usr/local directory (you might add --prefix option if you want it somewhere else), specifically:
/usr/local/include for gmp.h header file
/usr/local/lib for static and/or shared libgmp binaries
You might also try to compile your application with mini-gmp package, which is contained within GMP sources (it's located under mini-gmp directory). It's a subset of mpz_* and mpn_* routines, not as sophisticated and fast as normal GMP (and it doesn't have as much serious tests coverage), but it could make the job done with small footprint (it's contained in one header and C-source file). For such option be sure to obtain most recent version of GMP (or even get it from their repository).

Static library GNUSTEP and correct linking

I was checking out the portability of Objective-C via gnustep and ran into some problems...
I mean everything works on my 2 machines but the major problem is if I run my application on a platform where gnustep is not pre-installed... So I want to build it with static libraries. But I ran into several problems:
1.) I cant find the static libaries under /usr/local/lib so the question came up do they even exist within gnustep?
2.) In case there are static libraries available how to integrate it correctly into my gcc command?
sudo gcc -o main main.m GameRef.m SDLApplication.m SDLEvent.m SDLImage.m SDLMap.m SDLSprite.m Settings.m Utility.m -I -static `gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS` -L `gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES` -lgnustep-base -lSDL -fconstant-string-class=NSConstantString -std=c99 2>logFile
I'm currently using Ubuntu 12.04LTS and installed the SDL and Gnustep on one machine so the application runs fine... But not on the second because the shared libraries are missing so I need to add them as static but how?
The libraries in /usr/local/lib and other system 'lib' directories will be dynamic. They can't be used as static (AFAIK), and finding them wouldn't really help.
I'm no expert with GNUstep, but it sounds like you are missing the Objective-C runtime. You will need to download the source code of the GNUstep libraries and frameworks, and then compile them into static libraries yourself.
Really, wrapping all of those frameworks into your application will just add unnecessary work for both you and your end users. Dynamic libraries exist for a purpose. There's no reason to have multiple copies of the same code on the filesystem. Just require GNUstep as a dependency. Although its a slight pain for the users, they only need to do it once, and with most distros, installation is only a command or two away.

Objective-C compiler flags

When compiling Objective-C from the command line (gcc), what are some good flags to use? Many of the standard C flags (-Wall, -ansi, etc) don't play well with Objective-C.
I currently just use -lobjc and -frameworkwith various frameworks.
Many of the standard C flags (-Wall, -ansi, etc) don't play well with Objective-C
-Wall works perfectly fine with Objective-C.
The thing to do is build an Objective-C file with Xcode and have a look at the build transcript. I've just done that and here are some highlights:
-x objective-c I guess that means "compile as Objective-C", probably important
-arch x86_64 build for a particular CPU architecture
-std=gnu99 build for C99 + GNU extensions (actually surprised me, I thought Xcode used -std=c99).
-isysroot .... specifies the location of the SDK.
-mmacosx-version-min=10.6 I am compiling for 10.6 and up
-fobjc-gc-only this file was intended to be used with garbage collection and won't work without it, so I compile for GC only.
-Wall the obvious.
If you are compiling from the command line, it's probably a good idea to set the option to treat warnings as errors. I don't from within Xcode because the build results window remembers the uncleared warnings from previous builds.