We create an ELF file with tax information (DWARF) manually (for ARM microcontrollers). Format ELF and PE EXE Elf file extension

Golovna / Additional functionality

Version with good TOC and a lot of content: http://www.cirosantilli.com/elf-hello-world (press 30k char exchange here)

Standards

ELF is given by LSB:

  • core generic: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/elf-generic.html
  • core AMD64: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/book1.html

LSB is important to rely on other standards with minor extensions, except for:

    generic (offending SCO):

    • System V ABI 4.1 (1997) http://www.sco.com/developers/devspecs/gabi41.pdf, not 64 bits, wanting a magic number reserved for it. Those for the main files.
    • System V ABI Update DRAFT 17 (2003) http://www.sco.com/developers/gabi/2003-12-17/contents.html add 64 bits. Just update the divisions 4 and 5 of the front document: the stitches are filled with chins and, as before, they are asked.
  • specific architecture:

    • IA-32: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-IA32/LSB-Core-IA32/elf-ia32.html mainly at http://www.sco.com/developers /devspecs/abi386-4.pdf
    • AMD64: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/elf-amd64.html , mainly at http://www.x86-64.org/ documentation/abi.pdf

A better summary can be found at:

You can look at this structure for additional handy methods like readelf and objdump .

Create a butt

Allow me to break down the minimal example that Linux x86-64 wins:

Section .data hello_world db "Hello world!", 10 hello_world_len equ $ - hello_world section .text

Compiled for help

Nasm -w+all -f elf64 -o "hello_world.o" "hello_world.asm" ld -o "hello_world.out" "hello_world.o"

  • NASM 2.10.09
  • Binutils version 2.24 (replace ld)
  • Ubuntu 14.04

We do not beat the C program, so that we can simplify the analysis, which will be equal to 2 :-)

16 binary manifestations

hd hello_world.o hd hello_world.out

Global file structure

The ELF file contains the following parts:

  • ELF header. Indicate the position of the header table divided and the header tables of the programs.

    Table of headings in divisions (needed in the language of the icon file). The skin may be the headings of the e_shnum sections;

    N divisions N<= e_shnum (необязательно в исполняемом файле)

    Table of program headers (only for files to be selected). Some of them may e_phnum program headers, some of them indicate the location of the segment.

    N segments, s N<= e_phnum (необязательно в исполняемом файле)

The order of these parts is not fixed: one fixed rich - the ELF header, which may be the first in the file: Global documents seem to be:

ELF header

The easiest way to post a headline:

readelf -h hello_world.o readelf -h hello_world.out

Byte in object file:

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF...........| 00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.............| 00000020 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | [email protected]| 00000030 00 00 00 00 40 00 00 00 00 00 40 00 07 00 03 00 |[email protected]@.....|

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF...........| 00000010 02 00 3e 00 01 00 00 00 b0 00 40 00 00 00 00 00 |..> [email protected]| 00000020 40 00 00 00 00 00 00 00 10 01 00 00 00 00 00 00 |@...............| 00000030 00 00 00 00 40 00 38 00 02 00 40 00 06 00 03 00 |[email protected]@.....|

Structure filed:

Typedef struct ( unsigned char e_ident; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; ) Elf64_Ehdr;

Decay manually:

    0 0: EI_MAG = 7f 45 4c 46 = 0x7f "E", "L", "F": ELF magic number

    0 4: EI_CLASS = 02 = ELFCLASS64: 64-bit elf

    0 5: EI_DATA = 01 = ELFDATA2LSB: grand kints data

    0 6: EI_VERSION = 01: format version

    0 7: EI_OSABI (only in 2003) = 00 = ELFOSABI_NONE: no extension.

    08: EI_PAD = 8x 00: reserved bytes. Guilty but set to 0.

    1 0: e_type = 01 00 = 1 (big endian) = ET_REl: format to move

    File has 02 00 for ET_EXEC .

    1 2: e_machine = 3e 00 = 62 = EM_X86_64: AMD64 architecture

    1 4: e_version = 01 00 00 00: can be 1

    1 8: e_entry = 8x 00: entry point of the address of the entry, or 0, so it does not zastoovuetsya as for an object file, since there is no entry point.

    The file has b0 00 40 00 00 00 00 00 . TODO: what can we install? The kernel, here, assigns an IP without a middle value, it is not hard to program.

    2 0: e_phoff = 8x 00: Use program header table, 0, but not.

    40 00 00 00 for the file, so the vin starts immediately after the ELF header.

    2 8: e_shoff = 40 7x 00 = 0x40: Used to split header table file, 0, otherwise not.

    3 0: e_flags = 00000000 TODO. Specially for Arch.

    3 4: e_ehsize = 4000: size of the elf heading. Why the field? How can you change?

    3 6: e_phentsize = 00 00: Program skin header size, 0, but not.

    38 00 for the hacked file: the length of the file is 56 bytes

    3 8: e_phnum = 0000: number of program header entries, 0, which is none.

    02 00 for the linked file: є 2 entries.

    3 A: e_shentsize and e_shnum = 40 00 07 00: heading size to split this number of records

Header table

An array of Elf64_Shdr structures.

Leather record retrieving metadata about this division.

e_shoff of the ELF header gives the spam position, 0x40.

e_shentsize and e_shnum From the ELF header, it looks like we have 7 entries, wedge skin 0x40.

Again, the table takes bytes from 0x40 to 0x40 + 7 + 0x40 - 1 = 0x1FF.

Name some sections reserved for singing types of sections: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections, for example. .text required type SHT_PROGBITS and SHF_ALLOC + SHF_EXECINSTR

readelf -S hello_world.o:

There are 7 section headers, starting at offset 0x40: Section Headers: Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .data PROGBITS 0000000000000000 00000200 000000000000000d 0000000000000000 WA 0 0 4 [ 2] .text PROGBITS 0000000000000000 00000210 0000000000000027 0000000000000000 AX 0 0 16 [ 3] .shstrtab STRTAB 0000000000000000 00000240 0000000000000032 0000000000000000 0 0 1 [ 4] .symtab SYMTAB 0000000000000000 00000280 00000000000000a8 0000000000000018 5 6 4 [ 5] .strtab STRTAB 0000000000000000 00000330 0000000000000034 0000000000000000 0 0 1 [6] .rela.text RELA 00000000000000000 00000370 000000000000018 0000000000000018 4 2 4 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)

struct , in skin notation:

Typedef struct ( Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; 64;

Distributed

Distributed to index 0

Move from bytes from 0x40 to 0x7F.

The first section was always charming: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html

In addition, the number of sections is greater or more SHN_LORESERVE (0xff00), e_shnum may have the value SHN_UNDEF (0), and actually the number of records in the distribution header table is stored in the sh_size field of the header of the partition with index 0 (also record member sh_size).

Sections Figure 4-7: Special Section Indexes for other magic sections.

In index 0 SHT_NULL є obov'yazykovim. Chi іsnuyet іnshі vidi vikoristannya: What is the mischief in parsing SHT_NULL in ELF? ?

.data split

Data - section 1:

00000080 01 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 |................| 000000a0 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000b0 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

    Here 1 to say that the first character of this division starts with the first character of the division and ends with the first character NUL, setting row.data .

    Data - one of the names of distributions, as it may be the same value http://www.sco.com/developers/gabi/2003-12-17/ch4.strtab.html

    In these divisions, initial data is saved, as a way to make a contribution to the image of the memory of the program.

  • 80 4: sh_type = 01 00 00 00: SHT_PROGBITS: instead of distributing non-ELF jobs, just as the program interprets yoga. It's ok, because a .data .

    80 8: sh_flags = 03 7x 00: SHF_ALLOC and SHF_EXECINSTR: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#sh_flags , as required by distribution.

    90 0: sh_addr = 8x 00: in this virtual address will be placed placements at the end of the day, so there will be no placements

    90 8: sh_offset = 00 02 00 00 00 00 00 00 = 0x200: number of bytes in the beginning of the program to the first byte in this distribution

    a0 0: sh_size = 0d 00 00 00 00 00 00 00

    So take 0xD bytes, starting with sh_offset 200, mi bachimo:

    00000200 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 |Hello world!.. |

    AHA! Otzhe, our row "Hello world!" know in the distribution of data, as we said, tse NASM.

    As soon as we finish hd, we can look at it like this:

    Readelf-x.data hello_world.o

    Which one to enter:

    Hex dump of section ".data": 0x00000000 48656c6c 6f20776f 726c6421 0a Hello world!.

    NASM sets power days for which division, which is magically placed before: data: http://www.nasm.us/doc/nasmdoc7.html#section-7.9.2

    Also, pay attention to the fact that the wrong choice was made: a good C compiler by placing a row in .rodata to replace something that is only available for reading, and to allow further optimization of the OS.

    a0 8: sh_link and sh_info = 8x 0: don't stop to the type of distribution. http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections

    b0 0: sh_addralign = 04 = TODO: need to change it? Is there a target for sh_addr, and also for symbols in the middle of sh_addr?

    b0 8: sh_entsize = 00 = split not to avenge tables. Yakscho! = 0, which means that the table of records of the fixed size was distributed. Which file should have the readelf link, but there is room for .symtab and .rela.text distributions.

.text split

Now, if we have made one division by hand, give the graduate and graduate readelf -S of the other divisions.

Name Type Address Offset Size EntSize Flags Link Info Align [ 2 ] .text PROGBITS 0000000000000000 00000210 000000000000020 000

Text is written if it is not writable: so we can try to write some Linux segfaults. We wonder why we have a code:

Objdump -d hello_world.o

Hello_world.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000<_start>: 0: b8 01 00 00 00 mov $0x1,%eax 5: bf 01 00 00 00 mov $0x1,%edi a: 48 be 00 00 00 00 00 movabs $0x0,%rsi 11: 00 0 0d 00 00 00 mov $0xd,%edx 19:0f 05 syscall 1b:b8 3c 00 00 00 mov $0x3c,%eax 20:bf 00 00 00 00 mov $0x0,%edi 25:0

How can we grep b8 01 00 00 on hd, we can see only in 00000210, as it says in this distribution. І rozmir dorivnyuє 27, which is also confirmed. That's why we can talk about the correct division.

This looks like the correct code: a write , followed by exit .

Naytsіkavіsha part - row a, which is to rob:

Movabs $0x0,%rsi

pass the row address to the system wiki. In Denmark, the hour 0x0 is simply zapovnyuvachem. After the call, there will be a yoga change:

4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi

This modification is possible through the rela.text distribution data.

SHT_STRTAB

Partitions with sh_type == SHT_STRTAB are called row tables.

So the vicorists were divided into other divisions, if the names of a row of vicorists were divided. The section "Victorian" says:

  • what a row of stench vikoristovuyut
  • what is the index of the tables of whole rows, where does the row start

So, for example, we could make a row table, how to avenge: TODO: what do you need to start with \0?

Data: \0 a b c \0 d e f \0 Index: 0 1 2 3 4 5 6 7 8

І yakscho іnshiy razdіl want to win a row d e f stench of blame to indicate on index 5 of the tsgo razdіlu (letter d).

View row tables:

  • .shstrtab
  • .strtab

.shstrtab

Partition type: sh_type == SHT_STRTAB .

Zagalne im'ya: the title row was divided.

I've shared.shstrtab is reserved. The standard has:

Tsey split to avenge the names of splits.

Which branch should have the e_shstrnd field of the ELF header itself.

Row indexes of this division are specified by the sh_name field of division headers, which indicate rows.

Which branch does not have SHF_ALLOC enabled, it will not work for the program that wins.

Readelf-x.shstrtab hello_world.o

Hex dump of section ".shstrtab": 0x00000000 002e6461 7461002e 74657874 002e7368 ..data..text..sh 0x00000010 73747274 6162002e 73796d74 6162002e strtab..symtab.. 0x00000020 73747274 6162002e 72656c61 2e746578 strtab..rela.tex 0x00000030 7400 t.

Data from whom you have distributed may fix the format: http://www.sco.com/developers/gabi/2003-12-17/ch4.strtab.html

As we marvel at the names of other divisions, it’s better that all the stinks avenge the numbers, for example. section.text may number 7 .

Then the skin row will end if the first NUL character is found, for example. character 12 \ 0 the next time. text \ 0 .

.symtab

Partition type: sh_type == SHT_SYMTAB.

Common name: symbol table.

It is significant, back to back, that:

  • sh_link = 5
  • sh_info=6

In the SHT_SYMTAB division, the numbers mean that:

  • Rows
  • how to give symbol names, change from branch 5, .strtab
  • relocation data is rebuyed at branch 6, .rela.text

A good tool of a high level for sorting out this division:

Nm hello_world.o

which one is:

0000000000000000 T _start 0000000000000000 d hello_world 000000000000000d a hello_world_len

Tse, however, is a manifestation of a high level, in which deaks of types of symbols are omitted and in which symbols they are designated. More detailed analysis can be taken for help:

Readelf -s hello_world.o

which one is:

Symbol table ".symtab" contains 7 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello_world.asm 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 hello_world 5: 000000000000000d 0 NOTYPE LOCAL DEFAULT ABS hello_world_len 6: 00000000000

Binary table format is documented at http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html

Readelf-x.symtab hello_world.o

What do you give:

Hex dump of section ".symtab": 0x00000000 00000000 00000000 00000000 00000000 ................ 0x00000010 00000000 00000000 01000 ... . 0x00000020 00000000 000000 00000000 000000 000000 ............. .............. 0x00000050 00000000 00000000 00000000 00000000 ................ 0x00000060 11000000 00000100 00000000 000 ...... 0x00000070 00000000 0000000000 ................ 0x00000080 0d000000 00000000 00000000 00000000 10000200 00000000 00000000 -............ 0x000000a0 00000000 00000000 ....... .

Recording type:

Typedef struct ( Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; ) Elf64_Sym;

As in the tables of divisions, the first entry is charitable and is given by fixed, blank values.

Record 1 May ELF64_R_TYPE == STT_FILE . ELF64_R_TYPE is three in the middle of st_info.

Byte analysis:

    10 8: st_name = 01000000 = character 1 st.strtab , which is up to the offensive \0 to rob hello_world.asm

    This fragment of the information file can be broken into a linker, which determines how the segments of the segment should go.

    10 12: st_info = 04

    Bits 0-3 = ELF64_R_TYPE = Type = 4 = STT_FILE: main record meta - tag st_name to match the file name generated by this object file.

    Bits 4-7 = ELF64_ST_BIND = Binding = 0 = STB_LOCAL. Required value for STT_FILE .

    10 13: st_shndx = Symbol table Header table Index = f1ff = SHN_ABS . Needed for STT_FILE .

    20 0: st_value = 8x 00: required for value for STT_FILE

    20 8: st_size = 8x 00: no size seen

Now, from readelf, I will quickly interpret it.

STT_SECTION

There are two such elements, one pointing to .data, and the other to .text (indexes divided 1 and 2).

Number: Value Size Type Bind Vis Ndx Name 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2

TODO, what is the meta?

STT_NOTYPE

Then enter the most important characters:

Num: Value Size Type Bind Vis Ndx Name 4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 hello_world 5: 000000000000000d 0 NOTYPE LOCAL DEFAULT ABS hello_world_len 00 0

hello_world is located in the distribution.data (index 1). Value value 0: check the first byte of the distribution.

Start to set the visibility of GLOBAL, to the one we wrote:

global_start

at NASM. It is not necessary, the shards can be seen as an entry point. On view C, for promotional labels NASM є local.

hello_world_len refers to the special st_shndx == SHN_ABS == 0xF1FF .

0xF1FF is selected in such a way that it won't supercheat other branches.

st_value == 0xD == 13 , whichever is the value, which we have saved there for selection: the back of the row Hello World! .

Tse means that the movement is not in line with the value: it is a constant.

It's not a big optimization, how to work our assembler for us that can support ELF.

Yakby mi vikoristovuvali address hello_world_len in any place, the assembler will not zmіg bi pomiti yogo yak SHN_ABS , and the linker will be further relocated.

SHT_SYMTAB for the iconized file

For the NASM promotion, place the .symtab in the iconized file.

Tse vikoristovuєtsya less for nagodzhennya. Without symbols, we are completely blind and may redesign everything.

You can see it for help objcopy and download the file all the same will work. Such files that are iconized are called split iconized files.

.strtab

Eliminate rows for table characters.

Whose distribution has sh_type == SHT_STRTAB .

Show up on sh_link == 5 distribution.

Readelf-x.strtab hello_world.o

Hex dump of section ".strtab": 0x00000000 0068656c 6c6f5f77 6f726c64 2e61736d .hello_world.asm 0x00000010 0068656c 6c6f5f77 6f726c64 0068656c .hello_world.hel 0x00000020 6c6f5f77 6f726c64 5f6c656e 005f7374 lo_world_len._st 0x00000030 61727400 art.

This means that the ELF is exchanged, that it is globally changed that it is impossible to remove the NUL characters.

.rela.text

Distribution type: sh_type == SHT_RELA .

Head name: split the relocation.

Rela.text Reply to the data of the relocation, in which it is assigned, as the addresses are to be changed, if the remaining file of the hits is found. Tse vkazuє on the byte of the text area, yakі mаyut buti zmіnіnі, if zv'yazuvannya vіdbuvaієє іz zaznachennymi іїїїїї їїї її її її ії її ї їїї ї їїї ї її ї ї їїїїї

In the main wine, I rewrite the text of the object to avenge the address of the 0x0 zapovnyuvacha:

A:48 ru 00 00 00 00 00 movabs $0x0,%rsi 11:00 00 00

to the actual hacked code to remove the residual 0x6000d8:

4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi 4000c1: 00 00 00

Sh_info = 6 was specified.

readelf -r hello_world.o yes:

Relocation section ".rela.text" at offset 0x3b0 offset 1 point: Offset Info Type Sym. Value Sym. Name + Addend 00000000000c 000200000001 R_X86_64_64 0000000000000000 .data + 0

The distribution is not based on the file that is being checked.

Actual bytes:

00000370 0c 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |................| 00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

struct representations:

Typedef struct ( Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; ) Elf64_Rela;

    370 0: r_offset = 0xC: addresses to address.text , addresses to be changed

    370 8: r_info = 0x200000001. Mist 2 fields:

    • ELF64_R_TYPE = 0x1: value to deposit as exact architecture.
    • ELF64_R_SYM = 0x2: partitioned index, which address, volume.data, which has index 2.

    AMD64 ABI says that type 1 is called R_X86_64_64 and that VIN represents the S+A operation de:

    • S: character value in the object file is 0 here, so we can set it to 00 00 00 00 00 00 00 00 s movabs $0x0,%rsi
    • a: added to the r_added field

    Tsya addresses are added to the distribution, de pracyuє relocation.

    This move operation is 8 bytes.

    380 0: r_addend = 0

In such a rank, we put it in our butt, that the new address will be: S + A \u003d .data + 0 i, in this rank, the first in the distribution of data.

Program title table

It appears less at the file that is victorious.

It is up to the virtual memory of the process to remove information about those, like a file that is being viewed.

The linked file is created by an object linker file. The main tasks, as a viconous linker:

    determine how the objects were divided to see up to which segments of the selected file.

    With Binutils, it is necessary to analyze the linker script and work with the meaning of the default.

    You can select the linker script that is merged with ld --verbose , and install with ld -T .

    vikonuvat remіshchennya text rasdіla. It’s worth to lay it down in order, like a sprig of rozdіlіv rozmіshchuyusya in memory.

readelf -l hello_world.out yes:

Elf file type is EXEC (Executable file) Entry point 0x4000b0 There are 2 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000000d7 0x00000000000000d7 R E 200000 LOAD 0x00000000000000d8 0x00000000006000d8 0x00000000006000d8 0x000000000000000d 0x000000000000000d RW 200000 Section to Segment mapping: Segment Sections... 00 .text 01 .data

The ELF header e_phoff , e_phnum and e_phentsize told us that there are 2 program headers that start at 0x40 and up to 0x38 bytes of skin, so stink:

00000040 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 |[email protected]@..... | 00000060 d7 00 00 00 00 00 00 00 d7 00 00 00 00 00 00 00 |................| 00000070 00 00 20 00 00 00 00 00 |.. ..... |

00000070 01 00 00 00 06 00 00 00 | ........| 00000080 d8 00 00 00 00 00 00 00 d8 00 60 00 00 00 00 00 |..........`.....| 00000090 d8 00 60 00 00 00 00 00 0d 00 00 00 00 00 00 00 |..`.............| 000000a0 0d 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00 |.......... .....| typedef struct ( Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_X

Try the first:

  • 40 0: p_type = 01 00 00 00 = PT_LOAD: TODO. I think tse means that you will be interested in the riddle. Other types can be but not obov'yazkovo buti.
  • 40 4: p_flags = 05 00 00 00 = read and read allowed, do not write TODO
  • 40 8: p_offset = 8x 00 TODO: what? It looks like usunennya on the cob of segments. What does it mean that the segments are intertwined? You can play around with it: gcc -Wl,-Ttext-segment=0x400030 hello_world.c
  • 50 0: p_vaddr = 00 00 40 00 00 00 00 00: virtual memory mail address for occupied segment in
  • 50 8: p_paddr = 00 00 40 00 00 00 00 00: the initial physical address to be captured in memory. Only power for systems, for which programs can set a physical address. In a different way, like in System V systems, it might be. Looks like NASM just copy p_vaddrr
  • 60 0: p_filesz = d7 00 00 00 00 00 00 00: TODO vs p_memsz
  • 60 8: p_memsz = d7 00 00 00 00 00 00 00: TODO
  • 70 0: p_align = 00 00 20 00 00 00 00 00: 0 or 1 means no alignment is needed TODO, what does that mean? in a different way above the world with other fields

The other one is similar.

Section to Segment mapping:

let readelf tell us what:

  • 0-segment.text. Aha, that Vіn wins and is not writable.
  • 1-segment.data.
The standard extension tools compile your program to an ELF (Executable and Linkable Format) file, possibly including tax information. You can read the format specification. From the other side, skin architecture has its own peculiarities, for example, the peculiarities of ARM. Let's take a look at the format briefly.
The conversion file to the ELF format consists of the following parts:
1. Header (ELF Header)
Retrieve general information about the file and its main characteristics.
2. Program Header Table
Tse table of the relevant sections to the file segments of the memory, showing the capture, as the area of ​​the memory to write the skin section.
3. Sections
Sections to remove all information from the file (program, data, tax information, etc.)
Skin section may type, name and other parameters. In the ".text" section, select the code, in ".symtab" - the table of symbols of the program (names of files, procedures and changes), in ".strtab" - the table of rows, in sections with the prefix ".debug_" - customization information, etc. .d. .d. In addition, the file has an empty section with index 0.
4. Section Header Table
This is the table to replace the array of section headers.
The report format is reviewed by the ELF Creation.

DWARF Lookout

DWARF is a standardization format for customizable information. The standard can be downloaded from the official website. There lies a wonderful short look at the format: Introduction to the DWARF Debugging Format (Michael J. Eager).
Need more tax information? Vaughn allows:
  • install breakpoints not so on the physical address, but in the row number of the file output code of the function name
  • display and change the values ​​of global and local changes, as well as parameters of the function
  • display the stack of wikis (backtrace)
  • to convert the program pokrokovo not for one assembler instruction, but for rows of output code
This information is collected from a tree-like structure. A skin vuzol of a tree can be a father, it can be a mother of a mother and is called DIE (Debugging Information Entry). The skin vuzol has its own tag (type) and the list of attributes (powers) that describe the vuzol. Attributes can avenge everything that is worth it, for example, giving or sending to other universities. In addition, there is information that the pose of the tree is taken.
Nodes are divided into two main types: nodes that describe data, and nodes that describe code.
Woozley to describe the data:
  1. Tipi data:
    • The base type of the data (the wuzole with the DW_TAG_base_type type), for example, the int C type.
    • Warehouse types of data (showers)
    • Masivi
    • Structures, classes, associations, interfaces
  2. Data objects:
    • constants
    • function parameters
    • change
    • and etc.
The skin of the data object may have the DW_AT_location attribute, which indicates how the address is calculated, for which data is known. For example, you can change your mother to a fixed address, change to register or on the stack, be a member of a class or an object. Tsya addresses can be counted smoothly, so the standard transfers the so-called Location Expressions, so that the sequence of operators in a special internal stick machine can be avenged.
Woozley to describe the code:
  1. Procedures (functions) – nodes with the DW_TAG_subprogram tag. Nodes-on-boards can replace the descriptions of changes - parameters in the function and local changes in the function.
  2. Compilation Unit. Retrieve the information of the program and solve the problem with the father.
The information described above can be found in the ".debug_info" and ".debug_abbrev" sections.
More information:
  • Information about line numbers (section ".debug_line")
  • Info about macros (section ".debug_macinfo")
  • Call Frame Information (section ".debug_frame")

ELF creation

We will use the help of the libelf library from the elfutils package to create files in the EFL format. Merezha has a good article about libelf - LibELF by Example (unfortunately, the creation of files in it is described only briefly) as well as documentation.
The creation of the file is composed of a number of stages:
  1. Initialization libelf
  2. Creating a File Header (ELF Header)
  3. Creating a Program Header Table
  4. Section creation
  5. Write to file
Let's take a look at the stage of the report
Initialization libelf
You will occasionally need to call the elf_version(EV_CURRENT) function and invert the result. Yakshto vіn dіvnyuє EV_NONE - vinikla pardon that further diї work is not possible. Then we need to create the required file on disk, take the handle and pass it to the elf_begin function:
Elf*elf_begin(int fd, Elf_Cmd cmd, Elf*elf)
  • fd - file descriptor
  • cmd - mode (ELF_C_READ for reading information, ELF_C_WRITE for writing or ELF_C_RDWR for reading/writing), vin is due to the mode of the file being opened (ELF_C_WRITE in our mode)
  • elf - only needed for robots with archive files (.a), our picker needs to pass 0
The function rotates the descriptor on the creations, which is used by all libelf functions, 0 is rotated at the time of the pardon.
Header creation
The new file header is created by the elf32_newehdr function:
Elf32_Ehdr*elf32_newehdr(elf*elf);
  • elf - handle rotated by the elf_begin function
Turn 0 when clearing, or the indicator for the structure is the header of the ELF file:
#define EI_NIDENT 16 typedef struct ( unsigned char e_ident; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; ) Elf32_Ehdr;

Deyakі field її zapovnenі standard rank, deyakі need to fill us:

  • e_ident - byte array of identification, which may have such indexes:
    • EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3 - 4 bytes faulty symbols 0x7f, "ELF", which the elf32_newehdr function already did for us
    • EI_DATA - indicates the type of data encoding for the file: ELFDATA2LSB or ELFDATA2MSB. You need to set ELFDATA2LSB like this: e_ident = ELFDATA2LSB
    • EI_VERSION - header version of the file that is already installed for us
    • EI_PAD - not chippy
  • e_type - file type, can be ET_NONE - no type, ET_REL - file to be moved, ET_EXEC - file wrapping, ET_DYN - object file splits, etc. We need to set the file type to ET_EXEC
  • e_machine - architecture required for this file, for example EM_386 - for Intel architecture, for ARM we need to write here EM_ARM (40) - div. ELF for the ARM Architecture
  • e_version - version of the file, it is necessary to install a new language in EV_CURRENT
  • e_entry - entry point addresses, not binding for us
  • e_phoff - use of the program header in the file, e_shoff - use of the section header, not recoverable
  • e_flags - specific to the prapori processor, for our architecture (Cortex-M3) it is necessary to set equal to 0x05000000 (ABI version 5)
  • e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum - not smart
  • e_shstrndx - hide section number, where the table rows of section headers are located. We still don’t have any leftovers of the same sections, we’ll put the whole number later
Program header creation
As it happened earlier, the Program Header Table is the table of the section's validity to the file segments of the memory, so I want to know where to write the skin section. The header is created behind the help function elf32_newphdr:
Elf32_Phdr * elf32_newphdr(Elf * elf, size_t count);
  • elf is our handle
  • count - the number of created elements in the tables. Since we will only have one section (with program code), then count will be equal to 1.
Turn 0 when miltsi or kazіvnik on the title of the program.
The skin element of the header table is described by the following structure:
typedef struct ( Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_W;
  • p_type - type of segment (section), here we are responsible for specifying PT_LOAD - segment to be acquired
  • p_offset - file offset, zvіdki pochinaєtsya given section, yak zavantazhuvatemeetsya on the riddle. We have a section.text, so that you will know the number of headers for the file and the header of the program, we can calculate the sum of the total of these headers. A long time, whatever type, can be taken away for the help function elf32_fsize:
    size_t elf32_fsize(Elf_Type type, size_t count, unsigned int version); type - ELF_T_ххх constant here, we will need to expand ELF_T_EHDR and ELF_T_PHDR; count - the number of elements of the required type, version - optionally set to EV_CURRENT
  • p_vaddr, p_paddr - that virtual physical address, for which it will be occupied in the same section. Since we don’t have a virtual address, we’ll install it equal to the physical one, in the simplest way - 0, so that our program can take advantage of it.
  • p_filesz, p_memsz - section expansion for files and memory. We have the same stench, but there are still no fragments of the section with the program code, we will install them later
  • p_flags - enabled for the privatized memory segment. Can be PF_R - read, PF_W - write, PF_X - see any combination. Set p_flags equal to PF_R + PF_X
  • p_align - segment alignment, we have 4
Section creation
After the headings are created, the sections can be opened. An empty section is created for the additional function elf_newscn:
Elf_Scn*elf_newscn(Elf*elf);
  • elf – handle, rotated earlier by the elf_begin function
The function rotates the caller to the section or 0 for pardons.
After creating a section, it is necessary to remember the title of the section and create a description of these sections.
We can look at the section header for the additional function elf32_getshdr:
Elf32_Shdr * elf32_getshdr(Elf_Scn * scn);
  • scn - section indicator, which we took from the elf_newscn function.
The section heading looks like this:
typedef struct ( Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf3__d_sh;
  • sh_name - section name - used for row table section headers (section.shstrtab) - div. "Tables of rows"
  • sh_type - type in place of section, for section with program code it is necessary to set SHT_PROGBITS, for sections with row table - SHT_STRTAB, for symbol table - SHT_SYMTAB
  • sh_flags - flags of the section, which can be combined, and for which we need only three:
    • SHF_ALLOC - means that the section is interested in a riddle
    • SHF_EXECINSTR - section to retaliate the win code
    • SHF_STRINGS - section to sweep row table
    Obviously, for the section.text from the program, it is necessary to set the ensigns SHF_ALLOC + SHF_EXECINSTR
  • sh_addr - addresses for which section will be enchanted by the riddle
  • sh_offset - use file section - don't cheat, install library for us
  • sh_size - section size - not chіpaєmo
  • sh_link - retrieve the number of the linked section, required for linking the section with a similar table of rows (div. distance)
  • sh_info - additional information, how to deposit according to section type, set to 0
  • sh_addralign - address alignment, not readable
  • sh_entsize - how the section is stacked from a number of elements of the same value, specifying the value of such an element, not chіpaєmo
After filling in the header, it is necessary to create a description of the section data using the elf_newdata function:
Elf_Data * elf_newdata(Elf_Scn * scn);
  • scn - selectively remove indicator for a new section.
The function turns 0 for pardons, or the indicator for the Elf_Data structure, so you will need to remember:
typedef struct ( void * d_buf; Elf_Type d_type; size_t d_size; off_t d_off; size_t d_align; unsigned d_version; ) Elf_Data;
  • d_buf - indicator on the data, so it is necessary to write to the section
  • d_type - type of data, we need to know ELF_T_BYTE
  • d_size - data size
  • d_off - used in section, set to 0
  • d_align - alignment, can be set to 1 - no alignment
  • d_version - version, language set for EV_CURRENT
Special sections
For our purposes, we will need to create the minimum required set of sections:
  • .text - section with program code
  • .symtab - symbol table in the file
  • .strtab - a table of rows to remove the symbol names from the .symtab section, the shards in the rest are not the names themselves, but their indexes
  • .shstrtab - table of rows to delete section names
All sections are created as described in the front section, but the special section of the skin may have its own peculiarities.
Section.
This section is to remove the code that is being checked out, so you need to set sh_type to SHT_PROGBITS, sh_flags - to SHF_EXECINSTR + SHF_ALLOC, sh_addr - set to the same address, for which the whole code will be captured
Section.
Section to search for descriptions of the symbols (functions) of the program and files, which stinks have been described. It is made up of the following elements of the header, 16 bytes each:
typedef struct ( Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; ) Elf32_Sym;
  • st_name - character name (row table index. strtab)
  • st_value - value (addresses to the input for the function or 0 for the file). The Cortex-M3 shards can use the Thumb-2 command system, while the addresses of the language can be unpaired (real addresses + 1)
  • st_size - length of function code (0 for file)
  • st_info - symbol type and scope. To define the value of the field, use the macro
    #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
    where b is scope and t is character type
    The scope can be STB_LOCAL (the symbol is not visible in other object files) or STB_GLOBAL (visible). For simplicity, we use STB_GLOBAL.
    Symbol type - STT_FUNC for function, STT_FILE for file
  • st_other - set to 0
  • st_shndx - section index, symbol (section index.text) assigned to SHN_ABS for the file.
    The section index behind the її scn descriptor can be assigned to the elf_ndxscn helper:
    size_t elf_ndxscn(Elf_Scn *scn);

This section is created with a rank, only sh_type should be set to SHT_SYMTAB, and the section index.strtab should be written in the sh_link field, with such a rank, ts_sections will become related.
Section.
This section will remove the names of all symbols from section.symtab. Created as a normal section, but sh_type needs to be set to SHT_STRTAB, sh_flags to SHF_STRINGS, so the section becomes a row table.
Data for the section can be selected when passing through the output text array, the indicator for which we can then write in the description of the data section (d_buf).
Section.
Section - a table of rows to replace the headers of all sections of the file, including its own header. Created like this section.strtab. After the creation of the index, it is necessary to write in the e_shstrndx field of the file header.
Row tables
Table rows to replace the rows that go in a row will end with a zero byte, the first byte in this table is also 0. The row index in the table is just a shift in bytes on the cob of the table, in this order, the first row "name" may be index 1, offensive row "var" may index 6.
Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \0 n a m e \0 v a r \0
Write to file
Also, the headers of that section have already been formed, now you need to write them to the file and complete the work with libelf. Recording the elf_update function:
off_t elf_update(Elf * elf, Elf_Cmd cmd);
  • elf - handle
  • cmd - the command that is good for writing ELF_C_WRITE.
The function rotates -1 for pardons. The text of the pardon can be removed by calling the function elf_errmsg(-1), so that you can turn the indicator to the row with the pardon.
We finish the work with the elf_end function library, which is passed our descriptor. It's too much to close the file earlier.
However, the creations of the file do not retaliate against the lagoonal information, as we add it to the offensive distribution.

DWARF creation

Compiling similar information for additional libraries, included with any pdf-file with documentation (libdwarf2p.1.pdf - A Producer Library Interface to DWARF).
The creation of taxation information is made up of the following stages:
  1. Vuzlіv creation (DIE - Debugging Information Entry)
  2. The creation of the attributes of the university
  3. Creation of data types
  4. Creation of procedures (functions)
Let's take a look at the stage of the report
Initialization libdwarf producer
We will create tax information at the hour of compilation at the same time with the creation of symbols in the section.
For initialization, we will win the dwarf_producer_init_c function. The library has a few more initialization functions (dwarf_producer_init, dwarf_producer_init_b), which are subject to certain aspects described in the documentation. In principle, you can beat them up.

Dwarf_P_Debug dwarf_producer_init_c(Dwarf_Unsigned flags, Dwarf_Callback_Func_c func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void *user_data, Dwarf_Error *error)

  • flags - a combination of "or" a number of constants to define different parameters, for example, the size of the information, the sequence of bytes (little-endian, big-endian), the relocation format, for which language we need DW_DLC_WRITE and DW_DLC_SYMBOLIC_RELOCATIONS
  • func - callback function, which will be invoked when collapsing ELF sections with custom information. Report div. at the branch "Creation of sections with tax information"
  • errhand - an indicator for the function, as if you would call out when you win a pardon. Can pass 0
  • errarg - data to be passed to the errhand function, can be set to 0
  • user_data - data that will be passed to the func function, can be set to 0
  • error - pardon code, what to turn
Turning function Dwarf_P_Debug - a descriptor that is used for all upcoming functions, or -1 for times of pardon, in which case there will be a pardon code in error
Creation of Woozliv (DIE - Debugging Information Entry)
As it was described more, nalagodzhuvalnaya information establishes a tree-like structure. In order to create a vuzol of that tree, you need:
  • create yogo function dwarf_new_die
  • add new attributes
The wuzol is created for the additional function dwarf_new_die:
Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf
  • new_tag – node tag (type) – DW_TAG_xxxx constant, which can be found in the libdwarf.h file
  • parent, child, left_sibling, right_sibling - good father, bait, lion and right sus_di vuzla. It is not necessary to indicate all the parameters, it is enough to indicate one, set 0 instead of the others.
  • error - correct the code of the pardon when її viniknіnі
The function turns DW_DLV_BADADDR for pardons or the node descriptor Dwarf_P_Die at times of success
The creation of the attributes of the university
For the creation of node attributes, the value is the home of the dwarf_add_AT_хххх functions. Sometimes it is problematic to determine which function it is necessary to create a necessary attribute, so I found a few times digging at the library's output code. Acts with functions will be described here, acts below - in the relevant divisions. All stinks accept the ownerdie parameter - the descriptor of the node to which the attribute will be added, and turn the pardon code in the error parameter.
The dwarf_add_AT_name function adds the "im'ya" attribute (DW_AT_name) to the site. Most nodes may have names (for example, procedures, changes, constants), some names may or may not have names (for example, the Compilation Unit)
Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die ownerdie, char *name, Dwarf_Error *error)
  • name - the value of the attribute (name of the node)

The functions dwarf_add_AT_signed_const, dwarf_add_AT_unsigned_const add an attribute of that signed (unsigned) value to the command node. Signed and unsigned attributes are chosen for setting the values ​​of constants, rozmіrіv, numbers in a row, then. Function format:
Dwarf_P_Attribute dwarf_add_AT_(un)signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error *error)
  • dbg – Dwarf_P_Debug descriptor, removed during library initialization
  • attr - attribute, the value of which is set - DW_AT_xxxx constant, which can be found in the libdwarf.h file
  • value - attribute value
Turn DW_DLV_BADADDR at times of pardon or attribute descriptor on successful completion.
Compilation Unit
Whether a tree can have roots - we have only one compilation, so that we can find information about the program (for example, the name of the head file, mov programming, what is written, the name of the compiler, the sensitivity of symbols (changes, functions) to the function, the head register programs, mail address, etc.). In principle, everyday attributes are obov'yazkovimi. For example, let's create information about the main file and the compiler.
Information about the head file
To save information about the head file, the attribute "name" (DW_AT_name) is selected, disable the dwarf_add_AT_name function, as shown in the "Creating Node Attributes" section.
Information about the compiler
Victory function dwarf_add_AT_producer:
Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error *error)
  • producer_string - row of text information
Set DW_DLV_BADADDR at times of pardon or attribute descriptor on successful completion.
Created Common Information Entry
Call when calling the function (subprogram) and the parameters of the address of the turn are placed on the stack (if the compiler can work in its own way), it is called the Call Frame. The controller needs information about the format of the frame so that it correctly assigns the address of the return function and induces backtrace - a function callback, which instills in us a streaming function, and the parameters of these functions. Also, the registers of the processor are called, as they are saved on the stack. The code that reserves space on the stack and saves the processor register is called the function prologue, the code that restores the stack register is called the epilogue.
This information should be stored in the compiler. For example, the prologue and the epilogue are neobov'yazkovo owed to the very cob and, for example, functions; inodі the frame is won; processor registers can be saved in other registers, etc.
Therefore, the owner needs to know how to change the values ​​of the processor register and de stink will be saved when entering the procedure. This information is called Call Frame Information - information about the frame format. For the skin address in the program (to clear the code), the address of the frame in memory (Canonical Frame Address - CFA) is specified, and information about the processor's register, for example, you can specify that:
  • register is not taken from the procedure
  • register does not change its value in the procedure
  • the register is saved on the stack behind the address CFA+n
  • register is saved in another register
  • the register is saved in the memory for a specific address, as it can be counted in a non-obvious way
  • and etc.
Some of the information is to be specified for the skin address of the code, but it is also summarized and taken at a glance in the .debug_frame section. So, since the address to the address won't change much, only її change at the sight of the instructions DW_CFA_хххх are encoded. Skin instructions for one change, for example:
  • DW_CFA_set_loc - point to the current address of the program
  • DW_CFA_advance_loc - pass indicator for a sprat of bytes
  • DW_CFA_def_cfa - specify the address of the stack frame (numeric constant)
  • DW_CFA_def_cfa_register - specify the address of the stack frame (taken from the processor register)
  • DW_CFA_def_cfa_expression - specify how to calculate the address of the stack frame
  • DW_CFA_same_value - indicates that the register is not changed
  • DW_CFA_register - specify which register to save in another register
  • and etc.
The .debug_frame section elements are entries that can be of two types: Common Information Entry (CIE) and Frame Description Entry (FDE). CIE to avenge information that is common for FDE records, rudely seems to describe the same type of procedures. FDE describes a skin-specific procedure. When you enter the procedure, the controller will start by clicking instructions from CIE, and then from FDE.
My compiler creates procedures that have CFAs in the sp(r13) register. We create CIE for all procedures. For which one is the dwarf_add_frame_cie function:
Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr init_bytes, Dwarf_Un
  • augmenter - string for UTF-8 encoding, the presence of which shows that before CIE or FDE is additional platform-information. We put an empty row
  • code_align - code alignment in bytes (we have 2)
  • data_align - data alignment for the frame (set to -4, which means all parameters take 4 bytes on the stack and grow down in memory)
  • ret_addr_reg - register to retrieve the address of the procedure's turn (we have 14)
  • init_bytes - an array to retrieve DW_CFA_хххх instructions. Unfortunately, there is no manual way to generate this array. You can form it manually, or look at it in the elf-file, whichever compiler generates, which I created. For my password, 3 bytes: 0x0C, 0x0D, 0, which is decrypted like DW_CFA_def_cfa: r13 ofs 0
  • init_bytes_len - length of the init_bytes array
The function rotates DW_DLV_NOCOUNT when militating or the CIE descriptor, which can be changed at the FDE creation hour for the skin procedure, which can be seen from the “FDE procedure creation” branch
Creation of data types
Before that, in order to create the procedures for that change, it is necessary to create knots on the back of the head, which correspond to the types of data. Types of data are impersonal, but stinks are grounded on base types (elementary types on square int, double then.), other types are based on base types.
Base type - wuzol іz tag DW_TAG_base_type. The new one can have buti attributes:
  • "im'ya" (DW_AT_name)
  • "encoding" (DW_AT_encoding) - means how the data itself describes the given base type (for example, DW_ATE_boolean - logical, DW_ATE_float - floating point, DW_ATE_signed - signed cel, DW_ATE_unsigned - unsigned cel, etc.)
  • "size" (DW_AT_byte_size - size for bytes or DW_AT_bit_size - size for bits)
Also, the higher education institution can take revenge on other neobov'yazkovy attributes.
For example, to create a 32-bit cilium-sign base type int, we would need to create a vuzel with the DW_TAG_base_type tag and set its attributes DW_AT_name - int, DW_AT_encoding - DW_ATE_signed, DW_AT_byte_size - 4.
After creating basic types, you can create similar ones in them. Such nodes are responsible for the DW_AT_type attribute - sending their base type. For example, a pointer to int - a vuzol with the DW_TAG_pointer_type tag is guilty of revenge in the DW_AT_type attribute, which was set on the previous creations of the "int" type.
The attribute from the request to another node is created by the dwarf_add_AT_reference function:
Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error *error)
  • attr - attribute, at times DW_AT_type
  • otherdie - descriptor of the node to the type, which one is requested
A collection of procedures
For the creation of procedures, it is necessary to explain one type of taxation information - Line Number Information. It will serve for setting the skin machine instructions to the sing line of the output code and for the possibility of post-line customization of the program. This information is collected from the .debug_line section. If we had a small enough space, then it would be saved from the look of the matrix, one row for skin instructions with such columns:
  • file name with exit code
  • row number of which file
  • file column number
  • chi є іnstruction by the cob of the operator chi to the block of operators
  • and etc.
Such a matrix would be even greater, so that її should be squeezed. First, the rows that are duplicated, seen, and in a different way, not the rows themselves are saved, but only change in them. These changes look like commands for a terminal machine, and the information itself is already taken into account by the program, as if it were “winned” by the automatic machine. The commands of the program look like this, for example: DW_LNS_advance_pc - put the command leader to the deuce address, DW_LNS_set_file - insert the file, which has a procedure assigned to it, DW_LNS_const_add_pc - insert the command leader of a few bytes then.
On such a low level, it is difficult to create information, so in the libdwarf library, a few functions have been transferred, which makes the task easier.
It is expensive to save the file name for the skin instructions, so the name should be saved in the special table. To create a file index, it is necessary to vicariate the dwarf_add_file_decl function:
Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error *error)
  • name - the name of the file
  • dir_idx – index of the folder where the file is located. The index can be taken from the help function dwarf_add_directory_decl. If you want to tie more paths, you can set 0 as a folder index and do not tie dwarf_add_directory_decl
  • time_mod – file modification hour, may not be specified (0)
  • length - expand the file, also not binding (0)
The function to turn the file index or DW_DLV_NOCOUNT at pardon times.
For the creation of information about line numbers, there are three functions: dwarf_add_line_entry_b, dwarf_lne_set_address, dwarf_lne_end_sequence, as we can see below.
The creation of taxation information for the procedure is given at the end of the stage:
  • created to the procedure symbol of the section.
  • creating a procedure node with attributes
  • creation of FDE procedures
  • setting parameters in a procedure
  • collection of information about row numbers
Creation of the procedure symbol
The procedure symbol is created as described in the "Section.symtab" section. For them, the symbols of procedures are interleaved with the symbols of files for which they change the input code of these procedures. I first create a symbol to the file, then procedures. With whom the file becomes more precise, and if such a procedure is rebuyed from a streaming file, the file does not need to be created again.
Creating a Procedure Node with Attributes
On the other hand, we create the node for the additional function dwarf_new_die (div. division "Creation of Wuzley"), specifying as the DW_TAG_subprogram tag, and as a father - Compilation Unit (which is a global procedure) or a DIE (which is local). Let's create attributes:
  • procedure name (function dwarf_add_AT_name, div. "Created node attributes")
  • row number of the file, where the procedure code is originated (attribute DW_AT_decl_line), function dwarf_add_AT_unsigned_const (div. "Created node attributes")
  • mail address of the procedure (attribute DW_AT_low_pc), function dwarf_add_AT_targ_address, div.
  • end address of the procedure (attribute DW_AT_high_pc), function dwarf_add_AT_targ_address, div.
  • the type of the result that is turned by the procedure (attribute DW_AT_type - set before creation type, div. "Created data types"). As the procedure does not rotate anything - it is not necessary to create any attribute
The attributes DW_AT_low_pc and DW_AT_high_pc need to be set to the function dwarf_add_AT_targ_address_b specifically recognized for this:
Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
  • attr - attribute (DW_AT_low_pc or DW_AT_high_pc)
  • pc_value - address value
  • sym_index – index of the procedure symbol in the table. Neobov'viscous, can be transmitted 0
The function to turn DW_DLV_BADADDR for pardons.
Creation of FDE procedures
As it was said earlier in the "Creation of the Common Information Entry" section, for a skin procedure, it is necessary to create a description of the frame, which should be used in the kilka stages:
  • Creation of a new FDE (div. Creation of the Common Information Entry)
  • bringing the created FDE to the list
  • adding instructions to the created FDE
You can create a new FDE using the dwarf_new_fde function:
Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error)
The function will change the new FDE handle to DW_DLV_BADADDR for pardon.
You can get a new FDE to the list with the help of dwarf_add_frame_fde:
Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym
  • fde - selectively descriptor
  • die - procedure DIE (div. Create procedure node with attributes)
  • cie - CIE descriptor (common information entry div.)
  • virt_addr - mail address of our procedure
  • code_len - procedure length in bytes
Function to turn DW_DLV_NOCOUNT at times of pardon.
If so, you can add instructions DW_CFA_хххх to our FDE. Use the dwarf_add_fde_inst and dwarf_fde_cfa_offset functions. First, add the given instruction to the list:
Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)
  • op - instruction code (DW_CFA_хххх)
  • val1, val2 - instruction parameters (different for skin instructions, div. Standard, section 6.4.2 Call Frame Instructions)
The dwarf_fde_cfa_offset function adds the DW_CFA_offset instruction:
Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *error)
  • fde - handle to created FDE
  • reg - register, which is written to the frame
  • offset - offset of the frame (not in bytes, but in frame elements, div. Common Information Entry, data_align)
For example, the compiler creates a procedure that saves the register lr (r14) for a prolose like a stack frame. Насамперед потрібно додати інструкцію DW_CFA_advance_loc з першим параметром, рівним 1, що означає просування регістра pc на 2 байти (див. Створення Common Information Entry, code_align), потім додати DW_CFA_def_cfa_offset з параметром 4 (завдання зміщення даних у ф функцію dwarf_fde_cfa_offset з параметром reg=14 offset=1, which means register r14 is written to the frame with offsets of -4 bytes in CFA.
Creating procedure parameters
The creation of the parameters of the procedure is similar to the creation of the most significant changes, divs. "Creation of Changes and Constants"
Creation of information about row numbers
The creation of this information is as follows:
  • at the beginning of the procedure, we start the instruction block with the dwarf_lne_set_address function
  • for skin line code (or machine instructions) we create information about the exit code (dwarf_add_line_entry)
  • for example, the procedure ends the block of instructions with the function dwarf_lne_end_sequence
The dwarf_lne_set_address function sets the address for which the block of instructions starts:
Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error *error)
  • offs - procedure addresses (addresses of the first machine instruction)
  • sym_idx - symbol index (not binding, you can enter 0)

The dwarf_add_line_entry_b function adds to the section.debug_line information about the lines of the output code. I call this function for the skin machine instructions:
Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Bool is_epilogue_begin, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)
  • file_index - file index of the output code, previously removed by the dwarf_add_file_decl function (div. "Creating procedures")
  • code_offset - addresses of threaded machine instructions
  • lineno - row number of output code file
  • column_number - column number of the output code file
  • is_source_stmt_begin - 1st line instruction first in code in a lineno row (I start vicorist 1)
  • is_basic_block_begin - 1st line instruction first in the block of statements (I need to start 0)
  • is_epilogue_begin - 1st inline instruction first in the epilogue of the procedure (not binding, I have 0)
  • is_prologue_end - 1st inline instruction to stop at the prologue of the procedure (obv'yazykovo!)
  • isa - instruction set architecture (instruction set architecture). Obov'yazkovo sled to specify DW_ISA_ARM_thumb for ARM Cortex M3!
  • discriminator. One position (file, row, stompchik) of the output code can be used for different machine instructions. In such a time, for the sets of such instructions, it is necessary to install different discriminators. There are no such behaviors, but there can be 0
The function turns 0 (success) or DW_DLV_NOCOUNT (pardon).
Once you're done, the dwarf_lne_end_sequence function ends the procedure:
Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr address; Dwarf_Error *error)
  • address - addresses of the threaded machine instruction
Turn 0 (success) or DW_DLV_NOCOUNT (pardon).
On which we complete the creation of the procedure.
Creation of change and constants
Zagalom zminnі dosi simple. They have є іm'ya, a place of memory (or a register of the processor), where they know their data, as well as the type of data. As if changing globally - її the father can be the Odinitsa Compilation, as well as the local - a different university (especially the parameters of the procedures are taken into account, they can be the procedure itself). It is also possible to indicate, in which file, in a row and column, there is a change of voice.
In the simplest way, the value of the change is known for a certain fixed address, but a lot of changes are dynamically created when entering the procedure on the stack or register, and sometimes the calculation of the address of the value can be non-trivial. The standard has a mechanism for describing where the value of the change is located - address expressions (location expressions). Address viraz - the price of typing instructions (constant DW_OP_хххх) for a fort-like sewing machine, in fact, the price of mov with debugging, procedures and arithmetic operations. I can’t look back over my words, we are actually only called a little bit of instructions:
  • DW_OP_addr - specify change address
  • DW_OP_fbreg - specify the change to the base register (name the stack indicator)
  • DW_OP_reg0… DW_OP_reg31 - indicative of those that are changed by the selected register
In order to create an address virase, you need to create an empty virase (dwarf_new_expr) first, add a new instruction (dwarf_add_expr_addr, dwarf_add_expr_gen, etc.) and add it to the node as the value of the DW_AT_location attribute (dwarf_add_AT_location.
The function of creating an empty address window turns the descriptor or 0 for pardons:
Dwarf_Expr dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error *error)
To add captions to a virus, it is necessary to include the dwarf_add_expr_gen function:
Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)
  • opcode - operation code, constant DW_OP_хххх
  • val1, val2 – instruction parameters (div. Standard)

For the explicit setting of the changeable address, the change of the forward one is due to the dwarf_add_expr_addr function:
Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Signed sym_index, Dwarf_Error *error)
  • expr - descriptor of the address virase, to which the instruction is given
  • address - change addresses
  • sym_index - symbol index in the table. Neobov'viscous, can be transmitted 0
The function also rotates DW_DLV_NOCOUNT at different pardons.
You can add the address virus to the site using the dwarf_add_AT_location_expr function:
Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *error)
  • ownerdie - vuzol, to which viraz can reach
  • attr - attribute (at times DW_AT_location)
  • loc_expr - a handle to a previously created address virase
The function rotates the attribute descriptor or DW_DLV_NOCOUNT at times of pardon.
Changes (as well as procedure parameters) and constants - the primary nodes with the tag DW_TAG_variable, DW_TAG_formal_parameter and DW_TAG_const_type are optional. For them, you need the following attributes:
  • change/constant name (function dwarf_add_AT_name, div. "Created node attributes")
  • row number of the file, declaring the change (attribute DW_AT_decl_line), function dwarf_add_AT_unsigned_const (div. "Created node attributes")
  • file name index (attribute DW_AT_decl_file), function dwarf_add_AT_unsigned_const (div. "Create node attributes")
  • change/constant data type (attribute DW_AT_type - set before creation type, div. "Created data types")
  • address virase (div. vishche) - required for change or procedure parameter
  • or the value for the constant (attribute DW_AT_const_value, div. "Created node attributes")
The creation of sections with taxation information
After creating all the nodes of the tree of nalagodzhuvalnoї іnformatsії, you can proceed to the formation of the elf-section with it. There are two stages:
  • We need to call the dwarf_transform_to_disk_form function back to back, just like we wrote the callback function for creating the needed elf sections once for the skin section
  • for the skin section, the dwarf_get_section_bytes function will return the data to us, as it will be necessary to write down the corresponding section
Function
dwarf_transform_to_disk_form (Dwarf_P_Debug dbg, Dwarf_Error* error)
translate the custom information we have created into a binary format, but do not write anything to disk. Won turn back to us a lot of created elf-sections or DW_DLV_NOCOUNT for pardons. For the skin section, there will be a callback function called, which was passed during library initialization to the dwarf_producer_init_c function. You can write this function yourself. Її specification is as follows:
typedef int (*Dwarf_Callback_Func_c)(char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_index, void * user_da,
  • name - name of the elf-section, how to create
  • size – section size
  • type - section type
  • flags - section ensigns
  • link - section link field
  • info - section information field
  • sect_name_index – optionally rotate section index with relocations (not binding)
  • user_data - transmitted to us as such, as my yoga was set in the library initialization function
  • error - you can pass the pardon code here
Our functions are responsible for:
  • create a new section (function elf_newscn, div. Create sections)
  • create section header (function elf32_getshdr, ibid.)
  • remember yogo correctly (div. ibid.). It's simple, because the section header fields match the parameters of our function. fields sh_addr, sh_offset, sh_entsize are set to 0, and sh_addralign to 1
  • rotate the index of the created section (function elf_ndxscn, div. "Section.symtab") or -1 for pardons (by setting the pardon code in error)
  • it is also our fault to skip the ".rel" section (in our viewport) by turning 0 when the function is turned
When the dwarf_transform_to_disk_form function is completed, it will return the number of created sections to us. We will need to go through the loop from 0 to the skin section, following these lines:
  • Create data to write to the section using the dwarf_get_section_bytes function:
    Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Error* error)
    • dwarf_section - section number. May be in the interval 0..n, where n is the number returned to us by the dwarf_transform_to_disk_form function
    • elf_section_index - rotates the section index, it is necessary to write data into the box
    • length - dozhina tsikh danih
    • error - do not tweet
    The function rotates the indicator to remove data or 0 (in that case,
    if there are no more sections for folding)
  • create a data handle of the streaming section (function elf_newdata, div. Create sections) and save it (div. ibid.), setting:
    • d_buf - indicator on the data, taken by us from the forward function
    • d_size - rozmir tsikh danih (ibid.)
Completion of work with the library
After forming the sections, you can finish the robot with the libdwarf function dwarf_producer_finish:
Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error* error)
The function turns DW_DLV_NOCOUNT for pardons.
I respect that this step will not be recorded on the disc. Recording needs to work for additional functions of the distribution "ELF Creation - Recording to a file".

Visnovok

On whom everything.
I repeat, the creation of nalagodzhuvalnoi іnformatsiї - the topic is already great, and I didn’t touch on the rich topics, only showing the curtain. Bazhayuchi can gloat to the point of indiscretion.
As soon as you have food, I will try to testify on them.

For visibility on the computer installed antivirus software possible, possible scan all files on the computer, as well as the skin file okremo. You can scan any file by right-clicking on the file and selecting the check option to check the file for viruses.

For example, on whom the little one was seen file my-file.elf, then right-click on the desired file, and select the option in the file menu "Scan for help AVG". When you select this option, AVG Antivirus will be asked to scan the file for viruses.


Sometimes a pardon can be blamed on the result incorrect software installation what can be connected with the problem, what is vinyl in the installation process. Can you set up your operating system Link your ELF file with the correct software, spitting on such a name "associate file extensions".

Sometimes simple Reinstalling Dolphin (emulator) You can solve your problem by properly calling ELF from Dolphin (emulator). In other cases, problems with file associations can be blamed as a result nasty software programming retailer, and you may need to contact the retailer for further assistance.


Porada: Try Dolphin updates (emulator) to the rest of the version to see if the rest of the updates are installed.


Might be obvious, but often In the middle, the ELF file itself could be the cause of the problem.. If you have received the file via an email attachment, or you have captured it from the website, and the capture process is interrupted (for example, turning on the live or for some other reason), the file can be corrupted. If possible, try making a new copy of the ELF file and try again.


Carefully: Poshkodzhenie file can cause subsequent blockages in the front, or even if it's a fluke program on your PC, it's even more important to keep your computer updated with anti-virus updates.


Just like your ELF file problems with hardware security on your computer, you may need to open the file Update Appliance Drivers, pov'yazanih іz cim possessed.

What is the problem ring up according to the types of multimedia files, yakі lie down in the form of a successful solution of hardware security in the middle of the computer, for example, sound card or video card. For example, if you want to open an audio file, if you can't open it, you might need Update sound card drivers.


Porada: So when trying to open an ELF file, you will accept pardon notification, pov'yazanu z.SYS file, problem, ymovіrno, maybe buti connected with poshkogenimi or outdated device drivers, as it is necessary to change. This process can be facilitated with the help of software for updating drivers, such as DriverDoc.


How did the little ones solve the problem, and you're still having problems opening ELF files, but it might be related to number of available system resources. For some versions of the ELF files, you may need a significant amount of resources (for example, memory / RAM, enumeration pressure) for a hard drive on your computer. Such a problem often happens, as you can easily download old computer hardware without security, and at the same time fill up a new operating system.

Such a problem can be blamed, if it is important for the computer to get out of work, the operating system shards (those other services that run in the background) can conserve a lot of resources to read the ELF file. Try to close all the programs on your PC, first open the Nintendo Wii Game File. Having used all the available resources on your computer, you will have the best brain for trying to open the ELF file.


Yakscho wi vikonali all described above croki, and your ELF file, as before, does not display, you may need to renewal of possession. У більшості випадків, навіть при використанні старих версій обладнання, обчислювальна потужність може бути більш ніж достатньою для більшості додатків користувача (якщо ви не виконуєте багато ресурсомісткої роботи процесора, такий як 3D-рендеринг, фінансове/наукове моделювання або інтенсивна мультимедійна робота) . in such a manner, completely immovable, so that your computer does not get the necessary memory(often called "RAM", chi operational memory) scheduling a file.

We hope they helped you solve the problem with the ELF file. If you don't know where you can download the program from our list, click on the link (named the program) - You will know the report information about the location, stars, download the secure installation version of the required program.

We can help you with advice specifically on the price or similar nutrition:

  • How to open a file with ELF extensions?
  • How to convert an ELF file to another format?
  • What is the extension of the ELF format?
  • What programs can serve the ELF file?

As a result of reviewing the materials on the other side, you, as before, did not take away the sufficient evidence on the same from the submissions of the food, it means that the information about the ELF file provided here is not correct. Get in touch with us, vikoristovuyuchi contact form and write, what information you did not know.

What else can cause problems?

There can be more reasons why you cannot open an ELF file (not only the most common programs).
Perche- the ELF file may be incorrectly connected (insane) from the installed addendum for this maintenance. At this time, you need to independently change your link. Therefore, I can right-click the bear button on the ELF file, which is necessary to edit, click the option "Vіdkriti for help" and then select the program from the list, as we installed it. In the event of such a problem, the ELF file is to be blamed again.
In a different way- a file, which you want to open, you can just use it. At this time, it will be better to know the new version, or download it again from the same dzherel (maybe because of the drive in the front session, the capture of the ELF file did not end and the wine could not be correctly entered).

Do you want to help?

If you have additional information about the expansion of the ELF file, we will be happy to share it with the coristuvachi of our site. Hurry up with the form and send us your information about the ELF file.

© 2022 androidas.ru - All about Android