Skip to content

Commit 7de88e1

Browse files
committed
Add ELF header structures for ELF generation
These changes introduce elf32_hdr_t, elf32_phdr_t and elf32_shdr_t structures to represent the ELF header, program header and section header, respectively. By using these structures, the ELF generation process becomes more readable when filling in header data.
1 parent e3a7201 commit 7de88e1

File tree

2 files changed

+176
-108
lines changed

2 files changed

+176
-108
lines changed

src/defs.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,3 +547,48 @@ typedef struct {
547547
var_t *var;
548548
int polluted;
549549
} regfile_t;
550+
551+
/* FIXME: replace char[2] with a short data type in ELF header structures */
552+
/* ELF header */
553+
typedef struct {
554+
char e_ident[16];
555+
char e_type[2];
556+
char e_machine[2];
557+
int e_version;
558+
int e_entry;
559+
int e_phoff;
560+
int e_shoff;
561+
int e_flags;
562+
char e_ehsize[2];
563+
char e_phentsize[2];
564+
char e_phnum[2];
565+
char e_shentsize[2];
566+
char e_shnum[2];
567+
char e_shstrndx[2];
568+
} elf32_hdr_t;
569+
570+
/* ELF program header */
571+
typedef struct {
572+
int p_type;
573+
int p_offset;
574+
int p_vaddr;
575+
int p_paddr;
576+
int p_filesz;
577+
int p_memsz;
578+
int p_flags;
579+
int p_align;
580+
} elf32_phdr_t;
581+
582+
/* ELF section header */
583+
typedef struct {
584+
int sh_name;
585+
int sh_type;
586+
int sh_flags;
587+
int sh_addr;
588+
int sh_offset;
589+
int sh_size;
590+
int sh_link;
591+
int sh_info;
592+
int sh_addralign;
593+
int sh_entsize;
594+
} elf32_shdr_t;

src/elf.c

Lines changed: 131 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void elf_write_str(strbuf_t *elf_array, char *vals)
1515
* Note that strbuf_puts() does not push the null character.
1616
*
1717
* If necessary, use elf_write_byte() to append the null character
18-
* after calling strbuf_puts().
18+
* after calling elf_write_str().
1919
*/
2020
strbuf_puts(elf_array, vals);
2121
}
@@ -36,53 +36,68 @@ void elf_write_int(strbuf_t *elf_array, int val)
3636
strbuf_putc(elf_array, e_extract_byte(val, i));
3737
}
3838

39+
void elf_write_blk(strbuf_t *elf_array, void *blk, int sz)
40+
{
41+
char *ptr = blk;
42+
for (int i = 0; i < sz; i++)
43+
strbuf_putc(elf_array, ptr[i]);
44+
}
45+
3946
void elf_generate_header()
4047
{
41-
/* ELF header */
42-
elf_write_int(elf_header, 0x464c457f); /* Magic: 0x7F followed by ELF */
43-
elf_write_byte(elf_header, 1); /* 32-bit */
44-
elf_write_byte(elf_header, 1); /* little-endian */
45-
elf_write_byte(elf_header, 1); /* EI_VERSION */
46-
elf_write_byte(elf_header, 0); /* System V */
47-
elf_write_int(elf_header, 0); /* EI_ABIVERSION */
48-
elf_write_int(elf_header, 0); /* EI_PAD: unused */
49-
elf_write_byte(elf_header, 2); /* ET_EXEC */
50-
elf_write_byte(elf_header, 0);
51-
elf_write_byte(elf_header, ELF_MACHINE);
52-
elf_write_byte(elf_header, 0);
53-
elf_write_int(elf_header, 1); /* ELF version */
54-
elf_write_int(elf_header, ELF_START + elf_header_len); /* entry point */
55-
elf_write_int(elf_header, 0x34); /* program header offset */
56-
elf_write_int(elf_header, elf_header_len + elf_code->size + elf_data->size +
57-
39 + elf_symtab->size +
58-
elf_strtab->size); /* section header offset */
59-
/* flags */
60-
elf_write_int(elf_header, ELF_FLAGS);
61-
elf_write_byte(elf_header, 0x34); /* header size */
62-
elf_write_byte(elf_header, 0);
63-
elf_write_byte(elf_header, 0x20); /* program header size */
64-
elf_write_byte(elf_header, 0);
65-
elf_write_byte(elf_header, 1); /* number of program headers */
66-
elf_write_byte(elf_header, 0);
67-
elf_write_byte(elf_header, 0x28); /* section header size */
68-
elf_write_byte(elf_header, 0);
69-
elf_write_byte(elf_header, 6); /* number of sections */
70-
elf_write_byte(elf_header, 0);
71-
elf_write_byte(elf_header, 5); /* section index with names */
72-
elf_write_byte(elf_header, 0);
48+
elf32_hdr_t hdr;
49+
hdr.e_ident[0] = 0x7F;
50+
hdr.e_ident[1] = 'E';
51+
hdr.e_ident[2] = 'L';
52+
hdr.e_ident[3] = 'F';
53+
hdr.e_ident[4] = 1; /* 32-bit */
54+
hdr.e_ident[5] = 1; /* little-endian */
55+
hdr.e_ident[6] = 1; /* EI_VERSION */
56+
hdr.e_ident[7] = 0; /* System V */
57+
hdr.e_ident[8] = 0; /* EI_ABIVERSION */
58+
hdr.e_ident[9] = 0;
59+
hdr.e_ident[10] = 0;
60+
hdr.e_ident[11] = 0;
61+
hdr.e_ident[12] = 0; /* EI_PAD: unused */
62+
hdr.e_ident[13] = 0;
63+
hdr.e_ident[14] = 0;
64+
hdr.e_ident[15] = 0;
65+
hdr.e_type[0] = 2; /* ET_EXEC */
66+
hdr.e_type[1] = 0;
67+
hdr.e_machine[0] = ELF_MACHINE;
68+
hdr.e_machine[1] = 0;
69+
hdr.e_version = 1; /* ELF version */
70+
hdr.e_entry = ELF_START + elf_header_len; /* entry point */
71+
hdr.e_phoff = 0x34; /* program header offset */
72+
hdr.e_shoff = elf_header_len + elf_code->size + elf_data->size + 39 +
73+
elf_symtab->size + elf_strtab->size;
74+
/* section header offset */
75+
hdr.e_flags = ELF_FLAGS; /* flags */
76+
hdr.e_ehsize[0] = 0x34; /* header size */
77+
hdr.e_ehsize[1] = 0;
78+
hdr.e_phentsize[0] = 0x20; /* program header size */
79+
hdr.e_phentsize[1] = 0;
80+
hdr.e_phnum[0] = 1;
81+
hdr.e_phnum[1] = 0;
82+
hdr.e_shentsize[0] = 0x28; /* section header size */
83+
hdr.e_shentsize[1] = 0;
84+
hdr.e_shnum[0] = 6;
85+
hdr.e_shnum[1] = 0;
86+
hdr.e_shstrndx[0] = 5;
87+
hdr.e_shstrndx[1] = 0;
88+
elf_write_blk(elf_header, &hdr, sizeof(elf32_hdr_t));
7389

7490
/* program header - code and data combined */
75-
elf_write_int(elf_header, 1); /* PT_LOAD */
76-
elf_write_int(elf_header, elf_header_len); /* offset of segment */
77-
elf_write_int(elf_header, ELF_START + elf_header_len); /* virtual address */
78-
elf_write_int(elf_header,
79-
ELF_START + elf_header_len); /* physical address */
80-
elf_write_int(elf_header,
81-
elf_code->size + elf_data->size); /* size in file */
82-
elf_write_int(elf_header,
83-
elf_code->size + elf_data->size); /* size in memory */
84-
elf_write_int(elf_header, 7); /* flags */
85-
elf_write_int(elf_header, 4); /* alignment */
91+
elf32_phdr_t phdr;
92+
phdr.p_type = 1; /* PT_LOAD */
93+
phdr.p_offset = elf_header_len; /* offset of segment */
94+
phdr.p_vaddr = ELF_START + elf_header_len; /* virtual address */
95+
phdr.p_paddr = ELF_START + elf_header_len; /* physical address */
96+
phdr.p_filesz = elf_code->size + elf_data->size; /* size in file */
97+
phdr.p_memsz = elf_code->size + elf_data->size; /* size in memory */
98+
phdr.p_flags = 7; /* flags */
99+
phdr.p_align = 4; /* alignment */
100+
elf_write_blk(elf_header, &phdr, sizeof(elf32_phdr_t));
86101
}
87102

88103
void elf_generate_sections()
@@ -109,82 +124,90 @@ void elf_generate_sections()
109124
elf_write_byte(elf_section, 0);
110125

111126
/* section header table */
127+
elf32_shdr_t shdr;
128+
int ofs = elf_header_len;
112129

113130
/* NULL section */
114-
elf_write_int(elf_section, 0);
115-
elf_write_int(elf_section, 0);
116-
elf_write_int(elf_section, 0);
117-
elf_write_int(elf_section, 0);
118-
elf_write_int(elf_section, 0);
119-
elf_write_int(elf_section, 0);
120-
elf_write_int(elf_section, 0);
121-
elf_write_int(elf_section, 0);
122-
elf_write_int(elf_section, 0);
123-
elf_write_int(elf_section, 0);
131+
shdr.sh_name = 0;
132+
shdr.sh_type = 0;
133+
shdr.sh_flags = 0;
134+
shdr.sh_addr = 0;
135+
shdr.sh_offset = 0;
136+
shdr.sh_size = 0;
137+
shdr.sh_link = 0;
138+
shdr.sh_info = 0;
139+
shdr.sh_addralign = 0;
140+
shdr.sh_entsize = 0;
141+
elf_write_blk(elf_section, &shdr, sizeof(elf32_shdr_t));
124142

125143
/* .text */
126-
elf_write_int(elf_section, 0xb);
127-
elf_write_int(elf_section, 1);
128-
elf_write_int(elf_section, 7);
129-
elf_write_int(elf_section, ELF_START + elf_header_len);
130-
elf_write_int(elf_section, elf_header_len);
131-
elf_write_int(elf_section, elf_code->size);
132-
elf_write_int(elf_section, 0);
133-
elf_write_int(elf_section, 0);
134-
elf_write_int(elf_section, 4);
135-
elf_write_int(elf_section, 0);
144+
shdr.sh_name = 0xb;
145+
shdr.sh_type = 1;
146+
shdr.sh_flags = 7;
147+
shdr.sh_addr = ELF_START + elf_header_len;
148+
shdr.sh_offset = ofs;
149+
shdr.sh_size = elf_code->size;
150+
shdr.sh_link = 0;
151+
shdr.sh_info = 0;
152+
shdr.sh_addralign = 4;
153+
shdr.sh_entsize = 0;
154+
elf_write_blk(elf_section, &shdr, sizeof(elf32_shdr_t));
155+
ofs += elf_code->size;
136156

137157
/* .data */
138-
elf_write_int(elf_section, 0x11);
139-
elf_write_int(elf_section, 1);
140-
elf_write_int(elf_section, 3);
141-
elf_write_int(elf_section, elf_code_start + elf_code->size);
142-
elf_write_int(elf_section, elf_header_len + elf_code->size);
143-
elf_write_int(elf_section, elf_data->size);
144-
elf_write_int(elf_section, 0);
145-
elf_write_int(elf_section, 0);
146-
elf_write_int(elf_section, 4);
147-
elf_write_int(elf_section, 0);
158+
shdr.sh_name = 0x11;
159+
shdr.sh_type = 1;
160+
shdr.sh_flags = 3;
161+
shdr.sh_addr = elf_code_start + elf_code->size;
162+
shdr.sh_offset = ofs;
163+
shdr.sh_size = elf_data->size;
164+
shdr.sh_link = 0;
165+
shdr.sh_info = 0;
166+
shdr.sh_addralign = 4;
167+
shdr.sh_entsize = 0;
168+
elf_write_blk(elf_section, &shdr, sizeof(elf32_shdr_t));
169+
ofs += elf_data->size;
148170

149171
/* .symtab */
150-
elf_write_int(elf_section, 0x17);
151-
elf_write_int(elf_section, 2);
152-
elf_write_int(elf_section, 0);
153-
elf_write_int(elf_section, 0);
154-
elf_write_int(elf_section,
155-
elf_header_len + elf_code->size + elf_data->size);
156-
elf_write_int(elf_section, elf_symtab->size); /* size */
157-
elf_write_int(elf_section, 4);
158-
elf_write_int(elf_section, elf_symbol_index);
159-
elf_write_int(elf_section, 4);
160-
elf_write_int(elf_section, 16);
172+
shdr.sh_name = 0x17;
173+
shdr.sh_type = 2;
174+
shdr.sh_flags = 0;
175+
shdr.sh_addr = 0;
176+
shdr.sh_offset = ofs;
177+
shdr.sh_size = elf_symtab->size;
178+
shdr.sh_link = 4;
179+
shdr.sh_info = elf_symbol_index;
180+
shdr.sh_addralign = 4;
181+
shdr.sh_entsize = 16;
182+
elf_write_blk(elf_section, &shdr, sizeof(elf32_shdr_t));
183+
ofs += elf_symtab->size;
161184

162185
/* .strtab */
163-
elf_write_int(elf_section, 0x1f);
164-
elf_write_int(elf_section, 3);
165-
elf_write_int(elf_section, 0);
166-
elf_write_int(elf_section, 0);
167-
elf_write_int(elf_section, elf_header_len + elf_code->size +
168-
elf_data->size + elf_symtab->size);
169-
elf_write_int(elf_section, elf_strtab->size); /* size */
170-
elf_write_int(elf_section, 0);
171-
elf_write_int(elf_section, 0);
172-
elf_write_int(elf_section, 1);
173-
elf_write_int(elf_section, 0);
186+
shdr.sh_name = 0x1f;
187+
shdr.sh_type = 3;
188+
shdr.sh_flags = 0;
189+
shdr.sh_addr = 0;
190+
shdr.sh_offset = ofs;
191+
shdr.sh_size = elf_strtab->size;
192+
shdr.sh_link = 0;
193+
shdr.sh_info = 0;
194+
shdr.sh_addralign = 1;
195+
shdr.sh_entsize = 0;
196+
elf_write_blk(elf_section, &shdr, sizeof(elf32_shdr_t));
197+
ofs += elf_strtab->size;
174198

175199
/* .shstr */
176-
elf_write_int(elf_section, 1);
177-
elf_write_int(elf_section, 3);
178-
elf_write_int(elf_section, 0);
179-
elf_write_int(elf_section, 0);
180-
elf_write_int(elf_section, elf_header_len + elf_code->size +
181-
elf_data->size + elf_symtab->size +
182-
elf_strtab->size);
183-
elf_write_int(elf_section, 39);
184-
elf_write_int(elf_section, 0);
185-
elf_write_int(elf_section, 0);
186-
elf_write_int(elf_section, 1);
187-
elf_write_int(elf_section, 0);
200+
shdr.sh_name = 1;
201+
shdr.sh_type = 3;
202+
shdr.sh_flags = 0;
203+
shdr.sh_addr = 0;
204+
shdr.sh_offset = ofs;
205+
shdr.sh_size = 39;
206+
shdr.sh_link = 0;
207+
shdr.sh_info = 0;
208+
shdr.sh_addralign = 1;
209+
shdr.sh_entsize = 0;
210+
elf_write_blk(elf_section, &shdr, sizeof(elf32_shdr_t));
188211
}
189212

190213
void elf_align()

0 commit comments

Comments
 (0)