Changeset 3352c45
- Timestamp:
- May 20, 2011 1:25:19 PM (10 years ago)
- Branches:
- master
- Children:
- e2c98ac
- Parents:
- 0e719b8e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
core/c/jcpuid/src/jcpuid.c
r0e719b8e r3352c45 1 1 #include "jcpuid.h" 2 3 /** 4 5 From: http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well 6 7 Perhaps the most accessible documentation on what PIC code is and how an ELF dynamic linker works is 8 John Levine's Linkers and Loaders (and it has amazing sketches, too!). The Gentoo documentation also 9 has an Introduction to Position Independent Code. I'd like to give a few hints on how to fix the 10 shlib-with-non-pic-code lintian error caused by inline assembly on the i386 and amd64 platforms, 11 as well as build errors that may occur due to inline assembly being used. 12 13 I'm not going to cover the trivial "all objects were not built using gcc's -fPIC flag" problem. 14 It usually requires a fix to the build system, not to the code. 15 16 gcc can't find a register (i386) 17 18 PIC on i386 uses a register to store the GOT (global offset table) address. 19 This register is usually %ebx, making it unavailable for use by inline assembly 20 (and also restricting the compiler's register usage when compiling C or C++ code). 21 So the following perfectly valid code will not build with the -fPIC flag: 22 23 void cpuid(uint32_t op, uint32_t reg[4]) 24 { 25 asm volatile("cpuid" 26 : "=a"(reg[0]), "=b"(reg[1]), "=c"(reg[2]), "=d"(reg[3]) 27 : "a"(op) 28 : "cc"); 29 } 30 31 Using -fPIC, gcc will say something around the lines of error: can't find a register in class 'BREG' 32 while reloading 'asm'. Several things need to be done to fix this: 33 34 * use a register other than %ebx 35 * save %ebx if it risks being clobbered by the assembly code, and don't tell gcc about %ebx at all (it doesn't need to know anyway) 36 * if we saved %ebx by pushing it on the stack, make sure the inline assembly code takes the new stack offset into account 37 38 And here is the PIC-compliant version: 39 40 **/ 2 41 3 42 //Executes the indicated subfunction of the CPUID operation … … 21 60 #else 22 61 //Use GCC assembler notation 23 asm 62 asm volatile 24 63 ( 25 " cpuid"26 : "=a" (a),27 "=b" (b),28 "=c"(c),29 "=d"(d)64 "pushl %%ebx \n\t" /* save %ebx */ 65 "cpuid \n\t" 66 "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */ 67 "popl %%ebx \n\t" /* restore the old %ebx */ 68 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) 30 69 :"a"(iFunction) 70 : "cc" 31 71 ); 32 72 #endif
Note: See TracChangeset
for help on using the changeset viewer.