Wrapper link options for HPUX Itanium - linker

With PA-RISC version linker provides the +afs flag to alias function symbols and GCC provides the -wrap option.
I am looking for a similar wrapper hook methodology to for HPUX 11iv3 Itanium. Any recommendation

HPUX 11iv3 does support the PA Risc linker option +afs, it is undocumented in 11iv3 so if you want to try it look at the PA Risc man pages.
There is a difference.
On IPF, if the definition is in the same translation unit as the reference, then binding is at compile time by default. This is the reverse case on PA (SOM and ELF).
When something is bound at compile time, the instruction sequence differs and binding does not take linkage table route.
Probably this is the reason why +afs is undocumented on IPF.
But, if we use "-Bextern=symbol" compiler option then the compiler behavior is as on PA i.e. all references to the symbol will be through the linkage table and above test case will work on IPF as well.
But performance penalty will occur if -Bextern is applied to a symbol that is resolved in the same load module.

Related

How to remove all the unused functions from the map file?

I was wondering if there is way to remove ALL the unused functions listed in the map file for an embedded project developed in C and using the IAR embedded workbench for ARM IDE, which uses its own compiler and linker:
IAR C/C++ Compiler for ARM 8.30
IAR ELF Linker for ARM 8.30
IAR Assembler for ARM 8.30
I have noticed that not all the functions listed in the map file are the used functions that actually are used at run time, is there any optimization way to remove all unused functions?
For example a third library is used in the project and FuncA() is part of that inside which there might be a switch case and for every case a different static function in called, lets say FuncA1(), FuncA2(), ... FuncAn(). We would enter each case based on the code and usage of the FuncA() so it it obvious that not all of the FuncA1(), FuncA2(), ... FuncAn() functions would be called in the project, however, all of them are listed in the map file.
Is it possible to remove such functions from the map file? If yes how?
Removal of unused functions with external linkage is necessarily a function of the linker rather then the compiler. However a linker is not required to support that and any support is toolchain dependent and may require specific link-time optimisation switches to be applied.
Unused functions with static linkage could be removed by the compiler.
We could enter each case based on the code and the function that calls FuncA() so it it obvious that not all of the FuncA1(), FuncA2(), ... FuncAn() functions would be called
If the functions FuncAx() have static linkage, but are explicitly referenced in the function FuncA() with external linkage, then neither the compiler nor the linker should be able to remove the functions, because the compiler has no a-priori knowledge of how FuncA() will be called, and the linker has no reference to functions with static linkage, or necessarily understanding of the language semantics that would make it apparent the switch cases in question are not invoked.
It is possible I guess that a sophisticated toolchain with a C language aware linker and with link-time whole program optimisation might remove dead code more aggressively, but that is certainly tool-chain specific. Most linkers are source language agnostic and merely resolve symbols in the object code and in some case remove code to which no link has been made.

How to use GNU atomic memory access functions in keil

I want to use GCC built-in functions like __sync_fetch_and_add, but I compile my code with Keil, if I use these functions in my code, it will be show err like this:
Error: L6218E: Undefined symbol __sync_fetch_and_add_4 (referred from XXXX.o).
I found there are some describes with GNU atomic memory access functions in Keil's documents, so I guess that keil may be support these functions, but I don't know how to use them. Should I include some header files or add some config in keil?
I'm no expert, but the link seems to be about ARM DS-5, which is a separate compiler i.e. not the same as Keil's MDK. So the documentation doesn't apply.
Implementing those functions is not super hard; if all else fails I would look at the compiler output from GCC, and just re-implement it.
Alternatively read up on the LDREX/STREX instructions and those for memory barriers, and have fun! :)
UPDATE: I think __sync_fetch_and_add_4() is new, but Keil only supports GCC's older suite of built-ins. Notice that __sync_fetch_and_add_4 does not appear in the list of functions they say that they support. This GCC manual page says:
Prior to GCC 4.7 the older __sync intrinsics were used. An example of an undefined symbol from the use of __sync_fetch_and_add on an unsupported host is a missing reference to __sync_fetch_and_add_4.
So it seems Keil is tracking a pretty old version of GCC? On the other hand, I do see __sync_fetch_and_add() in the list, and I guess that "magically" generates a call to __sync_fetch_and_add_4() if used on a 32-bit quantity. Weird.

Undefined reference to symbol on a static library

I'm trying to compile a binary linking it with a static library libfoo.a:
gcc -L. -o myapp myapp.o -lfoo
But I'm getting the following error from the linker:
libfoo.c:101: undefined reference to `_TRACE'
The problem is I don't have the source code for libfoo.a library.
I tried to get the reference for _TRACE symbol in the library and I got this:
nm libfoo.a | grep TRACE
U _TRACE
Assuming that _TRACE will not affect the inner workings in libfoo.a, is it possible to get the linker to define some placeholder value for this symbol so that I can compile my code?
Assuming that _TRACE will not affect the inner workings in libfoo.a
That seems an unreasonably hopeful assumption.
is it possible to get the linker to define some placeholder value for this symbol so that I can compile my code?
The first thing to do is to check libfoo's documentation. It is unusual for a static library to depend on a symbol that the user is expected to define; in fact, such an arrangement does not work cleanly with traditional linkers. I see several plausible explanations:
You need to link some other (specific) library after libfoo to provide a definition for that symbol.
Code that uses libfoo is expected to #include an associated header, and that header provides a tentative definition of _TRACE.
Programs that use libfoo are required to be built with a specific toolchain and maybe specific options.
It's just broken.
Only in case (4) is it appropriate to try to manually provide a definition for the symbol in question, and in that case your best bet is to proceed more or less as in case (1), by building an object that provides the definition and linking it after the library. Of course, that leaves you trying to guess what the definition should be.
If _TRACE is a global variable then defining it as an intmax_t with initial value 0 might work even if the library expects a different-size integer or one with different signedness. If it is supposed to be a function, however, then you're probably toast. There are too many signatures it could have, too many possible expectations for behavior. There is no reason to think that you could provide a suitable place-holder.
As I suspected, the _TRACE function is a sort of debugging function. And I was right assuming it would not affect the inner workings of libfoo.a.
I solved the problem defining the _TRACE function as:
int _TRACE(char*, ...) { return 0; }
Of course, this solution is only temporary and cannot be used in production, but it fits my purposes of compiling the code.
If you're using GCC 5.1 or later and/or C++11, there was an ABI change.
You can spot this issue using nm -C: if the symbol is defined (not U) but has a [abi:cxx11] appended to it, then it was compiled with the new ABI. From the link:
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro.
If you have access to the source code (not your case specifically), you can use -Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0, the latter forcing the compiler not to use the new ABI.
All your code, including libraries, should be consistent.

How can I set a compiler warning (GNU GCC) when overwriting a weak function

Library functions have the weak attribute set by default (see [1]) and could be "overwritten" with functions having the same signature by accident.
For example printf internally calls fputc and I could easily declare one of my functions int fputc(int, FILE *).
If that happens, I would like to receive a compiler warning.
Is there a way to tell the compiler to warn me in case of overwriting a weak function?
[1] https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html
(I am guessing you are on Linux, and compiling and linking your application as usual, in particular with the libc.so dynamically linked)
Library functions have the weak attribute set by default
This is not always true; on my system fputc is not a weak symbol:
% nm -D /lib/x86_64-linux-gnu/libc-2.21.so|grep fputc
000000000006fdf0 T fputc
0000000000071ea0 T fputc_unlocked
(if it was weak, the T would be a W, and indeed write is weak)
BTW, redefining your own fputc (or malloc) is legitimate (and could be useful, but is very tricky), provided it keeps a semantic conforming to the standard. More generally weak symbols are expected to be redefinable (but this is tricky).
Is there a way to tell the compiler to warn me in case of overwriting a weak function?
No (the compiler cannot warn you reliably).
Since the only thing which could give you some warning is not the compiler (which does not know which particular libc would be used at runtime, you might upgrade your libc.so after compilation) but the linker, and more precisely the dynamic linker, that is ld-linux(8). And the warnings could reliably only be given at runtime (because the libc.so might be different at build time and at run time). Perhaps you want LD_DYNAMIC_WEAK.
If you are ready to spend weeks working on a solution, you might consider using GCC MELT with your own MELT extension and customize a recent GCC to emit a warning when a weak symbol from the libc available at compile time (which might not be the same libc dynamically linked at runtime, so such a check has limited usefulness) is redefined.
Perhaps you might use some LD_PRELOAD trick.
Also, if you linked statically your application, the linker could give you diagnostics if you redefine a libc function.
Read also Drepper's How to Write a Shared Library & Levine's Linkers & loaders book.

Size optimization options

I am trying to sort out an embedded project where the developers took the option of including all the h and c files into a c file, then they can compile just that one file with the -whole-program option to get good size optimization.
I hate this and am determined to make this into a traditional program just using LTO to achieve the same.
The versions included with the dev kit are;
aps-gcc (GCC) 4.7.3 20130524 (Cortus)
GNU ld (GNU Binutils) 2.22
With one .o file .text is 0x1c7ac, fractured into 67 .o files .text comes out as 0x2f73c, I added the LTO stuff and reduced it to 0x20a44, good but nowhere near enough.
I have tried --gc-sections and using the linker plugin option but they made no further improvment.
Any suggestions, am I see the right sort of improvement from LTO?
To get LTO to work perfectly you need to have the same information and optimisation algorithms available at link stage as you have at compile stage. The GNU tools cannot do this and I believe this was actually one of the motivating factors in the creation of LLVM/Clang.
If you want to inspect the difference in detail I'd suggest you generate a Map file (ld option -Map <filename>) for each option and see if there are functions which haven't been in-lined or functions that are larger. The lack of in-lining you can manually resolve by forcing those functions to inline by moving the definition of the function into a header file and defining it as extern inline which effectively turns it into a macro (this is a GNU extension).
Larger functions are likely not being subject to constant propagation and I don't think there's anything you can do about that. You can make some improvements by carefully declaring the function attributes such as const, leaf, noreturn, pure, and returns_nonnull. These effectively promise that the function will behave in a particular way that the compiler may otherwise detect if using a single compilation unit, and that allow additional optimisations.
In contrast, Clang can compile your object code to a special kind of bytecode (LLVM stands for Low Level Virtual Machine, like JVM is Java Virtual Machine, and runs bytecode) and then optimisation of this bytecode can be performed at link time (or indeed run-time, which is cool). Since this bytecode is what is optimised whether you do LTO or not, and the optimisation algorithms are common between the compiler and the linker, in theory Clang/LLVM should give exactly the same results whether you use LTO or not.
Unfortunately now that the C backend has been removed from LLVM I don't know of any way to use the LLVM LTO capabilities for the custom CPU you're targeting.
In my opinion, the method chosen by the previous developers is the correct one. It is the method that gives the compiler the most information and thus the most opportunities to perform the optimizations that you want. It is a terrible way to compile (any change will require the whole project to be compiled) so marking this as just an option is a good idea.
Of course, you would have to run all your integration tests against such a build, but that should be trivial to do. What is the downside of the chosen approach except for compilation time (which shouldn't be an issue because you don't need to build in that manner all the time ... just for integration tests).

Resources