C 如何使用链接器脚本指定特定节的内存地址?

C 如何使用链接器脚本指定特定节的内存地址?,c,assembly,ld,C,Assembly,Ld,我正在从事一个大型项目,该项目涉及编写一个Perl脚本来转换汇编文件,我试图确定转换后汇编文件的外观,以及编译它们的过程。我一直很难找到一个简单的例子。我从一个简单的程序开始,fib.c。我编译了它,然后添加了一个名为“跳板”的部分 .file "fib.c" .text .globl fib .type fib, @function fib: .LFB0: .cfi_startproc p

我正在从事一个大型项目,该项目涉及编写一个Perl脚本来转换汇编文件,我试图确定转换后汇编文件的外观,以及编译它们的过程。我一直很难找到一个简单的例子。我从一个简单的程序开始,fib.c。我编译了它,然后添加了一个名为“跳板”的部分

        .file   "fib.c"
        .text
        .globl  fib
        .type   fib, @function
fib:
.LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        pushl   %ebx
        subl    $20, %esp
        cmpl    $0, 8(%ebp)
        jne     .L2
        .cfi_offset 3, -12
        movl    $1, %eax
        jmp     .SB1
.LBL1:
        jmp     .L3
.L2:
        cmpl    $1, 8(%ebp)
        jne     .L4
        movl    $1, %eax
        jmp     .SB2
.LBL2:
        jmp     .L3
.L4:
        movl    8(%ebp), %eax
        subl    $1, %eax
        movl    %eax, (%esp)
        call    fib
        movl    %eax, %ebx
        movl    8(%ebp), %eax
        subl    $2, %eax
        movl    %eax, (%esp)
        call    fib
        addl    %ebx, %eax
.L3:
        addl    $20, %esp
        popl    %ebx
        .cfi_restore 3
        popl    %ebp
        .cfi_def_cfa 4, 4
        .cfi_restore 5
        ret
        .cfi_endproc
.LFE0:
        .size   fib, .-fib
        .section        .rodata
.LC0:
        .string "Usage: fib <n>\n"
.LC1:
        .string "f(%d) = %d\n"
        .text
        .globl  main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        andl    $-16, %esp
        subl    $32, %esp
        cmpl    $2, 8(%ebp)
        je      .L6
        movl    stderr, %eax
        movl    %eax, %edx
        movl    $.LC0, %eax
        movl    %edx, 12(%esp)
        movl    $15, 8(%esp)
        movl    $1, 4(%esp)
        movl    %eax, (%esp)
        call    fwrite
        movl    $1, (%esp)
        call    exit
.L6:
        movl    12(%ebp), %eax
        addl    $4, %eax
        movl    (%eax), %eax
        movl    %eax, (%esp)
        call    atoi
        movl    %eax, 24(%esp)
        movl    24(%esp), %eax
        movl    %eax, (%esp)
        call    fib
        movl    %eax, 28(%esp)
        movl    $.LC1, %eax
        movl    28(%esp), %edx
        movl    %edx, 8(%esp)
        movl    24(%esp), %edx
        movl    %edx, 4(%esp)
        movl    %eax, (%esp)
        call    printf
        movl    $0, (%esp)
        call    exit
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .section        .springboard,"ax",@progbits
.SB2:
        jmp     .LBL2
.SB1:
        jmp     .LBL1
.LFE2:
        .size   .springboard, .-.springboard
        .ident  "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
        .section        .note.GNU-stack,"",@progbits
我遇到的问题是GNU链接器脚本。我希望能够把跳板部分放在一个特定的内存地址。以下是脚本:

OUTPUT_FORMAT(elf32-i386)
ENTRY(main)

SB_START = 0x08148508;

SECTIONS
{

        . = SB_START;
        .springboard : { *(.springboard) }

}
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048134  08048134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000038  08048168  08048168  00000168  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000090  080481a0  080481a0  000001a0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       00000064  08048230  08048230  00000230  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  00000012  08048294  08048294  00000294  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  080482a8  080482a8  000002a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000010  080482c8  080482c8  000002c8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000030  080482d8  080482d8  000002d8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000024  08048308  08048308  00000308  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000070  08048330  08048330  00000330  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         00000188  080483a0  080483a0  000003a0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         00000015  08048528  08048528  00000528  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       00000024  08048540  08048540  00000540  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame     000000e0  08048564  08048564  00000564  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .dynamic      000000c8  08049644  08049644  00000644  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .got          00000004  0804970c  0804970c  0000070c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .got.plt      00000024  08049710  08049710  00000710  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .data         00000004  08049734  08049734  00000734  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .bss          00000004  08049738  08049738  00000738  2**2
                  ALLOC
 20 .comment      0000002a  00000000  00000000  00001512  2**0
                  CONTENTS, READONLY
 21 .springboard  0000000a  08148508  08148508  00001508  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
我已经在这上面呆了一段时间,尝试了一些不同的东西,我对链接器脚本非常陌生,所以也许这对你们中的一些人来说会很容易

使用
objdump-x fib查看没有链接器脚本的部分

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048114  08048114  00000114  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048128  08048128  00000128  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000038  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000090  08048180  08048180  00000180  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       00000064  08048210  08048210  00000210  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  00000012  08048274  08048274  00000274  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  08048288  08048288  00000288  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000010  080482a8  080482a8  000002a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000030  080482b8  080482b8  000002b8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000024  080482e8  080482e8  000002e8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000070  08048310  08048310  00000310  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         00000188  08048380  08048380  00000380  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .springboard  0000000a  08048508  08048508  00000508  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .fini         00000015  08048514  08048514  00000514  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .rodata       00000024  0804852c  0804852c  0000052c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame     000000e0  08048550  08048550  00000550  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .dynamic      000000c8  08049630  08049630  00000630  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .got          00000004  080496f8  080496f8  000006f8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .got.plt      00000024  080496fc  080496fc  000006fc  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .data         00000004  08049720  08049720  00000720  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .bss          00000004  08049724  08049724  00000724  2**2
                  ALLOC
 21 .comment      0000002a  00000000  00000000  00000724  2**0
                  CONTENTS, READONLY
然后是脚本:

OUTPUT_FORMAT(elf32-i386)
ENTRY(main)

SB_START = 0x08148508;

SECTIONS
{

        . = SB_START;
        .springboard : { *(.springboard) }

}
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048134  08048134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000038  08048168  08048168  00000168  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000090  080481a0  080481a0  000001a0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       00000064  08048230  08048230  00000230  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  00000012  08048294  08048294  00000294  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  080482a8  080482a8  000002a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000010  080482c8  080482c8  000002c8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000030  080482d8  080482d8  000002d8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000024  08048308  08048308  00000308  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000070  08048330  08048330  00000330  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         00000188  080483a0  080483a0  000003a0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         00000015  08048528  08048528  00000528  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       00000024  08048540  08048540  00000540  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame     000000e0  08048564  08048564  00000564  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .dynamic      000000c8  08049644  08049644  00000644  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .got          00000004  0804970c  0804970c  0000070c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .got.plt      00000024  08049710  08049710  00000710  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .data         00000004  08049734  08049734  00000734  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .bss          00000004  08049738  08049738  00000738  2**2
                  ALLOC
 20 .comment      0000002a  00000000  00000000  00001512  2**0
                  CONTENTS, READONLY
 21 .springboard  0000000a  08148508  08148508  00001508  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
我想了解更多关于我可以用链接器脚本做什么以及如何使用链接器脚本的信息。我读过其他的问题和教程,但还是很困惑。我不完全理解所有的部分是什么以及它们应该放在哪里,我想我应该从一些简单的东西开始,然后添加一个,但是我可能需要更详细地理解一些东西才能使它发挥作用。知道如何修复我的链接器脚本吗?关于这个主题,我还需要知道什么?谢谢

在Ubuntu机器上工作,我只关注32位程序。

你提到过吗?第3章确实解释了链接器脚本。不过,它不会赢得任何最佳手册奖。:)


您看到的部分是各种数据(.data、.bss、.rodata)和代码(.text、.init、.fini)部分。更多细节。还可以尝试用谷歌搜索部分名称。

问题在于行
条目(main)
。这表示程序将在该点启动

Argc和Argv由crt1.o设置,如下所述:

这意味着我们根本不需要进入点。如果我们把它作为我们的切入点,参数将无法正确设置。o也将调用main。链接器脚本现在如下所示:

OUTPUT_FORMAT(elf32-i386)

SECTIONS
{
        . = 0x08148508;
        .springboard : { *(.springboard) }
}

你不太清楚问题是什么。你想修什么?你的跳板确实到达了要求的地址。谢谢!我一直在读那份文件。我想问题是,当程序使用链接器脚本构建时,它不能正常运行。程序应该有一个参数,所以我可以用
/fib 3
调用它。如果没有参数,它将显示
用法:fib
。但是,当使用我的链接器脚本运行时,它总是显示用法。在链接器脚本中,我必须做些什么才能让参数工作吗?我找到了修复方法。问题是我需要取出
ENTRY(main)
。o设置argc和argv并调用main,听起来像:完全错过了链接器脚本中的那个条目。你可能应该创造一个答案并接受它。