I am getting an error with gcc(7.2.0) and also pgi(18.4) compilers.
There is a scientific application (in fortran) that I am compiling that has some dependencies.
These dependencies are compiled with -fPIC flag.
While compiling the main application, I get an error "relocation truncated to fit".
When I add the flag -mcmodel=medium(pgi), the compilation succeds.
But I am not willing to add this flag for some reasons.
Also when I compile the main application with -fPIC, i get linker error and a suggestion to add --no-relax flag.
After adding the same, I still get the relocation error.
Is there any way I can compile without the -mcmodel=medium flag?
Edit:
Also, when using gnu compilers, whatever mcmodel I use, I am getting the relocation error. Can this be something related to an old linker. Because I think, the application and its dependencies are compiled with 64 bit libraries, and the linker is what I assume operates with 32 bit libraries. As a reason for successful compilation with pgi when I perform /ld-linux.so --list , I get an error saying cannot map to zero fill pages. And while running the executable, I get a message as Killed.
Related
I am patching code into my car's ECU. This has a Motorola MC68376 processor, so I'm using the appropriate CPU32 instruction set.
I want to continue to write in assembly code so that I can explicitly manage control registers, RAM access and allocation, as well as copying code structures which are already in use.
My first patch was successfully compiled in EASy68k, but that program does not support the full instruction set for the CPU32. For example, the DIVS.L command is not supported, so I cannot take a quotient of a 32-bit value.
Thus, before writing my own compiler out of sheer incompetence with available tools, I'm looking for an easier path. I read that gcc has the capability to compile code for the CPU32, but I have failed to get it to work.
I'm using MinGW's gcc (6.3.0) and Eclipse (2020-03). I added the '-mcpu32' or '-march=cpu32' flags to the compiler call, according to:
https://gcc.gnu.org/onlinedocs/gcc/M680x0-Options.html
Unfortunately this returns an error:
gcc: error: unrecognized command line option '-mcpu32'; did you mean '-mcpu='?
or
error: bad value (cpu32) for -march= switch
May I please have some advice for making this work? Does anyone know of a better CPU32 compiler that works with Eclipse?
I did not understand that gcc is conventionally distributed as binary files that are compiled with different functionality to suit the needs of a given user.
There seem to be two paths forward:
1) compile my own cross-compiler version of GCC
2) download a pre-compiled cross-compiler version of GCC
I chose to follow route 2).
I began the process of installing the 'Windows Subsystem for Linux' and Ubuntu 20.04 Focal Fossa, because I found a pre-made compiler that should be capable of performing cross compilation for the m68k processor: "gobjc-10-m68k-linux-gnu"
https://ubuntu.pkgs.org/20.04/ubuntu-universe-i386/gobjc-10-m68k-linux-gnu_10-20200411-0ubuntu1cross1_i386.deb.html
While I was installing that, I also found an m68k-elf gcc toolchain that is pre-compiled for windows 10:
https://gnutoolchains.com/m68k-elf/
I played with the latter for much of today. Although I was unable to get the toolchain integrated well with Eclipse, it works from the command line to compile a *.s assembly code file. This includes compatibility with the '-mcpu32' flag that I wanted at the outset.
There is still a lot for me to figure out, even after floundering through learning gcc's assembler directives (https://www.eecs.umich.edu/courses/eecs373/readings/Assembler.pdf) and the differences in gcc's assembly syntax compared to the MC68k reference manual (https://www.nxp.com/files-static/archives/doc/ref_manual/M68000PRM.pdf).
I can even convert the code section of the output file to be a proper s-record by using objcopy with the '-O srec' and '--only-section=.text' flags. This helps me patch the code into my ECU.
Thus I've answered my original question.
I'm compiling a static library, let's call it static.a which is later linked by a shared library shared.so and by a final executable binary file (shared.so uses just a few functions from static.a maybe later this can be further splited). If I try to compile it suing gcc 7.4 I get this linker error:
/usr/bin/ld: ../../static.a(file.cpp.o): relocation R_X86_64_TPOFF32 against symbol `_ZGVZN6spdlog7details2os9thread_idEvE3tid' can not be used when making a shared object; recompile with -fPIC
I decided to try also gcc 9.1 and this error doesn't apear anymore.
should I always use -fpic when building a static library that will be used in a shared library? I know fpic adds some overhead.
how come a newer version of gcc can relocate the symbols of the static.a inside the shared library? Is this safe?
Thank you.
All code in shared library should be compiled with -fPIC so your static library should too. -fPIC does indeed introduce an overhead but to a large extent it can be mitigated with options like -fno-semantic-interposition and/or -fvisibility=hidden.
The error that you see is coming from the linker so it seems that the newer GCC does not use the problematic relocation. You can inspect the generated assembly to find out the difference in generated code.
I found out that the ARM-compiler armcc V5.05 does not compile uint64_t correctly into assembly code. It uses only one register instead of two so the result is truncated to 32 bits (though the compiler is not complaining).
As a workaround I used the gcc compiler, put the generated assembler code into a separate asm file and ran the ARM assembler. The target could not be created due to the error:
This register combination results in UNPREDICTABLE behaviour
which is really fatal, I suppose. After the C- "return" statement at the end of a function gcc inserts an offending SUB SP,R11,#0 or ADD SP,R11,#0 command before the ASM-return command BX LR. This is true with or without uint64_t.
Can I rely on gcc or is it a bug in armcc/armasm?
I'm trying to compile CMake using a non-default GCC installed in /usr/local/gcc530, on Solaris 2.11.
I have LD_LIBRARY_PATH=/usr/local/gcc530/lib/sparcv9
Bootstrap proceeds fine, bootstrapped cmake successfully compiles various object files, but when it tries to link the real cmake (and other executables), I get pages of "undefined reference" errors to various standard library functions, because, as running the link command manually with -Wl,-verbose shows, the linker links with /usr/lib/64/libstdc++.so of the system default, much older GCC.
This is because apparently CMake tries to find curses/ncurses libraries (even if I tell it BUILD_CursesDialog:BOOL=OFF), finds them in /usr/lib/64, and adds -L/usr/lib/64 to build/Source/CMakeFiles/cmake.dir/link.txt, which causes the linker to use libstdc++.so from there, and not my actual GCC's own.
I found a workaround: I can get the path to proper libraries from $CC -m64 -print-file-name=libstdc++.so then put it with -L into LDFLAGS when running ./configure, and all works well then.
Is there a less hacky way? It's really weird that I can't tell GCC to prioritize its own libraries.
Also, is there some way to have CMake explain where different parts of a resulting command line came from?
I'm running Solaris, so it's possible that this is specific to running GCC on Solaris. If I use GCC to generate a shared object, and then run nm on it to see undefined symbols, there will always be a reference to main:
[624] | 0| 0|NOTY |GLOB |0 |UNDEF |main
If I manually generate the same shared object using ld, the reference to main doesn't exist. If I run nm on the system libraries in /usr/lib, none of them appear to have references to main. Only shared libraries I compile myself with GCC.
Apps compiled against these shared libraries work fine and without errors. But I still don't understand why the reference to main is there in the first place. Any clues?
You forgot the -shared option in your gcc link command line.
EDIT: and you forgot -fPIC option on your compile command line (which is causing all the relocation errors at link time).
If you still get relocation errors with -fPIC on all compile lines, then you should rebuild all the archive libraries which you link in (libtoast_datetime, libtoast_assert, etc.) with -fPIC as well.