标签: linker-scripts

如何使用OBJCOPY的--add-section开关?

确实有两个问题与--add-section的使用有关。简单的标题中。根据我的阅读,我还无法弄清楚如何执行--add-section。

要使用add-section,我必须传递一个部分名称。如果我使用现有的节名称,程序将响应“无法添加节'.data':文件格式错误”。也许我只需要传递另一个参数。如果我希望使用新的节名称,则会警告“分配的节'.blob'不在段中”。

现在,除了“不在细分市场”警告之外,我还需要我的功能才能正常工作。我想弄清楚是否存在将这个Blob放入可执行文件的合法方法。我会链接进去,但这不是那么容易,因为我要添加的数据是从可执行文件本身的内容生成的。

第二个问题确实是我关心的问题。给定链接完成后才能计算blob,有没有一种方法可以执行以下操作。

  1. 链接ELF文件
  2. 从ELF文件和其他数据生成Blob
  3. 将blob添加到ELF文件,以便在运行时将其加载到内存中的正确位置

    objcopy --add-section .blob=blob.o \ --set-section-flags .blob=alloc,contents,load,readonly \ --change-section-address .blob=ADDRESS \ program.elf program.blobbed.elf

我很乐意将一部分和/或片段添加到ELF文件中,作为链接的一部分,并在其中插入该blob。我不确定该怎么做。

我想到可以通过第二个链接来完成此任务,但是objcopy会更干净。

  1. 链接ELF文件
  2. 从ELF文件和其他数据生成Blob
  3. 重新链接包括新的blob.o的ELF文件

更新:只要重新链接在第一个链接所产生的程序部分中没有改变,则最后一种策略可能是可行的。它不是第一次尝试,但是有可能解决它。因此,希望使用--add-section来添加该blob而不是通过第二个链接。

embedded linker-scripts binutils

5
推荐指数
1
解决办法
4740
查看次数

如何在ld链接描述文件中使用INCLUDE命令

我有两个链接器脚本:common.ld它们定义了一些符号,并app.ld使用这些定义来定位这些部分.

如果我只将两个文件一起捕获,并将其提供给ld(通过gcc),它就可以了.如果我使用INCLUDE命令:

包括common.ld

我收到错误:

ld.exe:flags中的语法无效

collect2:ld返回1退出状态

我做错了什么?包含另一个加载脚本的正确语句是什么?


来自http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html#IDX204:

INCLUDE文件名

此时包括链接描述文件名.将在当前目录以及使用-L选项指定的任何目录中搜索该文件.您可以将呼叫嵌套到INCLUDE最多10级.

注意:我在Windows 7 PC上运行,使用Code Red的arm gcc工具,完整版:

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.6.2 20121016 (release) [ARM/embedded-4_6-branch revision 192487

gcc include linker-scripts

5
推荐指数
1
解决办法
8139
查看次数

将 memcpy 移动到另一个代码部分

我正在构建一个旨在在 ARM Cortex-M0+ 微控制器上运行的软件。它包括一个 USB 引导加载程序,在调用函数时作为辅助程序运行。我在编译期间插入函数时遇到问题memcpy

背景

链接描述文件是一切开始的地方。其中大部分都是非常简单和标准的。该程序也存储在那里.text并从那里执行。所有内容都.text存储在芯片的闪存部分。

奇怪的是引导加载程序运行的部分。为了能够写入所有闪存而不覆盖引导加载程序代码,我的引导加载程序入口点将引导加载程序的副本启动到微控制器的 SRAM 部分,然后从那里执行它。这样,引导加载程序就可以安全地擦除设备上的所有闪存,而不会无意中删除自身。

这是通过在链接器脚本中执行伪造的“覆盖”来实现的(真实的与OVERLAY我的用例不太匹配):

/**
 * The bootloader and general ram live in the same area of memory
 * NOTE: The bootloader gets its own special RAM space and it lives on top
 * of both .data and .bss.
 */

_shared_start = .;
.bootloader _shared_start : AT(_end_flash)
{
    /* We keep the bootloader and its data together */
    _start_bootloader_flash = LOADADDR(.bootloader);
    _start_bootloader = .; …
Run Code Online (Sandbox Code Playgroud)

c linker gcc arm linker-scripts

5
推荐指数
1
解决办法
1053
查看次数

将嵌入式程序拆分为内存中的多个部分

我正在开发一个嵌入式系统(Stellaris Launchpad)并编写一个简单的操作系统(作为一个爱好项目)。使用的工具链是 gcc-none-eabi。

我的下一步是习惯 MPU 以允许内核阻止用户程序更改特定数据。我有一堆 C 文件,我把它们分成两部分:内核和其他。我有以下链接器脚本可以开始:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH

    .data : /*AT(ADDR(.text) + SIZEOF(.text))*/ /*contains initialized data*/
    {
        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > SRAM AT > FLASH

    .bss : AT (ADDR(.data) + SIZEOF(.data)) /*contains unitialized data (should be …
Run Code Online (Sandbox Code Playgroud)

embedded linker linker-scripts

5
推荐指数
1
解决办法
4786
查看次数

什么是绝对符号以及如何在 C 中定义它?

在手册页中nm。它说

\n\n
\n

\xe2\x80\x9cA\xe2\x80\x9d 符号的值是绝对的,不会因进一步链接而改变。

\n
\n\n

但是,我不知道这意味着什么。如何在 C 中定义一个变量或其他东西以使其值绝对?

\n\n

test.c如果我在其文件范围内声明一个变量

\n\n
int a;\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在 的输出中nm,a 的条目在我的机器上将如下

\n\n
int a;\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我想知道我该怎么做才能使nm变量的输出 \xe2\x80\x9cA\xe2\x80\x9d 。而且我不知道 \xe2\x80\x9cabsolute\xe2\x80\x9d 是什么意思。

\n

c linker relocation ld linker-scripts

5
推荐指数
1
解决办法
3592
查看次数

如何使用 phdrs 命令修复链接描述文件中的重叠部分?

我正在尝试制作一个简单的操作系统内核的上半部分。当像我一样使用 Grub 作为引导加载程序时,还必须有一些下半部分(32 位)代码。因为我想让这个 32 位代码尽可能简短,所以我不想在其中编写一个 ELF 加载程序只是为了加载 64 位代码,因为这显然是荒谬的(这实际上是最常见的解决方案,但我如果可能的话想避免它)。

我发现链接描述文件允许加载与虚拟地址不同的地址。这很有用,这样我就可以加载 64 位部分以适应小型二进制文件,然后使用虚拟内存将正确的虚拟地址映射到它们加载的物理地址。除了低文本部分未放入文本段之外,此方法有效。入口点_start位于本节中。

除非我在命令中指定文本段,否则我无法将低文本部分(所在_start位置)放入文本段中PHDRS。当然,使用此命令使链接器决定放弃生成通常预期的段。当我也这样做时,这些部分最终会重叠,我不完全确定为什么。我按照数据、rodata、文本的顺序指定段,并且这些部分是相同的,但它们的加载内存地址是用rodata和交换的数据分配的,并且所有三个都是重叠的。

这是我的链接器脚本:

ENTRY(_start)

PHDRS {
    .low PT_LOAD FILEHDR PHDRS;
    .data PT_LOAD;
    .rodata PT_LOAD;
    .text PT_LOAD;
}

SECTIONS {
    . = 1M;

    .data_low BLOCK(4K) : ALIGN(4K) {
        *(.bss_low)
    } : .low

    .rodata_low BLOCK(4K) : ALIGN(4K) {
        KEEP(*(.multiboot_low))
        *(.rodata_low)
    } : .low

    .text_low BLOCK(4K) : ALIGN(4K) {
        *(.text_low)
    } : .low

    .stack 0xC0000000 : AT(0x200000) ALIGN(4K) {
        *(.bootstrap_stack)
    } : .data
    _LADD_ = …
Run Code Online (Sandbox Code Playgroud)

c assembly linker elf linker-scripts

5
推荐指数
0
解决办法
3046
查看次数

链接描述文件:定义符号大小和类型

我知道我可以在我的(GNU binutils )链接器脚本中定义一个符号/标签,ld只需为符号分配一个地址,如下所示:my_symbol = 0xdeadbeef; 但是,如果我想给该符号一个大小(如0x02和类型(如OBJECTFUNC)怎么办?它会显示在符号表 ( .symtab) 中吗?

symbols elf linker-scripts

5
推荐指数
0
解决办法
552
查看次数

链接器:将除两个之外的所有函数移动到特定的内存区域

我正在为 PIC32MX 微控制器开发固件。程序存储器应分为三段:

  • 第一节:中断服务程序和主函数(startup_region
  • 第 2 部分:剩余程序存储器的 50% ( program1)
  • 第 3 部分:剩余程序存储器的 50% ( program2)

固件仅存储在第 2 节或第 3 节中。另一个保留用于将来的更新。因此,活动区域可以安全地覆盖另一个区域以存储更新。一个配置位被翻转,第 0 部分的 main() 函数现在在重启时跳转到另一个程序。

因此,我需要链接器将除isr和之外的所有函数main放入第 1 节,将其他所有函数放入第 2 节。第 3 节必须完全留空,因为将来可能会覆盖它。

我已经尝试通过修改默认链接器脚本来实现这一点,但是我没有成功。

链接脚本.ld:

/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
  /* [...] */
  .text :
  {
    /* isr() and main() should be at the very first locations in program memory */
    *(.text.isr)
    *(.text.main)
    /* [...] */
    . = …
Run Code Online (Sandbox Code Playgroud)

c linker linker-scripts binutils

5
推荐指数
1
解决办法
112
查看次数

使用 gnu ld 链接器脚本覆盖隐藏的符号可见性

TL;DR:我可以使用 GNUld链接器--version-script或其他一些方法将具有hidden可见性(由于-fvisibility=hidden或显式__attribute__)的选定符号提升回default可见性,以便它们在共享库的全局符号表中可用?

有什么方法可以告诉 gnu ld version-scriptHIDDENglobal:version-script 部分中的符号提升为DEFAULT可见性?


对于一个相当奇怪的系统,我需要链接一个共享库,以便所有非静态函数符号都具有默认可见性,但所有其他符号都获得“隐藏”可见性,除非用适当的可见性属性明确注释。

如果有办法告诉gcc类似(无效的虚构语法)-fvisibility=hidden -fvisibility-functions=default,那就太完美了。

使用 gcc 编译 -fvisibility=hidden将使所有未注释的符号隐藏可见性。

所以我想我会使用链接器版本脚本将在 ELF 对象中具有全局范围和隐藏可见性的函数提升为默认(全局)可见性。

但是,当在链接器版本脚本global部分中命名符号时,GNU LD 似乎不会更改可见性属性。该local部分中的符号被隐藏,但该部分中已经隐藏的符号global不会被提升为default.

中商会

给定简化对象(宏扩展等):

/* Public global variables are annotated */
extern int exportvar __attribute__ ((visibility ("default")));
int exportvar;

/* Internal ones are not annotated */
extern int nonexportvar;
int …
Run Code Online (Sandbox Code Playgroud)

linker gcc llvm ld linker-scripts

5
推荐指数
0
解决办法
653
查看次数

如何使自定义部分可执行(.text 除外)

基本的 Hello World 就像之前在 x86_64 Linux 上多次看到的那样:

global my_start_symbol 

section .my_section

my_start_symbol:
        mov rax, 1
        mov rdi, 1 
        mov rsi, msg
        mov rdx, msg_len
        syscall 

        mov rax, 60
        xor rdi, rdi
        syscall

section .rodata:
msg: db "Hello, world!", 10 
msg_len: equ $ - msg
Run Code Online (Sandbox Code Playgroud)

我当前的ld链接器脚本:

__linux_mmap_min_addr = 0x10000;

ENTRY(my_start_symbol)

MEMORY
{
  rom (rx) : ORIGIN = 0, LENGTH = 512K
}

SECTIONS 
{
  . = __linux_mmap_min_addr;
  .my_section : 
  { 
    *(.my_section*) 
  } > rom
  .rodata : 
  {
    *(.rodata*) 
  } …
Run Code Online (Sandbox Code Playgroud)

linux x86-64 nasm ld linker-scripts

5
推荐指数
1
解决办法
842
查看次数

标签 统计

linker-scripts ×10

linker ×6

c ×4

gcc ×3

ld ×3

binutils ×2

elf ×2

embedded ×2

arm ×1

assembly ×1

include ×1

linux ×1

llvm ×1

nasm ×1

relocation ×1

symbols ×1

x86-64 ×1