dynamic framework: how to hide the local symbols? - xcode

I am building an .xcframework which contains an iphonesimulator and iphoneos frameworks. There is some Swift code, and some C++ code, which is linked into a shared object (Mach-O 64-bit dynamically linked shared library arm64). I build my C++ with -fvisibility=hidden, and only the symbols that I explicitly mark, are exported. But, when I run nm -gC, I see all kinds of symbols that are still there – and they are visible even in the iOS app that is built using this framework. For example, I have an inner class Secret (it is only used in one cpp file). And nm -gC shows me (and all hackers out there)
00010292 t Secret::getString() const
Is there a way to hide this and other sensitive information?
And, on the other hand, how can I keep the auto-generated _AlexSDKVersionNumber exported?

You should configure your project settings correctly for Stripping to hide internal names.
Go to Your target > Build Settings > Deployment:
Set Deployment Postprocessing to YES to enable Stripping.
Set Strip Style to Non-Global Symbols.
Now nm should provide global (external) symbols only for your binary.

As for keeping the auto-generated _AlexSDKVersionNumber exported, I came up with a not-so-dirty hack:
add a header file to my project, call it AlexSDK_vers.h:
extern __attribute__ ((visibility("default"))) const double AlexSDKVersionNumber;
in Build Settings, add OTHER_CFLAGS=-include\${PWD}/AlexSDK/AlexSDK_vers.h

Related

Go code building linker error. Can I link manually?

I am building Go code that uses CGo heavily and this code must be compiled into a shared or static library (static is highly preferred). (code for reference)
It all works just fine on Linux and Mac, but on Windows it fails on linker stage either saying that all 4 modes (c-shared, shared, c-archive, archive) are not available or if invoke go tool link -shared manually complains about missing windows specific instructions.
My understanding is that all I need to build usable lib.a is to compile everything I will use into object files (*.o) and then put it through ar to produce usable static library.
Now the question is whether I can completely skip Go's linker and based on prepared .o files create .a manually?
How would I go about doing that if that is even possible?
Looks like gcc on windows is unable to automatically discover necessary shared libraries. The problem was caused by GCC and not by Go.
Although for compiling Go I had to use self-compiled master tip as current release (1.6.2) does not support shared/static libraries on windows/amd64.
Manually feeding gcc with each shared library (ntdll, winmm etc) in default location (C:\Windows\SysWOW64) has fixed the problem.

Linking binary against functions/data in specific location in memory

I'm currently in the process of writing an intermediate-memory bootloader for an ATMega.
I'd like to place a section of commonly used functions and data in a specific location in memory, such that:
limited size of the bootloader section is not overcome
library functions, drivers, etc, are not reproduced by the application section and thus wasting space
For illustrative purposes, a map of the desired memory layout is below:
Following some help in this thread on avrfreaks, I'm to the point where I've been able to move all code (in my bootloader + library development environment - applications will be developed in separate projects) not tagged with __attribute__ ((section(".boot"))) to the shared library section successfully via means of a custom linker script.
It was suggested in the avrfreaks thread that I can link my applications by using avr-objcopy --strip-all --keep-symbol=fred --keep-symbol=greg ... boot.elf dummy.elf to create a symbol reference of what I have in my shared library, and then linking my applications against this memory layout with avr-gcc -o app.elf -Wl,--just-symbols=dummy.elf app1.o app2.o ....
The problem I face here is that I need to specify each symbol I want to keep in my dumy.elf. I can use the keep-symbols=<file> directive to specify a text file list of symbols to keep, but I still must generate this list.
I've noticed that there is a bunch of symbols that I don't want to include (stuff like C environment set-up code that is common in name, but different in functionality, for both the bootloader and application) that seems to start with the prefix '_' (but of course, there are some useful and large library functions with the same prefix, e.g. *printf and math routines). Perhaps there won't be conflicts if I link my application against the existing runtime code in the application/bootloader?
How can I generate a list of symbols for my library section that contains the code that I've written (maybe some sed magic and scanning header files)/excludes any symbols that may conflict in linking the application?
The project can be viewed in its current state at this github repository.
Edit: I want to make clear that I could tag everything I want to be in the shared library section with __attribute__ ((section(".library"))), but as I also want to share some rather large libc stuff (vsprintf, etc) between the bootloader and application, this becomes cumbersome very quickly. As such, I've elected to put everything not tagged as boot in the library memory region via a linker script.
Perhaps I just need some advice on my linker script, as I'm not super sure what I'm doing there.
Consider using -R <file> as linker option (gcc -Wl,-R -Wl,<file>).
This will generate references to (global) symbols in <file> just as if they were linked normally, but not include the referenced code.

How should I get Xcode to link an iOS project that uses a C++ static library

Using Xcode, I've written a Cocoa Touch static library, mainly in C++. It exposes a C interface for the benefit of Objective-C client code.
I have a client iOS app that uses it, and everything works and runs as expected, except that I found I needed to include a minimal .cpp file in the client project to get the link to succeed. Otherwise I get C++-related unresolved symbols, e.g. operator new(unsigned long).
The above hack is easy and effective, and so I guess I'm not breaking any laws, but is there a proper way to eliminate my linker errors?
Should be just a matter of adding -lc++ to the linker flags in the project settings, I'd have thought.
Add it under "Other Linker Flags" under "Linking" section of the "Build Settings" tab on your project's settings.

Make Xcode ignore LLVM build warnings in 3rd party project

I have a third party project in my Xcode workspace (it's a dependency for my main project) and I want Xcode to ignore all build warnings from that third party project.
Preferably I'd like to ignore all build warnings for the Vendor/* group in my project since that's where I put all my third party code.
Possible?
Yes, it's possible, but only if you compile the third-party files in a separate target. This way, you can set different compiler flags.
Let's say your main target is an application. You defined your build settings, as well as the compiler warning flags.
Now you want to use some third-party sources. You import them into your project, but they generate warning. You could of course change your main target's settings, but I'm pretty sure you want to keep your own settings.
Simply create an additional target in your project, which is a static library.
Removes the third-party files from your main target, and add them to the library.
In your main target's build phases, link your application with the static library.
This way, you'll be able to use the third-party code in your application, while having different compiler settings for third-party code.
It is possible on a per file basis, see the blog entry at http://blog.bluelightninglabs.com/2011/12/suppressing-xcode-warnings-on-a-per-file-basis/
To summarize: Use the compiler flags on the “Build phases” tab.
Go to Build Phases > Compile Sources. Optionally filter the list. Select the ones you want to exclude and then double click in the blank area under the Compiler Flags column. Add -w and hit return:
if you are worried only about warning via inclusion, then you can wrap your include statements in this:
#pragma clang diagnostic push
// in reality, you will likely need to disable *more* than Wmultichar
#pragma clang diagnostic ignored "-Wmultichar"
#include <TheirLibrary/include.h>
#pragma clang diagnostic pop
if you also want to disable the build warnings it generates, then you can use -w or GCC_WARN_INHIBIT_ALL_WARNINGS = YES for the third party target which you link to or bundle.
ideally, you will file reports with the vendor if it is closed. if it is open, then maybe you should just patch it yourself.

debug symbols lost during linking...?

I am developing for iOS with XCode 3.2. I compiled my code in debug mode with the -g option into a static library. I then linked this library with a bigger static library which has the main to create the final executable. This library was built in release mode without any of the debugging support. Now when debugging crashes, I don't see the symbols for my code. Where did they go? Were they stripped by the linker? How can I make the linker retain the debugging information for my library? I have no control over the other library so I won't be able to do anything there.
If you can build your library, in the Build Settings
Use the same Debug Information Format for both the library and your code. mixing for example "DWARF with dSYM File " with "DWARF" will not display the symbols
Build it with any flag related "strip" to NO (or deployment Postprocessing NO)

Resources