COFF: Difference between revisions

858 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
(→‎Section Header: Mention `/<digits>` format of long section names)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(2 intermediate revisions by one other user not shown)
Line 76:
The structure of this header can be found in filehdr.h, and is 20 bytes longs.
 
<sourcesyntaxhighlight lang="c">
{
unsigned short f_magic; /* Magic number */
Line 86:
unsigned short f_flags; /* Flags */
}
</syntaxhighlight>
</source>
 
The magic number varies from implementation to implementation, for example, DJGPP generates COFF files with the value 0x14C in this field.
Line 108:
The structure of this header can be found in aouthdr.h, and is 28 bytes long.
 
<sourcesyntaxhighlight lang="c">
{
unsigned short magic; /* Magic Number */
Line 119:
unsigned long data_start; /* Base of Data used for this file */
}
</syntaxhighlight>
</source>
 
===Section Header===
Line 131:
The structure of this header can be found in scnhdr.h, and is 40 bytes long.
 
<sourcesyntaxhighlight lang="c">
{
char s_name[8]; /* Section Name */
Line 144:
long s_flags; /* Flags for this section */
}
</syntaxhighlight>
</source>
 
The section 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 Table, 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 Table below.
Line 192:
The structure of this header can be found in reloc.h, and is 10 bytes long.
 
<sourcesyntaxhighlight lang="c">
{
long r_vaddr; /* Reference Address */
Line 198:
unsigned short r_type; /* Type of relocation */
}
</syntaxhighlight>
</source>
 
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 218:
The structure of this header can be found in linenum.h, and is 6 bytes long.
 
<sourcesyntaxhighlight lang="c">
{
union
Line 227:
unsigned short l_lnno; /* Line Number */
}
</syntaxhighlight>
</source>
 
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 241:
The structure of this header can be found in syms.h, and is 18 bytes long.
 
<sourcesyntaxhighlight lang="c">
{
char n_name[8]; /* Symbol Name */
Line 250:
char n_numaux; /* Auxiliary Count */
}
</syntaxhighlight>
</source>
 
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 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 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:
<sourcesyntaxhighlight lang="c">
{
union
Line 351:
}
}
</syntaxhighlight>
</source>
 
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 394 ⟶ 396:
</pre>
 
<sourcesyntaxhighlight lang="c">
int mGlobalInt;
short mGlobalShort;
Line 433 ⟶ 435:
return mTestValue;
}
</syntaxhighlight>
</source>
 
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 447 ⟶ 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]]