.comment section with two lines - linux

I have an executable with two lines in comment section as readelf shows :
readelf -p .comment ac_test
String dump of section '.comment':
[ 0] GCC: (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973]
[ 39] GCC: (GNU) 4.6.0
The 4.3.4 compiler is the one installed in the Suse Linux but the 4.6 is compiled from sources. I have fix the PATH to point to 4.6 so the executable is compiled with.
I have the doubt if in any way the 4.3.4 toolchain is used.
My question is : Why do I have two compilers in the .comment section?, is any problem with that?,
Thanks.

Hard to say with that little bit of information, but it's probable that the comment from the 4.3.4 compiler comes from an object or library that was linked into your binary (i.e. you didn't compile it yourself with your 4.6 compiler).

Related

Working with lower version of GLIBC: version `GLIBC_2.11` not found (required by g++)

I've installed GCC 7.1 on my machine and tried to use g++ on it, but it didn't work, saying this:
g++: /lib64/libc.so.6: version `GLIBC_2.11` not found (required by g++)
So then I did these:
$ strings /lib64/lib.so.6 | grep GLIB
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_PRIVATE
$ strings `which g++` | grep GLIB
GLIBC_2.3
GLIBC_2.11
GLIBC_2.2.5
Two things can be noted here:
The string GLIBC_2.11 isn't common to both of these outputs.
However, GLIBC_2.3 is common to both.
Questions:
1. What exactly do these strings mean? Why are there more than one string in both of them? What do they tell us?
2. My guess is that the absence of GLIBC_2.11 in libc explains why g++ doesn't work, as g++ requires it (as the error says itself). However, I'm confused what does the presence of GLIBC_2.3 in both actually mean? Does it mean that g++ can be instructed to use this instead of GLIBC_2.11? If so, how exactly? What is the command?
GLIBC_2.3 and GLIBC_2.11 are symbol versions. The dynamic linker uses them to perform a quick check for library compatibility at program startup: the system glibc must provide all symbol versions referenced by the program. Your glibc is apparently 2.5 (which would match Red Hat Enterprise Linux 5). This version lacks quite a few features added in later versions, and it turns out the pre-compiled GCC binary you are trying to run needs some of them.
To resolve this, you'll need a version of GCC compiled specifically for Red Hat Enterprise Linux 5. I haven't tried if the current GCC upstream sources build with the system compiler, which is … quite ancient by this time (although upstream still sticks with C++03 for exactly such needs). Some libstdc++ functionality may also need a newer kernel than 2.6.18, and some care is necessary to preserve compatibility between the new libstdc++ and the one installed with the system.

Tell which version of symbols are available for linking against (in libc)?

Ok, so I want to link against a lower version of libc / glibc, for compatibility. I noticed this answer about how to do this, on a case-by-case basis:
How can I link to a specific glibc version?
https://stackoverflow.com/a/2858996/920545
However, when I tried to apply this myself, I ran into problems, because I can't figure out what lower-version-number I should use to link against. Using the example in the answer, if I use "nm" to inspect the symbols provided by my /lib/libc.so.6 (which, in my case, is a link to libc-2.17.so), I see that it seems to provide versions 2.0 and 2.3 of realpath:
> nm /lib/libc.so.6 | grep realpath#
4878d610 T realpath##GLIBC_2.3
48885c20 T realpath#GLIBC_2.0
However, if I try to link against realpath#GLIBC_2.0:
__asm__(".symver realpath,realpath#GLIBC_2.0");
...i get an error:
> gcc -o test_glibc test_glibc.c
/tmp/ccMfnLmS.o: In function `main':
test_glibc.c:(.text+0x25): undefined reference to `realpath#GLIBC_2.0'
collect2: error: ld returned 1 exit status
However, using realpath#GLIBC_2.3 works... and the code from the example, realpath#GLIBC_2.2.5 works - even though, according to nm, no such symbol exists. (FYI, if I compile without any __asm__ instruction, then inspect with nm, I see that it linked against realpath#GLIBC_2.3, which makes sense; and I confirmed that linking to realpath#GLIBC_2.2.5 works.)
So, my question is, how the heck to I know which version of the various functions I can link against? Or even which are available? Are there some other kwargs I should be feeding to nm? Am I inspecting the wrong library?
Thanks!
It seems to me that you have mixed up your libraries and binaries a bit...
/lib/libc.so.6 on most Linux distributions is a 32-bit shared object and should contain the *#GLIBC_2.0 symbols. If you are on an x86_64 platform, though, I would expect GCC to produce an 64-bit binary by default. 64-bit binaries are generally linked against /lib64/libc.so.6, which would not contain compatibility symbols for an old glibc version like 2.0 - the x86_64 architecture did not even exist back then...
Try compiling your *#GLIBC_2.0 program with the -m32 GCC flag to force linking against the 32-bit C library.

linux command "file" shows "for GNU/Linux 2.6.24"

I always use the file command to check the file type, mostly after I compile a new project to make sure everything is fine.
The output is something similar to this below:
proj_out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=0x23d9f966854e09d721c6110d505247483dae02fe, stripped
My question is since my Linux Kernel is updated to 3.0+, why does it still shows it is compiled for older versions of Linux?
for GNU/Linux 2.6.24
Is it anything related to file command or do I have to do anything to compile my project against newer Linux Kernel?
Thanks
The kernel version displayed by file on an executable has nothing to do with the kernel installed on your system. It matches the C library the program was linked with at build time.
Your C compiler targets a specific C library (usually glibc). In turn, the C library targets a kernel API (i.e. the C library is built for a specific kernel). That is the version displayed by file.
You don't have to worry about the mimatch between the kernel version displayed by file and the kernel version installed on your machine.
#REALFREE: you can try the following experiment. Maybe it will
help you get a grasp of what's going on:
$ uname -r
3.10-2-amd64
$ gcc -Wall -Werror hello.c -o hello
$ readelf --notes ./hello
Displaying notes found at file offset 0x0000021c with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.32
The information about the ABI tag is contained in an elf
segment called NOTE. This information is written by the linker
when the program is compiled. It matches the ABI tag of the C library.
$ ldd ./hello
linux-vdso.so.1 (0x00007fffd31fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5f1a465000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5f1a827000)
$ readelf --notes /lib/x86_64-linux-gnu/libc.so.6
Displaying notes found at file offset 0x00000294 with length 0x00000020:
Propriétaire Taille des données Description
GNU 0x00000010 NT_GNU_ABI_TAG (étiquette de version ABI)
OS: Linux, ABI: 2.6.32
In order to build the C library, you have to select a kernel
version. Here, the C library was compiled for a 2.6.32 kernel but
it also works with more recent kernels. However, if the program
is run on a kernel older than 2.6.32, a kernel too old warning
is displayed.
That version number refers to the kernel headers from which the glibc C library was built on the host that the compiler was run on. Broadly, it shows the level of kernel that the executable will be expected to support.

Does the "ccmath" library compile on x86-64 linux?

Ccmath library:
http://freecode.com/projects/ccmath
It does not specify 32/64 bit in description, but when I compile on Ubuntu 10.10 64 bit it spits out error on asm-file compilling:
solv.s:13: Error: invalid instruction suffix for `push'
code line: pushl %ebp
But if I replace cc shell instruction for gcc -m32 its all OK!
However, can I compile it on x86-64? I have to link this to 64bit project.
That ccmath package looks like it hasn't been updated since 2001. Its assembly routines are not 64-bit capable. You should run the included non_intel.sh script as instructed in the INSTALL file. (As far as this package is concerned, x86-64 is non-intel because "intel" means "x86-32".)

Cuda compiler not working with GCC 4.5 +

I am new to Cuda, and I am trying to compile this simple test_1.cu file:
#include <stdio.h>
__global__ void kernel(void)
{
}
int main (void)
{
kernel<<<1,1>>>();
printf( "Hello, World!\n");
return 0;
}
using this: nvcc test_1.cu
The output I get is:
In file included from /usr/local/cuda/bin/../include/cuda_runtime.h:59:0,
from <command-line>:0:
/usr/local/cuda/bin/../include/host_config.h:82:2: error: #error -- unsupported GNU version! gcc 4.5 and up are not supported!
my gcc --version:
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
How can I install a second version of gcc (4.4 -) along with 4.6 without messing everything up?
I found this old topic:
CUDA incompatible with my gcc version
the answer was:
gcc 4.5 and 4.6 are not supported with CUDA - code won't compile and
the rest of the toolchain, including cuda-gdb, won't work properly.
You cannot use them, and the restriction is non-negotiable.
Your only solution is to install a gcc 4.4 version as a second
compiler (most distributions will allow that). There is an option to
nvcc --compiler-bindir which can be used to point to an alternative
compiler. Create a local directory and the make symbolic links to the
supported gcc version executables. Pass that local directory to nvcc
via the --compiler-bindir option, and you should be able to compile
CUDA code without effecting the rest of your system.
But I have no idea how to do it
In my case I didn't have root rights, so I couldn't fully replace the current gcc (4.7) with the older version 4.4 (which I think would be a bad alternative). Although I did have rights where CUDA was installed. My solution was to create an extra folder (e.g. /somepath/gccfornvcc/), wherever I had rights, then to create a link to an nvcc accepted compiler. I already had gcc 4.4 available (but you can install it, without removing your current version).
ln -s [path to gcc 4.4]/gcc-4.4 /somepath/gccfornvcc/gcc
Then, in the same folder where the nvcc binary lives, you should find a file called nvcc.profile . There you just need to add the following line:
compiler-bindir = /somepath/gccfornvcc
And that will make nvcc use the proper compiler. This helps keeping the system in a proper state, keeping the newest compiler, but nvcc (only nvcc) will use the old compiler version.
Doing some research online shows several methods for accomplishing this task. I just tested the method found here: http://www.vectorfabrics.com/blog/item/cuda_4.0_on_ubuntu_11.04 and it worked like a charm for me. It steps you through installing gcc 4.4 and creating scripts to run that version with nvcc. If you prefer trying the method mentioned in your post I'd recommend following that first link to install gcc4.4 and then create symbolic links as mentioned in your post. Creating symbolic links in Linux is accomplished by using the 'ln' command.
For example:
ln -s [source file/folder path] [linkpath]
This link gives a few examples of creating symbolic links on both Ubuntu and Windows: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/. Hopefully that points you in the right direction.
I guess you may try the new, beta, version, that based on LLVM.
Another way to make nvcc work with non-default compiler (unlike #Sluml's answer, it allows more flexibility):
At first, just like #Slump proposed, you need to create directory ~/local/gcc-4.4/, and then create there symlinks for right versions of gcc: for i in gcc gxx; do ln -s /usr/bin/${i}-4.4 ~/local/cudagcc/${i}; done. Now when you run nvcc -ccbin ~/local/gcc-4.4/ ... nvcc will use correct versions of gcc.
Here is small CMake snippet of forcing nvcc use specific host compiler.
option (CUDA_ENFORCE_HOST_COMPILER "Force nvcc to use the same compiler used to compile .c(pp) files insted of gcc/g++" OFF)
if (${CUDA_ENFORCE_HOST_COMPILER})
set (CMAKE_GCC_TEMP_DIR "CMakeGCC")
file(MAKE_DIRECTORY ${CMAKE_GCC_TEMP_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_C_COMPILER} ${CMAKE_GCC_TEMP_DIR}/gcc)
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CXX_COMPILER} ${CMAKE_GCC_TEMP_DIR}/g++)
set(CUDA_NVCC_FLAGS -ccbin ${CMAKE_GCC_TEMP_DIR} ${CUDA_NVCC_FLAGS})
endif()
Reference:
I update my gcc from 4.4 to 4.6. Then I could not use nvcc to compile my code. Luckily, by using the method provided by the following link. I set my default gcc compiler back to gcc 4.4. Now, I could compile file using either gcc4.4 or gcc4.6. quit cool
http://ubuntuguide.net/how-to-install-and-setup-gcc-4-1g4-1-in-ubuntu-10-0410-10

Resources