COFF: Difference between revisions

1,244 bytes added ,  26 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
mNo edit summary
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(8 intermediate revisions by 2 users not shown)
Line 18:
 
Secondly, the PE/COFF format also changes some of the COFF magic values (including the File Header one) and assigns them special meanings.
 
More information can be found in the [https://docs.microsoft.com/en-us/windows/win32/debug/pe-format "Microsoft Portable Executable and Common Object File Format Specification"] document.
 
==File Format==
Line 69:
 
Most COFF files contain additional space between the end of the Section table and the start of the Symbol table which stores the data for the sections themselves, although the location of this data relative to the Symbol (and String) table does not seem to be specified by the standard.
 
 
===File Header===
Line 77 ⟶ 76:
The structure of this header can be found in filehdr.h, and is 20 bytes longs.
 
<syntaxhighlight lang="c">
<pre>
{
unsigned short f_magic; /* Magic number */
Line 87 ⟶ 86:
unsigned short f_flags; /* Flags */
}
</syntaxhighlight>
</pre>
 
The magic number varies from implementation to implementation, for example, DJGPP generates COFF files with the value 0x14C in this field.
Line 109 ⟶ 108:
The structure of this header can be found in aouthdr.h, and is 28 bytes long.
 
<syntaxhighlight lang="c">
<pre>
{
unsigned short magic; /* Magic Number */
Line 120 ⟶ 119:
unsigned long data_start; /* Base of Data used for this file */
}
</syntaxhighlight>
</pre>
 
===Section Header===
Line 132 ⟶ 131:
The structure of this header can be found in scnhdr.h, and is 40 bytes long.
 
<syntaxhighlight lang="c">
<pre>
{
char s_name[8]; /* Section Name */
Line 145 ⟶ 144:
long s_flags; /* Flags for this section */
}
</syntaxhighlight>
</pre>
 
The Sectionsection name field stores the name of this section padded with NULL bytes if it is eight characters or fewer,; otherwise, this field contains either a pointer into the String tableTable, or a special name that starts with `/` and is followed by the decimal digits representing the offset within the String Table where the section name may be found. See the entry on the String tableTable below.
 
The Physical address field stores the memory start address for this file. If the file has been linked so that this section is to be loaded to a specific location in memory, this field will have been set to that value.
Line 193 ⟶ 192:
The structure of this header can be found in reloc.h, and is 10 bytes long.
 
<syntaxhighlight lang="c">
<pre>
{
long r_vaddr; /* Reference Address */
Line 199 ⟶ 198:
unsigned short r_type; /* Type of relocation */
}
</syntaxhighlight>
</pre>
 
The Address field gives the offset within the Section's raw data where the address starts. The reference will almost always be a 32-bit value starting at the given address, but this is dependant on implementation and the r_type field.
Line 213 ⟶ 212:
The Line Number table is an array of Line Number Entry structures and is zero based.
 
A COFF file can contain a Line number table for each Section, but it would be unusual to find relocationline number information for anything other than .text ( STYP_TEXT ) Sections.
 
Like the Relocation table, the Line Number table for a section has its location and length stored in the Section's header.
Line 219 ⟶ 218:
The structure of this header can be found in linenum.h, and is 6 bytes long.
 
<syntaxhighlight lang="c">
<pre>
{
union
Line 228 ⟶ 227:
unsigned short l_lnno; /* Line Number */
}
</syntaxhighlight>
</pre>
 
In brief, The line number table will contain an entry with a line number of zero in which the l_symndx field will indicate the function name Symbol in the Symbol table. This entry will be followed by additional entries with incrementing line numbers which indicate, through the l_paddr field, the byte offset into the section where this line starts. Given this, an exception that occurs during processing of the COFF file can be traced back to a function and a line number within that function.
Line 242 ⟶ 241:
The structure of this header can be found in syms.h, and is 18 bytes long.
 
<syntaxhighlight lang="c">
<pre>
{
char n_name[8]; /* Symbol Name */
Line 251 ⟶ 250:
char n_numaux; /* Auxiliary Count */
}
</syntaxhighlight>
</pre>
 
The Symbol name field stores the name of this symbol if it is eight characters or fewer, otherwise this field contains a pointer into the String table. See the entry on the String table below.
Line 329 ⟶ 328:
===String Table===
 
The String tableTable contains string names for any sections or symbols that are longer than eight characters.
 
The String tableTable immediately follows the Symbol tableTable, and can be located by using the following formula:
<pre>
String Table Offset = File Header.f_symptr + File Header.f_nsyms * sizeof( Symbol Table Entry )
Line 337 ⟶ 336:
</pre>
 
The first four bytes of the stringString tableTable are an integer indicating the overall size in bytes of the string table. Each of the strings in the table are null terminated.
 
The Section tableTable name field and the Symbol tableTable name field are actaullyactually more complicated than was detailed above, they in fact look more like this:
<syntaxhighlight lang="c">
<pre>
{
union
Line 352 ⟶ 351:
}
}
</syntaxhighlight>
</pre>
 
If the name is eight characters or fewer, then the field "zeroes" will be non-zero, and "name" should be interprettedinterpreted as a character array. Note that this field is not null-terminated unless it is fewer than eight characters in length.
 
If the name is more than eight characters, the "zeroes" field (the first four bytes of "name") will be zero. In this case the "offset" field should be used as an offset value into the String table to locate the Symbol or Section name.
 
NOTE: Some tools (like GCC) use a different format for the section name field. Instead of the first four bytes being zero and the last four being an offset into the string table (as described just above), the first byte is a `/`, and the rest are the decimal digits of the offset within the string table where the section name may be found. For example, a section named ".name_thats_too_long" will have "/4" stored in its section name field, assuming this is the first string stored in the string table.
 
==Example==
Line 395 ⟶ 396:
</pre>
 
<syntaxhighlight lang="c">
<pre>
int mGlobalInt;
short mGlobalShort;
Line 434 ⟶ 435:
return mTestValue;
}
</syntaxhighlight>
</pre>
 
As you can see, the static global variables are defined in either section 2 (.data) for the initialised ones, or section 3 (.bss) for the uninitialised, with n_value being an offset into the relevant section. The initialised global variables are also defined in section 2 (.data) with offsets.
Line 448 ⟶ 449:
=== External Links ===
* http://www.delorie.com/djgpp/doc/coff/
* [https://web.archive.org/web/20230703150217/https%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F9%2Fc%2F5%2F9c5b2167-8017-4bae-9fde-d599bac8184a%2Fpecoff_v83.docx Official Microsoft COFF Specification (2016)]
 
[[Category:Executable Formats]]