Position dependent code - gcc

I am using a processor that uses sparc v8 architecture. I would like to compile my executable such that each function call is absolute address. Using -fPIC option generate position independent code, is there any reverse of this flag ?

Most of GCC options have both -fxxx and -fno-xxx variants.
You can easily test if this is the case for fPIC. Just compile some simple test:
int main () { printf ("Hello, world!\n"); }
with command line like:
gcc -fPIC test.c -S
and look for PLT-relative call in assembler
call puts#PLT
Now try to cancel this option with its reverse:
gcc -fPIC test.c -S -fno-PIC
You will see, that PLT-relative call has gone, so everything works.

Related

Runtime Error with _mm_set1_epi32

I am trying to use SIMD instructions in some projects and everything is working fine, except that I can't use the _mm_set1_epi32(x) command (I can still just use _mm_set_epi32(x,x,x,x) and it works fine) but as soon as I want to use code from another source where the command is used I get a "memory access error" message (please excuse that I don't have the correct english translation for the error, I tried translating it from German where it is Speicherzugriffsfehler)
Some additional information:
I get the error in an empty project where I do nothing except use the command
I got this problem with no other command
For code examples, there is not really something to post here, except this:
int main() {
__m128i test = _mm_set1_epi32(1);
}
The error is at runtime, no problems with compiling.
I solved the problem. The flags I used to compile where wrong, thats also the reason why I didn't put any code, it would be just 1 line where I try to execute the command and the include for it in a main function.
So to the solution, I use now:
-g -std=c++11 -Wall -pedantic -msse4.1 -v
and before I used:
-g -std=c++11 -Wall -pedantic -msse -mmmx -msse2 -msse4.1 -v -mavx2

g++ 5.4.0 - unable to use C++14 standard

I installed gcc 5.4.0 recently, on Windows using Cygwin, because I wanted to test the C++14 standard features of g++. When I tried to compile, I get the following error:
$ g++-5.4.0 -std=c++14 test.cpp
-bash: g++-5.4.0: command not found
This is the code I wrote inside test.cpp:
#include <iostream>
int main()
{
auto lambda = [](auto x){ return x; };
std::cout << lambda("Hello generic lambda!\n");
return 0;
}
What could be the problem? I also tried replacing C++14 with C++11 in the command, but got the same error.
When Cygwin installs a g++ version (in your case, 5.4.0), it will place the g++ executable in your PATH variable. But the installation name is just g++.exe, so you can call the program like this:
g++ -std=c++14 test.cpp
If you really wanted to call the compiler with g++-5.4.0, you could symlink the actual g++ executable to that name:
ln -s /usr/bin/g++.exe /usr/bin/g++-5.4.0.exe
then you will be able to call the program from the command line with either g++ or g++-5.4.0:
g++-5.4.0 -std=c++14 test.cpp
g++ -std=c++14 test.cpp

line number information lost during linking in gcc

I'm using Red Hat 4.4.7-3 and gcc 4.8.3
I have code in two files(test.c and sum.c) and I compiled them separately with gcc(with debug information). In the last phase when I'm making the final output by combining both files, debug information is lost.
test.c:
int main()
{
int a=5,b=7;
int c=testsum(a,b);
printf("%d + %d=%d\n",a,b,c);
return 0;
}
sum.c:
int testsum(int a, int b)
{
return a+b;
}
I did the following:
gcc -c -g test.c -o test.o
gcc -c -g sum.c -o sum.o
gcc -g test.o sum.o -o output
When I do gdb sum.o then it is showing the line number information
(gdb) l testsum
1 int testsum(int a, int b)
2 {
3 return a+b;
4 }
but with the gdb output I'm not getting line number information.
(gdb) l testsum
No line number known for testsum.
(gdb)
I repeated the same thing on my personal laptop(gcc-4.8.real (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1) and here it is working perfectly fine. But I need the debug information in the final output on the redhat machine for some project.
Any suggestions/comments regarding obtaining the line number information in final executable would be much appreciated.
You need to compile and link with gcc -g. Perhaps you forgot the -g flag at link time.
And use surely want to compile with gcc -Wall -g since warnings are incredibly useful.
You should run gdb on the ELF executable file, not on object files (so gdb sum.o is wrong):
gdb ./output
You should have a Makefile (see this example) and build your program using GNU make
Perhaps the gdb on the remote Redhat server is not accepting the same DWARF format than on your local laptop. Check the versions of gdb. (Perhaps consider compiling on the remote sever, or passing some explicit debugging option like -gdwarf-3 or whatever is appropriate for the remote gdb to your gcc laptop compiler).

How to (cross-)compile to both ARM hard- and soft-float (softfp) with a single GCC (cross-)compiler?

I'd like to use a single (cross-)compiler to compile code for different ARM calling conventions: since I always want to use floating point and NEON instructions, I just want to select the hard-float calling convention or the soft-float (softfp) calling convention.
My compiler defaults to hard-float, but it supports both architectures that I need:
$ arm-linux-gnueabihf-gcc -print-multi-lib
.;
arm-linux-gnueabi;#marm#march=armv4t#mfloat-abi=soft
$
When I compile with the default parameters:
$ arm-linux-gnueabihf-g++ -Wall -o hello_world_armhf hello_world.cpp
It succeeds without any errors.
If I compile with the parameters returned by -print-multi-lib:
$ arm-linux-gnueabihf-g++ -marm -march=armv4t -mfloat-abi=soft -Wall -o hello_world hello_world.cpp
It again compiles without error (By the way, how can I test that the resultant code is hard- or soft-float?)
Unfortunately, if I try this:
$ arm-linux-gnueabihf-g++ -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -Wall -o hello_world hello_world.cpp
[...]/gcc/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: error: hello_world uses VFP register arguments, /tmp/ccwvfDJo.o does not
[...]/gcc/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: failed to merge target specific data of file /tmp/ccwvfDJo.o
collect2: error: ld returned 1 exit status
$
I've tested some other permutations of the parameters, but it seems that anything other than the combination shown by -print-multi-lib results in an error.
I've read ARM compilation error, VFP registered used by executable, not object file but the problem there was that some parts of the binary were soft- and some were hard-float. I have a single C++ file to compile...
What parameter(s) I miss to be able to compile with -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon?
How is it possible that the error is about VFP register arguments while I explicitly have -mfloat-abi=softfp in the command line which prohibits VFP register arguments?
Thanks!
For the records, hello_world.cpp contains the following:
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
You need another compiler with corresponding multilib support.
You can check multilib support with next command.
arm-none-eabi-gcc -print-multi-lib
.;
thumb;#mthumb
fpu;#mfloat-abi=hard
armv6-m;#mthumb#march=armv6s-m
armv7-m;#mthumb#march=armv7-m
armv7e-m;#mthumb#march=armv7e-m
armv7-ar/thumb;#mthumb#march=armv7
cortex-m7;#mthumb#mcpu=cortex-m7
armv7e-m/softfp;#mthumb#march=armv7e-m#mfloat-abi=softfp#mfpu=fpv4-sp-d16
armv7e-m/fpu;#mthumb#march=armv7e-m#mfloat-abi=hard#mfpu=fpv4-sp-d16
armv7-ar/thumb/softfp;#mthumb#march=armv7#mfloat-abi=softfp#mfpu=vfpv3-d16
armv7-ar/thumb/fpu;#mthumb#march=armv7#mfloat-abi=hard#mfpu=vfpv3-d16
cortex-m7/softfp/fpv5-sp-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=softfp#mfpu=fpv5-sp-d16
cortex-m7/softfp/fpv5-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=softfp#mfpu=fpv5-d16
cortex-m7/fpu/fpv5-sp-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=hard#mfpu=fpv5-sp-d16
cortex-m7/fpu/fpv5-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=hard#mfpu=fpv5-d16
https://stackoverflow.com/questions/37418986/how-to-interpret-the-output-of-gcc-print-multi-lib
How to interpret the output of gcc -print-multi-lib
With this configuration gcc -mfloat-abi=hard not only will build your files using FPU instructions but also link them with corresponding libs, avoiding "X uses VFP register arguments, Y does not" error.
The above-mentioned -print-multi-lib output produced by gcc with this patch and --with-multilib-list=armv6-m,armv7,armv7-m,armv7e-m,armv7-r,armv7-a,cortex-m7 configuration option.
If you are interested in building your own gcc with Cortex-A series multilib support, just use --with-multilib-list=aprofile configuration option for any arm*-*-* target without any patches (at list with gcc-6.2.0).
As per Linaro FAQ if your compiler prints arm-linux-gnueabi;#marm#march=armv4t#mfloat-abi=soft then you can only use -march=armv4t. If you want to use -march=armv7-a you need to build compiler yourself.
Following link could be helpful in building yourself GCC ARM Builds

linking g++ code with shared library build with gcc

I made shared library using gcc . I would like to link this library using g++ comiler with source code *.c.
Example
test_init.c
#include<stdio.h>
int test_init()
{
printf(" test init success\n");
return 0;
}
gcc -shared -o libtest.so test_init.c
test.c
#include<stdio.h>
extern int test_init();
main()
{
test_init();
}
g++ -I. -L. -ltest test.c
/tmp/ccuH5tIO.o: In function main':
test.c:(.text+0x7): undefined
reference totest_init()' collect2:
ld returned 1 exit status
Note: If i compile test.c with gcc it works, but i would like to use this approach due to other dependencies. Is it possible??
You call C routines from C++ by declaring them
extern "C" {
....
}
Look into a few header files on your system or Google around -- that's the only way to do it because of different function signature systems between the languages.
As Dirk said, change extern int test_init(); to extern "C" { int test_init(); }
Usually -llibrary should be after object files or c/c++ files in gcc command line
g++ -I. -L. test.c -ltest
The linker searches for the symbols mentioned in test.c after it's processed and when you put -llib before test.c, it's just unable to find them.
See man ld for more info.
Not sure how the things are when you use extern, perhaps something is different in this case.

Resources