GCC - how to tell linker not to skip unused sections - gcc

My problem is following:
I am trying to write embedded application, which must have it's own linker script supplied (using arm-none-eabi-gcc compiler/linker).
embedded bootloader loads binary and starts at 0x8000 address, this is why I need a dedicated linker script, which allows me to put desired startup function into this address. Script's code is following:
MEMORY
{
ram : ORIGIN = 0x8000, LENGTH = 0x1000
}
SECTIONS
{
.start : { *(.start) } > ram
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}
Having this what I want to do now is to have a function, that will be inserted into .start section, so that it's at the beginning of 0x8000. For this in my library I use following function:
__attribute__((section(".start"))) void notmain() {
main();
}
This seems to be working fine, but later I link this library with function notmain with the project, which defines main() function. During the link process I can see .start section no more exists and notmain symbol
is totally missing. When I move notmain function out of the library (into the project) its'all fine.
My understanding is, that linker sees, that .start section is not used at all in my Application, which makes it skip all the sections. I already tried adding several attributes to function notmain such as (__attribute__((used)) __attribute__((externally_visible))) but it did not work too (notmain is still missing from the final binary).
CMake source code is following:
** Project **
project(AutomaticsControlExample)
enable_language(ASM)
set(CMAKE_CXX_STANDARD 14)
set(SOURCES main.cpp PID.hpp)
set(DEPENDENCIES RPIRuntime PiOS)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${DEPENDENCIES})
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_OBJDUMP} -D ${PROJECT_NAME}
COMMAND ${CMAKE_OBJDUMP} -D ${PROJECT_NAME} > ${PROJECT_NAME}.list
COMMAND ${CMAKE_OBJCOPY} ${PROJECT_NAME} -O binary ${PROJECT_NAME}.bin
COMMAND ${CMAKE_OBJCOPY} ${PROJECT_NAME} -O ihex ${PROJECT_NAME}.hex)
** Library **
project(RPIRuntime)
enable_language(ASM)
set(CMAKE_CXX_STANDARD 14)
set(LINKER_SCRIPT memmap)
set(LINKER_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_SCRIPT}")
set(SOURCES
notmain.cpp
assert.cpp)
add_library(${PROJECT_NAME} STATIC ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${LINKER_FLAGS})
My question is: is there any way to prevent linker from omitting linking .start section?

As you know, a static library is an ar archive of object files.
Suppose libfoobar.a contains just foo.o and bar.o. A linkage:
g++ -o prog a.o foo.o bar.o # A
is not the same as the linkage:
g++ -o prog a.o -lfoobar. # B
The linker unconditionally consumes every object file in the linkage sequence,
so in case A, it links a.o, foo.o, bar.o in prog.
The linker does not unconditionally consume every object file that is a member of
a static library in the linkage sequence. A static library is a way of offering to
the linker a bunch of object files from which to pick the ones it needs.
Suppose that a.o calls function foo, which is defined in foo.o, and that
a.o references nothing defined in bar.o.
In that case, the linker unconditionally links a.o into prog, after which
prog contains an undefined reference to foo, for which the linker needs a
definition. Next it reaches libfoobar.a and inspects the archive (by its index,
normally) to see if any member of the archive defines foo. It finds that foo.o does
so. So it extracts foo.o from the archive and links it. It needs no definitions
for any symbols defined in bar.o, so bar.o is not added to the linkage. The
linkage B is exactly the same as:
g++ -o prog a.o foo.o
Suppose on the other hand that a.o calls bar, which is defined in bar.o,
and references nothing defined in foo.o. In that case, the linkage B is
exactly the same as:
g++ -o prog a.o bar.o
So an object file that you insert into a static library for linkage with
your executable will never be linked, by default, unless it provides a definition
for at least one symbol that is referenced, but not defined, in an object file
that has already been linked.
Your function notmain is not referenced in the only object file, main.o that
you are explicitly linking in your program. Therefore, when main.o is linked into your program,
the program contains no undefined reference to notmain: the linker requires no definition
of notmain - it has never heard of notmain - and will not link any object file
from within a static library to obtain a definition of notmain. This has nothing
to do with linkage sections.
When linking an ordinary program with static libraries, as a matter of course
you do it like:
g++ -o prog main.o x.o ... -ly -lz ....
where one of the *.o files - say main.o - is the object file that defines the main function. You never
put main.o in one of the static libraries. That's because, in a ordinary program,
main is not called in any of the other object files you are explicitly linking,
so if main.o was in one of your libraries, the linkage:
g++ -o prog x.o ... -ly -lz ...
would have no need to find a definition of main at any of -ly -lz ..., and no definition
of main would be linked.
The case is just the same with your notmain. If you want it linked you can do one of:-
Add -Wl,--undefined=notmain to your linkage options (replacing notmain with
the mangled name of notmain, for C++). This will make the linker assume it has an
undefined reference to notmain even though it hasn't seen any.
Add the command EXTERN(notmain) to your linker script (again with mangling
for C++). This is equivalent to 1.
Explicitly link an object file that defines notmain. Don't put it in a static library.
3 is effectively what you did when you discovered that:
When I move notmain function out of the library (into the project) its'all fine.
For 3, however, you don't need to compile notmain.cpp in your project and any other
project that needs notmain.o. You can build it independently, install it
in /usr/local/lib and explicitly add /usr/local/lib/notmain.o to the
linkage of your project. That would be following the example of GCC itself, which explicitly
links the crt*.o startup files of an ordinary program just by appending their
absolute names to the linkage, e.g.
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/crti.o
...
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/crtn.o

Related

LD: does --export-dynamic imply --whole-archive for a static lib if any of it's symbols are referenced?

My main executable links with a static library whose symbols need to be available for dynamic libraries loaded through dlopen(). I understand that I need to use -Wl,--export-dynamic,--whole-archive flags to make it work. However there are many libraries specified on the link command, some maybe unused, and I'm having difficulties applying --whole-archive selectively to the needed library through cmake within the current build infrastructure. What I'm seeing is that if only -Wl,--export-dynamic is used and the executable calls a function in the static library of interest, then the whole library gets included to the same effect of specifying --whole-archive for it, which is exactly what I need. Can I rely on this behavior to implicitly impose --whole-archive on libs whose symbols are referenced by the executable?
What I'm seeing is that if only -Wl,--export-dynamic is used and the executable calls a function in the static library of interest, then the whole library gets included to the same effect of specifying --whole-archive for it, which is exactly what I need.
This isn't supposed to happen, and it is very likely that you are mis-interpreting what you see.
Example:
// foo.c
int foo() { return 42; }
// bar.c
int bar() { return 24; }
// main.c
int main() { return foo() - 42; }
gcc -w -c foo.c bar.c main.c
ar ruv libfoobar.a foo.o bar.o
gcc -Wl,--export-dynamic main.o -L. -lfoobar
nm a.out | egrep ' (foo|bar)'
000000000000113c T foo
As you can see, the whole libfoobar.a was not included in the executable. Contrast with:
gcc -Wl,--export-dynamic main.o -L. -Wl,--whole-archive -lfoobar -Wl,--no-whole-archive
nm a.out | egrep ' (foo|bar)'
0000000000001147 T bar
000000000000113c T foo
Update:
if I add a function foo1() to foo.c it is pulled in, but it also happens regardless if --export-dynamic is supplied.
That is expected: the linker doesn't "split" a single .o file -- you get all or nothing.
You can change this behavior by using -ffunction-sections (and -fdata-sections for a good measure) at compile time and -Wl,--gc-sections at link time.
The cost is increased .o size and longer link time. The benefit is smaller executable.

Run two instances of the same C++ program simultaneously

I've got a C++ program with a Makefile, building (g++) and running on Windows cmd. Thing is, sometimes it takes a while to run and save the results, and I want to run it with different parameters at the same time so that I can do something else while I wait for the first instance to finish. It doesn't work though, because of the executable I guess:
>make
g++ -c -o main.o main.cpp
Assembler messages:
Fatal error: can't create main.o: Permission denied
make: *** [main.o] Error 1
You have two problems: The one you ask about, and the reason you ask this question in the first place.
Lets start with the problem you have...
Judging by the Makefile you show, you have it all wrong.
Rules are in the format
target: sources_the_target_depend_on
The target is usually a file that need to be created. For an object file that is the name of the actual object file itself. The source files that the object files then depend on should be on the right-hand side.
To take an example from you Makefile (before you edited it away):
graph2: graph2.o
g++ -g -c graph.cpp -o graph2.o
Here you tell make that the file graph2 depends on the file graph2.o, and then it creates the graph2.o file. That's wrong. The rule should be that the file graph2.o depends om the file graph.cpp and go on to generate the file graph2.o:
graph2.o: graph.cpp
g++ -g -c graph.cpp -o graph2.o
This indirectly leads to the problem you have, with this line (deduced from your error and the Makefile):
main: main.o utils.o graph.o heuristics.o
g++ -g main.cpp -o main.o utils.o graph.o heuristics.o
This contains the same error as discussed above: You say that the file main depends on main.o and then the rule create main.o. Your rule should be
main: main.cpp utils.o graph.o heuristics.o
g++ -g main.cpp -o main utils.o graph.o heuristics.o
Note also how I no longer name the executable file main.o, as that is supposed to be used for object files.
Now lets continue with the reason you have the problem in the first place: That you need to edit the code to change data or values.
This is a problem that you need to solve. One common way to solve it is through command line arguments. If your program parses the command line arguments passed to your program you can pass it the values that could change from run to run.
How to do this is whole chapter on its own, so I wont give you any more details. There are plenty of tutorials online.
Lastly, you can simplify your Makefile considerably, by using implicit rules and variables.
I would simply create the Makefile to look something like this
# The compiler to use
CXX = g++
# Flags to pass to the compiler (add warnings when building)
CXXFLAGS = -Wall
# The main executable file to generate
TARGET = main
# List the object files needed to generate the main executable file
OBJECTS = main.o utils.o graph.o heuristics.o
# The all target depends on your main executable file
# Also as the first target in the Makefile, if no specific target is specified
# this will be the one that is used (it's the "default" target for the Makefile)
all: $(TARGET)
# The main executable file depends on the object files
$(TARGET): $(OBJECTS)
This is really it. the object files will be built automatically from their respective source files, and then the executable program will be linked using the object files listed.

Makefile: Link several *.a to executable

I try to write a Makefile that takes several static libraries that have been created before and link the to an executable. Although one libary has a main-routine.
I get the error:
/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [dockSIM_gcc_release] Error 1
I tried it with just linking the library that has the main routine but the error stays the same and comes directly after invoking make.
The Makefile:
SHELL = /bin/sh
RM=/bin/rm -f
CXX=g++
PROGNAME=dockSIM_gcc_release
DEFINES=-DDOCKSIM_VERBOSE=FALSE -DNDEBUG -DPRINT_LOG_MSG=0 -DPRINT_DEBUG_MSG=0
LDFLAGS = -fopenmp -g -O3 -std=c++11 -mavx -mstackrealign -fstrict-aliasing
LIBS= -lnagc_mkl -lm -L../externalCode -lpardiso500-GNU481-X86-64 -lacml
FILENAMES = commandInterpreter_lib.a
OBJNAMES =
all: $(PROGNAME)
$(PROGNAME): $(FILENAMES)
$(CXX) $(LDFLAGS) $(DEFINES) -o $(PROGNAME) $(FILENAMES)
clean:
$(RM) *.mo *.ho *.o $(PROGNAME) core *~
test:
echo $(FILENAMES)
showlibs:
echo $(LIBS)
The flags are compatible with those that were used to compile the code.
g++ 4.9.3 is used.
Signature of the main-Routine:
int main(int argc, char* argv[])
Thanks for help and kind regards.
I can only guess what's wrong.
There is more to linking a static library than just a convenient bundle of object files to reduce command line length. In addition to that, the linker only links in object files which it thinks are needed. An object file is needed if there's some undefined symbol that the linker is looking for, that is contained in that object. If there's no symbol that the linker needs in the object, then the linker ignores the object and doesn't link it.
The normal way to build a program is to have the main program listed as object files on the command line: the linker always links every object file. This gives the linker a set of symbols which are defined (by the object files) and undefined (things the object files use but that aren't defined by them). Then the linker will go through the libraries on the link line and add in object files that resolve undefined symbols. These object files in turn may have other undefined symbols that the linker will need to resolve later, etc.
All I can guess is that by not having any object files on your link line, the linker doesn't see the object file in the library containing main as needed and so it doesn't link it.
I don't know why building with debug vs. non-debug makes a difference.
I didn't understand your comment about why you need to do things this way: even if the person who knew about this left, someone will need to learn about it to maintain the software.
In any event you have a few options.
One simple one is to use the "ar" program to extract out the object file containing main and link it directly: in addition to adding objects to libraries ar can extract them. Then you can link that object directly. See the man page for ar.
Another would be to look at the documentation for your compiler and linker and find flags that will force it to include the entire library, not just the unresolved symbols in the library. For the GCC/binutils linker, for example, you can pass -Wl,--whole-archive before the libraries you want to be fully included on the command line, then -Wl,--no-whole-archive after them to turn off that feature.

Linker and dependencies

For a Linux/g++ project, I have a helper library ("libcommon.a") that I wrote that is used in two different programs ("client" and "server"). One particular source file among several, oshelper.cpp, has a set of unrelated utility functions:
// header file
#ifndef OSHELPER_H
#define OSHELPER_H
size_t GetConsoleWidth();
uint32_t GetMillisecondCounter();
#endif
// -----------------------------------------
// Code file
#include "commonincludes.h"
#include "oshelper.h"
size_t GetConsoleWidth()
{
struct winsize ws = {};
ioctl(0, TIOCGWINSZ, &ws);
return ws.ws_col;
}
uint32_t GetMillisecondCounter()
{
timespec ts={};
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint32_t)(ts.tv_nsec / 1000000 + ts.tv_sec * 1000);
}
Both programs link to the library that contains these functions (libcommon.a or -lcommon).
"client" program calls both the GetConsoleWidth and GetMillisecondCounter function. And since GetMillisecondCounter ultimately depends on a call to "clock_gettime", -lrt is a required parameter to the linker such that librt is linked in. This is expected.
"server" just calls GetConsoleWidth. It never calls GetMillisecondCounter. But without "-lrt" being passed, the linker complains about the unresolved reference to clock_gettime. Which is obviously fixed by passing -lrt to g++. And then "ldd server" shows that librt.so.1 is still a runtime dependency. So the linkage to clock_gettime clearly did not get optimized away.
But when I separate the implementation of GetConsoleWidth into a seperate source file (but still part of libcommon.a), the linker stops complaining about the unresolved reference to clock_gettime and no longer insists that I pass in -lrt.
It's as if the g++ linker can only cull out unused object files, but not unused function calls.
What's going on here?
Update: the compiler and linker command lines are as basic as they can get:
g++ -c oshelper.cpp
g++ -c someotherfile.cpp
etc...
ar -rv libcommon.a oshelper.o someotherfile.o ...
g++ server.cpp -lcommon -lpthread -o server
g++ client.cpp -lcommon -lrt -o client
Without special commands an .o is linked in its entirety, and thus all he dependencies are required.
You need to build the compilation units in the library with compiler flags that put all symbols in separate sections, and then call the linker with an option that "garbage collects" sections, so that only code referenced directly or indirect from main (and maybe ctors/dtors) is linked in.
I don't know the commands exactly but search for gcc parameters like -ffunction-sections -fdata-sections -fvtable-gc and -gc-section(s)

gcc/ld: undefined reference to unused function

I'm using gcc 4.3.4 and ld 2.20.51 in Cygwin under Windows 7. Here's a simplified version of my problem:
foo.o contains function foo_bar() which calls bar() in bar.o
bar.o contains function bar()
main.c calls functions in foo.o, but foo_bar() is not in the call chain
If I try to compile main.c and link it to foo.o, I get an undefined reference to _foo_bar error from ld. As you can see from my Makefile except below, I've tried using flags for putting each function in its own section and having the linker discard unused sections.
COMPILE_CYGWIN = gcc -iquote$(INCDIR)
COMPILE = $(COMPILE_CYGWIN) -g -MMD -MP -Wall -ffunction-sections -Wl,-gc-sections $(DEFINE)
main_OBJECTS = main.o foo.o
main.exe : $(main_OBJECTS)
$(COMPILE) -o main.exe $(main_OBJECTS)
The function foo_bar() is a short function that provides a connection between two networking layers in a protocol stack. Some programs don't need it, so they won't link in the other object files related to the upper layer of the stack. It's a small function, and seems inappropriate to put it into its own .o file.
I don't understand why ld throws the error -- nothing is calling foo_bar(), so there's no need to include bar() in the final executable. A coworker has just told me that ld is not a "smart linker", so maybe what I'm trying to do isn't possible?
Unless the linker is from Cyberdyne Systems it has no way to know exactly which functions will actually be called. It only knows which ones are referenced. Even Skynet's linker can't predict what run-time decisions will be made or what will happen if you load a module dynamically at run-time and it starts calling various global functions1.
So, if you link in module m and it references function f, you will need to link with whatever module has f.
1. This problem is related to the Halting Problem and has been proven undecidable.
I hit the similar issue and I find this page:
http://lists.gnu.org/archive/html/bug-gnu-utils/2004-09/msg00098.html
Highligt:
The GNU linker still works at .o file granularity.
Gcc pulls in foo.o and then find bar() was undefined.
You'd better put foo_bar() into another .o file.

Resources