LINUX.ORG.RU

PIC на ARM


0

0

Как заставить arm-linux-as генерировать позиционно независимый код?

Сейчас он генерит код таким образом (извините, не могу привести 
конкретных выводов. доношу смысл):  

Пишу:
....
.L1:
        nop
        j   .L1
        j   .L2
        nop
.L2:
        nop
...

Он генерит таким образом: за 0 адрес принимается начало кода. Все 
остальные смещения отсчитываются от этого 0, а не от позиции инструкций j.


Опция -k ничего не меняет.
★★★★
Ответ на: комментарий от alexru

Проблема даже в том, что из доки следует, что в инструкциях j{xx} всегда применяется относительный адрес. То-есть ассемблер генерит не верный код в прнципе.

alexru ★★★★
() автор топика
Ответ на: комментарий от klalafuda

Мне нужен чистый бинарник. Без заголовков.

alexru ★★★★
() автор топика
Ответ на: комментарий от alexru

> Ха. У меня порнуховырезалка банит этот адрес из-за "nude".

hm.. ну тут я ничем не могу помочь :)

// wbr

klalafuda ★☆☆
()

простенький тест:

---test.c---
extern int check_arg(int arg);

int
foo(int arg)
{
    return arg ? check_arg(arg) : arg;
}
---test.c---

собираем без поддержки PIC:

$ cc -c -Wall -O2 -S test.c

---test.s---
        .file   "test.c"
        .text
        .p2align 2,,3
.globl foo
        .type   foo, @function
foo:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        testl   %eax, %eax
        jne     .L3
        xorl    %eax, %eax
        leave
        ret
        .p2align 2,,3
.L3:
        leave
        jmp     check_arg
        .size   foo, .-foo
        .ident  "GCC: (GNU) 3.3.3 (NetBSD nb3 20040520)"
---test.s---

собираем с поддержкой PIC:

$ cc -c -Wall -O2 -fpic -fPIC -S test.c

---test.s---
        .file   "test.c"
        .text
        .p2align 2,,3
.globl foo
        .type   foo, @function
foo:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        pushl   %eax
        movl    8(%ebp), %edx
        call    .L4
.L4:
        popl    %ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L4], %ebx
        xorl    %eax, %eax
        testl   %edx, %edx
        jne     .L3
.L1:
        movl    -4(%ebp), %ebx
        leave
        ret
        .p2align 2,,3
.L3:
        subl    $12, %esp
        pushl   %edx
        call    check_arg@PLT
        jmp     .L1
        .size   foo, .-foo
        .ident  "GCC: (GNU) 3.3.3 (NetBSD nb3 20040520)"
---test.s---

то, что это x86 а не arm сути дела не меняет. идея PIC понятна? :)

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Как оказывается играет. Может у меня не правильно компилятор собран,но в случае ARM-a я ничего такого не вижу.

Мне больше не понятен такой момент: в ARM-е инструкции j** в принципе всегда используют относительный адрес. А компилятор подставляет абсолютный.

alexru ★★★★
() автор топика
Ответ на: комментарий от klalafuda

ps: или же я не совсем понял оригинального вопроса (запросто). PIC (Position Independent Code) имеет вполне чёткое определение как в ELF так и в gcc в частности на уровне поддержки динамической линковки, а приведённая проблема я так понимаю с ней не связана.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от alexru

> Как оказывается играет. Может у меня не правильно компилятор собран,но в случае ARM-a я ничего такого не вижу.

ладно, сейчас соберу ARM toolchain и попробую на нём..

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Под PIC я понимаю то, что код (результирующий бинарник) можно разместить по любому адресу и отдать управление на точку входа и все будет работать. Для этого нужно, чтобы все инструкции перехода использовали относительные адреса (относительно собственного).

alexru ★★★★
() автор топика

>        j   .L1
>        j   .L2

что такое инструкция "j" ? afaik нет такой. для безусловного перехода используется B (Branch) или BL (Branch and Link). как следствие, переделать на:

---test.S---
        nop
.L1:
        nop
        b       .L1
        b       .L2
.L2:
        nop
---test.S---

версии as:

$ /usr/src/tooldir.NetBSD-3.99.8-i386/bin/arm--netbsdelf-as --version
GNU assembler 2.15
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License.  This program has absolutely no warranty.
This assembler was configured for a target of `arm--netbsdelf'.

собираем:

$ /usr/src/tooldir.NetBSD-3.99.8-i386/bin/arm--netbsdelf-as -o test.o test.S

разбираем:

---cut---
/usr/src/tooldir.NetBSD-3.99.8-i386/bin/arm--netbsdelf-objdump -d test.o

test.o:     file format elf32-littlearm

Disassembly of section .text:

00000000 <.text>:
   0:   e1a00000        nop                     (mov r0,r0)
   4:   e1a00000        nop                     (mov r0,r0)
   8:   eaffffff        b       c <.text+0xc>
   c:   ea000002        b       1c <.text+0x1c>
  10:   e1a00000        nop                     (mov r0,r0)
---cut---

как видно из разбора на основании описания инструкций в ARM DDI 0100E:
8 - безусловный переход по смещению -1
C - безусловный переход по смещению +2

-> AFAIU все верно и смещения, указываемые в инструкциях безусловного перехода, идут относительно точки вызова перехода, а не абстрактного нулевого адреса :)

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от alexru

> Под PIC я понимаю то, что код (результирующий бинарник) можно разместить по любому адресу и отдать управление на точку входа и все будет работать. Для этого нужно, чтобы все инструкции перехода использовали относительные адреса (относительно собственного).

btw для PIC в его обычном понимании этого недостаточно :)

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Значит у меня как-то криво собраны binutils. Спасибо огромное. буду разбираться.

Переход только вроде на 2<<2=4.

PS: с j я действительно маху дал :)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.