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