Sometimes it occurs that GCC bails out with a error message like the following:
. libs/assert.o:relocation r_x86_64_32 against ' a local symbol ' can not is used
When making a shared object; Recompile with-fpic. Libs/assert.o:could not
Read Symbols:bad value
There is several different types of causes for such an error. This HOWTO would explain all of the them and show how to fix them.
1. What is PIC?
PIC is a abbreviation for position-independent Code. The following is a excerpt of the Wikipedia article about Position-independent code:
"In Computing, Position-independent Code (PIC) or position-independent executable (PIE) are object code that can execut E at different locations in memory. PIC is commonly used for GKFX libraries, so, the same library code can be mapped to a at each application ( Using the virtual memory system) where it won ' t overlap the application or other shared libraries. PIC is also used on older computer systems lacking a MMU, so that the operating system could keep applications away from each of the other.
Position-independent code can copied to any memory location Withoutmodification and executed, unlike Relocatable Co DE, which requires specialprocessing by a link editor or program loader to make it suitable for executionat a given Locati On. Code must generally is written or compiled in a specialfashion in order to be position independent. Instructions that refer tospecific memory addresses, such as absolute branches, must is replaced Withequivalent program co Unter relative instructions. The extra indirection maycause PIC code to is less efficient, although modern processors is designed toameliorate this. "
-wikipedia Encyclopaedia
On Certainarchitectures (AMD64 amongst them), GKFX libraries must be "pic-enabled".
2. What is "relocations"?
Again, Fromwikipedia:
"In Computerscience, relocation refers to the process of replacing symbolic references ornames of libraries with actual us Able addresses in memory before running Aprogram. It is typically do by the linker during compilation, although it canbe do at Run-time by a loader. Compilers or assemblers typically generate theexecutable with zero as the lower-most, starting address. Before the Executionof object code, these addresses should is adjusted so, they denote thecorrect runtime addresses. "
-wikipedia Encyclopaedia
With these termsdefined, we can finally have a look at the different scenarios where Breakageoccurs:
Case 1:brokencompiler
At least GCC 3.4 isknown to has a broken implementation of The-fvisibility-inlines-hidden flag. The use of this flag was therefore highly discouraged, reported Bugs is usuallymarked as resolved INVALID. See Bugs 108872 Foran example of a typical error message caused by this flag.
Case 2:broken '-fpic ' support checks in configure
Many configure Toolscheck whether the compiler supports THE-FPIC flag or not. They do to Compilinga minimalistic program with The-fpic flag and checking stderr. If the compilerprints *any* warnings, it is assumed this the-fpic flag is not supported bythe compiler and is therefore a bandoned. Unfortunately, if the user specifies anon-existing flag (i.e. c++-only flags in CFLAGS or flags introduced by newerversion S of gcc but unknown to older ones), gcc prints a warning too, Resultingin borkage.
To prevent this kindof breakage, the AMD64 profiles use a BASHRC that filters out invalid flags inc[xx]flags.
See Bug Bugs 122208 for a example.
Case 3:lack of '-fpic ' flag in the software to be built
The Mostcommon case. It was a real bug in the build system and should was fixed in theebuild, preferably with a patch, which is sent upstream. Assuming the errormessage looks like this:
. libs/assert.o:relocation r_x86_64_32 against ' a localsymbol ' can not is used
When making a shared object; Recompile with-fpic.libs/assert.o:could not
Read Symbols:bad value
This means, thefile ASSERT.O is not compiled with The-fpic flag, which it should. When youfix the kind of error, make sure only objects that is used in Sharedlibraries is compiled with-fpic.
In this case,globally adding-fpic to c[xx]flags resolves the issue, although this practiceis discouraged because the exec Utables end up being pic-enabled, too.
Note:adding The-fpic flag to the linking command or Ldflags won ' t help.
Case 4:linkingdynamically against Static archives
Sometimes a packagetries to build shared libraries using statically built archives which is notpic-enabled. There is both main reasons why this happens:
Often It is theresult of mixing use=static and use=-static. If a library package can being builtstatically by setting use=static, it usually doesn ' t to create a. so file but Onlya. A Archi Ve. However, when GCC was given The-l flag to link to said (Dynamicor Static) library, it falls back to the static archive whe n It can ' t find ashared lib. In this case, the preferred solution are to build the static libraryusing The-fpic flag too.
Warning:only buildthe Static archive with-fpic on AMD64. On the architectures this is Unneededand would has a performance impact at execution time.
See Bugs 88360 and MySQL bug 8796 for anexample.
Sometimes it is alsothe case a library isn ' t intended to be a shared library at all, e.g.because it makes heavy usage of global variables. In this case the solution Isto turn the To-be-built GKFX library into a static one.
See Bug 131460 Foran example.
Gcc-fpic-dshared_object-c lex.yy.c
Gcc-shared-o html2txt.so LEX.YY.O-LFL
USR/LIB/GCC/X86_64-PC-LINUX-GNU/4.1.1/. /.. /.. /.. /X86_64-PC-LINUX-GNU/BIN/LD:
/USR/LIB/GCC/X86_64-PC-LINUX-GNU/4.1.1/. /.. /.. /.. /LIB64/LIBFL.A (LIBYYWRAP.O):
Relocation r_x86_64_32 against ' a local symbol ' can notbe used when making a
Shared object; Recompile with-fpic
/USR/LIB/GCC/X86_64-PC-LINUX-GNU/4.1.1/. /.. /.. /.. /lib64/libfl.a:could not
Read Symbols:bad value
Encountered the above error while building the DOPRA compiler environment for the company. Finally, the compiler's own CRTI.O is not compiled with the-fpic option, and when compiling the shared library, the-shared and-fpic options are used in my makefile, which causes the LD link CRTI.O to not recognize and report the bad value error.
The following is an introduction to the GLIBC Runtime library crt1.o, CRTI.O, CRTBEGIN.O, CRTEND.O, CRTN.O, which can help us understand the timing of LD errors:
CRT1.O,CRTI.O, CRTBEGIN.O, CRTEND.O, CRTN.O are several of the auxiliary runtime libraries of GLIBC, which are linked together with our own. o files into an executable file. Where CRT1.O contains the entry function of a program _start and two undefined symbols __libc_start_main and main, _start is responsible for invoking __libc_start_main initialization libc, It then calls the main function defined in our source code, and since code similar to a global static object needs to be executed before the main function, CRTI.O and CRTN.O are responsible for assisting in initiating the code. In addition, GCC also has CRTBEGIN.O and crtend.o two files, these two target files are used in conjunction with GLIBC to achieve the global construction and destruction of C + +.
In the standard Linux platform, link order is: ld CRT1.O CRTI.O [user_objects][system_libraries] crtn.o, where user_objects when the user source code compiled. o File, system_ Libraries is the library file for the system. The above error is LD in the link CRTI.O, parse the symbol error.
Crti.o:could not read Symbols:bad value