220 likes | 448 Views
Linking, Loading and Mapping. A look at how Operating System utilities and services support application deployment . Overview of source translation. User-created files. C/C++ Source and Header Files. Assembly Source Files. Makefile. C/C++ Source and Header Files. Assembly
E N D
Linking, Loading and Mapping A look at how Operating System utilities and services support application deployment
Overview of source translation User-created files C/C++ Source and Header Files Assembly Source Files Makefile C/C++ Source and Header Files Assembly Source Files Linker Command File preprocessor Make Utility compiler assembler Object Files Object Files Archive Utility Library Files Library Files Linker and Locator Shared Object File Linkable Image File Executable Image File Link Map File
Executable versus Linkable ELF Header ELF Header Program-Header Table (optional) Program-Header Table Section 1 Data Segment 1 Data Section 2 Data Segment 2 Data Section 3 Data Segment 3 Data … Section n Data … Segment n Data Section-Header Table Section-Header Table (optional) Linkable File Executable File
Role of the Linker ELF Header ELF Header Section 1 Data Program-Header Table Section 2 Data … Section n Data Segment 1 Data Section-Header Table Segment 2 Data Linkable File … Segment n Data ELF Header Section 1 Data Section 2 Data Executable File … Section n Data Section-Header Table Linkable File
ELF Header e_ident [ EI_NIDENT ] 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 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’ courseid.o courseid.b ELF Header extract Section (.text) Section (.text) extract Section (.data) Section (.data) extract Section (.bss) Section (.bss) extract Section (.rodata) Section (.rodata) other sections Section (.rel.text) perform address-relocations Section-Header Table Linkable File These two sections happen to be empty in our particular example
Memory: Physical vs. Virtual Virtual Address Space (4 GB) Portions of physical memory are “mapped” by the CPU into regions of each task’s ‘virtual’ address-space Physical address space (1 GB)
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 Portions of secondary memory can be “mapped” to unused regions of a task’s virtual address-space via the CPU’s page-fault mechanism Virtual address space Disk storage (files) Physical address space file file
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 offset If 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” );