1 ! Copyright (C) 2010 Erik Charlebois.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.strings alien.syntax arrays
4 classes.struct io.encodings.ascii kernel locals sequences
5 specialized-arrays strings typed ;
15 CONSTANT: EI_VERSION 6
17 CONSTANT: EI_ABIVERSION 8
20 CONSTANT: ELFMAG0 HEX: 7f
21 CONSTANT: ELFMAG1 HEX: 45
22 CONSTANT: ELFMAG2 HEX: 4c
23 CONSTANT: ELFMAG3 HEX: 46
25 CONSTANT: ELFCLASS32 1
26 CONSTANT: ELFCLASS64 2
28 CONSTANT: ELFDATA2LSB 1
29 CONSTANT: ELFDATA2MSB 2
31 CONSTANT: ELFOSABI_SYSV 0
32 CONSTANT: ELFOSABI_HPUX 1
33 CONSTANT: ELFOSABI_NETBSD 2
34 CONSTANT: ELFOSABI_LINUX 3
35 CONSTANT: ELFOSABI_SOLARIS 6
36 CONSTANT: ELFOSABI_AIX 7
37 CONSTANT: ELFOSABI_IRIX 8
38 CONSTANT: ELFOSABI_FREEBSD 9
39 CONSTANT: ELFOSABI_TRU64 10
40 CONSTANT: ELFOSABI_MODESTO 11
41 CONSTANT: ELFOSABI_OPENBSD 12
42 CONSTANT: ELFOSABI_OPENVMS 13
43 CONSTANT: ELFOSABI_NSK 14
44 CONSTANT: ELFOSABI_AROS 15
45 CONSTANT: ELFOSABI_ARM_AEABI 64
46 CONSTANT: ELFOSABI_ARM 97
47 CONSTANT: ELFOSABI_STANDALONE 255
54 CONSTANT: ET_LOOS HEX: FE00
55 CONSTANT: ET_HIOS HEX: FEFF
56 CONSTANT: ET_LOPROC HEX: FF00
57 CONSTANT: ET_HIPROC HEX: FFFF
69 CONSTANT: EM_MIPS_RS3_LE 10
70 CONSTANT: EM_SPARC64 11
71 CONSTANT: EM_PARISC 15
72 CONSTANT: EM_VPP500 17
73 CONSTANT: EM_SPARC32PLUS 18
86 CONSTANT: EM_SPARCV9 43
87 CONSTANT: EM_TRICORE 44
89 CONSTANT: EM_H8_300 46
90 CONSTANT: EM_H8_300H 47
92 CONSTANT: EM_H8_500 49
94 CONSTANT: EM_MIPS_X 51
95 CONSTANT: EM_COLDFIRE 52
96 CONSTANT: EM_68HC12 53
101 CONSTANT: EM_STARCORE 58
103 CONSTANT: EM_ST100 60
104 CONSTANT: EM_TINYJ 61
105 CONSTANT: EM_X86_64 62
108 CONSTANT: EM_ST9PLUS 67
110 CONSTANT: EM_68HC16 69
111 CONSTANT: EM_68HC11 70
112 CONSTANT: EM_68HC08 71
113 CONSTANT: EM_68HC05 72
118 CONSTANT: EM_JAVELIN 77
119 CONSTANT: EM_FIREPATH 78
122 CONSTANT: EM_HUANY 81
123 CONSTANT: EM_PRISM 82
130 CONSTANT: EM_MN10300 89
131 CONSTANT: EM_MN10200 90
133 CONSTANT: EM_OPENRISC 92
134 CONSTANT: EM_ARC_A5 93
135 CONSTANT: EM_XTENSA 94
136 CONSTANT: EM_VIDEOCORE 95
137 CONSTANT: EM_TMM_GPP 96
138 CONSTANT: EM_NS32K 97
140 CONSTANT: EM_SNP1K 99
141 CONSTANT: EM_ST200 100
142 CONSTANT: EM_IP2K 101
145 CONSTANT: EM_F2MC16 104
146 CONSTANT: EM_MSP430 105
147 CONSTANT: EM_BLACKFIN 106
148 CONSTANT: EM_SE_C33 107
150 CONSTANT: EM_ARCA 109
151 CONSTANT: EM_UNICORE 110
154 CONSTANT: EV_CURRENT 1
156 CONSTANT: EF_ARM_EABIMASK HEX: ff000000
157 CONSTANT: EF_ARM_BE8 HEX: 00800000
159 CONSTANT: SHN_UNDEF HEX: 0000
160 CONSTANT: SHN_LOPROC HEX: FF00
161 CONSTANT: SHN_HIPROC HEX: FF1F
162 CONSTANT: SHN_LOOS HEX: FF20
163 CONSTANT: SHN_HIOS HEX: FF3F
164 CONSTANT: SHN_ABS HEX: FFF1
165 CONSTANT: SHN_COMMON HEX: FFF2
168 CONSTANT: SHT_PROGBITS 1
169 CONSTANT: SHT_SYMTAB 2
170 CONSTANT: SHT_STRTAB 3
173 CONSTANT: SHT_DYNAMIC 6
175 CONSTANT: SHT_NOBITS 8
177 CONSTANT: SHT_SHLIB 10
178 CONSTANT: SHT_DYNSYM 11
179 CONSTANT: SHT_LOOS HEX: 60000000
180 CONSTANT: SHT_GNU_LIBLIST HEX: 6ffffff7
181 CONSTANT: SHT_CHECKSUM HEX: 6ffffff8
182 CONSTANT: SHT_LOSUNW HEX: 6ffffffa
183 CONSTANT: SHT_SUNW_move HEX: 6ffffffa
184 CONSTANT: SHT_SUNW_COMDAT HEX: 6ffffffb
185 CONSTANT: SHT_SUNW_syminfo HEX: 6ffffffc
186 CONSTANT: SHT_GNU_verdef HEX: 6ffffffd
187 CONSTANT: SHT_GNU_verneed HEX: 6ffffffe
188 CONSTANT: SHT_GNU_versym HEX: 6fffffff
189 CONSTANT: SHT_HISUNW HEX: 6fffffff
190 CONSTANT: SHT_HIOS HEX: 6fffffff
191 CONSTANT: SHT_LOPROC HEX: 70000000
192 CONSTANT: SHT_ARM_EXIDX HEX: 70000001
193 CONSTANT: SHT_ARM_PREEMPTMAP HEX: 70000002
194 CONSTANT: SHT_ARM_ATTRIBUTES HEX: 70000003
195 CONSTANT: SHT_ARM_DEBUGOVERLAY HEX: 70000004
196 CONSTANT: SHT_ARM_OVERLAYSECTION HEX: 70000005
197 CONSTANT: SHT_HIPROC HEX: 7fffffff
198 CONSTANT: SHT_LOUSER HEX: 80000000
199 CONSTANT: SHT_HIUSER HEX: 8fffffff
201 CONSTANT: SHF_WRITE 1
202 CONSTANT: SHF_ALLOC 2
203 CONSTANT: SHF_EXECINSTR 4
204 CONSTANT: SHF_MERGE 16
205 CONSTANT: SHF_STRINGS 32
206 CONSTANT: SHF_INFO_LINK 64
207 CONSTANT: SHF_LINK_ORDER 128
208 CONSTANT: SHF_OS_NONCONFORMING 256
209 CONSTANT: SHF_GROUP 512
210 CONSTANT: SHF_TLS 1024
211 CONSTANT: SHF_MASKOS HEX: 0f000000
212 CONSTANT: SHF_MASKPROC HEX: f0000000
214 CONSTANT: STB_LOCAL 0
215 CONSTANT: STB_GLOBAL 1
217 CONSTANT: STB_LOOS 10
218 CONSTANT: STB_HIOS 12
219 CONSTANT: STB_LOPROC 13
220 CONSTANT: STB_HIPROC 15
222 CONSTANT: STT_NOTYPE 0
223 CONSTANT: STT_OBJECT 1
225 CONSTANT: STT_SECTION 3
227 CONSTANT: STT_COMMON 5
229 CONSTANT: STT_LOOS 10
230 CONSTANT: STT_HIOS 12
231 CONSTANT: STT_LOPROC 13
232 CONSTANT: STT_HIPROC 15
234 CONSTANT: STN_UNDEF 0
236 CONSTANT: STV_DEFAULT 0
237 CONSTANT: STV_INTERNAL 1
238 CONSTANT: STV_HIDDEN 2
239 CONSTANT: STV_PROTECTED 3
243 CONSTANT: PT_DYNAMIC 2
244 CONSTANT: PT_INTERP 3
249 CONSTANT: PT_LOOS HEX: 60000000
250 CONSTANT: PT_HIOS HEX: 6fffffff
251 CONSTANT: PT_LOPROC HEX: 70000000
252 CONSTANT: PT_ARM_ARCHEXT HEX: 70000000
253 CONSTANT: PT_ARM_EXIDX HEX: 70000001
254 CONSTANT: PT_ARM_UNWIND HEX: 70000001
255 CONSTANT: PT_HIPROC HEX: 7fffffff
257 CONSTANT: PT_ARM_ARCHEXT_FMTMSK HEX: ff000000
258 CONSTANT: PT_ARM_ARCHEXT_PROFMSK HEX: 00ff0000
259 CONSTANT: PT_ARM_ARCHEXT_ARCHMSK HEX: 000000ff
260 CONSTANT: PT_ARM_ARCHEXT_FMT_OS HEX: 00000000
261 CONSTANT: PT_ARM_ARCHEXT_FMT_ABI HEX: 01000000
262 CONSTANT: PT_ARM_ARCHEXT_PROF_NONE HEX: 00000000
263 CONSTANT: PT_ARM_ARCHEXT_PROF_ARM HEX: 00410000
264 CONSTANT: PT_ARM_ARCHEXT_PROF_RT HEX: 00520000
265 CONSTANT: PT_ARM_ARCHEXT_PROF_MC HEX: 004d0000
266 CONSTANT: PT_ARM_ARCHEXT_PROF_CLASSIC HEX: 00530000
268 CONSTANT: PT_ARM_ARCHEXT_ARCH_UNKN HEX: 00
269 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv4 HEX: 01
270 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv4T HEX: 02
271 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv5T HEX: 03
272 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv5TE HEX: 04
273 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv5TEJ HEX: 05
274 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6 HEX: 06
275 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6KZ HEX: 07
276 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6T2 HEX: 08
277 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6K HEX: 09
278 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv7 HEX: 0A
279 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6M HEX: 0B
280 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6SM HEX: 0C
281 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv7EM HEX: 0D
286 CONSTANT: PF_MASKOS HEX: 00ff0000
287 CONSTANT: PF_MASKPROC HEX: ff000000
290 CONSTANT: DT_NEEDED 1
291 CONSTANT: DT_PLTRELSZ 2
292 CONSTANT: DT_PLTGOT 3
294 CONSTANT: DT_STRTAB 5
295 CONSTANT: DT_SYMTAB 6
297 CONSTANT: DT_RELASZ 8
298 CONSTANT: DT_RELAENT 9
299 CONSTANT: DT_STRSZ 10
300 CONSTANT: DT_SYMENT 11
303 CONSTANT: DT_SONAME 14
304 CONSTANT: DT_RPATH 15
305 CONSTANT: DT_SYMBOLIC 16
307 CONSTANT: DT_RELSZ 18
308 CONSTANT: DT_RELENT 19
309 CONSTANT: DT_PLTREL 20
310 CONSTANT: DT_DEBUG 21
311 CONSTANT: DT_TEXTREL 22
312 CONSTANT: DT_JMPREL 23
313 CONSTANT: DT_BIND_NOW 24
314 CONSTANT: DT_INIT_ARRAY 25
315 CONSTANT: DT_FINI_ARRAY 26
316 CONSTANT: DT_INIT_ARRAYSZ 27
317 CONSTANT: DT_FINI_ARRAYSZ 28
318 CONSTANT: DT_RUNPATH 29
319 CONSTANT: DT_FLAGS 30
320 CONSTANT: DT_ENCODING 32
321 CONSTANT: DT_PREINIT_ARRAY 32
322 CONSTANT: DT_PREINIT_ARRAYSZ 33
323 CONSTANT: DT_LOOS HEX: 60000000
324 CONSTANT: DT_HIOS HEX: 6fffffff
325 CONSTANT: DT_LOPROC HEX: 70000000
326 CONSTANT: DT_ARM_RESERVED1 HEX: 70000000
327 CONSTANT: DT_ARM_SYMTABSZ HEX: 70000001
328 CONSTANT: DT_ARM_PREEMPTYMAP HEX: 70000002
329 CONSTANT: DT_ARM_RESERVED2 HEX: 70000003
330 CONSTANT: DT_HIPROC HEX: 7fffffff
332 TYPEDEF: ushort Elf32_Half
333 TYPEDEF: uint Elf32_Word
334 TYPEDEF: int Elf32_Sword
335 TYPEDEF: uint Elf32_Off
336 TYPEDEF: uint Elf32_Addr
337 TYPEDEF: ushort Elf64_Half
338 TYPEDEF: uint Elf64_Word
339 TYPEDEF: ulonglong Elf64_Xword
340 TYPEDEF: longlong Elf64_Sxword
341 TYPEDEF: ulonglong Elf64_Off
342 TYPEDEF: ulonglong Elf64_Addr
345 { e_ident uchar[16] }
346 { e_type Elf32_Half }
347 { e_machine Elf32_Half }
348 { e_version Elf32_Word }
349 { e_entry Elf32_Addr }
350 { e_phoff Elf32_Off }
351 { e_shoff Elf32_Off }
352 { e_flags Elf32_Word }
353 { e_ehsize Elf32_Half }
354 { e_phentsize Elf32_Half }
355 { e_phnum Elf32_Half }
356 { e_shentsize Elf32_Half }
357 { e_shnum Elf32_Half }
358 { e_shstrndx Elf32_Half } ;
361 { e_ident uchar[16] }
362 { e_type Elf64_Half }
363 { e_machine Elf64_Half }
364 { e_version Elf64_Word }
365 { e_entry Elf64_Addr }
366 { e_phoff Elf64_Off }
367 { e_shoff Elf64_Off }
368 { e_flags Elf64_Word }
369 { e_ehsize Elf64_Half }
370 { e_phentsize Elf64_Half }
371 { e_phnum Elf64_Half }
372 { e_shentsize Elf64_Half }
373 { e_shnum Elf64_Half }
374 { e_shstrndx Elf64_Half } ;
377 { sh_name Elf32_Word }
378 { sh_type Elf32_Word }
379 { sh_flags Elf32_Word }
380 { sh_addr Elf32_Addr }
381 { sh_offset Elf32_Off }
382 { sh_size Elf32_Word }
383 { sh_link Elf32_Word }
384 { sh_info Elf32_Word }
385 { sh_addralign Elf32_Word }
386 { sh_entsize Elf32_Word } ;
389 { sh_name Elf64_Word }
390 { sh_type Elf64_Word }
391 { sh_flags Elf64_Xword }
392 { sh_addr Elf64_Addr }
393 { sh_offset Elf64_Off }
394 { sh_size Elf64_Xword }
395 { sh_link Elf64_Word }
396 { sh_info Elf64_Word }
397 { sh_addralign Elf64_Xword }
398 { sh_entsize Elf64_Xword } ;
401 { st_name Elf32_Word }
402 { st_value Elf32_Addr }
403 { st_size Elf32_Word }
406 { st_shndx Elf32_Half } ;
409 { st_name Elf64_Word }
412 { st_shndx Elf64_Half }
413 { st_value Elf64_Addr }
414 { st_size Elf64_Xword } ;
417 { r_offset Elf32_Addr }
418 { r_info Elf32_Word } ;
421 { r_offset Elf32_Addr }
422 { r_info Elf32_Word }
423 { r_addend Elf32_Sword } ;
426 { r_offset Elf64_Addr }
427 { r_info Elf64_Xword } ;
430 { r_offset Elf64_Addr }
431 { r_info Elf64_Xword }
432 { r_addend Elf64_Sxword } ;
435 { p_type Elf32_Word }
436 { p_offset Elf32_Off }
437 { p_vaddr Elf32_Addr }
438 { p_paddr Elf32_Addr }
439 { p_filesz Elf32_Word }
440 { p_memsz Elf32_Word }
441 { p_flags Elf32_Word }
442 { p_align Elf32_Word } ;
445 { p_type Elf64_Word }
446 { p_flags Elf64_Word }
447 { p_offset Elf64_Off }
448 { p_vaddr Elf64_Addr }
449 { p_paddr Elf64_Addr }
450 { p_filesz Elf64_Xword }
451 { p_memsz Elf64_Xword }
452 { p_align Elf64_Xword } ;
455 { d_tag Elf32_Sword }
456 { d_val Elf32_Word } ;
459 { d_tag Elf64_Sxword }
460 { d_val Elf64_Xword } ;
462 SPECIALIZED-ARRAYS: Elf32_Shdr Elf64_Shdr uchar ;
463 UNION: Elf32/64_Ehdr Elf32_Ehdr Elf64_Ehdr ;
464 UNION: Elf32/64_Shdr Elf32_Shdr Elf64_Shdr ;
465 UNION: Elf32/64_Shdr-array Elf32_Shdr-array Elf64_Shdr-array ;
467 TYPED: 64-bit? ( elf: Elf32/64_Ehdr -- ? )
468 e_ident>> EI_CLASS swap nth ELFCLASS64 = ;
470 TYPED: elf-header ( c-ptr -- elf: Elf32/64_Ehdr )
471 [ Elf64_Ehdr memory>struct 64-bit? ] keep swap
472 [ Elf64_Ehdr memory>struct ]
473 [ Elf32_Ehdr memory>struct ] if ;
475 TYPED:: elf-section-headers ( elf: Elf32/64_Ehdr -- headers: Elf32/64_Shdr-array )
476 elf [ e_shoff>> ] [ e_shnum>> ] bi :> ( off num )
477 off elf >c-ptr <displaced-alien> num
479 [ <direct-Elf64_Shdr-array> ]
480 [ <direct-Elf32_Shdr-array> ] if ;
482 TYPED:: elf-section-data ( elf: Elf32/64_Ehdr header: Elf32/64_Shdr -- uchar-array/f )
483 header [ sh_offset>> elf >c-ptr <displaced-alien> ] [ sh_size>> ] bi <direct-uchar-array> ;
485 TYPED:: elf-section-data-by-name ( elf: Elf32/64_Ehdr name: string -- header/f uchar-array/f )
486 elf elf-section-headers :> sections
487 elf e_shstrndx>> :> ndx
488 elf ndx sections nth elf-section-data >c-ptr :> section-names
491 sh_name>> section-names <displaced-alien> ascii alien>string name =
494 [ dup elf swap elf-section-data ]
497 TYPED:: elf-section-names ( elf: Elf32/64_Ehdr -- names )
498 elf elf-section-headers :> sections
499 elf ".shstrtab" elf-section-data-by-name nip >c-ptr :> section-names
501 sh_name>> section-names <displaced-alien>