I am setting up a CMake build for an excisting project, and has successfully compiled all sources (.c) and reached the linker-stage.
Here I run into the following error:
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: cannot find gc-sections: No such file or directory.
The compilation is done using "arm-none-eabi-gcc" with the following flags:
-Wall -fdata-sections -ffunction-sections -std=gnu99 -mabi=aapcs -mcpu=cortex-m4 -mthumb -mfloat-abi=hard'
The linker uses the following flags:
-Wl,-Map=out.map -Wl,gc-sections -mabi=aapcs -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -T${LINKER_SCRIPT_PATH}
Anyone understand why the linker is loooking for gc_sections?
Edit: Apparently I miss the leading hyphens of the argument. The correct linker flag is of course -Wl,--gc-sections, not -Wl,gc-sections.
How embarrassing.
Apparently I missed the leading hyphens of the argument. The correct linker flag is of course -Wl,--gc-sections, not -Wl,gc-sections.
How embarrassing.
Related
I would like to report a bug but I cannot make a new account in bugzilla.
I use the gcc-arm-none-eabi-10.3-2021.10 version.
My C Code is auto-generated from Simulink. When I use the pointer *rtu_AngleMecIn then in assembly code the variable is not used and the program is not working.
When I changed the auto generated Code manually, I added the global variable Sig_MechanicalAnlge instead of the pointer. Then the assembly code seems plausible and the global variable Sig_MechanicalAngle is used.
Are you think this is a bug or Matlab Code Generator has generated wrong C Code?
I use the following Compiler options in Cmake.
#compile options add_compile_options(-mcpu=cortex-m4 -std=gnu11 -g -DDEBUG -DUSE_HAL_DRIVER -DSTM32F446xx -Og -ffunction-sections -fdata-sections -Wall -Wextra -fstack-usage --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffile-prefix-map=/home/runner/work/Nyx_Simulink/Nyx_Simulink/Code=.)
When trying to compile with flag I get the following error:
Error in dyn.load(dllfile) :
unable to load shared object '/home/Projects/RBOrB/src/RBOrB.so':
/home/Projects/RBOrB/src/RBOrB.so: undefined symbol: __gcov_merge_add
My Makevars looks like this:
CXXFLAGS += -O3 -march=native -fprofile-generate
PKG_CXXFLAGS += -O3 -std=c++11 -march=native -fprofile-generate
PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()") $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
Does R not support this or am I doing something wrong?
Suggestions:
Use the same -std=c++11 in both CXXFLAGS and PKG_CXXFLAGS
A quick google suggests that -fprofile-generate needs corresponding linkage flags. Can you confirm that -fprofile-generate appears in the link command too?
Confirm that everything works correctly without profile flags.
From memory, I'm not sure that setting CXXFLAGS actually works. I believe your changes here may be overwritten.
I get a segmentation fault from a memory allocation statement just because I have linked some unrelated procedures to the binary.
I have a very simple Fortran program:
program whatsoever
!USE payload_modules
double precision,allocatable:: Vmat(:,:,:)
allocate(Vmat(2,2,2))
Vmat=1
write(*,*) Vmat
deallocate (Vmat)
! some more lines of code using procedures from payload_module
end program whatsoever
Compiling this using gfortran whatsoever.f95 -o whatsoever leads to a program with the expected behaviour. Of course, this program is not made to print eight times 1.000 but to call the payload_modules, yet hidden in the comments. However, if I compile and link the program with the modules issuing
gfortran -c -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none payload_module1.f90 payload_module2.f90 whatsever.f95
gcc -g -nostdlib -v -Wl,--verbose -std=gnu99 -shared -Wl,-Bsymbolic-functions \
-Wl,-z,relro -o whatsoever whatsoever.o payload_module1.o payload_module2.o
the program whatsoever doesn't run any more. I get a segmentation fault at the allocate statement. I have not yet uncommented the lines related to the modules (however, uncommenting them leads to the same behaviour)!
I know that the payload modules' code is not buggy because I ran it before from R and wrapped this working code into a f90-module. There are no name collisions; nothing in the modules is called Vmat. There is only one other call to allocate in the modules. It never caused any trouble. There is still plenty of memory left. gdb didn't give me any hints expect a memory address.
How can linking routines that are actually not called crash a program?
Compiling your code with
gfortran whatsoever.f95 -o whatsoever
is working because you link against the system libraries, everything is in place. This would correspond to
gfortran whatsoever.f95 payload_module1.f90 payload_module2.f90 -o whatsoever
which would also work. The commands you used instead omit the system libraries, and the code fails at the first time you call a function from there (the allocation). You don't see that you are missing the libraries, because you create a shared object (which is typically linked against the libraries later on).
You chose to separate compiling the objects and linking them into an executable. Doing this for Fortran program using gcc you need to specify the Fortran libraries, so there's a -lgfortran missing.
I'm not sure about that particular choice of compile options... -shared is usually used for libraries, are you sure you want a shared binary (whatever that is)?
With -nostdlib you tell the compiler not to link against the system libraries. You would then need to specify those libraries (which you don't).
For the main program test.F90 and a module payload.F90, I run
gfortran -c -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none payload.F90 test.F90
gcc -g -v -Wl,--verbose -std=gnu99 -Wl,-Bsymbolic-functions \
-Wl,-z,relro -lgfortran -o whatsoever test.o payload.o
This compiles and executes correctly.
It might be easier to use the advance options with gfortran:
gfortran -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none -Wl,-Bsymbolic-functions -Wl,-z,relro \
payload.F90 test.F90 -o whatsoever
The result is the same.
I'm having a hard time generating breakpad symbols on Linux from stripped binaries.
I compile with:
gcc-4.4 -c -I../include -D_LINUX -m64 -fPIC -D__LP64__ -D_GNU_SOURCE -Wno-switch -Wno-missing-braces -fno-strict-aliasing -Wreturn-type -Wall -Wno-unknown-pragmas -Wno-parentheses -pipe -fmessage-length=0 -g -DRELEASE -O3 -o lin/voxl.o voxl.c -fvisibility=hidden
There are also some C++ files.
I then link with:
g++-4.4 -o ../liblin/foo.so -shared <objects> <libs> -z origin -Wl,-R,\$ORIGIN -Wl,-rpath,../liblin
And finally strip debug information into .debug files with:
objcopy --only-keep-debug ../liblin/foo.so ../liblin/foo.so.debug
objcopy --strip-debug ../liblin/foo.so
objcopy --add-gnu-debuglink=../liblin/foo.so.debug ../liblin/foo.so
The resulting binary can be debugged with GDB with full symbol information. It contains a .gnu_debuglink section which refers to foo.so.debug (no dir path), which is correct.
However, dump_syms doesn't seem to be following the link, even though the code being edited in this patch strongly suggests that it should. I get this output in stderr:
liblin/foo.so, section '.eh_frame': the call frame entry at offset 0x18 uses a DWARF expression to describe how to recover register '.cfa', but this translator cannot yet translate DWARF expressions to Breakpad postfix expressions
liblin/foo.so: file contains no debugging information (no ".stab" or ".debug_info" sections)
The resulting symbol file is 2MB, whether or not the .gnu_debuglink section is present in the ELF. When using this 2MB symbol file with minidump_stackwalk, the wrong functions appear on stack frames. When I run dump_syms on a binary with embedded symbols the output file is 9MB and stack frames are correct.
What am I doing wrong?
This turned out to be two things:
To load symbols from external files you must provide a directory path to dump_syms, even if the symbols are in the same folder as the binaries. e.g. dump_syms foo.so .
There is a bug in Breakpad that means external symbols will never be loaded even if they are found. I've submitted a patch to fix it.
My usecase is as follows:
I am using a typical SDK that comes with Makefile based projects
I belive the linker is patched gcc. gcc --version gives me 4.3.4
SDK defines the linker script (lets call it Linker.ld)
Linker.ld includes LinkerMemMap.cfg, which defines the absolute addresses for various sections in the linked ELF image
SDK provides application templates based on Makefiles (GNU Make 3.81) and make itself
In the SDK provided Makefile template, when gcc is invoked the Linker.ld is provided with -T command line option, as follows:
gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf
My requirement is as follows:
I would like to use the sections as defined in Linker.ld and use the memory map as per LinkerMemMap.cfg however tweak a particular symbol(lets call it SYMBOL_RAM_START) defined in LinkerMemMap.cfg
What works:
I have tried in the makefile, prior to linking the final ELF image, copy the LinkerMemMap.cfg (which is included by Linker.ld) to the build directory and patch it to redefine SYMBOL_RAM_START. This does work as the linker searches for the linker scripts and the files included by the linker scripts in the current folder first.
What doesn't:
Unfortunately our stakeholders think the above method is too risky and complex to understand. I would like to override the symbol value on the linker command line with something like below:
gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections,--defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf
gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf
gcc $(OBJS) -l$(Lib1) -l$(Lib2) --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf
None of these seem to have any effect on the linked image created by the linker.
Can --defsym override the symbols defined by linkerscript specified using -T?
Could any of you please see what am I doing wrong here?
While waiting for someone to respond, I did resolve the issue. There are few issues with the problem here and I thought of explaining my findings for someone who might do the same mistake.
First of all Any options to be passed to the linker must be specified with -Xlinker or with -Wl. Hence both 2 and 3 won't work in the above case. The corrected 2 and 3 would be as follows:
Is correct already
gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -Xlinker --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf
gcc $(OBJS) -l$(Lib1) -l$(Lib2) -Xlinker --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf
Now for the case of options 1 & 2 above, --defsym comes after linker script and SYMBOL_RAM_START was already defined by the linker script. It does override it. But the overriden value will not be used, because the sections have already been defined as the linker script has already been used.
For the case of option 3 above, the SYMBOL_RAM_START was defined before the linker script was read by the linker. Hence when linker script is parsed, the value specified in the script overrides it.
Solution:
In order for this to work, the linker script will need to conditionally initialize the symbol SYMBOL_RAM_START, something like below:
SYMBOL_RAM_START = DEFINED( SYMBOL_RAM_START ) ? SYMBOL_RAM_START : DEFAULT_VALUE ;
Given the above in the linker script, when the SYMBOL_RAM_START was defined before the linker script is included (as shows in option 3 above) it did work. But in the end I had to patch the linker script.
This solution doesn't really override the symbol, but provides a way in which a symbol can be defined so that it can be overridden.