简体   繁体   中英

How do I specify the memory address for a specific section with a linker script?

I'm working on a big project that involves writing a Perl script to transform assembly files and I'm trying to determine what the assembly files will look like after the transformation, and what the process is to compile them. I've been having trouble getting a simple example to work. I'm starting with a simple program, fib.c. I compiled it, and then added a section called the springboard.

        .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

I used these commands to compile it further:

as -o fib.o fib.S -32
ld -melf_i386 -o fib -dynamic-linker /lib/ld-linux.so.2 /usr/lib32/crt1.o /usr/lib32/crti.o fib.o -lc /usr/lib32/crtn.o script.ld

The part I'm having trouble with is the GNU linker script. I want to be able to put the springboard section at a specific memory address. Here's the script:

OUTPUT_FORMAT(elf32-i386)
ENTRY(main)

SB_START = 0x08148508;

SECTIONS
{

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

}

I've been stuck on this for a while and tried a few different things and I'm very new to linker scripts so maybe this will be easy for some of you.

Looking at the sections without the linker script using 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

And then with the script:

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

I would love to learn more about what I can do with linker scripts and how do to it. I've read other questions and tutorials but am still pretty confused. I don't fully understand what all the sections are and where they should go, I thought I'd start with something simple and add one, but I might to understand things in more detail to get it to work. Any idea on how to fix my linker script? What else do I need to know about this subject? Thanks!

Working on an Ubuntu machine and I'm only focused on 32-bit programs.

You did refer to GNU linker manual ? Chapter 3 does explain linker scripts. It's won't win any awards for best manuals, though. :)

The sections you see are various data (.data, .bss, .rodata) and code (.text, .init, .fini) sections. More details here . Also try googling up section names.

The problem was the line ENTRY(main) . That indicates the program will start at that point.

Argc and Argv get set up by crt1.o, as explained here: How to correctly use a simple linker script? Executable gets SIGKILL when run

That means we don't need an entry point at all. And if we put that as our entry point, the arguments won't get set up correctly. crt1.o will also call into main. The linker script now looks like this:

OUTPUT_FORMAT(elf32-i386)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM