Remove unused import
[pyelftools.git] / test / external_tools / elf_creator.c
1 /* Loosely based on the code in a Knol by Roberto Garcia Lopez:
2 **
3 ** http://knol.google.com/k/roberto-garca-lpez/creating-elf-relocatable-object-files/1ohwel4gqkcn2/3#
4 **
5 ** Note: This file is released under the terms of the LGPL2 license.
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <libelf.h>
12 #include <err.h>
13 #include <sysexits.h>
14
15
16 const char* OUTFILE = "generated.o";
17
18 // Definition of the default string table section ".shstrtab"
19 const char defaultStrTable[] =
20 {
21 /* offset 00 */ '\0', // The NULL section
22 /* offset 01 */ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0',
23 /* offset 11 */ '.', 's', 't', 'r', 't', 'a', 'b', '\0',
24 /* offset 19 */ '.', 's', 'y', 'm', 't', 'a', 'b', '\0',
25 /* offset 27 */ '.', 'c', 'o', 'm', 'm', 'e', 'n', 't', '\0',
26 /* offset 36 */ '.', 'b', 's', 's', '\0',
27 /* offset 41 */ '.', 'd', 'a', 't', 'a', '\0',
28 /* offset 47 */ '.', 'r', 'e', 'l', '.', 't', 'e', 'x', 't', '\0',
29 /* offset 57 */ '.', 't', 'e', 'x', 't', '\0'
30 };
31
32 const char defaultStrTableLen = sizeof(defaultStrTable);
33
34 // Offsets of section names in the string table
35 const char _shstrtab_offset = 1;
36 const char _strtab_offset = 11;
37 const char _symtab_offset = 19;
38 const char _text_offset = 57;
39
40 // Position of sections within the object file
41 const char _shstrtab = 1;
42 const char _strtab = 2;
43 const char _symtab = 3;
44 const char _text = 4;
45
46 const char TEXT_CONTENTS[] = {0x91, 0x92, 0x93, 0x94};
47
48
49 //----------------------------------------------------------------------------
50
51 int main()
52 {
53 int FileDes;
54 Elf *pElf;
55 Elf32_Ehdr *pEhdr;
56 Elf32_Shdr *pShdr;
57 Elf_Scn *pScn;
58 Elf_Data *pData;
59
60 // Create the ELF header
61 if (elf_version(EV_CURRENT) == EV_NONE) // It must appear before "elf_begin()"
62 errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1));
63
64 if ((FileDes = open(OUTFILE, O_CREAT | O_WRONLY | O_TRUNC, 0777)) < 0)
65 errx(EX_OSERR, "open \"%s\" failed", "compiled.o");
66
67 if ((pElf = elf_begin(FileDes, ELF_C_WRITE, NULL)) == NULL) // 3rd argument is ignored for "ELF_C_WRITE"
68 errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
69
70 if ((pEhdr = elf32_newehdr(pElf)) == NULL)
71 errx(EX_SOFTWARE, "elf32_newehdr() failed: %s", elf_errmsg(-1));
72
73 pEhdr->e_ident[EI_CLASS] = ELFCLASS32; // Defined by Intel architecture
74 pEhdr->e_ident[EI_DATA] = ELFDATA2LSB; // Defined by Intel architecture
75 pEhdr->e_machine = EM_386; // Intel architecture
76 pEhdr->e_type = ET_REL; // Relocatable file (object file)
77 pEhdr->e_shstrndx = _shstrtab; // Point to the shstrtab section
78
79 // Create the section "default section header string table (.shstrtab)"
80 if ((pScn = elf_newscn(pElf)) == NULL)
81 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
82 if ((pData = elf_newdata(pScn)) == NULL)
83 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
84
85 pData->d_align = 1;
86 pData->d_buf = (void *) defaultStrTable;
87 pData->d_type = ELF_T_BYTE;
88 pData->d_size = defaultStrTableLen;
89
90 if ((pShdr = elf32_getshdr(pScn)) == NULL)
91 errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
92
93 pShdr->sh_name = _shstrtab_offset; // Point to the name of the section
94 pShdr->sh_type = SHT_STRTAB;
95 pShdr->sh_flags = 0;
96
97 // Create the section ".strtab"
98 if ((pScn = elf_newscn(pElf)) == NULL)
99 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
100 if ((pData = elf_newdata(pScn)) == NULL)
101 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
102
103 const char strtab[] = {0, 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', '.','x', 0, '_', 's', 't', 'a', 'r', 't', 0};
104
105 pData->d_align = 1;
106 pData->d_buf = (void *) strtab;
107 pData->d_type = ELF_T_BYTE;
108 pData->d_size = sizeof(strtab);
109
110 if ((pShdr = elf32_getshdr(pScn)) == NULL)
111 errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
112
113 pShdr->sh_name = _strtab_offset;
114 pShdr->sh_type = SHT_STRTAB;
115 pShdr->sh_flags = 0;
116
117 // Create the section ".symtab"
118 if ((pScn = elf_newscn(pElf)) == NULL)
119 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
120 if ((pData = elf_newdata(pScn)) == NULL)
121 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
122
123 Elf32_Sym x[4];
124
125 // Definition of the undefined section (this must be the first item by the definition of TIS ELF)
126 x[0].st_name = 0;
127 x[0].st_value = 0;
128 x[0].st_size = 0;
129 x[0].st_info = 0;
130 x[0].st_other = 0;
131 x[0].st_shndx = SHN_UNDEF;
132
133 // Definition of the name of the source file (this must be the second item by the definition in TIS ELF)
134 x[1].st_name = 1;
135 x[1].st_value = 0;
136 x[1].st_size = 0;
137 x[1].st_info = ELF32_ST_INFO(STB_LOCAL, STT_FILE); // This is the value that st_info must have (because of TIS ELF)
138 x[1].st_other = 0;
139 x[1].st_shndx = SHN_ABS; // The section where the symbol is
140
141 // Definition of the ".text" section as a section in the ".symtab" section
142 x[2].st_name = 0;
143 x[2].st_value = 0;
144 x[2].st_size = 0;
145 x[2].st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
146 x[2].st_other = 0;
147 x[2].st_shndx = _text; // The section where the symbol is
148
149 // Definition of the "_start" symbol
150 x[3].st_name = 13; // Offset in the "strtab" section where the name start
151 x[3].st_value = 0;
152 x[3].st_size = 0;
153 x[3].st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE);
154 x[3].st_other = 0;
155 x[3].st_shndx = _text; // The section where the symbol is
156
157 pData->d_align = 4;
158 pData->d_buf = (void *) x;
159 pData->d_type = ELF_T_BYTE;
160 pData->d_size = sizeof(x);
161
162 if ((pShdr = elf32_getshdr(pScn)) == NULL)
163 errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
164
165 pShdr->sh_name = _symtab_offset; // Point to the name of the section
166 pShdr->sh_type = SHT_SYMTAB;
167 pShdr->sh_flags = 0;
168 pShdr->sh_link = _strtab; // point to the section .strtab (the section that contain the strings)
169 pShdr->sh_info = ELF32_ST_INFO(STB_LOCAL, 3); // the second argument is beause of TIS ELF (One greater than the symbol table index of the last local symbol (binding STB_LOCAL))
170
171 // Create many sections named .text
172 for (int i = 0; i < 70000; ++i) {
173 if ((pScn = elf_newscn(pElf)) == NULL)
174 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
175 if ((pData = elf_newdata(pScn)) == NULL)
176 errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
177
178 pData->d_align = 4;
179 pData->d_buf = (void *)TEXT_CONTENTS;
180 pData->d_type = ELF_T_BYTE;
181 pData->d_size = sizeof(TEXT_CONTENTS);
182
183 if ((pShdr = elf32_getshdr(pScn)) == NULL)
184 errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
185
186 pShdr->sh_name = _text_offset;
187 pShdr->sh_type = SHT_PROGBITS;
188 pShdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
189 }
190
191 // Update the sections internally
192 if (elf_update(pElf, ELF_C_NULL) < 0)
193 errx(EX_SOFTWARE, "elf_update(NULL) failed: %s.", elf_errmsg(-1));
194 // Write the object file
195 if (elf_update(pElf, ELF_C_WRITE) < 0)
196 errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1));
197 // Close all handles
198 elf_end(pElf);
199 close(FileDes);
200 printf("Generated file: %s\n", OUTFILE);
201
202 return 0;
203 }
204