]> gitweb.factorcode.org Git - factor.git/blob - extra/elf/elf.factor
use radix literals
[factor.git] / extra / elf / elf.factor
1 ! Copyright (C) 2010 Erik Charlebois.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.data alien.strings
4 alien.syntax arrays classes.struct fry io.encodings.ascii
5 io.mmap kernel locals math math.intervals sequences
6 specialized-arrays strings typed assocs ;
7 IN: elf
8
9 ! FFI data
10 CONSTANT: EI_NIDENT 16
11 CONSTANT: EI_MAG0       0
12 CONSTANT: EI_MAG1       1
13 CONSTANT: EI_MAG2       2
14 CONSTANT: EI_MAG3       3
15 CONSTANT: EI_CLASS      4
16 CONSTANT: EI_DATA       5
17 CONSTANT: EI_VERSION    6
18 CONSTANT: EI_OSABI      7
19 CONSTANT: EI_ABIVERSION 8
20 CONSTANT: EI_PAD        9
21
22 CONSTANT: ELFMAG0       0x7f
23 CONSTANT: ELFMAG1       0x45
24 CONSTANT: ELFMAG2       0x4c
25 CONSTANT: ELFMAG3       0x46
26
27 CONSTANT: ELFCLASS32 1
28 CONSTANT: ELFCLASS64 2
29
30 CONSTANT: ELFDATA2LSB 1
31 CONSTANT: ELFDATA2MSB 2
32
33 CONSTANT: ELFOSABI_SYSV       0
34 CONSTANT: ELFOSABI_HPUX       1
35 CONSTANT: ELFOSABI_NETBSD     2
36 CONSTANT: ELFOSABI_LINUX      3
37 CONSTANT: ELFOSABI_SOLARIS    6
38 CONSTANT: ELFOSABI_AIX        7
39 CONSTANT: ELFOSABI_IRIX       8
40 CONSTANT: ELFOSABI_FREEBSD    9
41 CONSTANT: ELFOSABI_TRU64      10
42 CONSTANT: ELFOSABI_MODESTO    11
43 CONSTANT: ELFOSABI_OPENBSD    12
44 CONSTANT: ELFOSABI_OPENVMS    13
45 CONSTANT: ELFOSABI_NSK        14
46 CONSTANT: ELFOSABI_AROS       15
47 CONSTANT: ELFOSABI_ARM_AEABI  64
48 CONSTANT: ELFOSABI_ARM        97
49 CONSTANT: ELFOSABI_STANDALONE 255
50
51 CONSTANT: ET_NONE   0
52 CONSTANT: ET_REL    1
53 CONSTANT: ET_EXEC   2
54 CONSTANT: ET_DYN    3
55 CONSTANT: ET_CORE   4
56 CONSTANT: ET_LOOS   0xFE00
57 CONSTANT: ET_HIOS   0xFEFF
58 CONSTANT: ET_LOPROC 0xFF00
59 CONSTANT: ET_HIPROC 0xFFFF
60
61 CONSTANT: EM_NONE         0
62 CONSTANT: EM_M32          1
63 CONSTANT: EM_SPARC        2
64 CONSTANT: EM_386          3
65 CONSTANT: EM_68K          4
66 CONSTANT: EM_88K          5
67 CONSTANT: EM_486          6
68 CONSTANT: EM_860          7
69 CONSTANT: EM_MIPS         8
70 CONSTANT: EM_S370         9
71 CONSTANT: EM_MIPS_RS3_LE  10
72 CONSTANT: EM_SPARC64      11
73 CONSTANT: EM_PARISC       15
74 CONSTANT: EM_VPP500       17
75 CONSTANT: EM_SPARC32PLUS  18
76 CONSTANT: EM_960          19
77 CONSTANT: EM_PPC          20
78 CONSTANT: EM_PPC64        21
79 CONSTANT: EM_S390         22
80 CONSTANT: EM_SPU          23
81 CONSTANT: EM_V800         36
82 CONSTANT: EM_FR20         37
83 CONSTANT: EM_RH32         38
84 CONSTANT: EM_RCE          39
85 CONSTANT: EM_ARM          40
86 CONSTANT: EM_ALPHA        41
87 CONSTANT: EM_SH           42
88 CONSTANT: EM_SPARCV9      43
89 CONSTANT: EM_TRICORE      44
90 CONSTANT: EM_ARC          45
91 CONSTANT: EM_H8_300       46
92 CONSTANT: EM_H8_300H      47
93 CONSTANT: EM_H8S          48
94 CONSTANT: EM_H8_500       49
95 CONSTANT: EM_IA_64        50
96 CONSTANT: EM_MIPS_X       51
97 CONSTANT: EM_COLDFIRE     52
98 CONSTANT: EM_68HC12       53
99 CONSTANT: EM_MMA          54
100 CONSTANT: EM_PCP          55
101 CONSTANT: EM_NCPU         56
102 CONSTANT: EM_NDR1         57
103 CONSTANT: EM_STARCORE     58
104 CONSTANT: EM_ME16         59
105 CONSTANT: EM_ST100        60
106 CONSTANT: EM_TINYJ        61
107 CONSTANT: EM_X86_64       62
108 CONSTANT: EM_PDSP         63
109 CONSTANT: EM_FX66         66
110 CONSTANT: EM_ST9PLUS      67
111 CONSTANT: EM_ST7          68
112 CONSTANT: EM_68HC16       69
113 CONSTANT: EM_68HC11       70
114 CONSTANT: EM_68HC08       71
115 CONSTANT: EM_68HC05       72
116 CONSTANT: EM_SVX          73
117 CONSTANT: EM_ST19         74
118 CONSTANT: EM_VAX          75
119 CONSTANT: EM_CRIS         76
120 CONSTANT: EM_JAVELIN      77
121 CONSTANT: EM_FIREPATH     78
122 CONSTANT: EM_ZSP          79
123 CONSTANT: EM_MMIX         80
124 CONSTANT: EM_HUANY        81
125 CONSTANT: EM_PRISM        82
126 CONSTANT: EM_AVR          83
127 CONSTANT: EM_FR30         84
128 CONSTANT: EM_D10V         85
129 CONSTANT: EM_D30V         86
130 CONSTANT: EM_V850         87
131 CONSTANT: EM_M32R         88
132 CONSTANT: EM_MN10300      89
133 CONSTANT: EM_MN10200      90
134 CONSTANT: EM_PJ           91
135 CONSTANT: EM_OPENRISC     92
136 CONSTANT: EM_ARC_A5       93
137 CONSTANT: EM_XTENSA       94
138 CONSTANT: EM_VIDEOCORE    95
139 CONSTANT: EM_TMM_GPP      96
140 CONSTANT: EM_NS32K        97
141 CONSTANT: EM_TPC          98
142 CONSTANT: EM_SNP1K        99
143 CONSTANT: EM_ST200        100
144 CONSTANT: EM_IP2K         101
145 CONSTANT: EM_MAX          102
146 CONSTANT: EM_CR           103
147 CONSTANT: EM_F2MC16       104
148 CONSTANT: EM_MSP430       105
149 CONSTANT: EM_BLACKFIN     106
150 CONSTANT: EM_SE_C33       107
151 CONSTANT: EM_SEP          108
152 CONSTANT: EM_ARCA         109
153 CONSTANT: EM_UNICORE      110
154
155 CONSTANT: EV_NONE    0
156 CONSTANT: EV_CURRENT 1
157
158 CONSTANT: EF_ARM_EABIMASK 0xff000000
159 CONSTANT: EF_ARM_BE8      0x00800000
160
161 CONSTANT: SHN_UNDEF  0x0000
162 CONSTANT: SHN_LOPROC 0xFF00
163 CONSTANT: SHN_HIPROC 0xFF1F
164 CONSTANT: SHN_LOOS   0xFF20
165 CONSTANT: SHN_HIOS   0xFF3F
166 CONSTANT: SHN_ABS    0xFFF1
167 CONSTANT: SHN_COMMON 0xFFF2
168
169 CONSTANT: SHT_NULL               0
170 CONSTANT: SHT_PROGBITS           1
171 CONSTANT: SHT_SYMTAB             2
172 CONSTANT: SHT_STRTAB             3
173 CONSTANT: SHT_RELA               4
174 CONSTANT: SHT_HASH               5
175 CONSTANT: SHT_DYNAMIC            6
176 CONSTANT: SHT_NOTE               7
177 CONSTANT: SHT_NOBITS             8
178 CONSTANT: SHT_REL                9
179 CONSTANT: SHT_SHLIB              10
180 CONSTANT: SHT_DYNSYM             11
181 CONSTANT: SHT_LOOS               0x60000000
182 CONSTANT: SHT_GNU_LIBLIST        0x6ffffff7
183 CONSTANT: SHT_CHECKSUM           0x6ffffff8
184 CONSTANT: SHT_LOSUNW             0x6ffffffa
185 CONSTANT: SHT_SUNW_move          0x6ffffffa
186 CONSTANT: SHT_SUNW_COMDAT        0x6ffffffb
187 CONSTANT: SHT_SUNW_syminfo       0x6ffffffc
188 CONSTANT: SHT_GNU_verdef         0x6ffffffd
189 CONSTANT: SHT_GNU_verneed        0x6ffffffe
190 CONSTANT: SHT_GNU_versym         0x6fffffff
191 CONSTANT: SHT_HISUNW             0x6fffffff
192 CONSTANT: SHT_HIOS               0x6fffffff
193 CONSTANT: SHT_LOPROC             0x70000000
194 CONSTANT: SHT_ARM_EXIDX          0x70000001
195 CONSTANT: SHT_ARM_PREEMPTMAP     0x70000002
196 CONSTANT: SHT_ARM_ATTRIBUTES     0x70000003
197 CONSTANT: SHT_ARM_DEBUGOVERLAY   0x70000004
198 CONSTANT: SHT_ARM_OVERLAYSECTION 0x70000005
199 CONSTANT: SHT_HIPROC             0x7fffffff
200 CONSTANT: SHT_LOUSER             0x80000000
201 CONSTANT: SHT_HIUSER             0x8fffffff
202
203 CONSTANT: SHF_WRITE            1
204 CONSTANT: SHF_ALLOC            2
205 CONSTANT: SHF_EXECINSTR        4
206 CONSTANT: SHF_MERGE            16
207 CONSTANT: SHF_STRINGS          32
208 CONSTANT: SHF_INFO_LINK        64
209 CONSTANT: SHF_LINK_ORDER       128
210 CONSTANT: SHF_OS_NONCONFORMING 256
211 CONSTANT: SHF_GROUP            512
212 CONSTANT: SHF_TLS              1024
213 CONSTANT: SHF_MASKOS           0x0f000000
214 CONSTANT: SHF_MASKPROC         0xf0000000
215
216 CONSTANT: STB_LOCAL  0
217 CONSTANT: STB_GLOBAL 1
218 CONSTANT: STB_WEAK   2
219 CONSTANT: STB_LOOS   10
220 CONSTANT: STB_HIOS   12
221 CONSTANT: STB_LOPROC 13
222 CONSTANT: STB_HIPROC 15
223
224 CONSTANT: STT_NOTYPE   0
225 CONSTANT: STT_OBJECT   1
226 CONSTANT: STT_FUNC     2
227 CONSTANT: STT_SECTION  3
228 CONSTANT: STT_FILE     4
229 CONSTANT: STT_COMMON   5
230 CONSTANT: STT_TLS      6
231 CONSTANT: STT_LOOS    10
232 CONSTANT: STT_HIOS    12
233 CONSTANT: STT_LOPROC  13
234 CONSTANT: STT_HIPROC  15
235
236 CONSTANT: STN_UNDEF 0
237
238 CONSTANT: STV_DEFAULT   0
239 CONSTANT: STV_INTERNAL  1
240 CONSTANT: STV_HIDDEN    2
241 CONSTANT: STV_PROTECTED 3
242
243 CONSTANT: PT_NULL        0
244 CONSTANT: PT_LOAD        1
245 CONSTANT: PT_DYNAMIC     2
246 CONSTANT: PT_INTERP      3
247 CONSTANT: PT_NOTE        4
248 CONSTANT: PT_SHLIB       5
249 CONSTANT: PT_PHDR        6
250 CONSTANT: PT_TLS         7
251 CONSTANT: PT_LOOS        0x60000000
252 CONSTANT: PT_HIOS        0x6fffffff
253 CONSTANT: PT_LOPROC      0x70000000
254 CONSTANT: PT_ARM_ARCHEXT 0x70000000
255 CONSTANT: PT_ARM_EXIDX   0x70000001
256 CONSTANT: PT_ARM_UNWIND  0x70000001
257 CONSTANT: PT_HIPROC      0x7fffffff
258
259 CONSTANT: PT_ARM_ARCHEXT_FMTMSK       0xff000000
260 CONSTANT: PT_ARM_ARCHEXT_PROFMSK      0x00ff0000
261 CONSTANT: PT_ARM_ARCHEXT_ARCHMSK      0x000000ff
262 CONSTANT: PT_ARM_ARCHEXT_FMT_OS       0x00000000
263 CONSTANT: PT_ARM_ARCHEXT_FMT_ABI      0x01000000
264 CONSTANT: PT_ARM_ARCHEXT_PROF_NONE    0x00000000
265 CONSTANT: PT_ARM_ARCHEXT_PROF_ARM     0x00410000
266 CONSTANT: PT_ARM_ARCHEXT_PROF_RT      0x00520000
267 CONSTANT: PT_ARM_ARCHEXT_PROF_MC      0x004d0000
268 CONSTANT: PT_ARM_ARCHEXT_PROF_CLASSIC 0x00530000
269
270 CONSTANT: PT_ARM_ARCHEXT_ARCH_UNKN      0x00
271 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv4    0x01
272 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv4T   0x02
273 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv5T   0x03
274 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv5TE  0x04
275 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv5TEJ 0x05
276 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6    0x06
277 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6KZ  0x07
278 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6T2  0x08
279 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6K   0x09
280 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv7    0x0A
281 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6M   0x0B
282 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv6SM  0x0C
283 CONSTANT: PT_ARM_ARCHEXT_ARCH_ARCHv7EM  0x0D
284
285 CONSTANT: PF_X        1
286 CONSTANT: PF_W        2
287 CONSTANT: PF_R        4
288 CONSTANT: PF_MASKOS   0x00ff0000
289 CONSTANT: PF_MASKPROC 0xff000000
290
291 CONSTANT: DT_NULL            0
292 CONSTANT: DT_NEEDED          1
293 CONSTANT: DT_PLTRELSZ        2
294 CONSTANT: DT_PLTGOT          3
295 CONSTANT: DT_HASH            4
296 CONSTANT: DT_STRTAB          5
297 CONSTANT: DT_SYMTAB          6
298 CONSTANT: DT_RELA            7
299 CONSTANT: DT_RELASZ          8
300 CONSTANT: DT_RELAENT         9
301 CONSTANT: DT_STRSZ           10
302 CONSTANT: DT_SYMENT          11
303 CONSTANT: DT_INIT            12
304 CONSTANT: DT_FINI            13
305 CONSTANT: DT_SONAME          14
306 CONSTANT: DT_RPATH           15
307 CONSTANT: DT_SYMBOLIC        16
308 CONSTANT: DT_REL             17
309 CONSTANT: DT_RELSZ           18
310 CONSTANT: DT_RELENT          19
311 CONSTANT: DT_PLTREL          20
312 CONSTANT: DT_DEBUG           21
313 CONSTANT: DT_TEXTREL         22
314 CONSTANT: DT_JMPREL          23
315 CONSTANT: DT_BIND_NOW        24
316 CONSTANT: DT_INIT_ARRAY      25
317 CONSTANT: DT_FINI_ARRAY      26
318 CONSTANT: DT_INIT_ARRAYSZ    27
319 CONSTANT: DT_FINI_ARRAYSZ    28
320 CONSTANT: DT_RUNPATH         29
321 CONSTANT: DT_FLAGS           30
322 CONSTANT: DT_ENCODING        32
323 CONSTANT: DT_PREINIT_ARRAY   32
324 CONSTANT: DT_PREINIT_ARRAYSZ 33
325 CONSTANT: DT_LOOS            0x60000000
326 CONSTANT: DT_HIOS            0x6fffffff
327 CONSTANT: DT_LOPROC          0x70000000
328 CONSTANT: DT_ARM_RESERVED1   0x70000000
329 CONSTANT: DT_ARM_SYMTABSZ    0x70000001
330 CONSTANT: DT_ARM_PREEMPTYMAP 0x70000002
331 CONSTANT: DT_ARM_RESERVED2   0x70000003
332 CONSTANT: DT_HIPROC          0x7fffffff
333
334 TYPEDEF: ushort    Elf32_Half
335 TYPEDEF: uint      Elf32_Word
336 TYPEDEF: int       Elf32_Sword
337 TYPEDEF: uint      Elf32_Off
338 TYPEDEF: uint      Elf32_Addr
339 TYPEDEF: ushort    Elf64_Half
340 TYPEDEF: uint      Elf64_Word
341 TYPEDEF: ulonglong Elf64_Xword
342 TYPEDEF: longlong  Elf64_Sxword
343 TYPEDEF: ulonglong Elf64_Off
344 TYPEDEF: ulonglong Elf64_Addr
345
346 STRUCT: Elf32_Ehdr
347     { e_ident     uchar[16]  }
348     { e_type      Elf32_Half }
349     { e_machine   Elf32_Half }
350     { e_version   Elf32_Word }
351     { e_entry     Elf32_Addr }
352     { e_phoff     Elf32_Off  }
353     { e_shoff     Elf32_Off  }
354     { e_flags     Elf32_Word }
355     { e_ehsize    Elf32_Half }
356     { e_phentsize Elf32_Half }
357     { e_phnum     Elf32_Half }
358     { e_shentsize Elf32_Half }
359     { e_shnum     Elf32_Half }
360     { e_shstrndx  Elf32_Half } ;
361
362 STRUCT: Elf64_Ehdr
363     { e_ident     uchar[16]  }
364     { e_type      Elf64_Half }
365     { e_machine   Elf64_Half }
366     { e_version   Elf64_Word }
367     { e_entry     Elf64_Addr }
368     { e_phoff     Elf64_Off  }
369     { e_shoff     Elf64_Off  }
370     { e_flags     Elf64_Word }
371     { e_ehsize    Elf64_Half }
372     { e_phentsize Elf64_Half }
373     { e_phnum     Elf64_Half }
374     { e_shentsize Elf64_Half }
375     { e_shnum     Elf64_Half }
376     { e_shstrndx  Elf64_Half } ;
377
378 STRUCT: Elf32_Shdr
379     { sh_name      Elf32_Word  }
380     { sh_type      Elf32_Word  }
381     { sh_flags     Elf32_Word  }
382     { sh_addr      Elf32_Addr  }
383     { sh_offset    Elf32_Off   }
384     { sh_size      Elf32_Word  }
385     { sh_link      Elf32_Word  }
386     { sh_info      Elf32_Word  }
387     { sh_addralign Elf32_Word  }
388     { sh_entsize   Elf32_Word  } ;
389
390 STRUCT: Elf64_Shdr
391     { sh_name      Elf64_Word  }
392     { sh_type      Elf64_Word  }
393     { sh_flags     Elf64_Xword }
394     { sh_addr      Elf64_Addr  }
395     { sh_offset    Elf64_Off   }
396     { sh_size      Elf64_Xword }
397     { sh_link      Elf64_Word  }
398     { sh_info      Elf64_Word  }
399     { sh_addralign Elf64_Xword }
400     { sh_entsize   Elf64_Xword } ;
401
402 STRUCT: Elf32_Sym
403     { st_name  Elf32_Word }
404     { st_value Elf32_Addr }
405     { st_size  Elf32_Word }
406     { st_info  uchar      }
407     { st_other uchar      }
408     { st_shndx Elf32_Half } ;
409
410 STRUCT: Elf64_Sym
411     { st_name  Elf64_Word  }
412     { st_info  uchar       }
413     { st_other uchar       }
414     { st_shndx Elf64_Half  }
415     { st_value Elf64_Addr  }
416     { st_size  Elf64_Xword } ;
417
418 STRUCT: Elf32_Rel
419     { r_offset Elf32_Addr }
420     { r_info   Elf32_Word } ;
421
422 STRUCT: Elf32_Rela
423     { r_offset Elf32_Addr  }
424     { r_info   Elf32_Word  }
425     { r_addend Elf32_Sword } ;
426
427 STRUCT: Elf64_Rel
428     { r_offset Elf64_Addr  }
429     { r_info   Elf64_Xword } ;
430
431 STRUCT: Elf64_Rela
432     { r_offset Elf64_Addr   }
433     { r_info   Elf64_Xword  }
434     { r_addend Elf64_Sxword } ;
435
436 STRUCT: Elf32_Phdr
437     { p_type   Elf32_Word  }
438     { p_offset Elf32_Off   }
439     { p_vaddr  Elf32_Addr  }
440     { p_paddr  Elf32_Addr  }
441     { p_filesz Elf32_Word  }
442     { p_memsz  Elf32_Word  }
443     { p_flags  Elf32_Word  }
444     { p_align  Elf32_Word  } ;
445
446 STRUCT: Elf64_Phdr
447     { p_type   Elf64_Word  }
448     { p_flags  Elf64_Word  }
449     { p_offset Elf64_Off   }
450     { p_vaddr  Elf64_Addr  }
451     { p_paddr  Elf64_Addr  }
452     { p_filesz Elf64_Xword }
453     { p_memsz  Elf64_Xword }
454     { p_align  Elf64_Xword } ;
455
456 STRUCT: Elf32_Dyn
457     { d_tag Elf32_Sword }
458     { d_val Elf32_Word  } ;
459
460 STRUCT: Elf64_Dyn
461     { d_tag Elf64_Sxword }
462     { d_val Elf64_Xword  } ;
463
464 ! Low-level interface
465 SPECIALIZED-ARRAYS: Elf32_Shdr Elf64_Shdr Elf32_Sym Elf64_Sym Elf32_Phdr Elf64_Phdr uchar ;
466 UNION: Elf32/64_Ehdr Elf32_Ehdr Elf64_Ehdr ;
467 UNION: Elf32/64_Shdr Elf32_Shdr Elf64_Shdr ;
468 UNION: Elf32/64_Shdr-array Elf32_Shdr-array Elf64_Shdr-array ;
469 UNION: Elf32/64_Sym Elf32_Sym Elf64_Sym ;
470 UNION: Elf32/64_Sym-array Elf32_Sym-array Elf64_Sym-array ;
471 UNION: Elf32/64_Phdr Elf32_Phdr Elf64_Phdr ;
472 UNION: Elf32/64_Phdr-array Elf32_Phdr-array Elf64_Phdr-array ;
473
474 TYPED: 64-bit? ( elf: Elf32/64_Ehdr -- ? )
475     e_ident>> EI_CLASS swap nth ELFCLASS64 = ;
476
477 TYPED: elf-header ( c-ptr -- elf: Elf32/64_Ehdr )
478     [ Elf64_Ehdr memory>struct 64-bit? ] keep swap
479     [ Elf64_Ehdr memory>struct ]
480     [ Elf32_Ehdr memory>struct ] if ;
481
482 TYPED:: elf-section-headers ( elf: Elf32/64_Ehdr -- headers: Elf32/64_Shdr-array )
483     elf [ e_shoff>> ] [ e_shnum>> ] bi :> ( off num )
484     off elf >c-ptr <displaced-alien> num
485     elf 64-bit?
486     [ Elf64_Shdr <c-direct-array> ]
487     [ Elf32_Shdr <c-direct-array> ] if ;
488
489 TYPED:: elf-program-headers ( elf: Elf32/64_Ehdr -- headers: Elf32/64_Phdr-array )
490     elf [ e_phoff>> ] [ e_phnum>> ] bi :> ( off num )
491     off elf >c-ptr <displaced-alien> num
492     elf 64-bit?
493     [ Elf64_Phdr <c-direct-array> ]
494     [ Elf32_Phdr <c-direct-array> ] if ;
495
496 TYPED: elf-loadable-segments ( headers: Elf32/64_Phdr-array -- headers: Elf32/64_Phdr-array )
497     [ p_type>> PT_LOAD = ] filter ;
498
499 TYPED:: elf-segment-sections ( segment: Elf32/64_Phdr sections: Elf32/64_Shdr-array -- sections )
500     segment [ p_offset>> dup ] [ p_filesz>> + ] bi [a,b)                            :> segment-interval
501     sections [ dup [ sh_offset>> dup ] [ sh_size>> + ] bi [a,b) 2array ] { } map-as :> section-intervals
502     section-intervals [ second segment-interval interval-intersect empty-interval = not ]
503     filter keys ;
504
505 TYPED:: virtual-address-segment ( elf: Elf32/64_Ehdr address -- program-header/f )
506     elf elf-program-headers elf-loadable-segments [
507         [ p_vaddr>> dup ] [ p_memsz>> + ] bi [a,b)
508         address swap interval-contains?
509     ] find nip ;
510
511 TYPED:: virtual-address-section ( elf: Elf32/64_Ehdr address -- section-header/f )
512     elf address virtual-address-segment :> segment
513     segment elf elf-section-headers elf-segment-sections :> sections
514     address segment p_vaddr>> - segment p_offset>> + :> faddress
515     sections [
516         [ sh_offset>> dup ] [ sh_size>> + ] bi [a,b)
517         faddress swap interval-contains?
518     ] find nip ;
519
520 TYPED:: elf-segment-data ( elf: Elf32/64_Ehdr header: Elf32/64_Phdr -- uchar-array/f )
521     header [ p_offset>> elf >c-ptr <displaced-alien> ] [ p_filesz>> ] bi uchar <c-direct-array> ;
522
523 TYPED:: elf-section-data ( elf: Elf32/64_Ehdr header: Elf32/64_Shdr -- uchar-array/f )
524     header [ sh_offset>> elf >c-ptr <displaced-alien> ] [ sh_size>> ] bi uchar <c-direct-array> ;
525
526 TYPED:: elf-section-data-by-index ( elf: Elf32/64_Ehdr index -- header/f uchar-array/f )
527     elf elf-section-headers     :> sections
528     index sections nth          :> header
529     elf header elf-section-data :> data
530     header data ;
531
532 TYPED:: elf-section-name ( elf: Elf32/64_Ehdr header: Elf32/64_Shdr -- name: string )
533     elf elf e_shstrndx>> elf-section-data-by-index nip >c-ptr :> section-names
534     header sh_name>> section-names <displaced-alien> ascii alien>string ;
535
536 TYPED:: elf-section-data-by-name ( elf: Elf32/64_Ehdr name: string -- header/f uchar-array/f )
537     elf elf-section-headers                      :> sections
538     elf e_shstrndx>>                             :> ndx
539     elf ndx sections nth elf-section-data >c-ptr :> section-names
540     sections rest [
541         sh_name>> section-names <displaced-alien> ascii alien>string name =
542     ] find nip
543     [ dup elf swap elf-section-data ]
544     [ f f ] if* ;
545
546 TYPED:: elf-sections ( elf: Elf32/64_Ehdr -- sections )
547     elf elf-section-headers                                   :> sections
548     elf elf e_shstrndx>> elf-section-data-by-index nip >c-ptr :> section-names
549     sections [
550         [ sh_name>> section-names <displaced-alien>
551           ascii alien>string ] keep 2array
552     ] { } map-as ;
553
554 TYPED:: elf-symbols ( elf: Elf32/64_Ehdr section-data: uchar-array -- symbols )
555     elf ".strtab" elf-section-data-by-name nip >c-ptr :> strings
556     section-data [ >c-ptr ] [ length ] bi
557     elf 64-bit?
558     [ Elf64_Sym heap-size / Elf64_Sym <c-direct-array> ]
559     [ Elf32_Sym heap-size / Elf32_Sym <c-direct-array> ] if
560     [ [ st_name>> strings <displaced-alien> ascii alien>string ] keep 2array ] { } map-as ;
561
562 ! High level interface
563 TUPLE: elf elf-header ;
564 TUPLE: section name elf-header section-header data ;
565 TUPLE: segment elf-header program-header data ;
566 TUPLE: symbol name elf-header sym data ;
567
568 GENERIC: sections ( obj -- sections )
569     
570 : <elf> ( c-ptr -- elf )
571     elf-header elf boa ;
572
573 M:: elf sections ( elf -- sections )
574     elf elf-header>> elf-sections
575     [
576         first2 :> ( name header )
577         elf elf-header>> header elf-section-data :> data
578         name elf elf-header>> header data section boa
579     ] { } map-as ;
580
581 :: segments ( elf -- segments )
582     elf elf-header>> elf-program-headers
583     [| header |
584         elf elf-header>> header elf-segment-data :> data
585         elf elf-header>> header data segment boa
586     ] { } map-as ;
587
588 M:: segment sections ( segment -- sections )
589     segment program-header>>
590     segment elf-header>> elf-section-headers
591     elf-segment-sections
592
593     [| header |
594         segment elf-header>> header elf-section-name :> name
595         segment elf-header>> header elf-section-data :> data
596         name segment elf-header>> header data section boa
597     ] { } map-as ;
598
599 :: symbols ( section -- symbols )
600     section elf-header>>
601     section data>>
602     elf-symbols
603     [
604         first2 :> ( name sym )
605         name section elf-header>> sym f symbol boa
606     ] { } map-as ;
607     
608 :: symbol-data ( symbol -- data )
609     symbol [ elf-header>> ] [ sym>> st_value>> ] bi virtual-address-segment :> segment
610     symbol sym>> st_value>> segment p_vaddr>> - segment p_offset>> + :> faddress
611     faddress symbol elf-header>> >c-ptr <displaced-alien>
612     symbol sym>> st_size>> uchar <c-direct-array> ;
613
614 : find-section ( sections name -- section/f )
615     '[ name>> _ = ] find nip ; inline
616
617 : find-symbol ( symbols name -- symbol/f )
618     '[ name>> _ = ] find nip ; inline
619
620 : find-section-symbol ( sections section symbol -- symbol/f )
621     [ find-section ] dip over [
622         [ symbols ] dip find-symbol ] [ 2drop f ] if ;
623
624 : with-mapped-elf ( path quot -- )
625     '[
626         address>> <elf> @
627     ] with-mapped-file ; inline