Skip to content

Commit

Permalink
doc: describe COFF file structure
Browse files Browse the repository at this point in the history
  • Loading branch information
d0p1s4m4 committed Mar 21, 2024
1 parent e9ec779 commit a4d5179
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 9 deletions.
69 changes: 69 additions & 0 deletions docs/COFF.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#+TITLE: Common Object File Format (COFF)

** COFF File Structure

#+begin_src
+-----------------------+
| |
| File Header |
| |
+-----------------------+----
| | \
| Optional File Header | | Only for executable file
| (a.out header) | /
+-----------------------+----
| | \
| Section Header 1 | |
| | |
+-----------------------+ |
. . | Section Headers
. . |
+-----------------------+ |
| | |
| Section Header n | |
| | /
+-----------------------+----
| | \
| Section 1 Raw Data | |
| | |
+-----------------------+ |
. . | Raw data
. . | (Executable Code and Initialized Data)
+-----------------------+ |
| | |
| Section n Raw Data | |
| | /
+-----------------------+----
| | \
| Section 1 Relocation | |
| Information | |
+-----------------------+ |
. . | Relocation
. . | Information
+-----------------------+ |
| | |
| Section n Relocation | |
| Information | /
+-----------------------+----
| |
| Symbol Table |
| |
+-----------------------+
| |
| String Table |
| |
+-----------------------+

#+end_src

*** File Header

| Type | Description |
|----------+---------------------------------|
| uint16_t | Version ID (~0x014c~ for i386) |
| uint16_t | Number of section headers |
| uint32_t | Timestamp |
| uint32_t | Symtab address |
| uint32_t | Number of entries in the symtab |
| uint16_t | Optional header size |
| uint16_t | Flags |
25 changes: 21 additions & 4 deletions include/coff.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ typedef struct scnhdr
uint16_t s_nreloc;
uint16_t s_nlnno;
int32_t s_flags;
} SCNHDR;
} __attribute__((packed)) SCNHDR;

# define SCNHSZ sizeof(SCNHDR)

Expand All @@ -79,7 +79,7 @@ typedef struct reloc
uint32_t r_vaddr;
uint32_t r_symndx;
uint16_t r_type;
} RELOC;
} __attribute__((packed)) RELOC;
# define RELSZ 10

# define R_ABS 0x000
Expand All @@ -96,8 +96,25 @@ typedef struct lineno
uint32_t l_paddr;
} l_addr;
uint16_t l_lnno;
} LINENO;

} __attribute__((packed)) LINENO;
# define LINESZ 6

typedef struct sym
{
uint8_t n_name[8];
int32_t n_value;
int16_t n_scnum;
uint16_t n_type;
uint8_t n_sclass;
uint8_t n_numaux;
} __attribute__((packed)) SYM;
# define SYMSZ 18

# define N_UNDEF (0x0)
# define N_ABS (-0x1)
# define N_DEBUG (-0x2)

# define C_EXT 0x2
# define C_STAT 0x3

#endif /* !COFF_H */
36 changes: 31 additions & 5 deletions tools/coff-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
static char *prg_name;
static char *outfile = "a.out";

typedef struct section
{
} Section;


static void
usage(int retcode)
{
Expand Down Expand Up @@ -38,7 +43,9 @@ main(int argc, char **argv)
FILE *fp;
FILHDR fhdr;
SCNHDR shdr;
AOUTHDR aout;
uint8_t *buffer;
SYM entry;
int idx;

prg_name = argv[0];

Expand Down Expand Up @@ -82,12 +89,31 @@ main(int argc, char **argv)

if (fhdr.f_opthdr > 0)
{
fread(&aout, 1, AOUTHSZ, fp);
buffer = malloc(fhdr.f_opthdr);
fread(buffer, 1, fhdr.f_opthdr, fp);
free(buffer);
}

fread(&shdr, 1, SCNHSZ, fp);
printf("name: %c%c%c%c%c%c%c%c\n", shdr.s_name[0], shdr.s_name[1],shdr.s_name[2],shdr.s_name[3],shdr.s_name[4],shdr.s_name[5],shdr.s_name[6],shdr.s_name[7]);
printf("flags: 0x%x\n", shdr.s_flags);
for (idx = 0; idx < fhdr.f_nscns; idx++)
{
fread(&shdr, 1, SCNHSZ, fp);
printf("Section: %c%c%c%c%c%c%c%c\n", shdr.s_name[0], shdr.s_name[1],shdr.s_name[2],shdr.s_name[3],shdr.s_name[4],shdr.s_name[5],shdr.s_name[6],shdr.s_name[7]);
printf("\tflags: 0x%x\n", shdr.s_flags);
printf("\tsize: %d\n", shdr.s_size);
}

fseek(fp, fhdr.f_symptr, SEEK_SET);

for (idx = 0; idx < fhdr.f_nsyms; idx++)
{
fread(&entry, 1, SYMSZ, fp);
printf("name: %c%c%c%c%c%c%c%c\n", entry.n_name[0], entry.n_name[1],entry.n_name[2],entry.n_name[3],entry.n_name[4],entry.n_name[5],entry.n_name[6],entry.n_name[7]);
printf("\tvalue: %d\n", entry.n_value);
printf("\tscnum: %hd\n", entry.n_scnum);
printf("\ttype: %hd\n", entry.n_type);
printf("\tsclass: %d\n", entry.n_sclass);
printf("\tnumaux: %d\n", entry.n_numaux);
}

fclose(fp);

Expand Down

0 comments on commit a4d5179

Please sign in to comment.