interfacing with elf files

29
Interfacing with ELF files An introduction to the Executable and Linkable Format (ELF) binary file specification standard

Upload: clark-wall

Post on 03-Jan-2016

40 views

Category:

Documents


0 download

DESCRIPTION

Interfacing with ELF files. An introduction to the Executable and Linkable Format (ELF) binary file specification standard. Overview of source translation. User-created files. C/C++ Source and Header Files. Assembly Source Files. Makefile. C/C++ Source and Header Files. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Interfacing with ELF files

Interfacing with ELF files

An introduction to the Executable and Linkable Format (ELF) binary

file specification standard

Page 2: Interfacing with ELF files

Library Files

Object Files

Assembly Source

Files

C/C++ Source and Header

Files

Overview of source translation

MakefileC/C++ Source

and HeaderFiles

Assembly Source

Files

Linker Script

File

User-created files

preprocessor

compiler assembler

Make Utility

Object Files

Shared Object

File

Linkable Image File

Executable Image File

Link Map File

Linker and Locator Library Files

Archive Utility

Page 3: Interfacing with ELF files

Section-Header Table(optional)

Executable versus Linkable

ELF Header

Section 2 Data

Section 3 Data

…Section n Data

Segment 1 Data

Segment 2 Data

Segment 3 Data

…Segment n Data

Linkable File Executable File

Section-Header Table

Program-Header Table(optional)

Program-Header Table

ELF Header

Section 1 Data

Page 4: Interfacing with ELF files

Role of the Linker

ELF Header

Section-Header Table

Section 1 DataSection 2 Data

…Section n Data

ELF Header

Section-Header Table

Section 1 DataSection 2 Data

…Section n Data

ELF Header

Program-Header Table

Segment 1 Data

Segment 2 Data

…Segment n Data

Linkable File

Linkable File

Executable File

Page 5: Interfacing with ELF files

ELF Header

e_type e_machine e_version e_entry e_phoff

e_shoff e_flags e_ehsize e_phentsize e_phnum e_shentsize

e_shnum e_shstrndx

e_ident [ EI_NIDENT ]

Section-Header Table: e_shoff, e_shentsize, e_shnum, e_shstrndx

Program-Header Table: e_phoff, e_phentsize, e_phnum, e_entry

NOTE: The sizes of these fields, and their arrangement, is slightly different forthe ELF64 files that are produced by default on our x86_64 Linux workstations.

Page 6: Interfacing with ELF files

Section-Headers

sh_name sh_type sh_flags sh_addr sh_offset

sh_size sh_link sh_info sh_addralign sh_entsize

NOTE: These are for the ELF32 file-format.

Page 7: Interfacing with ELF files

Program-Headers

p_type p_offset p_vaddr p_paddr

p_filesz p_memsz p_flags p_align

NOTE: These are for the ELF32 file-format.

Page 8: Interfacing with ELF files

Official ELF documentation

• The official document that describes ELF file-formats for both the ‘linkable’ and the ‘executable’ files is available online on our CS630 course website (see ‘Resources’)

• (Be aware that this document has been revised to accommodate programs that will be run on platforms which implement 64-bit addresses and processor registers)

Page 9: Interfacing with ELF files

Memory: Physical vs. Virtual

VirtualAddressSpaces(4 GB)

Physicaladdress space

(4 GB)

Portions of physical memory are “mapped” by the CPU into regions of each task’s ‘virtual’ address-space

Page 10: Interfacing with ELF files

Linux ‘Executable’ ELF files

• An Executable ELF32 file produced by the Linux linker is configured to execute in a private ‘virtual’ address space, whereby every program gets loaded at the identical virtual memory-address (i.e., 0x08048000)

• We will soon study the x86 CPU’s paging mechanism which makes this possible (i.e., after we have finished Project #1)

Page 11: Interfacing with ELF files

Linux ‘Linkable’ ELF files

• It is possible that some ‘linkable’ ELF files are self-contained (i.e., they may not need to be linked with any other object-files, or with any shared libraries)

• Our ‘manydots.o’ is one such example• So we can write our own system-code that

can execute the instructions contained in a stand-alone ‘linkable’ object-module, using the CPU’s ‘segmented’ physical memory

Page 12: Interfacing with ELF files

Our ‘loadmap.cpp’ utility

• We created a tool that ‘parses’ a linkable ELF file, to identify each section’s length, type, and location within the object-module

• For those sections containing the ‘text’ and ‘data’ for the program, we build segment-descriptors, based on where the linkable image-file will reside in physical memory

• Then we jump to the ‘_start’ entry-point

Page 13: Interfacing with ELF files

32-bit versus 16-bit code

• Linux’s compilers, and the ‘as’ assembler, can produce object-files that are intended to reside in ’32-bit’ memory-segments (i.e., the D-bit in a code-segment descriptor is set to 1)

• This affects the CPU’s interpretation of all the machine-instructions it subsequently fetches

• Our ‘as’ assembler can produce both16-bit and 32-bit code (although its default is 64-bit code)

• We employ ‘.code32’ or ‘.code16’ directives

Page 14: Interfacing with ELF files

Example: ‘as’ Listing

.code320x0000 01 D8 add %eax, %ebx0x0002 66 01 D8 add %ax, %bx0x0005 90 nop

.code160x0006 66 01 D8 add %eax, %ebx0x0009 01 D8 add %ax, %bx0x000B 90 nop

.end

Page 15: Interfacing with ELF files

Demo-program

• We created a Linux program (‘linuxapp.s’) that invokes two system-calls (‘write’ and ‘exit’)

• We assembled it with the ‘as’ assembler:$ as --32 linuxapp.s –o linuxapp.o

• This linkable ELF object-file ‘linuxapp.o’ should then be written to our hard-disk partition (‘/dev/sda4’) at sector 65, using the ‘dd’ utility:

$ dd if=linuxapp.o of=/dev/sda4 seek=65

• So it will get loaded into memory by ‘cs630ipl’

Page 16: Interfacing with ELF files

Memory-Map

IVT

ROM-BIOS DATA

BOOT-LOADER

‘tryelf32.b’image

Both ‘tryelf32.b’ and ‘linuxapp.o’ will get loaded into ram from sectors 1..127 of the disk-partition by our ‘cs630ipl.b’ program-loader

0x00010000

0x00018000

0x00000400

0x00007C00 ‘cs630ipl.b’ is read from CS630 disk-partition via ROM-BIOS bootstrap

‘linuxapp.o’ image

hard disk

Page 17: Interfacing with ELF files

Segment Descriptors

• We created 32-bit segment-descriptors for the ‘text’ and ‘data’ sections of ‘linuxapp.o’ (in a Local Descriptor Table) with DPL=3

• For the ‘.text’ section: offset in ELF file = 0x34 size = 0x24

• So its segment-descriptor is:

.word 0x0023, 0x8034, 0xFA01, 0x0040

(base-address = load-address + file-offset)

Page 18: Interfacing with ELF files

Descriptors (continued)

• For the ‘.data’ section:offset in ELF file = 0x58 size = 0x16

• So its segment-descriptor is: .word 0x0015, 0x8058, 0xF201, 0x0040

(base-address = load-address + file-offset)• For our ring3 stack (not part of ELF file):

.word 0x0000, 0x0000, 0xF602, 0x00C0Note: It’s an ‘expand-down’ data-segment!

Page 19: Interfacing with ELF files

‘Expand-Down’ segments

base-address

segment limit

Normal ‘Expand-Up’ Data-Segment

base-address

segment limit

Special ‘Expand-Down’ Data-Segment

Page 20: Interfacing with ELF files

Task-State Segment

• Because any system-calls (via int 0x80) will cause privilege-level transitions, we will need to setup a Task-State Segment (to store a ring0 stack-pointer SS0:ESP0)

theTSS: .long 0, 0, 0 # 3 longwords

• Its segment-descriptor goes into our GDT:

.word 0x000B, theTSS, 0x8901, 0x0000

Page 21: Interfacing with ELF files

Transition to Ring 3

• Recall that we use ‘lret’ to enter ring-3:pushw $userSSpushw $0pushw $userCSpushw $0lret

(NOTE: This assumes we are coming from a 16-bit code-segment in protected-mode)

Page 22: Interfacing with ELF files

System-Call Dispatcher

• All system-calls get ‘vectored’ through our IDT’s interrupt-gate number 0x80

• For ‘linuxapp.o’ we only need to implement two system-calls: ‘exit’ and ‘write’

• But to simplify future enhancements, we use a ‘jump-table’ anyway (although for now it has a few ‘dummy’ entries, which can easily be modified later on)

Page 23: Interfacing with ELF files

System-Call ID-numbers

• System-call ID #0 (it will never be needed)• System-call ID #1 is for ‘exit’ (required)• System-call ID #2 is for ‘fork’ (deferred)• System-call ID #3 is for ‘read’ (deferred)• System-call ID #4 is for ‘write’ (required)• System-call ID #5 is for ‘open’ (deferred)• System-call ID #6 is for ‘close’ (deferred)(NOTE: over 300 system-calls exist in Linux)

Page 24: Interfacing with ELF files

Defining our jump-table

sys_call_table:

.longdo_nothing # for service 0

.longdo_exit # for service 1

.longdo_nothing # for service 2

.longdo_nothing # for service 3

.longdo_write # for service 4

.equ NR_SYS_CALLS, ( . - sys_call_table)/4

Page 25: Interfacing with ELF files

Setting up IDT Gate 0x80

• The Descriptor Privilege Level must be 3

• The Gate-Type should be ‘386 Trap-Gate’

• The entry-point will be our ‘isrSVC’ label

# Interrupt Descriptor Table’s entry for SuperVisor Call (int $0x80)

mov $0x80, %ebx # table-entry array-indexlea theIDT(, %ebx, 8), %di # descriptor offset-addressmovw $isrSVC, %ss:0(%di) # entry-point offset’s lowordmovw $privCS, %ss:2(%di) # selector for code-segmentmovw $0xEF00, %ss:4(%di) # Gate-Type: 386 Trap-Gatemovw $0x0000, %ss:6(%di) # entry-point offset’s hiword

Page 26: Interfacing with ELF files

Using our jump-table

isrSVC: # service-number is found in EAX

cmp $NR_SYS_CALLS, %eax

jb idok

xor %eax, %eax

idok: jmp *sys_call_table(, eax, 4)

Page 27: Interfacing with ELF files

Our ‘exit’ service

• When the application invokes the ‘exit’ system-call, our mini ‘operating system’ should leave protected-mode and return back to our boot-loader program

• The ‘exit-code’ parameter (in %ebx) may just as well be discarded (since this isn’t yet a multitasking operating-system)

Page 28: Interfacing with ELF files

Our ‘write’ service

• We only implement writing to the STDOUT device (i.e., the video display console)

• For most characters in the user’s buffer, we just write the ascii-code (and standard display-attribute) directly to video memory at the current cursor-location and advance the cursor (scrolling the screen if needed)

• Special ascii control-codes (‘\n’, ‘\r’, ‘\b’) are treated differently, as on a TTY device

Page 29: Interfacing with ELF files

In-Class Exercise

• The ‘manydots.s’ demo (to be used with Project #1) uses the ‘read’ system-call (in addition to the ‘write’ and ‘exit’ services)

• However, you could still ‘execute’ it, using our ‘tryelf32.s’ mini operating-system, by letting the ‘read’ service simply “do nothing” (or return with some kind of “hard-coded” buffer-contents)

• You just need to modify the LDT descriptors so they’ll conform to ELF sections in ‘manydots.o’