对于LD脚本的理解

脚本模型:

 

ENTRY(__entry)

 

SECTIONS
{
 . = 0x0 + SIZEOF_HEADERS;
 
 .hash : {*(.hash)}
 
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rel.dyn        :
    {
      *(.rel.init)
      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
      *(.rel.fini)
      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
      *(.rel.ctors)
      *(.rel.dtors)
      *(.rel.got)
      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
    }

  .rel.plt        : { *(.rel.plt) }
  .dynsym         : { *(.dynsym) }
  .entry_init : {*(.entry_init)}
  __param_addr = . ;
    .text xxx          : AT( __param_addr + 100)@此处将会出现问题(将导致.plt以及.got覆盖.text),原因为__param_addr 为运行态当前地址,则当使用AT指明.text段加载地址为当前运行地址再加上100,但后面的.plt以及got段又使用默认的加载地址(即加载地址与运行地址相等),这样就会在链接的时候造成.text段有100字节的加载地址与.ply段重叠! 
  {
    *(.text .stub .text.* .gnu.linkonce.t.*)
    KEEP (*(.text.*personality*))
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
    *(.rodata.str1.4)
    *(.rodata)
  } =0
 
  .plt            : { *(.plt) }
  .got            : { *(.got.plt) *(.got) }
  .data           :
  {
    __data_start = . ;
    *(.data .data.* .gnu.linkonce.d.*)
    KEEP (*(.gnu.linkonce.d.*personality*))
    SORT(CONSTRUCTORS)
  }
  __bss_start__ = .;
 .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 32 / 8 : 1);
  }
 __bss_end__ = .;
 end = .;
 _end = .;
}

 

要点:.textxxx           : AT( __param_addr + 100)@此处将会出现问题(将导致.plt以及.got覆盖.text),原因为__param_addr 为运行态当前地址,则当使用AT指明.text段加载地址为当前运行地址再加上100,但后面的.plt以及got段又使用默认的加载地址(即加载地址与运行地址相等),这样就会在链接的时候造成.text段有100字节的加载地址与.ply段重叠! 
  {
    *(.text .stub .text.* .gnu.linkonce.t.*)
    KEEP (*(.text.*personality*))
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
    *(.rodata.str1.4)
    *(.rodata)
  } =0


:.textxxx  为链接脚本任意命名,可在反汇编中查询到此段名称,但*(.text .stub .text.* .gnu.linkonce.t.*)中的.text段为各.o中真实的.text段内容(gcc将会默认代码段为.text,默认全局可读写变量数据为.data段,默认只读全局数据为.rodata段,默认未初始化的可读写数据为.bss段),如果在某个函数前面加上__attribute__ ((section(".MAIN_DATA"))) 则将改变函数默认的.text段,而归为新命名的.MAIN_DATA段,同理,如果在某个全局变量前面加__attribute__ ((section(".MAIN_DATA")))则该变量由原来默认的.data段变为新命名 的.MAIN_DATA段。

__param_addr = . ;的写法需要注意为 xx = , ;  而非xx=.;


z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值