arm-linux-ld的缺省linker script

本文展示了在RedHat系统下执行arm-linux-ld --verbose的输出结果,包含GNU ld版本及支持的仿真类型,重点呈现了内部链接器脚本,脚本中定义了输出格式、架构、入口等信息,还对各段(如.text、.data、.bss等)的布局和属性进行了详细设置。

在RedHat下通过执行 arm-linux-ld --verbose 得到:
GNU ld version 2.11.2 (with BFD 2.11.2)
  Supported emulations:
   armelf_linux
   armelf
using internal linker script:
==================================================
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
       "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
 SEARCH_DIR(/usr/local/arm/2.95.3/arm-linux/lib);
/* Do we need any of these for elf?
   __DYNAMIC = 0;    */
SECTIONS
{
  /* Read-only sections, merged into text segment: */
  . = 0x00008000 + SIZEOF_HEADERS;
  .interp     : { *(.interp)  }
  .hash          : { *(.hash)  }
  .dynsym        : { *(.dynsym)  }
  .dynstr        : { *(.dynstr)  }
  .gnu.version   : { *(.gnu.version) }
  .gnu.version_d   : { *(.gnu.version_d) }
  .gnu.version_r   : { *(.gnu.version_r) }
  .rel.init      : { *(.rel.init) }
  .rela.init     : { *(.rela.init) }
  .rel.text      :
    {
      *(.rel.text)
      *(.rel.text.*)
      *(.rel.gnu.linkonce.t.*)
    }
  .rela.text     :
    {
      *(.rela.text)
      *(.rela.text.*)
      *(.rela.gnu.linkonce.t.*)
    }
  .rel.fini      : { *(.rel.fini) }
  .rela.fini     : { *(.rela.fini) }
  .rel.rodata    :
    {
      *(.rel.rodata)
      *(.rel.rodata.*)
      *(.rel.gnu.linkonce.r.*)
    }
  .rela.rodata   :
    {
      *(.rela.rodata)
      *(.rela.rodata.*)
      *(.rela.gnu.linkonce.r.*)
    }
  .rel.data      :
    {
      *(.rel.data)
      *(.rel.data.*)
      *(.rel.gnu.linkonce.d.*)
    }
  .rela.data     :
    {
      *(.rela.data)
      *(.rela.data.*)
      *(.rela.gnu.linkonce.d.*)
    }
  .rel.ctors     : { *(.rel.ctors) }
  .rela.ctors    : { *(.rela.ctors) }
  .rel.dtors     : { *(.rel.dtors) }
  .rela.dtors    : { *(.rela.dtors) }
  .rel.got       : { *(.rel.got)  }
  .rela.got      : { *(.rela.got)  }
  .rel.sdata     :
    {
      *(.rel.sdata)
      *(.rel.sdata.*)
      *(.rel.gnu.linkonce.s.*)
    }
  .rela.sdata     :
    {
      *(.rela.sdata)
      *(.rela.sdata.*)
      *(.rela.gnu.linkonce.s.*)
    }
  .rel.sbss      :
    {
      *(.rel.sbss)
      *(.rel.sbss.*)
      *(.rel.gnu.linkonce.sb.*)
    }
  .rela.sbss     :
    {
      *(.rela.sbss)
      *(.rela.sbss.*)
      *(.rel.gnu.linkonce.sb.*)
    }
  .rel.sdata2    :
    {
      *(.rel.sdata2)
      *(.rel.sdata2.*)
      *(.rel.gnu.linkonce.s2.*)
    }
  .rela.sdata2   :
    {
      *(.rela.sdata2)
      *(.rela.sdata2.*)
      *(.rela.gnu.linkonce.s2.*)
    }
  .rel.sbss2     :
    {
      *(.rel.sbss2) 
      *(.rel.sbss2.*)
      *(.rel.gnu.linkonce.sb2.*)
    }
  .rela.sbss2    :
    {
      *(.rela.sbss2) 
      *(.rela.sbss2.*)
      *(.rela.gnu.linkonce.sb2.*)
    }
  .rel.bss       :
    {
      *(.rel.bss)
      *(.rel.bss.*)
      *(.rel.gnu.linkonce.b.*)
    }
  .rela.bss      :
    {
      *(.rela.bss)
      *(.rela.bss.*)
      *(.rela.gnu.linkonce.b.*)
    }
  .rel.plt       : { *(.rel.plt)  }
  .rela.plt      : { *(.rela.plt)  }
  .init          :
  {
    KEEP (*(.init))
  } =0
  .plt      : { *(.plt) }
  .text      :
  {
    *(.text)
    *(.text.*)
    *(.stub)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
    *(.gnu.linkonce.t.*)
    *(.glue_7t) *(.glue_7)
  } =0
  .fini      :
  {
    KEEP (*(.fini))
  } =0
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  .rodata   : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
  .rodata1   : { *(.rodata1) }
  .sdata2   : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
  .sbss2   : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN(0x8000) + (. & (0x8000 - 1));
  .data    :
  {
    __data_start = . ;
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1   : { *(.data1) }
  .eh_frame : { KEEP (*(.eh_frame)) }
  .gcc_except_table : { *(.gcc_except_table) }
  .ctors   :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    /* We don't want to include the .ctor section from
       from the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
   .dtors         :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .got    : { *(.got.plt) *(.got) }
  .dynamic       : { *(.dynamic) }
  /* We want the small data sections together, so single-instruction offsets
     can access them all, and initialized data all before uninitialized, so
     we can shorten the on-disk segment size.  */
  .sdata     :
  {
    *(.sdata)
    *(.sdata.*)
    *(.gnu.linkonce.s.*)
  }
  _edata = .;
  PROVIDE (edata = .);
  __bss_start = .;
  __bss_start__ = .;
  .sbss      :
  {
    PROVIDE (__sbss_start = .);
    PROVIDE (___sbss_start = .);
    *(.dynsbss)
    *(.sbss)
    *(.sbss.*)
    *(.gnu.linkonce.sb.*)
    *(.scommon)
    PROVIDE (__sbss_end = .);
    PROVIDE (___sbss_end = .);
  }
  .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.  */
   . = ALIGN(32 / 8);
  }
  . = ALIGN(32 / 8);
  _end = .;
  _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
  PROVIDE (end = .);
  /* Stabs debugging sections.  */
  .stab 0 : { *(.stab) }
  .stabstr 0 : { *(.stabstr) }
  .stab.excl 0 : { *(.stab.excl) }
  .stab.exclstr 0 : { *(.stab.exclstr) }
  .stab.index 0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment 0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* These must appear regardless of  .  */
}


==================================================

<think>嗯,用户现在问的是关于在交叉编译时使用make命令并指定各种工具链参数的含义。我需要先回顾一下之前的历史对话。之前用户询问了如何在ARM架构上交叉编译H.264库,比如x264,我详细介绍了步骤,包括安装工具链、配置、编译安装等。现在用户可能是在实际应用中遇到了具体的make命令参数的问题,想了解每个参数的意义。 首先,用户给出的命令是:make CC=arm-linux-gcc AR=arm-linux-ar LD=arm-linux-gcc RANLIB=arm-linux-ranlib STRIP=arm-linux-strip。这看起来是在调用make时覆盖了默认的编译工具,指定了交叉编译器的各个工具。我需要逐个解释每个参数的作用,以及它们在整个编译过程中的角色。 接下来,我需要确保每个变量的含义准确无误。CC是C编译器,AR是静态库归档工具,LD是链接器,RANLIB用于生成静态库的索引,STRIP用于去除调试符号。这些都是在交叉编译时常用的变量,用来覆盖项目默认的本地工具链,确保使用ARM架构的工具链。 然后,我需要考虑用户可能的背景。用户可能正在尝试手动指定这些工具,而不是通过配置脚本(如configure)。这可能是因为某些项目可能需要手动设置,或者用户遇到configure无法正确识别工具链的情况。需要解释这些参数的重要性,以及为什么在交叉编译时需要指定它们。 另外,用户可能在之前的步骤中按照指导使用了交叉编译工具链,但在实际执行make时遇到了问题,比如工具链未正确应用,导致编译出的仍然是x86的可执行文件。这时候,手动指定这些变量可以确保整个构建过程使用正确的工具。 还需要注意用户可能的误区。例如,是否所有项目都支持通过make参数指定这些变量?或者是否需要同时设置其他环境变量,如CXX、CFLAGS、LDFLAGS等。这时候可能需要提醒用户,不同项目的构建系统可能不同,有些可能需要更全面的配置。 此外,用户可能没有意识到有些项目在configure阶段已经确定了工具链,如果在make阶段再次覆盖,是否会导致冲突?或者是否需要两者结合使用,比如在configure时指定--host和交叉编译前缀,同时在make时覆盖某些工具?需要指出这一点,并建议用户优先使用项目的配置脚本,除非必要才手动指定。 最后,用户可能希望了解如何验证这些参数是否生效,比如检查生成的中间文件或最终二进制文件的架构是否正确,或者通过查看构建日志确认使用的工具链是否正确。可能需要给出一些验证的方法,如使用file命令检查二进制文件类型,或者查看make的输出信息。 总结来说,用户的需求是理解这些make参数的具体作用,确保交叉编译的正确性,并可能解决在编译过程中遇到的问题。我的回答需要详细解释每个参数,说明其在编译流程中的作用,并给出实际应用的注意事项,帮助用户正确应用这些参数,避免常见错误。</think>在使用 `make` 进行交叉编译时,通过 `CC=arm-linux-gcc AR=arm-linux-ar ...` 的形式指定工具链参数,是为了覆盖构建系统默认的本地工具链,强制使用针对目标架构(如ARM)的交叉编译工具。以下是每个参数的具体含义和作用: --- ### **参数详解** #### **1. `CC=arm-linux-gcc`** - **含义**:指定 **C编译器**(C Compiler)为 `arm-linux-gcc`。 - **作用**: 用于编译C语言源代码。交叉编译时需替换为针对目标架构(如ARM)的编译器,确保生成的二进制文件兼容目标平台(而非宿主机x86/x64)。 #### **2. `AR=arm-linux-ar`** - **含义**:指定 **静态库归档工具**(Archiver)为 `arm-linux-ar`。 - **作用**: 用于将多个目标文件(`.o`)打包成静态库(`.a`)。交叉编译时必须使用目标平台的归档工具,否则生成的静态库可能无法在目标设备上链接。 #### **3. `LD=arm-linux-gcc`** - **含义**:指定 **链接器**(Linker)为 `arm-linux-gcc`(或直接指定 `arm-linux-ld`)。 - **作用**: 负责将目标文件和库链接为最终可执行文件或动态库。直接使用 `arm-linux-gcc` 调用链接器可能更便捷(隐含调用 `ld` 并自动传递标准库路径)。 #### **4. `RANLIB=arm-linux-ranlib`** - **含义**:指定 **静态库索引生成工具**(Random Library Generator)为 `arm-linux-ranlib`。 - **作用**: 为静态库(`.a`)生成符号索引,加速链接过程。若未指定交叉编译版本的 `ranlib`,可能因索引格式不兼容导致链接错误。 #### **5. `STRIP=arm-linux-strip`** - **含义**:指定 **符号剥离工具**(Strip Tool)为 `arm-linux-strip`。 - **作用**: 移除可执行文件或库中的调试符号(如 `.debug` 段),减少文件体积。需使用目标平台的 `strip` 工具,否则可能损坏二进制文件。 --- ### **典型应用场景** 此命令用于 **直接覆盖构建系统的默认工具链**,常见于以下情况: 1. **未使用 `./configure` 配置工具链**: 某些项目可能未通过 `./configure` 脚本配置交叉编译参数,需手动指定工具链。 2. **覆盖配置阶段的默认值**: 即使已运行 `./configure`,也可在 `make` 阶段强制使用特定工具链。 3. **简化小型项目的编译**: 对于简单的 `Makefile` 项目,直接通过命令行参数指定工具链更快捷。 --- ### **示例命令** ```bash make \ CC=arm-linux-gcc \ AR=arm-linux-ar \ LD=arm-linux-gcc \ RANLIB=arm-linux-ranlib \ STRIP=arm-linux-strip ``` --- ### **注意事项** #### 1. **工具链路径问题** - 需确保交叉编译工具(如 `arm-linux-gcc`)已正确安装,且在系统 `PATH` 环境变量中,否则需指定绝对路径(如 `/opt/toolchain/bin/arm-linux-gcc`)。 #### 2. **依赖其他工具** - 若项目依赖其他工具(如 `CXX` 用于C++编译),需补充指定: ```bash CXX=arm-linux-g++ ... ``` #### 3. **与 `./configure` 配合使用** - 对于支持 `./configure` 的项目(如 `x264`),更推荐通过 `--host` 和 `--cross-prefix` 配置交叉编译,例如: ```bash ./configure --host=arm-linux --cross-prefix=arm-linux- ``` 这会自动设置 `CC`、`AR` 等参数,避免手动指定。 #### 4. **验证工具链兼容性** - 编译完成后,可通过 `file` 命令检查生成文件的架构: ```bash file output_binary # 期望输出:ELF 32-bit LSB executable, ARM... ``` --- ### **常见问题** #### **Q1: 为何要指定 `LD=arm-linux-gcc` 而不是 `arm-linux-ld`?** - 直接使用 `arm-linux-gcc` 调用链接器,可以自动传递标准库路径(如 `libc`),避免手动指定 `-L` 参数,简化编译流程。 #### **Q2: 如果漏掉某些参数(如 `RANLIB`)会怎样?** - 可能导致静态库索引生成失败,链接时出现 `undefined reference` 错误。建议完整指定所有工具链参数。 #### **Q3: 是否需要同时设置环境变量(如 `CROSS_COMPILE`)?** - 部分项目支持通过 `CROSS_COMPILE=arm-linux-` 自动推导工具链前缀(如 `CC=$(CROSS_COMPILE)gcc`),但需具体项目支持。手动指定各参数更通用。 --- ### **总结** 通过 `CC`、`AR`、`LD` 等参数显式指定交叉编译工具链,是确保生成文件兼容目标平台(如ARM)的关键步骤。尤其适用于未通过 `configure` 脚本配置的简单项目或需手动覆盖默认工具链的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值