Linking, Loading and Mapping
description
Transcript of Linking, Loading and Mapping
Linking, Loading and Mapping
A look at how Operating System utilities and services support
application deployment
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 Command
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
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
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
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
Section-Headers
sh_name sh_type sh_flags sh_addr sh_offset
sh_size sh_link sh_info sh_addralign sh_entsize
Program-Headers
p_type p_offset p_vaddr p_paddr
p_filesz p_memsz p_flags p_align
Linux ‘Executable’ ELF files
• The Executable ELF files produced by the Linux linker are configured for execution 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 Pentium’s paging mechanism which makes all this possible (Also read Chapter 8 in Stallings textbook)
Linux ‘Linkable’ ELF files
• But it is possible that some ‘linkable’ ELF files are self-contained (i.e., they do not need to be linked with other object-files or libraries)
• Our ‘courseid.o’ is such an example; you use this command to produce ‘courseid.o’:
$ gcc -c courseid.cpp• The GNU linker (named ‘ld’) will let us override
its usual linking rules if we use a special-format linker script (ours is named ‘ldscript’ on website)
Our ‘elfinfo.cpp’ tool
• We wrote a program that ‘parses’ an ELF file, showing a breakdown of its sections
• You can use it to examine ‘courseid.o’
$ ./elfinfo courseid.o
• It shows the section-names and locations
‘Binary-Executable’ format
• Instead of the usual ELF executable-fornat file, we can produce a ‘binary-executable’ file (intended to be ‘loaded’ at address 0): $ ld courseid.o –T ldscript –o courseid.b
• The linker-script instructs ‘ld’ to combine our object-file’s ‘.text’, ‘.data’ and ‘.bss’ sections
• The ELF header and other sections get omitted • ‘ld’ performs memory-address ‘relocations’ as
needed, so that any global addresses become offsets from the starting-address (i.e., from zero)
What ‘ld’ does with ‘courseid.o’
ELF Header
Section-Header Table
Section (.text)Section (.data)
Linkable File
Section (.bss)
Section (.rel.text)
Section (.text)
perform address-relocations
extract
These two sections happen to be empty in our particular example
other sections
courseid.ocourseid.b
Section (.rodata)
Section (.data)Section (.bss)
Section (.rodata)
extractextractextract
Memory: Physical vs. Virtual
VirtualAddressSpace(4 GB)
Physicaladdress space
(1 GB)
Portions of physical memory are “mapped” by the CPU into regions of each task’s ‘virtual’ address-space
Mapping a file to memory
• The ‘mmap()’ function allows a program to ask the kernel to setup a memory-mapping
• The contents of a file can be ‘mapped’ to a designated virtual address in user-space
• If the file contains executable instructions, the CPU can be made to ‘execute’ them by simply calling the entry-point address
• We will illustrate this with ‘launch.cpp’
Memory-Mapping a disk-file
Virtualaddressspace
Physicaladdress space
Portions of secondary memory can be “mapped” to unused regions of a task’s virtual address-space via the CPU’s page-fault mechanism
file
file
Disk storage (files)
How file-mapping is requested
The ‘mmap()’ function takes six arguments-- the region’s desired virtual-address
-- the region’s length (expressed in bytes) -- access privileges (e.g., PROT_READ) -- mapping-type flags (e.g., MAP_FIXED) -- the file’s ID-number (from ‘open()’) -- the file’s starting offsetIf successful, it returns map’s virtual address
Steps to follow
• 1) Open the file with ‘open()’ function
• 2) Determine length of the region to map
• 3) Request the mapping with ‘mmap()’
• 4) Close the file-descriptor with ‘close()’
• 4) Use the mapped region as normal data
• 5) Destroy the mapping with ‘munmap()’
Executing ‘courseid.b’
• Declare a function-pointer and initialize it with the virtual address of the entry-point
void (*my_program)( void ) = 0x00000000;
• Map the executable file to virtual memory at its expected load-address (0x00000000)
• Execute the memory-mapped program using an ordinary (indirect) C function-call
my_program();
Our ‘launch.cpp’ Demo
• We have written an application program that illustrates the foregoing memory-map steps
• After you try out this demo, you can gain a better understanding of ‘mmap()’ if you add a few extra statements to ‘launch.cpp’ and recompile it
• Add calls to ‘getchar()’ before and after each of the key operations, and then examine the ‘/proc/<pid>/maps’ file (from another virtual console) each time the demo pauses for input
Alternatives
• Can I map my file to a different address and still execute it just as easily?
• Yes – if you adjust the ‘load-address’ used by your linker script, and also adjust your ‘mmap()’ argument and function-pointer accordingly
• But you have to use a ‘load-address’ that’s a multiple of the CPU’s page-size (i.e., 4K)
In-Class exercise #1
• Try using 0x00040000 as your linker script ‘load-address’ and re-link the ‘courseid.o’ object-file to get a new ‘courseid.b’ file
• Then modify the ‘launch.cpp’ source-code so it uses this new virtual-address as the ‘mmap()’ start-address and the function pointer’s value (i.e., use the assignment
myexec = ( void (*)( ) )0x00040000;
In-class exercise #2
• See if you can modify the ‘courseid.cpp’ program so that it will use one or more function-arguments passed to it from its caller: e.g., int main( int len, char *msg );
• Also make it return some function-value: e.g., return len;
• Then modify ‘launch.cpp’ accordingly:
e.g., int retval = myexec( 6, “Hello\n” );