ELF Tutorial: Difference between revisions

m
Fix typing errors
[unchecked revision][unchecked revision]
m (Fix typing errors)
Line 84:
===Checking the ELF Header===
 
Before an ELF file can be loaded, linked, relocated or otherwise processed, it's important to ensure that the machine trying to perform the aforementioned is able to do. This entails that the file is a valid ELF file targeting the local machine's architecture, byte order and CPU type, and that any operating system speficspecific semantics are satisfied.
 
<source lang="cpp">
Line 109:
</source>
 
Assuming that an ELF file has already been loaded into memory (either by the bootloader or otherwise), the first step to loading an ELF file is checking the ELF header for the magic number that should be present at the begining of the file. A minimal implementation of this could simply treat the image of file in memory as a string and do a comparisioncomparison against a predefined string. In the example above, the comparision is done byte by byte through the ELF header type, and provides detailed feedback when the method encounters an error.
 
<source lang="cpp">
Line 141:
</source>
 
The next step to loading an ELF object is to check that the file in question is intended to run on the machine that has loaded it. Again, the ELF header provides the necessary information about the file's indendedintended target. The code above assumes that you have implemented a function called '''elf_check_file'''() (or used the one provided above), and that the local machine is i386, little-endian and 32-bit. It also only allows for executable and relocatable files to be loaded, although this can be changed as necessary.
 
====Loading the ELF File====
Line 181:
==The ELF Section Header==
 
The ELF format defines a lot of different types of section and their relevant headers, not all of which are present in every file, and there's no guarantee on which order they are appear in. Thus, in order to parse and process these sections the format also defines section headers, which contains information such as section names, sizes, locations and other relevant information. The list of all the section headers in an ELF image is referedreferred to as the section header table.
 
<source lang="cpp">
Line 198:
</source>
 
The section header table contains a number of important fields, some of which have different meanings for different sections. Another point of interest is that the '''sh_name''' field does not point directly to a string, instead it gives the offset of a string in the section name string table (the index of the table itself is defined in the ELF header by the field '''e_shstrndx'''). Each header also defines the position of the actual section in the file image in the field '''sh_offset''', as an offset from the beginingbeginning of the file.
 
<source lang="cpp">
Line 223:
===Accessing Section Headers===
 
Getting access to the section header itself isn't very difficult: It's position in the file image is defined by '''e_shoff''' in the ELF header and the number of section headers is in turn defined by '''e_shnum'''. Notably, the first entry in the section header is a NULL entry; that is to say, fields in the header are 0. The section headers are continuous, so given a pointer to the first entry, subsequent entries can accessed with simple pointer arithmaticarithmetic or array operations.
 
<source lang="cpp">
Line 235:
</source>
 
The two methods above provide convinient access to section headers on a by-index basis using the principals noted above, and they will be used fruquentlyfrequently in the example code that follows.
 
===Section Names===
Line 265:
==ELF Sections==
 
ELF object files can have a very large number of sections, however, it is important to note that only some sections need to be processed during program loading, and not all of them may exist within the object file itself (iei.e. the BSS). This segment will describe a number of sections that should be processed during program loading (given they are present).
 
===The Symbol Table===
Line 282:
</source>
 
Each symbol table entry contains a number of notable bits of information such as the symbol name ('''st_name''', may be '''STN_UNDEF'''), the symbol's value ('''st_value''', may be absolute or relative address of value), and the field '''st_info''' which conatinscontains both the symbol type and binding. As an aside, the first entry in each symbol table is a NULL entry, so all of it's fields are 0.
 
<source lang="cpp">
Line 322:
</source>
 
The above performs a check against both the symbol table index and the symbol index; if either is undefined, 0 is returned. Otherwise the section header entry for the symbol table at the given index is accessed. It then checks that the symbol table index is not outside the bounds of the symbol table. If the check fails an error message is displayed and an error code is returned, otherwise the symbol table entry at the given index is is retreivedretrieved.
 
<source lang="cpp">
Line 347:
</source>
 
If the section to which the symbol is relative (given by '''st_shndx''') is equal to '''SHN_UNDEF''', the symbol is external and must be linked to its definition. The string table is retreivedretrieved for the current symbol table (the string table for a given symbol table is available in the table's section header in '''sh_link'''), and the symbol's name is found in the string table. Next the function '''elf_lookup_symbol'''() is used to find a symbol defintiondefinition by name (this function is not provided, a minimal implementation always return NULL). If the symbol definition is found, it is returned. If the symbol has the '''STB_WEAK''' flag (is a weak symbol) 0 is returned, otherwise an error message is displayed and an error code returned.
 
<source lang="cpp">
Line 362:
 
 
If the the value of '''sh_ndx''' is equal to '''SHN_ABS''', the symbol's value is absolute and is reurnedreturned immidiatelyimmediately. If '''sh_ndx''' doesn't contain a special value, that means the symbol is defined in the local ELF object. Since the value given by '''sh_value''' is relative to a section defined '''sh_ndx''', the relevant section header entry is accessed, and the symbol's address is computed by adding the address of the file in memory to the symbol's value with its section offset.
 
===The String Table===
Anonymous user