Article:LowLevelAsm

Материал из QNX.ORG.RU

Перейти к: навигация, поиск

Содержание

LowLevel Assembly в QNX6

Вступление

Идея заняться этой темой родилась у меня во время обсуждения данной темы в одной из веток нашего форума. И тогда задал я себе вопрос "А почему бы не сделать что-то вроде Linux Assembly для QNX 6?", т.е. заняться написанием программ на чистом ассемблере без применения языка Си и его библиотек.

Итак, напишем простенькую программу типа helloworld на ассемблере. Однако, несмотря на кажущуюся простоту, задача перед нами стоит не простая. Надо написать программу так, чтоб она корректно вела себя в программной среде микроядерной ОС QNX 6.x и при этом не использовала ни одной статической или динамической библиотеки. Чтож, посмотрим что у нас получится... :)

Секции

Не секрет, что QNX6 использует формат исполняемого файла ELF. Данный формат представляет из себя набор секций разного назначения, которые интерпретируются загрузчиком в процессе запуска исполняемого файла. Часть секций загружается прямо в память, часть служит для коррекции загруженных данных, часть присутствует "просто так" и при загрузке игнорируется.

Посмотрим что по умолчанию при трансляции формирует gcc в среде QNX6. Для этого напишем простую программу на Си, оттранслируем ее и посмотрим список секций.

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[]) {
	printf("Hello World!\n");
	exit(0);
}
# gcc helloworldc.c -o helloworldc
# strip helloworldc
# ./helloworldc
Hello World!
# ls -l helloworldc
-rwxrwxr-x  1 root      root           3148 Oct 21 11:03 helloworldc
# objdump -x helloworldc

helloworldc:     file format elf32-i386
helloworldc
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x080484d8

Program Header:
    PHDR off    0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
         filesz 0x000000c0 memsz 0x000000c0 flags r-x
  INTERP off    0x000000f4 vaddr 0x080480f4 paddr 0x080480f4 align 2**0
         filesz 0x00000014 memsz 0x00000014 flags r--
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
         filesz 0x000006d8 memsz 0x000006d8 flags r-x
    LOAD off    0x000006d8 vaddr 0x080496d8 paddr 0x080496d8 align 2**12
         filesz 0x0000010c memsz 0x00000130 flags rw-
 DYNAMIC off    0x000006ec vaddr 0x080496ec paddr 0x080496ec align 2**2
         filesz 0x000000b0 memsz 0x000000b0 flags rw-
    NOTE off    0x00000108 vaddr 0x08048108 paddr 0x08048108 align 2**0
         filesz 0x00000018 memsz 0x00000018 flags r--

Dynamic Section:
  NEEDED               libc.so.3
  INIT                 0x08048410
  FINI                 0x080486bc
  HASH                 0x08048120
  STRTAB               0x080482d4
  SYMTAB               0x080481b4
  STRSZ                0x000000c4
  SYMENT               0x00000010
  DEBUG                0x00000000
  PLTGOT               0x080497a0
  PLTRELSZ             0x00000050
  PLTREL               0x00000011
  JMPREL               0x080483c0
  REL                  0x08048398
  RELSZ                0x00000028
  RELENT               0x00000008

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000014  080480f4  080480f4  000000f4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note         00000018  08048108  08048108  00000108  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000094  08048120  08048120  00000120  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000120  080481b4  080481b4  000001b4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       000000c4  080482d4  080482d4  000002d4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rel.dyn      00000028  08048398  08048398  00000398  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .rel.plt      00000050  080483c0  080483c0  000003c0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .init         0000000d  08048410  08048410  00000410  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .plt          000000b0  08048420  08048420  00000420  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .text         000001ec  080484d0  080484d0  000004d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .fini         00000008  080486bc  080486bc  000006bc  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .rodata       0000000d  080486c4  080486c4  000006c4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .eh_frame     00000004  080486d4  080486d4  000006d4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 13 .ctors        00000008  080496d8  080496d8  000006d8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .dtors        00000008  080496e0  080496e0  000006e0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .jcr          00000004  080496e8  080496e8  000006e8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .dynamic      000000b0  080496ec  080496ec  000006ec  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .data         00000004  0804979c  0804979c  0000079c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .got          00000044  080497a0  080497a0  000007a0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .bss          00000024  080497e4  080497e4  000007e4  2**2
                  ALLOC
 20 .comment      00000036  00000000  00000000  000007e4  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
no symbols

Что мы видим тут? Мы видим малый размер файла и имеющий 21 секцию. Мы собрали запускаемый файл, требующий динамическую линковку при загрузке. Об этом однозначно говорит наличие секции .interp и зависимость от библиотеки libc.so.3 .

Попробуем теперь собрать программу статически.

# gcc --static helloworldc.c -o helloworldcs
# strip helloworldcs
# ./helloworldcs
Hello World!
# ls -l helloworldcs
-rwxrwxr-x  1 root      root          43644 Oct 21 11:03 helloworldcs
# objdump -x helloworldcs

helloworldcs:     file format elf32-i386
helloworldcs
architecture: i386, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x080480c8

Program Header:
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
         filesz 0x00009a48 memsz 0x00009a48 flags r-x
    LOAD off    0x00009a48 vaddr 0x08052a48 paddr 0x08052a48 align 2**12
         filesz 0x0000064c memsz 0x00000a74 flags rw-
    NOTE off    0x00000094 vaddr 0x08048094 paddr 0x08048094 align 2**0
         filesz 0x00000018 memsz 0x00000018 flags r--

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .note         00000018  08048094  08048094  00000094  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .init         0000000d  080480ac  080480ac  000000ac  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .text         00008f2c  080480c0  080480c0  000000c0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .fini         00000008  08050fec  08050fec  00008fec  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .rodata       000009cf  08051000  08051000  00009000  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .eh_frame     00000078  080519d0  080519d0  000099d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .ctors        00000008  08052a48  08052a48  00009a48  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  7 .dtors        00000008  08052a50  08052a50  00009a50  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .jcr          00000004  08052a58  08052a58  00009a58  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  9 .data         00000618  08052a60  08052a60  00009a60  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 10 .got          0000001c  08053078  08053078  0000a078  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 11 .bss          0000041c  080530a0  080530a0  0000a094  2**5
                  ALLOC
 12 .comment      0000072c  00000000  00000000  0000a094  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
no symbols

Что мы имеем: больший размер, 13 секций, отсутствие зависимостей от библиотек. Данный результат близок к тому чего мы добиваемся, но мы хотим ассемблера! :)

Для тех кто хочет больше узнать о формате ELF могу предложить почитать документацию.

WIP!

Здесь планируется разместить небольшой материал о написании программ для QNX 6.x на языке Ассемблер без применения Си.

Ждите... :)