Does PE/COFF have an equivalent to LC_UUID / .note.gnu.build-id? - portable-executable

Under macOS, Mach-O binaries contain an LC_UUID load command which holds a UUID uniquely identifying each build of the binary, created from a hash of the build inputs; if you change the source and rebuild it, the UUID will change.
On Linux, ELF binaries contain a .note.gnu.build-id which performs the same function, although it is not in the format of a UUID.
Is there any equivalent concept for PE/COFF binaries (executables and/or DLLs) under Windows?

Related

macOS - Convert ELF shared object file to MACHO

I have a .so library file that I need to reference from C under macOS. file gives:
ELF 32-bit MSB shared object, MIPS, MIPS-II version 1 (SYSV), dynamically linked, stripped
How can I munge the contents of the library so that it can be linked under macOS?
I have tried: objconv, objdump, readelf, dwarfdump - but the flags and output are unintelligible to me so far.
The joint furthest I get is with gobjcopy, but then:
gobjcopy: Unable to change endianness of input file(s)
Also, objconv throws:
Error 2022: Cannot convert executable file
Do I need to deconstruct the .so into object files first, convert each and then bundle them back up to together?
Thanks for all help.

Mono on Mac: DllNotFoundException despite SQLite.Interop.dll being in dllmap

I have a C# application that uses SQLite and works fine on Windows.
The same Visual Studio project compiles fine in Xamarin Studio, but when running I get:
DllNotFoundException: SQLite.Interop.dll
Despite:
libsqlite3.0.dylib is in /usr/lib and also in the same folder as the executable and other DLLs
. is part of the $DYLD_LIBRARY_PATH
The executable and all SQLite-using DLLs have a matching <the_exe_or_dll_including_filename_extension>.config file containing:
<configuration>
<dllmap dll="sqlite" target="libsqlite.0.dylib" os="osx"/>
<dllmap dll="sqlite3" target="libsqlite3.0.dylib" os="osx"/>
</configuration>
I also tried adding <dllmap dll="SQLite.Interop.dll" target="libsqlite3.0.dylib" os="osx"/>, not better.
What is the problem?
You can easily find where mono is looking for that native library by setting the MONO_LOG_LEVEL to debug and MONO_LOG_MASK filtering to only DLL related messages.
export MONO_LOG_LEVEL=debug
export MONO_LOG_MASK=dll
mono yourprogram.exe
or as a one liner so you do not have to unset env vars:
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe
Mono and the OS-X dynamic link editor ('man dyld' for details) does not require DYLD_LIBRARY_PATH to be set to the current directory ('.'). Note: Linux does require LD_LIBRARY_PATH to include the current directory, if that is your intention.
Move those dll map files out of the way to remove them from the equation.
Unset DYLD_LIBRARY_PATH
cd in the directory that contains your CIL based exe, dlls and native dylib(s)
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe
Using the native dll/shared library trace output you can track which library is not being found (or one of its dependancies) or if it is the wrong ARCH for your mono version.
If you are still having problems, we would need to know which SQLite library you are using the options that you are using to compile it (or the arch version if getting it via a Nuget). A posting your dll trace output would quickly solve things also.
Notes:
I am assuming you are using the System.Data.SQLite library and are compiling the the options "/p:UseInteropDll=true /p:UseSqliteStandard=false".
Mono includes a SQLite in it's default install, it is 32-bit on OS-X:
file /Library/Frameworks/Mono.framework/Versions/4.0.2/lib/libsqlite3.dylib
/Library/Frameworks/Mono.framework/Versions/4.0.2/lib/libsqlite3.dylib: Mach-O dynamically linked shared library i386
Assuming you are using the OS-X package installer from Mono, thus are getting the 32-bit version of Mono and thus need 32-bit versions of the native libraries.
>>file `which mono`
/usr/bin/mono: Mach-O executable i386
The /usr/lib/libsqlite3.0.dylib is a multi ARCH fat binary, so that library is not a problem, but your debug output might show another one that is a problem,
>>file /usr/lib/libsqlite3.0.dylib
libsqlite3.0.dylib: Mach-O universal binary with 3 architectures
libsqlite3.0.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
libsqlite3.0.dylib (for architecture i386): Mach-O dynamically linked shared library i386
libsqlite3.0.dylib (for architecture x86_64h): Mach-O 64-bit dynamically linked shared library x86_64
You need to build and supply SQLite.Interop.dll (or more precisely libSQLite.Interop.dylib). The Mono distribution packages don't include it, probably because it's native code and really needs to be built on the target platform.
System.Data.SQLite on Windows uses a mixed mode approach (Managed data adapter + sqlite native code in one assembly). Mono however doesn't really support mixed mode assemblies.
So on MacOS there are two alternatives when it comes to building System.Data.SQLite on Windows:
Use interop dll.
Use libsqlite.x.x.dylib.
Both of these are native code and need to be built on the Mac.
Interop is Windows com speak so it's a bit disconcerting to see it used in a MacOS context. What this native dll is is the sqlite source code compiled up with some additional native code that can be P\Invoked by System.Data.SQLite. There are some benefits to using the interop dll as opposed to the sqlite dylib.
System.Data.SQLite ships with a copy of the relevant SQLite native source code in ./SQLite.Interop/src.core. You can build the interop library by running compile-interop-assembly-release.sh on the Mac. This will build libSQLite.Interop.dylib. Drop that in beside System.Data.SQLite and you should be good to go.
If you turn on Mono dll tracing you can watch the loader (see mono 4.8.0 loader.c) searching for the dll in various locations and with various name substitutions. Eventually it finds our dylib. It is also possible to use a dllmap entry in the System.Data.SQLite.dll.config file to direct the runtime to the dll. In my case Mono is on my app bundle so I have:
<dllmap dll="SQLite.Interop.dll" target="#executable_path/../Mono/libSQLite.Interop.dylib" os="!windows"/>
The dllmap target argument is passed to dlopen() so #executable_path et al are all usable.
I prefer this approach as it goes into the repo and provides some insight into what is going on when there's a foul up.

How to Convert 64bit COFF to OMF?

I need to convert a 64bit .lib file from COFF to OMF. Coff2Omf.exe works fine with 32bit libs but gives...
ERROR: COFF error: FOOx64.lib
(coffread.cpp, 1637) : invalid machine type detected
...on a 64bit lib.
Is there an updated tool or similar to use for this?
Per Embarcadero's documentation:
Differences Between Clang-based C++ Compilers and Previous-Generation C++ Compilers
Object and Library File Format
BCC32 and its associated tools use OMF in .obj and .lib files.
Clang-based C++ compilers use ELF in .o and .a files.
This difference means, for example, that when you migrate a 32-bit Windows applications you must change references to .lib and .obj files to be .a and .o, respectively.
BCC64.EXE, the C++ 64-bit Windows Compiler
Compiled object file
ELF64 format
#pragma link
Do not specify the file extension (.ext) of modulename, as long as you are using default file types. The linkers assume the following default values for the file extension (.ext) of modulename:
.obj extension for BCC32
.o extension for:
Clang-based C++ compilers
BCCOSX
So if you omit the .ext, then the correct extension is automatically used according to your current target platform.
OMF is only used by the 32bit compiler/linker. The 64bit compiler/linker uses ELF64 instead.
I wonder if OMF specification have ever existed for 64-bit architecture. By the way, why do you need 64-bit OMF files? 64-bit versions on C++Builder are based on LLVM compiler backend, which produces ELF object files (as far as i know)
I don't know if something like coff2elf is bundled with C++Builder XE7, but, probably you can use opensource tools, like "Object File Converter", look for it here:
http://www.agner.org/optimize/#objconv

Can I build both 32-bit and 64-bit architectures of a library on Mac OS?

I need to build a library (Ipopt) on Mac OS X and use it from two different programs (Python & Matlab). However, one program is 32-bit and the other is 64-bit. Do I have to build two separate libraries of the two architectures then set the path accordingly for each program? Or can I build both architectures in the same library file(s) and the program will select the correct architecture to load? If I can, then how?
Thanks!
You can build both architectures and combine them into a single binary. The tool to do this is lipo.
For example, if you had built libpopt as a 32 bit library and placed it in lib/, and built it again as a 64 bit library and placed that in lib64/, then the command to combine these two could be:
lipo lib/libpopt.a lib64/libpopt.a -create -output libUniversal/libpopt.a
For more information, see the lipo man page (here, or through man lipo).

An objcopy equivalent for Mac / iPhone?

I would like to rename symbols inside object files (.o) with something that would be the Mac equivalent of binutils' objcopy --redefine-syms tool.
I found no arm-apple-darwin10-objcopy. I tried the MacPorts' arm-elf-binutils port and also tried to play a bit with otool and segedit without much success.
Any ideas please?
Sounds like a job for Agner Fog's objconv.
From the announcement:
I have now finished making full support for Mach-O files in the object file converter mentioned in my previous posts. You may use it as a replacement for the missing objcopy utility.
Objconv can be used for the following purposes:
Convert object files and library/archive files between Mach-O, ELF, COFF and OMF formats for all x86 and x86-64 platforms.
Change symbol names in object files, make symbols weak, add alias names to symbols.
Build, modify and convert static library files (*.a, *.lib) across platforms (Mac, Linux, BSD, Windows)
Dump object files and executable files
Disassemble object files and executable files. Very good disassembler.
objconv manual
objconv.zip - source
I know I'm resurrecting this post from the dead, but...
I have a sudden need to do this as well, and discovering that objcopy doesn't work on OSX was a bit of a shock. But I think it's possible to use ld to achieve the same effect:
ld -r input.o -o output.o -alias oldsymbol newsymbol -unexported_symbol oldsymbol
This really just creates an alias for the symbol under a new name and hides the old one.
I haven't had a chance to do much testing yet, but looking at the output file with nm shows it seems to be doing the right thing.
objconv does not currently work for ARM, so this option is not available for iPhone. It should be no problem to use objconv from elf to mach-o for mac osx x86/x64 though. Let me know if you found a solution for ARM

Resources