Building objdump on osx to allow disassembling arm64 objects - macos

I'm trying to disassemble openSSL that I've built for iOS targeting arm64 architecture with objdump (from GNU binutil) giving it following options:
./objdump openssl -f (file headers), -t (symbol table), and -h (section headers)
but getting following error:
BFD: bfd_mach_o_scan: unknown architecture 0x100000c/0x0
objdump: ./openssl: File format not recognized
TARGET:
BFD: bfd_mach_o_scan: unknown architecture 0x100000c/0x0
The objdump -v 2.21.1 that I've built with following options:
./configure CC="gcc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk -arch i386" CXX="g++ -arch i386" -disable-werror -enable-install-libiberty -enable-targets=arm-eabi
was working fine with all arm 32-bit architectures but failed to disassemble arm64.
Does anyone know how to build objdump to allow calling:
./objdump openssl -f (file headers), -t (symbol table), and -h (section headers)
for binary that was build targeting arm64?
Thanks in advance

The objdump you're using doesn't know about the arm64 arch. 0x100000c/0x0 is the cputype (CPU_TYPE_ARM64) and cpusubtype CPU_SUBTYPE_ARM64_ALL.
Why use objdump? The otool(1) program works well and is included in the Xcode developer tools / command line tools package. The command line options are a little different but one look at the man page will make it clear how to use it.

Related

Datatable for ARM architecture?

import datatable as dt
Throws an ImportError:
ImportError: dlopen(miniforge3/lib/python3.9/site-packages/datatable/lib/_datatable.cpython-39-darwin.so, 0x0002): tried: 'miniforge3/lib/python3.9/site-packages/datatable/lib/_datatable.cpython-39-darwin.so' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e)))
Is there an ARM version in development?
This was resolved in https://github.com/h2oai/datatable/issues/3003#issuecomment-866386747
Running lipo -info `which clang++ will return
Architectures in the fat file: /usr/bin/clang++ are: x86_64 arm64e so you need to switch to arm64e only.
To switch to arm64 for compilation, run
env /usr/bin/arch -arm64 /bin/zsh --login
https://vineethbharadwaj.medium.com/m1-mac-switching-terminal-between-x86-64-and-arm64-e45f324184d9 details how to make aliases in your .zshrc for quickly switching between x86 and arm64.

ffmpeg refuses to compile for x86_64 arch on M1 mac

I'm trying to build a universal binary of ffmpeg on MacOS, by compiling it twice (for arm64 and x86_64) and then using the lipo tool to combine the resulting binaries. I'm on an M1 Mac, so uname -m returns arm64 on my machine.
When running the configure script like so:
./configure --arch=x86_64
It outputs:
install prefix /usr/local
source path .
C compiler gcc
C library
ARCH c (generic)
...
And after running make, inspecting the built binaries with lipo -archs reveals that it's building them for arm64.
The result is the same if I add --enable-crosscompile to the configure call.
Based on this post, I also tried --arch=x86, but that had the exact same result, configure script displayed arch as c (generic) and inspecting artefacts with lipo shows they are built for arm64 architecture.
Does anyone have any ideas? Why is the configure script just refusing to build for x86_64?
You can speify -cc to make clang compile x86_64 binary.
Try:
./configure --enable-cross-compile --prefix=./install_x86_64 --arch=x86_64 --cc='clang -arch x86_64'
Note: don't forget to clear the outdated files by
make distclean
By the way, I have successfully built universal binrary of FFmpeg, you can refer to my build scripts. make_compile.py compile both x86_64 and arm64 binraries, and make_universal.py use lipo to generate universal binrary.
Reference
https://ffmpeg.org/platform.html
https://github.com/FFmpeg/gas-preprocessor

How to build openssl for M1 and for Intel?

I have a project which needs to use Libcrypto - and I have two versions of Libcrypto (libcrypto.a (from OpenSSL 1.1.1) built for ARM64) and (lcrypto.a (from OpenSSL 1.0.2) for Intel). Leaving aside the issues of whether it's good practice or not to have two different versions, I can say that if I include libcrypto.a then I can build and run on M1 and it works fine on M1. If I include lcrypto.a then I can build and run on Intel and it works fine on Intel. What I can't do is include them both (linker error - The linked library 'lcrypto.a' is missing one or more architectures required by this target: arm64.) - and if I can't include them both then I can't build a fat binary, and my app is less than entirely useful!
My question is How can I include both in my project - or where can I get (and how can I include) a fat version of Libcrypto? I've looked at this https://github.com/balthisar/openssl-xcframeworks/releases and this https://developer.apple.com/forums/thread/670631 but I'm none the wiser. I think I built a Fat Binary - but the Fat Binary I thought that I built doesn't work for either architecture!
Use command lipo to combine binaries
Compile Intel and ARM versions separately (arm version requires Xcode 12).
export MACOSX_DEPLOYMENT_TARGET=10.9
cp -r openssl-1.1.1t openssl-1.1.1t-arm64
cp -r openssl-1.1.1t openssl-1.1.1t-x86_x64
Build the Intel half
cd openssl-1.1.1t-x86_x64
./Configure darwin64-x86_64-cc shared
make
NOTE: For openssl-1.1.1q use -Wno-error=implicit-function-declaration as a configure parameter
Build the Arm half
export MACOSX_DEPLOYMENT_TARGET=10.15 /* arm64 only with Big Sur -> minimum might be 10.16 or 11.0 */)
cd ../openssl-1.1.1t-arm64
./Configure enable-rc5 zlib darwin64-arm64-cc no-asm
make
NOTE: For openssl-1.1.1q use -Wno-error=implicit-function-declaration as a configure parameter
To create universal binary use command lipo:
cd ..
mkdir openssl-mac
lipo -create openssl-1.1.1t-arm64/libcrypto.a openssl-1.1.1t-x86_x64/libcrypto.a -output openssl-mac/libcrypto.a
lipo -create openssl-1.1.1t-arm64/libssl.a openssl-1.1.1t-x86_x64/libssl.a -output openssl-mac/libssl.a
Verify that resulting binary contains both architectures:
file libcrypto.a libssl.a
libcrypto.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64]
libcrypto.a (for architecture x86_64): current ar archive random library
libcrypto.a (for architecture arm64): current ar archive random library
libssl.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64]
libssl.a (for architecture x86_64): current ar archive random library
libssl.a (for architecture arm64): current ar archive random library
PS: If you plan to use dynamic library combine dylib files using lipo and run instal_name_tool
cd openssl-mac
install_name_tool -id '#rpath/libcrypto.1.1.1.dylib' libcrypto.1.1.1.dylib
install_name_tool -id '#rpath/libssl.1.1.dylib' libssl.1.1.dylib
otool -D libssl.1.1.dylib /* to verify */
Result:
libssl.1.1.dylib:
#rpath/libssl.1.1.dylib
Even though this question already has an accepted answer, I'd like to mention that I found an easier way to do this that doesn't require using lipo, just in case it helps make someone else's life easier.
The trick is to force it to compile for both architectures simultaneously.
Before calling Configure in the openssl source directory, create a file somewhere convenient (for the purposes of explaining I'll just have it in the home folder) named cc, and have it contain the following text:
#!/bin/bash
if [[ $* == *-arch\ x86_64* ]] && ! [[ $* == *-arch\ arm64* ]]; then
echo Forcing compilation with arm64
cc -arch arm64 $#
else
cc $#
fi
That script will automatically add -arch arm64 to any compilation command that only includes -arch x86_64, and leave all other compilation commands unmodified.
Give it execute permissions:
chmod a+x ~/cc
Then execute the following in your shell to force compilation with this shell script:
export CC=/Users/yourname/cc
Then proceed with configuring and building as though for arm64, but tell it to compile as x86_64:
./Configure enable-rc5 zlib no-asm darwin64-x86_64-cc
make
make install
The resulting static libs and dylibs will already be x86_64 / arm64 universal!

How to link fftw3 in Xcode? (Mac)

i followed script on ( How do I link third party libraries like fftw3 and sndfile to an iPhone project in Xcode? )
but i got an Error. firstly by configuration :
./configure --host=arm-apple-darwin --target=arm-apple-darwin
--enable-float --enable-neon .... checking whether C compiler accepts -march=armv7 -mfpu=neon... no configure: error: Need a compiler with support for -march=armv7 -mfpu=neon
and at the end by copying the ARM library to a temporary location :
lipo -arch armv7 $RESULT_DIR/libfftw3f_armv7.a -arch armv7s
$RESULT_DIR/libfftw3f_armv7s.a -arch i386 $RESULT_DIR/libfftw3f_i386.a
-arch x86_64 $RESULT_DIR/libfftw3f_x86_64.a -arch arm64 $RESULT_DIR/libfftw3f_arm64.a -create -output $RESULT_DIR/libfftw3f.a
lipo: unknown architecture specification flag: arm64 in specifying
input file -arch arm64 ios-library/libfftw3f_arm64.a
lipo: known
architecture flags are: any little big ppc64 x86_64 ppc970-64 ppc i386
m68k hppa sparc m88k i860 veo arm ppc601 ppc603 ppc603e ppc603ev
ppc604 ppc604e ppc750 ppc7400 ppc7450 ppc970 i486 i486SX pentium i586
pentpro i686 pentIIm3 pentIIm5 pentium4 m68030 m68040 hppa7100LC veo1
veo2 veo3 veo4 armv4t armv5 xscale armv6 armv6m armv7 armv7f armv7s
armv7k armv7m armv7em
lipo: Usage: lipo [input_file] ... [-arch
input_file] ... [-info] [-detailed_info] [-output output_file]
[-create] [-arch_blank ] [-thin ] [-remove ] ... [-extract ] ...
[-extract_family ] ... [-verify_arch ...] [-replace ] ...
i am using the gcc49 and Mac OS X 10.9.2, iOS 7.1. any idea ? thanks
by First Error, the configure should be like this:
./configure --host=arm-apple-darwin --target=arm-apple-darwin --enable-float
( without --enable-neon )
and the second Error, its because the libraries are all from the arch x86_64. they should have the right architecture ( libfftw3f_i386.a should have the arch. i386.a and libfftw3f_armv7s.a the arch. armv7s.a and so on )
i could make the right library for FFTW by using macports (or u can use homebrew) to install a universal build of the library for use with OpenFrameworks.
type this into a terminal window:
sudo port install fftw-3 +universal
the port install command will place the fftw3.h header file in your_HD/opt/local/include folder, and the libfftw3.a library in your_HD/opt/local/lib folder. To use the library in your OF project, add these two files to your project via the menu option Project -> Add to project...
thanks for every help and special thanks #Adam Freeman

Compiling gcc with AVR options

I want to generate the assembly file of my code oriented to the AVR architecture, I am using gcc version 4.7.2 with the following arguments:
g++ -O3 -Wall -S -Wp,-mmcu=atmega8 -o "src\Compression.o" "..\src\Compression.cpp"
but I am getting the following error:
cc1plus.exe: error: unrecognized command line option '-mmcu=atmega8'
But I got the command options from the gcc website:
http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/AVR-Options.html#AVR-Options
There should be something that I am missing, could you help me with this please!
If gcc does not accept -mmcu, you are probably not using a gcc with support for the AVR architecture.
It's normally used like this:
avr-gcc -mmcu=atmega328p
because it's not only the preprocessor, it's actually other tools as well which require this setting (linker, assembler).
Normally the architecture gcc is compiled for is indicated by a prefix, in this case it's avr- by convention.
So the solution is to get a toolchain with AVR support. You can download it from Atmel's web site, even for Linux.
Update
If you like to check the configuration of your gcc, you can use -dumpmachine to check for the target processor
$ gcc -dumpmachine
i486-linux-gnu
$ arm-none-eabi-gcc -dumpmachine
arm-none-eabi
$ avr-gcc -dumpmachine
avr
If you look at the target specific options using --target-help
$ gcc --target-help | grep march
-march= Generate code for given CPU
you can see that the Linux gcc does accept -march as well. It probably fails later.
gcc is a very complex piece of software, because it just supports so many different architectures. From that perspective it works amazingly well.
Another interesting option is -v
$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8'
[...]
to see how that gcc has been built.
And there could be another trap down the road (multi-libs), as you can see here

Resources