1 /* Loosely based on the code in a Knol by Roberto Garcia Lopez:
3 ** http://knol.google.com/k/roberto-garca-lpez/creating-elf-relocatable-object-files/1ohwel4gqkcn2/3#
5 ** Note: This file is released under the terms of the LGPL2 license.
16 const char* OUTFILE
= "generated.o";
18 // Definition of the default string table section ".shstrtab"
19 const char defaultStrTable
[] =
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'
32 const char defaultStrTableLen
= sizeof(defaultStrTable
);
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;
40 // Position of sections within the object file
41 const char _shstrtab
= 1;
42 const char _strtab
= 2;
43 const char _symtab
= 3;
46 const char TEXT_CONTENTS
[] = {0x91, 0x92, 0x93, 0x94};
49 //----------------------------------------------------------------------------
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));
64 if ((FileDes
= open(OUTFILE
, O_CREAT
| O_WRONLY
| O_TRUNC
, 0777)) < 0)
65 errx(EX_OSERR
, "open \"%s\" failed", "compiled.o");
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));
70 if ((pEhdr
= elf32_newehdr(pElf
)) == NULL
)
71 errx(EX_SOFTWARE
, "elf32_newehdr() failed: %s", elf_errmsg(-1));
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
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));
86 pData
->d_buf
= (void *) defaultStrTable
;
87 pData
->d_type
= ELF_T_BYTE
;
88 pData
->d_size
= defaultStrTableLen
;
90 if ((pShdr
= elf32_getshdr(pScn
)) == NULL
)
91 errx(EX_SOFTWARE
, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
93 pShdr
->sh_name
= _shstrtab_offset
; // Point to the name of the section
94 pShdr
->sh_type
= SHT_STRTAB
;
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));
103 const char strtab
[] = {0, 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', '.','x', 0, '_', 's', 't', 'a', 'r', 't', 0};
106 pData
->d_buf
= (void *) strtab
;
107 pData
->d_type
= ELF_T_BYTE
;
108 pData
->d_size
= sizeof(strtab
);
110 if ((pShdr
= elf32_getshdr(pScn
)) == NULL
)
111 errx(EX_SOFTWARE
, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
113 pShdr
->sh_name
= _strtab_offset
;
114 pShdr
->sh_type
= SHT_STRTAB
;
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));
125 // Definition of the undefined section (this must be the first item by the definition of TIS ELF)
131 x
[0].st_shndx
= SHN_UNDEF
;
133 // Definition of the name of the source file (this must be the second item by the definition in TIS ELF)
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)
139 x
[1].st_shndx
= SHN_ABS
; // The section where the symbol is
141 // Definition of the ".text" section as a section in the ".symtab" section
145 x
[2].st_info
= ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
);
147 x
[2].st_shndx
= _text
; // The section where the symbol is
149 // Definition of the "_start" symbol
150 x
[3].st_name
= 13; // Offset in the "strtab" section where the name start
153 x
[3].st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
);
155 x
[3].st_shndx
= _text
; // The section where the symbol is
158 pData
->d_buf
= (void *) x
;
159 pData
->d_type
= ELF_T_BYTE
;
160 pData
->d_size
= sizeof(x
);
162 if ((pShdr
= elf32_getshdr(pScn
)) == NULL
)
163 errx(EX_SOFTWARE
, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
165 pShdr
->sh_name
= _symtab_offset
; // Point to the name of the section
166 pShdr
->sh_type
= SHT_SYMTAB
;
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))
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));
179 pData
->d_buf
= (void *)TEXT_CONTENTS
;
180 pData
->d_type
= ELF_T_BYTE
;
181 pData
->d_size
= sizeof(TEXT_CONTENTS
);
183 if ((pShdr
= elf32_getshdr(pScn
)) == NULL
)
184 errx(EX_SOFTWARE
, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
186 pShdr
->sh_name
= _text_offset
;
187 pShdr
->sh_type
= SHT_PROGBITS
;
188 pShdr
->sh_flags
= SHF_ALLOC
| SHF_EXECINSTR
;
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));
200 printf("Generated file: %s\n", OUTFILE
);