Gcc-shared-O hack. So hack. c
/Usr/bin/ld:/tmp/ccuzrewa. O: Relocation r_x86_64_32 against 'a local symbol' can not be used when making a shared object; recompile with-FPIC
/Tmp/ccuzrewa. O: cocould not read symbols: Bad Value
Collect2: LD returned 1 exit status
This error does not occur after the-FPIC parameter is added.
Gcc-FPIC-shared-O hack. So hack. c
-FPIC acts on the compilation stage and tells the compiler to generate position-independent code ),
There is no absolute address in the generated code, and all corresponding addresses are used. Therefore, the code can be loaded to any memory by the loader.
Can be correctly executed. This is exactly what the Shared Library requires. When the shared library is loaded, the memory location is not fixed.
Gcc-shared-FPIC-O 1.so 1. c here, the-FPIC parameter PIC is set to position independent codepic. so file code segment becomes truly shared. If-FPIC is not added, load the file. in the so file code segment, the Data Object referenced by the code segment needs to be relocated. The relocation will modify the content of the Code segment, which causes each use of this. the so file code snippet process will generate this in the kernel. so file code segment copy. each copy is different, depending on this. so file code segment and Data Segment memory ing location.
So compiled without FPIC is to be reloaded and relocated again based on the loaded location (because the code in it is not the location-independent code)
If multiple applications are used together, each program must maintain a copy of so code. (Because so is loaded in different locations by each program, the code after the relocation is obviously different and cannot be shared)
We always use FPIC to generate so, and never use FPIC to generate.
FPIC has nothing to do with dynamic links. Similar to libc. So, you do not need to compile FPIC, but such so must redirect all the tables when loading them to the address space of the user program.
Therefore, it is not always bad to compile so without using FPIC.
If you meet the following four requirements/conditions:
1. This database may need to be updated frequently.
2. This database requires high efficiency (especially when there are many global applications)
3. The database is not very large.
4. The Library does not need to be shared by multiple applications.
If you can use a compiled shared library without this parameter, there may be two reasons:
1: The-FPIC option is enabled for GCC by default.
2: loader makes your code location irrelevant
From the perspective of GCC, shared should include the FPIC option, but it does not seem to be supported by all systems, so it is best to explicitly add the FPIC option. See
'-Shared'
Produce a shared object which can then be linked with other
Objects to form an executable. Not all systems support this
Option. For predictable results, you must also specify the same
Set of options that were used to generate code ('-FPIC', '-FPIC ',
Or model suboptions) When you specify this option. (1)
-When FPIC is used, the PIC code is generated. So must be PIC to achieve dynamic link. Otherwise, dynamic link cannot be implemented.
The main difference between non-pic and PIC code is that access global data and jump label are different.
For example, an access global data command,
Non-pic: LD R3, var1
The PIC format is: LD R3, [email protected], meaning from where the index of the got table is var1-offset
A value is loaded at the indicated address, that is, four bytes at [email protected] are actually var1 addresses. This address is only known when running, filled in by dynamic-loader (ld-linux.so.
For example, the jump label command
The situation of non-pic is: Jump printf, which means to call printf.
The PIC format is: Jump [email protected],
It means to jump to the address indicated at the place where the index of the got table is printf-offset,
The code at this address is placed in. PLT section,
Each external function corresponds to a piece of code called dynamic-loader (ld-linux.so) to find the address of the function (printf in this example ), write the address to the location where the index of the got table is printf-offset,
Execute this function at the same time. In this way, when you call printf for 2nd times, it will jump directly to the address of printf without having to look for it again.
Got is a data section and a table. In addition to several dedicated entries, the content of each entry can be modified when executed;
PLT is a text section and a piece of code. It does not need to be modified during execution.
Each target has different PIC implementation mechanisms, but they are similar. For example, MIPS does not have. PLT, but is called. stub. It has the same function as. PLT.
It can be seen that the execution of dynamic links is complex and longer than that of static links. However, the size is greatly reduced. PIC and dynamic link technology are an important milestone in the development of computer development.
Mentioned above in GCC manul
-FPIC if the got size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that-FPIC does not work; in that case, recompile with-FPIC instead. (These maximums are 8 K on the names of the disks and 32 K on the m68k and RS/6000. the 386 has no such limit .)
-FPIC if supported for the target machine, emit position-independent code, suitable for Dynamic Linking and avoiding any limit on the size of the global offset table. this option makes a difference on the m68k, PowerPC and iSCSI. position-independent code requires special support, and therefore works only on certain machines.
The key lies in the size of the jump entry in the got global offset table.
The intel processor should be 4 bytes in a unified manner.
Due to the special requirements of assembly code or machine code on powerpc, the jump items are short and long.
-To save memory, the FPIC reserves a "short" length in the got.
-FPIC uses larger jump items.
Reference: http://blog.sina.com.cn/s/blog_54f82cc201011op1.html