zoukankan      html  css  js  c++  java
  • 编译连接优化

    最近在做exe体积优化的事情,于是把vc10编译器连接器有关的选项都过了一遍

    一般情况下,使用/O1做最小体积优化

    根据msdn介绍,/O1等于/Og /Os /Oy /Ob2 /Gs /GF /Gy,也就是说
    /O1 会自动开启 <Global Optimization>/Og、<Favor small code>/Os、<Omit Frame Pointers> /Oy、<string pooling>/GF、/Gs(Control Stack Checking Calls)、<Enable Function-Level Linking> /Gy
    并且/O1 会自动关闭 <basic runtime checks>、<smaller type checks>

    这些参数作用分别是

    /Og表达式合并,变量寄存器化,循环优化,nrvo

    /Os优化以体积优先

    /Oy令编译器编译函数时,prologue不产生push ebp; mov ebp esp,epilogue不产生pop ebp代码,函数体内不产生基于ebp寻址的代码,对调试程序有一定影响,特别是当程序使用动态栈内存分配时

    /Ob2,展开inline函数

    /GF,不用说了

    /Gs,默认是4k,当函数栈变量大于4k时,调用_chkstk函数分配更多的栈空间

    /Gy,合并相同的函数,例如不同命名空间内相同的函数、模板类的非模板函数;去除没有使用的函数

    接下来需要设置以下选项,使exe体积更小
    关闭<inline fuction expansion> /Ob0,禁止编译器展开标记为inline的函数,个人认为,人为的inline不可取,应更相信编译器及连接器的能力
    开启<whole program optimization> /GL,用于支撑连接器/LTCG
    禁止<enable c++ exceptions> no/EH,编译参数不要加上任何/EH相关的参数
    禁止<buffer security check> /GS- 不插入缓冲区检查代码

    缓冲区溢出检查原理,在函数栈内,返回地址与栈变量间插入4字节标记,进入函数时设置值,函数返回时检查该值是否被修改,如果被修改,就证明函数栈溢出

    可参考msdn http://msdn.microsoft.com/library/aa290051.aspx
    开启/Gy后,需要配合连接器 /OPT:REF /OPT:ICF
    禁止<Enable Run-Time Type Information> /GR- 不使用C++ RTTI,对极少数使用dynamic_cast有影响

    连接器选项
    开启<merge section> /MERGE .rdata=.text 合并相同属性PE段,减少PE文件体积;不能合并不同属性段,.rsrc段必须单独存在
    禁止<randomized base address> /DYNAMICBASE:NO 注意,randomized base address是vista引入的一种防御缓冲区溢出攻击的手段

    根据msdn,vista开始,dll加载的地址不再是固定不变,在256个可能的地址内随机选择一个,这样做使缓冲区溢出攻击的目标地址变得不可确定。

    注意,若开启这个选项,就表明这个模块支持rba,加载地址必然是随机;但不开启,并不代表加载地址不变,windows加载dll时如果地址冲突,会选择新的地址加载,这个能力由下面这个选项决定是否开启
    开启<fixed base address> /FIXED 与上一个选项联合作用,使连接器不生成PE的.reloc段,减少PE文件体积;注意只针对exe,dll不应该这样设置;如果dll不支持可变基址,地址冲突时将导致dll无法加载
    不支持<image has safe exception handlers> /SAFESEH:NO 不创建SEH表,safe exception handlers table是一种防御缓冲区溢出攻击的手段;注意,启用安全SEH处理表后,只有在表内登记的异常情况才允许执行异常处理例程,用于防止缓冲区溢出攻击改写异常处理例程地址。
    开启<link-time code generation> <profile guided optimization> /LTCG LTCG:PGI PGO 连接器代码生成,可在模块间进行代码优化;应优先使用PGI PGO,如果条件不允许,单独使用LTCG也能得到比较好的效果

  • 相关阅读:
    gym 101064 G.The Declaration of Independence (主席树)
    hdu 4348 To the moon (主席树 区间更新)
    bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)
    ACM-ICPC 2018 南京赛区网络预赛 G Lpl and Energy-saving Lamps(线段树)
    hdu 4417 Super Mario (主席树)
    poj 2236 Wireless Network (并查集)
    查看 scala 中的变量数据类型
    彻底搞定Maven
    Spark :【error】System memory 259522560 must be at least 471859200 Error initializing SparkContext.
    ip地址、子网掩码、网关与网卡、DNS的区别及用处
  • 原文地址:https://www.cnblogs.com/rickerliang/p/4193091.html
Copyright © 2011-2022 走看看