读书人

M$VC怎么生成位置无关代码(-fpic)

发布时间: 2012-02-17 17:50:42 作者: rapoo

M$VC如何生成位置无关代码(-fpic)

C/C++ code
gcc 系列好像都很简单, 不知道最新的M$VC有这个选项没....比如这样子:#include <stdio.h>int main(){#ifdef __i386__    ((void(*)( int(*)(const char*)))(    "\x55\x89\xE5\x53\xE8\x1B\x00\x00\x00\x81\xC3\x77\x7F\xFB\xF7\x83"    "\xEC\x14\x8D\x83\xA8\x80\x04\x08\x89\x04\x24\xFF\x55\x08\x83\xC4"    "\x14\x5B\x5D\xC3\x8B\x1C\x24\xC3\x48\x65\x6C\x6C\x6F\x20\x57\x6F"    "\x72\x6C\x64\x21\x00"))( puts );#elif defined( __arm_le__ )    ((void(*)( int(*)(const char*)))(        "\x08\x40\x2D\xE9\x00\x30\xA0\xE1\x10\x00\x9F\xE5\x00\x00\x8F\xE0"        "\x0F\xE0\xA0\xE1\x13\xFF\x2F\xE1\x08\x40\xBD\xE8\x1E\xFF\x2F\xE1"        "\x10\x00\x00\x00\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21"        "\x00\x00\x00\x00"))( puts );#endifreturn 0;}-----------------------------shell code 是这样子生成的:void foobar( void(*fun)(char*) ){    fun( "Hello World!" );}gcc -m32 -O3 1.c -c -fpic ; ld -melf_i386 -e foobar 1.o -o 1.elf ; objcopy -O binary 1.elf 1.binarm-none-eabi-gcc -O3 -c 1.c -fpic ; arm-none-eabi-ld -e foobar 1.o -o 1.elf ; arm-none-eabi-objcopy.exe -O binary 1.elf 1.bin-----------------------------难道我生成在M$VC跑的程序也要用gcc生成代码么, 没天理啊...


[解决办法]
集思广益......
[解决办法]
gcc 系列好像都很简单, 不知道最新的M$VC有这个选项没....

比如这样子:
#include <stdio.h>

[解决办法]
是不是代码要在不同芯片处理器上跑?vs有编译选择,可以选不同的芯片,还有位数.
[解决办法]
我没看懂lz的意思

按字面意思,这个不是位置无关的范畴(-fPIC),而是编译器内部预处理的范畴

vc里如果编译i386的就在编译开关里加入 /D "__i386__"
如果编译arm的就在编译开关里加入 /D "__arm_le__"

你可能问gcc为什么不用加呢,这个是编译gcc时内部就预定义的
比如gcc,你在shell里输入
gcc -posix -E -dM - </dev/null
那么就可以知道gcc默认有哪些预处理,这里面必定有 __i386__

类似的,
arm-none-eabi-gcc -posix -E -dM - </dev/null
里面必定有 __arm_le__
[解决办法]
关于-fPIC,我反倒说不清楚了,一般只要记住,在Linux系统里(大部分系统,有些不支持),生成shared库时必须加入-fPIC
[解决办法]
哦,基本明白了

还有一个疑问,vc不能调用elf,你的gcc是在win下用的还是Linux下?
vc用的通用版本还是ce或者别的?
[解决办法]
每天回帖即可获得10分可用分!
[解决办法]
探讨

这个objcopy出来的代码是二进制格式, 不是elf的, 不依赖于可执行文件格式就可以运行. 当然也可以在VC里运行, 你把它想象成一段 bootloader 的代码就可以了...

[解决办法]
我明白了,按目前的工具来说,是无解的,因为vc的link只有设置基址的方式
[解决办法]
探讨

现在弄起来太麻烦, 我先在 win 下编译一个 linux 的 cross-toolchain 先 ....

[解决办法]
windows to Linux的cross toolchain很多,lz可以下载一个
[解决办法]
这个版本还可以
http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20NonWin/vityan/

我原来想自己编译来,搜了下已经有了,性能还行,就没费这事
[解决办法]
learning......


[解决办法]
cygwin显然慢啊,我现在很少用cygwin了,基本上就是msys+mingw/mingw64项目,不过比linux原生的gcc编译速度还要慢一截,但是比cygwin的编译速度快多了
[解决办法]

探讨

唉, cygwin都用了6年多了, 不能因为稍微有点慢就换吧... 还是先凑合着...
build_kernel_headers build_binutils 过了, 正在跑 build_static_gcc , 还在step1 , 按这个编译速度估计, 估计还得30分钟能编译好第一遍gcc , 编译好了我就不用起 VMWare 了...

[解决办法]
学习!!!!!!!!!
[解决办法]
MSVC除了cl /?下的那堆选项再外加program指令,看起来并有楼主所需要的。
不像开源的GCC:开源的好处就是参数多的吓人。
[解决办法]
探讨

MSVC除了cl /?下的那堆选项再外加program指令,看起来并有楼主所需要的。
不像开源的GCC:开源的好处就是参数多的吓人。

[解决办法]
不懂啊
[解决办法]
探讨

引用:

MSVC除了cl /?下的那堆选项再外加program指令,看起来并有楼主所需要的。
不像开源的GCC:开源的好处就是参数多的吓人。


Loaden你pragma写错了……

[解决办法]
额.....
[解决办法]
探讨

M$VC link 可以merge数据段, 我试试看 merge .rodata .text 看看行不行 ... link 能直接生成2进制格式文件没...
cygwin 下 static gcc 好了, 不过编译glibc有点小毛病, 唉... 我还是在 linux 下编译好 glibc 然后在来到 cygwin 下编译 final_gcc 算了, 这样编译速度也快很多, 咋开始我忘掉了.……

[解决办法]
探讨

唉, 我忘了cl生成的代码不是位置无关的, merge 了代码段也没用,唉...

[解决办法]
汗,要不你直接用反汇编工具把它汇编改掉算了……
[解决办法]
探讨

简单的代码手工改肯定没问题三, 如果是个复杂的, 包含了很多文件的上万行的代码, 改起来会死人的...
看来还是用gcc生成这些代码算了, 不过感觉上很怪异啊...

[解决办法]
study
[解决办法]
MS的编译器没有与gcc -fpic对应或者类似的选项。不过PE文件提供了重定位代码的全部条件,按照需要就可以重定位代码了。另外,按照一定的编码规范,对于规模不大的代码,cl.exe也可以生成位置无关的代码。
这里提供了简单的MS编译器生成完全重定位代码的方法。最后,还希望楼主多多研究,多多发现,并把更多的方法公开给大家,呵呵。
[解决办法]
啥情况,一口气那么多人回帖。。。
[解决办法]
探讨

啥情况,一口气那么多人回帖。。。

[解决办法]
道我生成在M$VC跑的程序也要用gcc生成代码么
[解决办法]
坐下看看
[解决办法]
可以选不同的芯片,还有位数
[解决办法]
学习。
[解决办法]
这个看起来很靠谱 回家试验下
[解决办法]
kankan!
[解决办法]
学习。



[解决办法]
挺好。。。学习 了
[解决办法]
恩恩,学习学习
[解决办法]
CPU厂商不止这些吧
[解决办法]
不知道win下面的dll是否是生成的位置无关的代码
[解决办法]
查到msdn上面这么说:默认情况下,面向 Itanium 的 Visual C++ 编译器会生成与位置无关的代码。/QIPF_noPIC 将生成具有位置相关代码的映像。


[解决办法]
应该不是因为CPU指令集类型的缘故吧?没理由 gcc可以做到,vc做不到啊。
[解决办法]
难道是vc想追求那点性能所以....
[解决办法]

探讨应该是M$总是使用PE格式, 反正PE格式带着重定位信息, 位置有关无关无所谓...
gcc却要照顾各种各样的格式, elf , a.out , bin 都要, 如果都是生成 elf 那就无所谓了, 如果是其他的不支持重定位的格式, 位置无关就很重要了...

读书人网 >C++

热点推荐