metasm 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. data/BUGS +11 -0
  2. data/CREDITS +17 -0
  3. data/README +270 -0
  4. data/TODO +114 -0
  5. data/doc/code_organisation.txt +146 -0
  6. data/doc/const_missing.txt +16 -0
  7. data/doc/core_classes.txt +75 -0
  8. data/doc/feature_list.txt +53 -0
  9. data/doc/index.txt +59 -0
  10. data/doc/install_notes.txt +170 -0
  11. data/doc/style.css +3 -0
  12. data/doc/use_cases.txt +18 -0
  13. data/lib/metasm.rb +80 -0
  14. data/lib/metasm/arm.rb +12 -0
  15. data/lib/metasm/arm/debug.rb +39 -0
  16. data/lib/metasm/arm/decode.rb +167 -0
  17. data/lib/metasm/arm/encode.rb +77 -0
  18. data/lib/metasm/arm/main.rb +75 -0
  19. data/lib/metasm/arm/opcodes.rb +177 -0
  20. data/lib/metasm/arm/parse.rb +130 -0
  21. data/lib/metasm/arm/render.rb +55 -0
  22. data/lib/metasm/compile_c.rb +1457 -0
  23. data/lib/metasm/dalvik.rb +8 -0
  24. data/lib/metasm/dalvik/decode.rb +196 -0
  25. data/lib/metasm/dalvik/main.rb +60 -0
  26. data/lib/metasm/dalvik/opcodes.rb +366 -0
  27. data/lib/metasm/decode.rb +213 -0
  28. data/lib/metasm/decompile.rb +2659 -0
  29. data/lib/metasm/disassemble.rb +2068 -0
  30. data/lib/metasm/disassemble_api.rb +1280 -0
  31. data/lib/metasm/dynldr.rb +1329 -0
  32. data/lib/metasm/encode.rb +333 -0
  33. data/lib/metasm/exe_format/a_out.rb +194 -0
  34. data/lib/metasm/exe_format/autoexe.rb +82 -0
  35. data/lib/metasm/exe_format/bflt.rb +189 -0
  36. data/lib/metasm/exe_format/coff.rb +455 -0
  37. data/lib/metasm/exe_format/coff_decode.rb +901 -0
  38. data/lib/metasm/exe_format/coff_encode.rb +1078 -0
  39. data/lib/metasm/exe_format/dex.rb +457 -0
  40. data/lib/metasm/exe_format/dol.rb +145 -0
  41. data/lib/metasm/exe_format/elf.rb +923 -0
  42. data/lib/metasm/exe_format/elf_decode.rb +979 -0
  43. data/lib/metasm/exe_format/elf_encode.rb +1375 -0
  44. data/lib/metasm/exe_format/macho.rb +827 -0
  45. data/lib/metasm/exe_format/main.rb +228 -0
  46. data/lib/metasm/exe_format/mz.rb +164 -0
  47. data/lib/metasm/exe_format/nds.rb +172 -0
  48. data/lib/metasm/exe_format/pe.rb +437 -0
  49. data/lib/metasm/exe_format/serialstruct.rb +246 -0
  50. data/lib/metasm/exe_format/shellcode.rb +114 -0
  51. data/lib/metasm/exe_format/xcoff.rb +167 -0
  52. data/lib/metasm/gui.rb +23 -0
  53. data/lib/metasm/gui/cstruct.rb +373 -0
  54. data/lib/metasm/gui/dasm_coverage.rb +199 -0
  55. data/lib/metasm/gui/dasm_decomp.rb +369 -0
  56. data/lib/metasm/gui/dasm_funcgraph.rb +103 -0
  57. data/lib/metasm/gui/dasm_graph.rb +1354 -0
  58. data/lib/metasm/gui/dasm_hex.rb +543 -0
  59. data/lib/metasm/gui/dasm_listing.rb +599 -0
  60. data/lib/metasm/gui/dasm_main.rb +906 -0
  61. data/lib/metasm/gui/dasm_opcodes.rb +291 -0
  62. data/lib/metasm/gui/debug.rb +1228 -0
  63. data/lib/metasm/gui/gtk.rb +884 -0
  64. data/lib/metasm/gui/qt.rb +495 -0
  65. data/lib/metasm/gui/win32.rb +3004 -0
  66. data/lib/metasm/gui/x11.rb +621 -0
  67. data/lib/metasm/ia32.rb +14 -0
  68. data/lib/metasm/ia32/compile_c.rb +1523 -0
  69. data/lib/metasm/ia32/debug.rb +193 -0
  70. data/lib/metasm/ia32/decode.rb +1167 -0
  71. data/lib/metasm/ia32/decompile.rb +564 -0
  72. data/lib/metasm/ia32/encode.rb +314 -0
  73. data/lib/metasm/ia32/main.rb +233 -0
  74. data/lib/metasm/ia32/opcodes.rb +872 -0
  75. data/lib/metasm/ia32/parse.rb +327 -0
  76. data/lib/metasm/ia32/render.rb +91 -0
  77. data/lib/metasm/main.rb +1193 -0
  78. data/lib/metasm/mips.rb +11 -0
  79. data/lib/metasm/mips/compile_c.rb +7 -0
  80. data/lib/metasm/mips/decode.rb +253 -0
  81. data/lib/metasm/mips/encode.rb +51 -0
  82. data/lib/metasm/mips/main.rb +72 -0
  83. data/lib/metasm/mips/opcodes.rb +443 -0
  84. data/lib/metasm/mips/parse.rb +51 -0
  85. data/lib/metasm/mips/render.rb +43 -0
  86. data/lib/metasm/os/gnu_exports.rb +270 -0
  87. data/lib/metasm/os/linux.rb +1112 -0
  88. data/lib/metasm/os/main.rb +1686 -0
  89. data/lib/metasm/os/remote.rb +527 -0
  90. data/lib/metasm/os/windows.rb +2027 -0
  91. data/lib/metasm/os/windows_exports.rb +745 -0
  92. data/lib/metasm/parse.rb +876 -0
  93. data/lib/metasm/parse_c.rb +3938 -0
  94. data/lib/metasm/pic16c/decode.rb +42 -0
  95. data/lib/metasm/pic16c/main.rb +17 -0
  96. data/lib/metasm/pic16c/opcodes.rb +68 -0
  97. data/lib/metasm/ppc.rb +11 -0
  98. data/lib/metasm/ppc/decode.rb +264 -0
  99. data/lib/metasm/ppc/decompile.rb +251 -0
  100. data/lib/metasm/ppc/encode.rb +51 -0
  101. data/lib/metasm/ppc/main.rb +129 -0
  102. data/lib/metasm/ppc/opcodes.rb +410 -0
  103. data/lib/metasm/ppc/parse.rb +52 -0
  104. data/lib/metasm/preprocessor.rb +1277 -0
  105. data/lib/metasm/render.rb +130 -0
  106. data/lib/metasm/sh4.rb +8 -0
  107. data/lib/metasm/sh4/decode.rb +336 -0
  108. data/lib/metasm/sh4/main.rb +292 -0
  109. data/lib/metasm/sh4/opcodes.rb +381 -0
  110. data/lib/metasm/x86_64.rb +12 -0
  111. data/lib/metasm/x86_64/compile_c.rb +1025 -0
  112. data/lib/metasm/x86_64/debug.rb +59 -0
  113. data/lib/metasm/x86_64/decode.rb +268 -0
  114. data/lib/metasm/x86_64/encode.rb +264 -0
  115. data/lib/metasm/x86_64/main.rb +135 -0
  116. data/lib/metasm/x86_64/opcodes.rb +118 -0
  117. data/lib/metasm/x86_64/parse.rb +68 -0
  118. data/misc/bottleneck.rb +61 -0
  119. data/misc/cheader-findpppath.rb +58 -0
  120. data/misc/hexdiff.rb +74 -0
  121. data/misc/hexdump.rb +55 -0
  122. data/misc/metasm-all.rb +13 -0
  123. data/misc/objdiff.rb +47 -0
  124. data/misc/objscan.rb +40 -0
  125. data/misc/pdfparse.rb +661 -0
  126. data/misc/ppc_pdf2oplist.rb +192 -0
  127. data/misc/tcp_proxy_hex.rb +84 -0
  128. data/misc/txt2html.rb +440 -0
  129. data/samples/a.out.rb +31 -0
  130. data/samples/asmsyntax.rb +77 -0
  131. data/samples/bindiff.rb +555 -0
  132. data/samples/compilation-steps.rb +49 -0
  133. data/samples/cparser_makestackoffset.rb +55 -0
  134. data/samples/dasm-backtrack.rb +38 -0
  135. data/samples/dasmnavig.rb +318 -0
  136. data/samples/dbg-apihook.rb +228 -0
  137. data/samples/dbghelp.rb +143 -0
  138. data/samples/disassemble-gui.rb +102 -0
  139. data/samples/disassemble.rb +133 -0
  140. data/samples/dump_upx.rb +95 -0
  141. data/samples/dynamic_ruby.rb +1929 -0
  142. data/samples/elf_list_needed.rb +46 -0
  143. data/samples/elf_listexports.rb +33 -0
  144. data/samples/elfencode.rb +25 -0
  145. data/samples/exeencode.rb +128 -0
  146. data/samples/factorize-headers-elfimports.rb +77 -0
  147. data/samples/factorize-headers-peimports.rb +109 -0
  148. data/samples/factorize-headers.rb +43 -0
  149. data/samples/gdbclient.rb +583 -0
  150. data/samples/generate_libsigs.rb +102 -0
  151. data/samples/hotfix_gtk_dbg.rb +59 -0
  152. data/samples/install_win_env.rb +78 -0
  153. data/samples/lindebug.rb +924 -0
  154. data/samples/linux_injectsyscall.rb +95 -0
  155. data/samples/machoencode.rb +31 -0
  156. data/samples/metasm-shell.rb +91 -0
  157. data/samples/pe-hook.rb +69 -0
  158. data/samples/pe-ia32-cpuid.rb +203 -0
  159. data/samples/pe-mips.rb +35 -0
  160. data/samples/pe-shutdown.rb +78 -0
  161. data/samples/pe-testrelocs.rb +51 -0
  162. data/samples/pe-testrsrc.rb +24 -0
  163. data/samples/pe_listexports.rb +31 -0
  164. data/samples/peencode.rb +19 -0
  165. data/samples/peldr.rb +494 -0
  166. data/samples/preprocess-flatten.rb +19 -0
  167. data/samples/r0trace.rb +308 -0
  168. data/samples/rubstop.rb +399 -0
  169. data/samples/scan_pt_gnu_stack.rb +54 -0
  170. data/samples/scanpeexports.rb +62 -0
  171. data/samples/shellcode-c.rb +40 -0
  172. data/samples/shellcode-dynlink.rb +146 -0
  173. data/samples/source.asm +34 -0
  174. data/samples/struct_offset.rb +47 -0
  175. data/samples/testpe.rb +32 -0
  176. data/samples/testraw.rb +45 -0
  177. data/samples/win32genloader.rb +132 -0
  178. data/samples/win32hooker-advanced.rb +169 -0
  179. data/samples/win32hooker.rb +96 -0
  180. data/samples/win32livedasm.rb +33 -0
  181. data/samples/win32remotescan.rb +133 -0
  182. data/samples/wintrace.rb +92 -0
  183. data/tests/all.rb +8 -0
  184. data/tests/dasm.rb +39 -0
  185. data/tests/dynldr.rb +35 -0
  186. data/tests/encodeddata.rb +132 -0
  187. data/tests/ia32.rb +82 -0
  188. data/tests/mips.rb +116 -0
  189. data/tests/parse_c.rb +239 -0
  190. data/tests/preprocessor.rb +269 -0
  191. data/tests/x86_64.rb +62 -0
  192. metadata +255 -0
@@ -0,0 +1,145 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2009 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ require 'metasm/exe_format/main'
7
+ require 'metasm/encode'
8
+ require 'metasm/decode'
9
+
10
+ module Metasm
11
+ class Dol < ExeFormat
12
+ attr_accessor :header, :text, :data
13
+
14
+ class Header < SerialStruct
15
+ 7.times { |i| word "foff_text#{i}".to_sym }
16
+ 11.times { |i| word "foff_data#{i}".to_sym }
17
+ 7.times { |i| word "addr_text#{i}".to_sym }
18
+ 11.times { |i| word "addr_data#{i}".to_sym }
19
+ 7.times { |i| word "size_text#{i}".to_sym }
20
+ 11.times { |i| word "size_data#{i}".to_sym }
21
+ word :addr_bss
22
+ word :size_bss
23
+ word :entrypoint
24
+ mem :pad, 0x100-0xe4
25
+ end
26
+
27
+ def decode_word(edata = @encoded) edata.decode_imm(:u32, @endianness) end
28
+ def encode_word(w) Expression[w].encode(:u32, @endianness) end
29
+
30
+ def initialize(cpu = nil)
31
+ @endianness = :big
32
+ @header = Header.new
33
+ @text = []
34
+ @data = []
35
+ super(cpu)
36
+ end
37
+
38
+ def decode_header
39
+ @encoded.ptr = 0
40
+ @header.decode(self)
41
+ end
42
+
43
+ def decode
44
+ decode_header
45
+
46
+ 7.times { |i|
47
+ off = @header.send("foff_text#{i}")
48
+ sz = @header.send("size_text#{i}")
49
+ @text << @encoded[off, sz]
50
+ }
51
+ 11.times { |i|
52
+ off = @header.send("foff_data#{i}")
53
+ sz = @header.send("size_data#{i}")
54
+ @data << @encoded[off, sz]
55
+ }
56
+ end
57
+
58
+ def encode(ignored=nil)
59
+ binding = {}
60
+ addr = 0 # XXX
61
+ @encoded = EncodedData.new
62
+ @text.each_with_index { |s, i|
63
+ next if not s
64
+ @header.send("foff_text#{i}=", new_label("foff_text#{i}"))
65
+ @header.send("size_text#{i}=", new_label("size_text#{i}"))
66
+ @header.send("addr_text#{i}=", new_label("addr_text#{i}")) if not @header.send("addr_text#{i}")
67
+ }
68
+ @data.each_with_index { |s, i|
69
+ next if not s
70
+ @header.send("foff_data#{i}=", new_label("foff_data#{i}"))
71
+ @header.send("size_data#{i}=", new_label("size_data#{i}"))
72
+ @header.send("addr_data#{i}=", new_label("addr_data#{i}")) if not @header.send("addr_data#{i}")
73
+ }
74
+ @encoded << @header.encode(self)
75
+
76
+ @text.each_with_index { |s, i|
77
+ next if not s
78
+ binding[@header.send("foff_text#{i}")] = @encoded.length
79
+ binding[@header.send("size_text#{i}")] = s.length
80
+ binding[@header.send("addr_text#{i}")] = addr if @header.send("addr_text#{i}").kind_of? String
81
+ binding.update s.binding(addr)
82
+ @encoded << s
83
+ addr += s.length
84
+ }
85
+ @data.each_with_index { |s, i|
86
+ next if not s
87
+ binding[@header.send("foff_data#{i}")] = @encoded.length
88
+ binding[@header.send("size_data#{i}")] = s.length
89
+ binding[@header.send("addr_data#{i}")] = addr if @header.send("addr_data#{i}").kind_of? String
90
+ binding.update s.binding(addr)
91
+ @encoded << s
92
+ addr += s.length
93
+ }
94
+ @encoded.fixup! binding
95
+ @encoded.data
96
+ end
97
+
98
+ def parse_init
99
+ @textsrc ||= []
100
+ @datasrc ||= []
101
+ @cursource ||= @textsrc
102
+ super()
103
+ end
104
+
105
+ def parse_parser_instruction(instr)
106
+ case instr.raw.downcase
107
+ when '.text'; @cursource = @textsrc
108
+ when '.data'; @cursource = @datasrc
109
+ when '.entrypoint'
110
+ # ".entrypoint <somelabel/expression>" or ".entrypoint" (here)
111
+ @lexer.skip_space
112
+ if tok = @lexer.nexttok and tok.type == :string
113
+ raise instr if not entrypoint = Expression.parse(@lexer)
114
+ else
115
+ entrypoint = new_label('entrypoint')
116
+ @cursource << Label.new(entrypoint, instr.backtrace.dup)
117
+ end
118
+ @header.entrypoint = entrypoint
119
+ else super(instr)
120
+ end
121
+ end
122
+
123
+ def assemble(*a)
124
+ parse(*a) if not a.empty?
125
+ @text[0] ||= EncodedData.new
126
+ @text[0] << assemble_sequence(@textsrc, @cpu)
127
+ @textsrc.clear
128
+ @data[0] ||= EncodedData.new
129
+ @data[0] << assemble_sequence(@datasrc, @cpu)
130
+ @datasrc.clear
131
+ self
132
+ end
133
+
134
+ def each_section
135
+ 7.times { |i|
136
+ next if not @text[i]
137
+ yield @text[i], instance_variable_get("addr_text#{i}")
138
+ }
139
+ 11.times { |i|
140
+ next if not @data[i]
141
+ yield @data[i], instance_variable_get("addr_data#{i}")
142
+ }
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,923 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2009 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+
7
+ require 'metasm/exe_format/main'
8
+
9
+ module Metasm
10
+ class ELF < ExeFormat
11
+ MAGIC = "\x7fELF" # 0x7f454c46
12
+ CLASS = { 0 => 'NONE', 1 => '32', 2 => '64', 200 => '64_icc' }
13
+ DATA = { 0 => 'NONE', 1 => 'LSB', 2 => 'MSB' }
14
+ VERSION = { 0 => 'INVALID', 1 => 'CURRENT' }
15
+ ABI = { 0 => 'SYSV', 1 => 'HPUX', 2 => 'NETBSD', 3 => 'LINUX',
16
+ 6 => 'SOLARIS', 7 => 'AIX', 8 => 'IRIX', 9 => 'FREEBSD',
17
+ 10 => 'TRU64', 11 => 'MODESTO', 12 => 'OPENBSD', 97 => 'ARM',
18
+ 255 => 'STANDALONE'}
19
+ TYPE = { 0 => 'NONE', 1 => 'REL', 2 => 'EXEC', 3 => 'DYN', 4 => 'CORE' }
20
+ TYPE_LOPROC = 0xff00
21
+ TYPE_HIPROC = 0xffff
22
+
23
+ MACHINE = {
24
+ 0 => 'NONE', 1 => 'M32', 2 => 'SPARC', 3 => '386',
25
+ 4 => '68K', 5 => '88K', 6 => '486', 7 => '860',
26
+ 8 => 'MIPS', 9 => 'S370', 10 => 'MIPS_RS3_LE',
27
+ 15 => 'PARISC',
28
+ 17 => 'VPP500',18 => 'SPARC32PLUS', 19 => '960',
29
+ 20 => 'PPC', 21 => 'PPC64', 22 => 'S390',
30
+ 36 => 'V800', 37 => 'FR20', 38 => 'RH32', 39 => 'MCORE',
31
+ 40 => 'ARM', 41 => 'ALPHA_STD', 42 => 'SH', 43 => 'SPARCV9',
32
+ 44 => 'TRICORE', 45 => 'ARC', 46 => 'H8_300', 47 => 'H8_300H',
33
+ 48 => 'H8S', 49 => 'H8_500', 50 => 'IA_64', 51 => 'MIPS_X',
34
+ 52 => 'COLDFIRE', 53 => '68HC12', 54 => 'MMA', 55 => 'PCP',
35
+ 56 => 'NCPU', 57 => 'NDR1', 58 => 'STARCORE', 59 => 'ME16',
36
+ 60 => 'ST100', 61 => 'TINYJ', 62 => 'X86_64', 63 => 'PDSP',
37
+ 66 => 'FX66', 67 => 'ST9PLUS',
38
+ 68 => 'ST7', 69 => '68HC16', 70 => '68HC11', 71 => '68HC08',
39
+ 72 => '68HC05',73 => 'SVX', 74 => 'ST19', 75 => 'VAX',
40
+ 76 => 'CRIS', 77 => 'JAVELIN',78 => 'FIREPATH', 79 => 'ZSP',
41
+ 80 => 'MMIX', 81 => 'HUANY', 82 => 'PRISM', 83 => 'AVR',
42
+ 84 => 'FR30', 85 => 'D10V', 86 => 'D30V', 87 => 'V850',
43
+ 88 => 'M32R', 89 => 'MN10300',90 => 'MN10200',91 => 'PJ',
44
+ 92 => 'OPENRISC', 93 => 'ARC_A5', 94 => 'XTENSA',
45
+ 99 => 'PJ',
46
+ 0x9026 => 'ALPHA'
47
+ }
48
+
49
+ FLAGS = {
50
+ 'SPARC' => {0x100 => '32PLUS', 0x200 => 'SUN_US1',
51
+ 0x400 => 'HAL_R1', 0x800 => 'SUN_US3',
52
+ 0x8000_0000 => 'LEDATA'},
53
+ 'SPARCV9' => {0 => 'TSO', 1 => 'PSO', 2 => 'RMO'}, # XXX not a flag
54
+ 'MIPS' => {1 => 'NOREORDER', 2 => 'PIC', 4 => 'CPIC',
55
+ 8 => 'XGOT', 16 => '64BIT_WHIRL', 32 => 'ABI2',
56
+ 64 => 'ABI_ON32'}
57
+ }
58
+
59
+ DYNAMIC_TAG = { 0 => 'NULL', 1 => 'NEEDED', 2 => 'PLTRELSZ', 3 =>
60
+ 'PLTGOT', 4 => 'HASH', 5 => 'STRTAB', 6 => 'SYMTAB', 7 => 'RELA',
61
+ 8 => 'RELASZ', 9 => 'RELAENT', 10 => 'STRSZ', 11 => 'SYMENT',
62
+ 12 => 'INIT', 13 => 'FINI', 14 => 'SONAME', 15 => 'RPATH',
63
+ 16 => 'SYMBOLIC', 17 => 'REL', 18 => 'RELSZ', 19 => 'RELENT',
64
+ 20 => 'PLTREL', 21 => 'DEBUG', 22 => 'TEXTREL', 23 => 'JMPREL',
65
+ 24 => 'BIND_NOW',
66
+ 25 => 'INIT_ARRAY', 26 => 'FINI_ARRAY',
67
+ 27 => 'INIT_ARRAYSZ', 28 => 'FINI_ARRAYSZ',
68
+ 29 => 'RUNPATH', 30 => 'FLAGS', 31 => 'ENCODING',
69
+ 32 => 'PREINIT_ARRAY', 33 => 'PREINIT_ARRAYSZ',
70
+ 0x6fff_fdf5 => 'GNU_PRELINKED',
71
+ 0x6fff_fdf6 => 'GNU_CONFLICTSZ', 0x6fff_fdf7 => 'LIBLISTSZ',
72
+ 0x6fff_fdf8 => 'CHECKSUM', 0x6fff_fdf9 => 'PLTPADSZ',
73
+ 0x6fff_fdfa => 'MOVEENT', 0x6fff_fdfb => 'MOVESZ',
74
+ 0x6fff_fdfc => 'FEATURE_1', 0x6fff_fdfd => 'POSFLAG_1',
75
+ 0x6fff_fdfe => 'SYMINSZ', 0x6fff_fdff => 'SYMINENT',
76
+ 0x6fff_fef5 => 'GNU_HASH',
77
+ 0x6fff_fef6 => 'TLSDESC_PLT', 0x6fff_fef7 => 'TLSDESC_GOT',
78
+ 0x6fff_fef8 => 'GNU_CONFLICT', 0x6fff_fef9 => 'GNU_LIBLIST',
79
+ 0x6fff_fefa => 'CONFIG', 0x6fff_fefb => 'DEPAUDIT',
80
+ 0x6fff_fefc => 'AUDIT', 0x6fff_fefd => 'PLTPAD',
81
+ 0x6fff_fefe => 'MOVETAB', 0x6fff_feff => 'SYMINFO',
82
+ 0x6fff_fff0 => 'VERSYM', 0x6fff_fff9 => 'RELACOUNT',
83
+ 0x6fff_fffa => 'RELCOUNT', 0x6fff_fffb => 'FLAGS_1',
84
+ 0x6fff_fffc => 'VERDEF', 0x6fff_fffd => 'VERDEFNUM',
85
+ 0x6fff_fffe => 'VERNEED', 0x6fff_ffff => 'VERNEEDNUM'
86
+ }
87
+ DYNAMIC_TAG_LOPROC = 0x7000_0000
88
+ DYNAMIC_TAG_HIPROC = 0x7fff_ffff
89
+
90
+ # for tags between DT_LOPROC and DT_HIPROC, use DT_PROC[header.machine][tag-DT_LOPROC]
91
+ DYNAMIC_TAG_PROC = {
92
+ 'MIPS' => {
93
+ 1 => 'RLD_VERSION', 2 => 'TIME_STAMP', 3 => 'ICHECKSUM',
94
+ 4 => 'IVERSION', 5 => 'M_FLAGS', 6 => 'BASE_ADDRESS', 7 => 'MSYM',
95
+ 8 => 'CONFLICT', 9 => 'LIBLIST', 0x0a => 'LOCAL_GOTNO',
96
+ 0x0b => 'CONFLICTNO', 0x10 => 'LIBLISTNO', 0x11 => 'SYMTABNO',
97
+ 0x12 => 'UNREFEXTNO', 0x13 => 'GOTSYM', 0x14 => 'HIPAGENO',
98
+ 0x16 => 'RLD_MAP', 0x17 => 'DELTA_CLASS', 0x18 => 'DELTA_CLASS_NO',
99
+ 0x19 => 'DELTA_INSTANCE', 0x1a => 'DELTA_INSTANCE_NO',
100
+ 0x1b => 'DELTA_RELOC', 0x1c => 'DELTA_RELOC_NO', 0x1d => 'DELTA_SYM',
101
+ 0x1e => 'DELTA_SYM_NO', 0x20 => 'DELTA_CLASSSYM', 0x21 => 'DELTA_CLASSSYM_NO',
102
+ 0x22 => 'CXX_FLAGS', 0x23 => 'PIXIE_INIT', 0x24 => 'SYMBOL_LIB',
103
+ 0x25 => 'LOCALPAGE_GOTIDX', 0x26 => 'LOCAL_GOTIDX',
104
+ 0x27 => 'HIDDEN_GOTIDX', 0x28 => 'PROTECTED_GOTIDX',
105
+ 0x29 => 'OPTIONS', 0x2a => 'INTERFACE', 0x2b => 'DYNSTR_ALIGN',
106
+ 0x2c => 'INTERFACE_SIZE', 0x2d => 'RLD_TEXT_RESOLVE_ADDR',
107
+ 0x2e => 'PERF_SUFFIX', 0x2f => 'COMPACT_SIZE',
108
+ 0x30 => 'GP_VALUE', 0x31 => 'AUX_DYNAMIC',
109
+ }
110
+ }
111
+
112
+
113
+ DYNAMIC_FLAGS = { 1 => 'ORIGIN', 2 => 'SYMBOLIC', 4 => 'TEXTREL',
114
+ 8 => 'BIND_NOW', 0x10 => 'STATIC_TLS' }
115
+ DYNAMIC_FLAGS_1 = { 1 => 'NOW', 2 => 'GLOBAL', 4 => 'GROUP',
116
+ 8 => 'NODELETE', 0x10 => 'LOADFLTR', 0x20 => 'INITFIRST',
117
+ 0x40 => 'NOOPEN', 0x80 => 'ORIGIN', 0x100 => 'DIRECT',
118
+ 0x200 => 'TRANS', 0x400 => 'INTERPOSE', 0x800 => 'NODEFLIB',
119
+ 0x1000 => 'NODUMP', 0x2000 => 'CONFALT', 0x4000 => 'ENDFILTEE',
120
+ 0x8000 => 'DISPRELDNE', 0x10000 => 'DISPRELPND' }
121
+ DYNAMIC_FEATURE_1 = { 1 => 'PARINIT', 2 => 'CONFEXP' }
122
+ DYNAMIC_POSFLAG_1 = { 1 => 'LAZYLOAD', 2 => 'GROUPPERM' }
123
+
124
+ PH_TYPE = { 0 => 'NULL', 1 => 'LOAD', 2 => 'DYNAMIC', 3 => 'INTERP',
125
+ 4 => 'NOTE', 5 => 'SHLIB', 6 => 'PHDR', 7 => 'TLS',
126
+ 0x6474e550 => 'GNU_EH_FRAME', 0x6474e551 => 'GNU_STACK',
127
+ 0x6474e552 => 'GNU_RELRO' }
128
+ PH_TYPE_LOPROC = 0x7000_0000
129
+ PH_TYPE_HIPROC = 0x7fff_ffff
130
+ PH_FLAGS = { 1 => 'X', 2 => 'W', 4 => 'R' }
131
+
132
+ SH_TYPE = { 0 => 'NULL', 1 => 'PROGBITS', 2 => 'SYMTAB', 3 => 'STRTAB',
133
+ 4 => 'RELA', 5 => 'HASH', 6 => 'DYNAMIC', 7 => 'NOTE',
134
+ 8 => 'NOBITS', 9 => 'REL', 10 => 'SHLIB', 11 => 'DYNSYM',
135
+ 14 => 'INIT_ARRAY', 15 => 'FINI_ARRAY', 16 => 'PREINIT_ARRAY',
136
+ 17 => 'GROUP', 18 => 'SYMTAB_SHNDX',
137
+ 0x6fff_fff6 => 'GNU_HASH', 0x6fff_fff7 => 'GNU_LIBLIST',
138
+ 0x6fff_fff8 => 'GNU_CHECKSUM',
139
+ 0x6fff_fffd => 'GNU_verdef', 0x6fff_fffe => 'GNU_verneed',
140
+ 0x6fff_ffff => 'GNU_versym' }
141
+ SH_TYPE_LOOS = 0x6000_0000
142
+ SH_TYPE_HIOS = 0x6fff_ffff
143
+ SH_TYPE_LOPROC = 0x7000_0000
144
+ SH_TYPE_HIPROC = 0x7fff_ffff
145
+ SH_TYPE_LOUSER = 0x8000_0000
146
+ SH_TYPE_HIUSER = 0xffff_ffff
147
+
148
+ SH_FLAGS = { 1 => 'WRITE', 2 => 'ALLOC', 4 => 'EXECINSTR',
149
+ 0x10 => 'MERGE', 0x20 => 'STRINGS', 0x40 => 'INFO_LINK',
150
+ 0x80 => 'LINK_ORDER', 0x100 => 'OS_NONCONFORMING',
151
+ 0x200 => 'GROUP', 0x400 => 'TLS' }
152
+ SH_FLAGS_MASKPROC = 0xf000_0000
153
+
154
+ SH_INDEX = { 0 => 'UNDEF',
155
+ 0xfff1 => 'ABS', 0xfff2 => 'COMMON',
156
+ 0xffff => 'XINDEX', }
157
+ SH_INDEX_LORESERVE = 0xff00
158
+ SH_INDEX_LOPROC = 0xff00
159
+ SH_INDEX_HIPROC = 0xff1f
160
+ SH_INDEX_LOOS = 0xff20
161
+ SH_INDEX_HIOS = 0xff3f
162
+ SH_INDEX_HIRESERVE = 0xffff
163
+
164
+ SYMBOL_BIND = { 0 => 'LOCAL', 1 => 'GLOBAL', 2 => 'WEAK' }
165
+ SYMBOL_BIND_LOPROC = 13
166
+ SYMBOL_BIND_HIPROC = 15
167
+
168
+ SYMBOL_TYPE = { 0 => 'NOTYPE', 1 => 'OBJECT', 2 => 'FUNC',
169
+ 3 => 'SECTION', 4 => 'FILE', 5 => 'COMMON', 6 => 'TLS' }
170
+ SYMBOL_TYPE_LOPROC = 13
171
+ SYMBOL_TYPE_HIPROC = 15
172
+
173
+ SYMBOL_VISIBILITY = { 0 => 'DEFAULT', 1 => 'INTERNAL', 2 => 'HIDDEN', 3 => 'PROTECTED' }
174
+
175
+ RELOCATION_TYPE = { # key are in MACHINE.values
176
+ '386' => { 0 => 'NONE', 1 => '32', 2 => 'PC32', 3 => 'GOT32',
177
+ 4 => 'PLT32', 5 => 'COPY', 6 => 'GLOB_DAT',
178
+ 7 => 'JMP_SLOT', 8 => 'RELATIVE', 9 => 'GOTOFF',
179
+ 10 => 'GOTPC', 11 => '32PLT', 12 => 'TLS_GD_PLT',
180
+ 13 => 'TLS_LDM_PLT', 14 => 'TLS_TPOFF', 15 => 'TLS_IE',
181
+ 16 => 'TLS_GOTIE', 17 => 'TLS_LE', 18 => 'TLS_GD',
182
+ 19 => 'TLS_LDM', 20 => '16', 21 => 'PC16', 22 => '8',
183
+ 23 => 'PC8', 24 => 'TLS_GD_32', 25 => 'TLS_GD_PUSH',
184
+ 26 => 'TLS_GD_CALL', 27 => 'TLS_GD_POP',
185
+ 28 => 'TLS_LDM_32', 29 => 'TLS_LDM_PUSH',
186
+ 30 => 'TLS_LDM_CALL', 31 => 'TLS_LDM_POP',
187
+ 32 => 'TLS_LDO_32', 33 => 'TLS_IE_32',
188
+ 34 => 'TLS_LE_32', 35 => 'TLS_DTPMOD32',
189
+ 36 => 'TLS_DTPOFF32', 37 => 'TLS_TPOFF32' },
190
+ 'ARM' => { 0 => 'NONE', 1 => 'PC24', 2 => 'ABS32', 3 => 'REL32',
191
+ 4 => 'PC13', 5 => 'ABS16', 6 => 'ABS12',
192
+ 7 => 'THM_ABS5', 8 => 'ABS8', 9 => 'SBREL32',
193
+ 10 => 'THM_PC22', 11 => 'THM_PC8', 12 => 'AMP_VCALL9',
194
+ 13 => 'SWI24', 14 => 'THM_SWI8', 15 => 'XPC25',
195
+ 16 => 'THM_XPC22', 20 => 'COPY', 21 => 'GLOB_DAT',
196
+ 22 => 'JUMP_SLOT', 23 => 'RELATIVE', 24 => 'GOTOFF',
197
+ 25 => 'GOTPC', 26 => 'GOT32', 27 => 'PLT32',
198
+ 100 => 'GNU_VTENTRY', 101 => 'GNU_VTINHERIT',
199
+ 250 => 'RSBREL32', 251 => 'THM_RPC22', 252 => 'RREL32',
200
+ 253 => 'RABS32', 254 => 'RPC24', 255 => 'RBASE' },
201
+ 'IA_64' => { 0 => 'NONE',
202
+ 0x21 => 'IMM14', 0x22 => 'IMM22', 0x23 => 'IMM64',
203
+ 0x24 => 'DIR32MSB', 0x25 => 'DIR32LSB',
204
+ 0x26 => 'DIR64MSB', 0x27 => 'DIR64LSB',
205
+ 0x2a => 'GPREL22', 0x2b => 'GPREL64I',
206
+ 0x2c => 'GPREL32MSB', 0x2d => 'GPREL32LSB',
207
+ 0x2e => 'GPREL64MSB', 0x2f => 'GPREL64LSB',
208
+ 0x32 => 'LTOFF22', 0x33 => 'LTOFF64I',
209
+ 0x3a => 'PLTOFF22', 0x3b => 'PLTOFF64I',
210
+ 0x3e => 'PLTOFF64MSB', 0x3f => 'PLTOFF64LSB',
211
+ 0x43 => 'FPTR64I', 0x44 => 'FPTR32MSB',
212
+ 0x45 => 'FPTR32LSB', 0x46 => 'FPTR64MSB',
213
+ 0x47 => 'FPTR64LSB',
214
+ 0x48 => 'PCREL60B', 0x49 => 'PCREL21B',
215
+ 0x4a => 'PCREL21M', 0x4b => 'PCREL21F',
216
+ 0x4c => 'PCREL32MSB', 0x4d => 'PCREL32LSB',
217
+ 0x4e => 'PCREL64MSB', 0x4f => 'PCREL64LSB',
218
+ 0x52 => 'LTOFF_FPTR22', 0x53 => 'LTOFF_FPTR64I',
219
+ 0x54 => 'LTOFF_FPTR32MSB', 0x55 => 'LTOFF_FPTR32LSB',
220
+ 0x56 => 'LTOFF_FPTR64MSB', 0x57 => 'LTOFF_FPTR64LSB',
221
+ 0x5c => 'SEGREL32MSB', 0x5d => 'SEGREL32LSB',
222
+ 0x5e => 'SEGREL64MSB', 0x5f => 'SEGREL64LSB',
223
+ 0x64 => 'SECREL32MSB', 0x65 => 'SECREL32LSB',
224
+ 0x66 => 'SECREL64MSB', 0x67 => 'SECREL64LSB',
225
+ 0x6c => 'REL32MSB', 0x6d => 'REL32LSB',
226
+ 0x6e => 'REL64MSB', 0x6f => 'REL64LSB',
227
+ 0x74 => 'LTV32MSB', 0x75 => 'LTV32LSB',
228
+ 0x76 => 'LTV64MSB', 0x77 => 'LTV64LSB',
229
+ 0x79 => 'PCREL21BI', 0x7a => 'PCREL22',
230
+ 0x7b => 'PCREL64I', 0x80 => 'IPLTMSB',
231
+ 0x81 => 'IPLTLSB', 0x85 => 'SUB',
232
+ 0x86 => 'LTOFF22X', 0x87 => 'LDXMOV',
233
+ 0x91 => 'TPREL14', 0x92 => 'TPREL22',
234
+ 0x93 => 'TPREL64I', 0x96 => 'TPREL64MSB',
235
+ 0x97 => 'TPREL64LSB', 0x9a => 'LTOFF_TPREL22',
236
+ 0xa6 => 'DTPMOD64MSB', 0xa7 => 'DTPMOD64LSB',
237
+ 0xaa => 'LTOFF_DTPMOD22', 0xb1 => 'DTPREL14',
238
+ 0xb2 => 'DTPREL22', 0xb3 => 'DTPREL64I',
239
+ 0xb4 => 'DTPREL32MSB', 0xb5 => 'DTPREL32LSB',
240
+ 0xb6 => 'DTPREL64MSB', 0xb7 => 'DTPREL64LSB',
241
+ 0xba => 'LTOFF_DTPREL22' },
242
+ 'M32' => { 0 => 'NONE', 1 => '32', 2 => '32_S', 3 => 'PC32_S',
243
+ 4 => 'GOT32_S', 5 => 'PLT32_S', 6 => 'COPY',
244
+ 7 => 'GLOB_DAT', 8 => 'JMP_SLOT', 9 => 'RELATIVE',
245
+ 10 => 'RELATIVE_S' },
246
+ 'MIPS' => {
247
+ 0 => 'NONE', 1 => '16', 2 => '32', 3 => 'REL32',
248
+ 4 => '26', 5 => 'HI16', 6 => 'LO16', 7 => 'GPREL16',
249
+ 8 => 'LITERAL', 9 => 'GOT16', 10 => 'PC16',
250
+ 11 => 'CALL16', 12 => 'GPREL32',
251
+ 16 => 'SHIFT5', 17 => 'SHIFT6', 18 => '64',
252
+ 19 => 'GOT_DISP', 20 => 'GOT_PAGE', 21 => 'GOT_OFST',
253
+ 22 => 'GOT_HI16', 23 => 'GOT_LO16', 24 => 'SUB',
254
+ 25 => 'INSERT_A', 26 => 'INSERT_B', 27 => 'DELETE',
255
+ 28 => 'HIGHER', 29 => 'HIGHEST', 30 => 'CALL_HI16',
256
+ 31 => 'CALL_LO16', 32 => 'SCN_DISP', 33 => 'REL16',
257
+ 34 => 'ADD_IMMEDIATE', 35 => 'PJUMP', 36 => 'RELGOT',
258
+ 37 => 'JALR', 38 => 'TLS_DTPMOD32', 39 => 'TLS_DTPREL32',
259
+ 40 => 'TLS_DTPMOD64', 41 => 'TLS_DTPREL64',
260
+ 42 => 'TLS_GD', 43 => 'TLS_LDM', 44 => 'TLS_DTPREL_HI16',
261
+ 45 => 'TLS_DTPREL_LO16', 46 => 'TLS_GOTTPREL',
262
+ 47 => 'TLS_TPREL32', 48 => 'TLS_TPREL64',
263
+ 49 => 'TLS_TPREL_HI16', 50 => 'TLS_TPREL_LO16',
264
+ 51 => 'GLOB_DAT', 52 => 'NUM' },
265
+ 'PPC' => { 0 => 'NONE',
266
+ 1 => 'ADDR32', 2 => 'ADDR24', 3 => 'ADDR16',
267
+ 4 => 'ADDR16_LO', 5 => 'ADDR16_HI', 6 => 'ADDR16_HA',
268
+ 7 => 'ADDR14', 8 => 'ADDR14_BRTAKEN', 9 => 'ADDR14_BRNTAKEN',
269
+ 10 => 'REL24', 11 => 'REL14',
270
+ 12 => 'REL14_BRTAKEN', 13 => 'REL14_BRNTAKEN',
271
+ 14 => 'GOT16', 15 => 'GOT16_LO',
272
+ 16 => 'GOT16_HI', 17 => 'GOT16_HA',
273
+ 18 => 'PLTREL24', 19 => 'COPY',
274
+ 20 => 'GLOB_DAT', 21 => 'JMP_SLOT',
275
+ 22 => 'RELATIVE', 23 => 'LOCAL24PC',
276
+ 24 => 'UADDR32', 25 => 'UADDR16',
277
+ 26 => 'REL32', 27 => 'PLT32',
278
+ 28 => 'PLTREL32', 29 => 'PLT16_LO',
279
+ 30 => 'PLT16_HI', 31 => 'PLT16_HA',
280
+ 32 => 'SDAREL16', 33 => 'SECTOFF',
281
+ 34 => 'SECTOFF_LO', 35 => 'SECTOFF_HI',
282
+ 36 => 'SECTOFF_HA', 67 => 'TLS',
283
+ 68 => 'DTPMOD32', 69 => 'TPREL16',
284
+ 70 => 'TPREL16_LO', 71 => 'TPREL16_HI',
285
+ 72 => 'TPREL16_HA', 73 => 'TPREL32',
286
+ 74 => 'DTPREL16', 75 => 'DTPREL16_LO',
287
+ 76 => 'DTPREL16_HI', 77 => 'DTPREL16_HA',
288
+ 78 => 'DTPREL32', 79 => 'GOT_TLSGD16',
289
+ 80 => 'GOT_TLSGD16_LO', 81 => 'GOT_TLSGD16_HI',
290
+ 82 => 'GOT_TLSGD16_HA', 83 => 'GOT_TLSLD16',
291
+ 84 => 'GOT_TLSLD16_LO', 85 => 'GOT_TLSLD16_HI',
292
+ 86 => 'GOT_TLSLD16_HA', 87 => 'GOT_TPREL16',
293
+ 88 => 'GOT_TPREL16_LO', 89 => 'GOT_TPREL16_HI',
294
+ 90 => 'GOT_TPREL16_HA', 101 => 'EMB_NADDR32',
295
+ 102 => 'EMB_NADDR16', 103 => 'EMB_NADDR16_LO',
296
+ 104 => 'EMB_NADDR16_HI', 105 => 'EMB_NADDR16_HA',
297
+ 106 => 'EMB_SDAI16', 107 => 'EMB_SDA2I16',
298
+ 108 => 'EMB_SDA2REL', 109 => 'EMB_SDA21',
299
+ 110 => 'EMB_MRKREF', 111 => 'EMB_RELSEC16',
300
+ 112 => 'EMB_RELST_LO', 113 => 'EMB_RELST_HI',
301
+ 114 => 'EMB_RELST_HA', 115 => 'EMB_BIT_FLD',
302
+ 116 => 'EMB_RELSDA' },
303
+ 'SPARC' => { 0 => 'NONE', 1 => '8', 2 => '16', 3 => '32',
304
+ 4 => 'DISP8', 5 => 'DISP16', 6 => 'DISP32',
305
+ 7 => 'WDISP30', 8 => 'WDISP22', 9 => 'HI22',
306
+ 10 => '22', 11 => '13', 12 => 'LO10', 13 => 'GOT10',
307
+ 14 => 'GOT13', 15 => 'GOT22', 16 => 'PC10',
308
+ 17 => 'PC22', 18 => 'WPLT30', 19 => 'COPY',
309
+ 20 => 'GLOB_DAT', 21 => 'JMP_SLOT', 22 => 'RELATIVE',
310
+ 23 => 'UA32', 24 => 'PLT32', 25 => 'HIPLT22',
311
+ 26 => 'LOPLT10', 27 => 'PCPLT32', 28 => 'PCPLT22',
312
+ 29 => 'PCPLT10', 30 => '10', 31 => '11', 32 => '64',
313
+ 33 => 'OLO10', 34 => 'HH22', 35 => 'HM10', 36 => 'LM22',
314
+ 37 => 'PC_HH22', 38 => 'PC_HM10', 39 => 'PC_LM22',
315
+ 40 => 'WDISP16', 41 => 'WDISP19', 42 => 'GLOB_JMP',
316
+ 43 => '7', 44 => '5', 45 => '6', 46 => 'DISP64',
317
+ 47 => 'PLT64', 48 => 'HIX22', 49 => 'LOX10', 50 => 'H44',
318
+ 51 => 'M44', 52 => 'L44', 53 => 'REGISTER', 54 => 'UA64',
319
+ 55 => 'UA16', 56 => 'TLS_GD_HI22', 57 => 'TLS_GD_LO10',
320
+ 58 => 'TLS_GD_ADD', 59 => 'TLS_GD_CALL',
321
+ 60 => 'TLS_LDM_HI22', 61 => 'TLS_LDM_LO10',
322
+ 62 => 'TLS_LDM_ADD', 63 => 'TLS_LDM_CALL',
323
+ 64 => 'TLS_LDO_HIX22', 65 => 'TLS_LDO_LOX10',
324
+ 66 => 'TLS_LDO_ADD', 67 => 'TLS_IE_HI22',
325
+ 68 => 'TLS_IE_LO10', 69 => 'TLS_IE_LD',
326
+ 70 => 'TLS_IE_LDX', 71 => 'TLS_IE_ADD',
327
+ 72 => 'TLS_LE_HIX22', 73 => 'TLS_LE_LOX10',
328
+ 74 => 'TLS_DTPMOD32', 75 => 'TLS_DTPMOD64',
329
+ 76 => 'TLS_DTPOFF32', 77 => 'TLS_DTPOFF64',
330
+ 78 => 'TLS_TPOFF32', 79 => 'TLS_TPOFF64' },
331
+ 'X86_64' => { 0 => 'NONE',
332
+ 1 => '64', 2 => 'PC32', 3 => 'GOT32', 4 => 'PLT32',
333
+ 5 => 'COPY', 6 => 'GLOB_DAT', 7 => 'JMP_SLOT',
334
+ 8 => 'RELATIVE', 9 => 'GOTPCREL', 10 => '32',
335
+ 11 => '32S', 12 => '16', 13 => 'PC16', 14 => '8',
336
+ 15 => 'PC8', 16 => 'DTPMOD64', 17 => 'DTPOFF64',
337
+ 18 => 'TPOFF64', 19 => 'TLSGD', 20 => 'TLSLD',
338
+ 21 => 'DTPOFF32', 22 => 'GOTTPOFF', 23 => 'TPOFF32' }
339
+ }
340
+
341
+ DEFAULT_INTERP = '/lib/ld-linux.so.2'
342
+ DEFAULT_INTERP64 = '/lib64/ld-linux-x86-64.so.2'
343
+
344
+ class SerialStruct < Metasm::SerialStruct
345
+ new_int_field :addr, :off, :xword, :sword, :sxword
346
+ end
347
+
348
+ class Header < SerialStruct
349
+ mem :magic, 4, MAGIC
350
+ byte :e_class, 0, CLASS
351
+ byte :data, 0, DATA
352
+ byte :i_version, 'CURRENT', VERSION
353
+ byte :abi, 0, ABI
354
+ byte :abi_version
355
+ mem :ident_unk, 7
356
+ half :type, 0, TYPE
357
+ half :machine, 0, MACHINE
358
+ word :version, 'CURRENT', VERSION
359
+ addr :entry
360
+ off :phoff
361
+ off :shoff
362
+ word :flags
363
+ fld_bits(:flags) { |elf, hdr| FLAGS[hdr.machine] || {} }
364
+ halfs :ehsize, :phentsize, :phnum, :shentsize, :shnum, :shstrndx
365
+
366
+ def self.size elf
367
+ x = elf.bitsize >> 3
368
+ 40 + 3*x
369
+ end
370
+ end
371
+
372
+ class Segment < SerialStruct
373
+ attr_accessor :type, :offset, :vaddr, :paddr, :filesz, :memsz, :flags, :align
374
+ attr_accessor :encoded
375
+
376
+ def struct_specialized(elf)
377
+ return Segment32 if not elf
378
+ case elf.bitsize
379
+ when 32; Segment32
380
+ else Segment64
381
+ end
382
+ end
383
+
384
+ def self.size elf
385
+ x = elf.bitsize >> 3
386
+ 8 + 6*x
387
+ end
388
+ end
389
+
390
+ class Segment32 < Segment
391
+ word :type, 0, PH_TYPE
392
+ off :offset
393
+ addr :vaddr
394
+ addr :paddr
395
+ xword :filesz
396
+ xword :memsz
397
+ word :flags ; fld_bits :flags, PH_FLAGS
398
+ xword :align
399
+ end
400
+ class Segment64 < Segment
401
+ word :type, 0, PH_TYPE
402
+ word :flags ; fld_bits :flags, PH_FLAGS
403
+ off :offset
404
+ addr :vaddr
405
+ addr :paddr
406
+ xword :filesz
407
+ xword :memsz
408
+ xword :align
409
+ end
410
+
411
+ class Section < SerialStruct
412
+ word :name_p
413
+ word :type, 0, SH_TYPE
414
+ xword :flags ; fld_bits :flags, SH_FLAGS
415
+ addr :addr
416
+ off :offset
417
+ xword :size
418
+ word :link
419
+ word :info
420
+ xword :addralign
421
+ xword :entsize
422
+
423
+ attr_accessor :name, :encoded
424
+
425
+ def self.size elf
426
+ x = elf.bitsize >> 3
427
+ 16 + 6*x
428
+ end
429
+ end
430
+
431
+ class Symbol < SerialStruct
432
+ def struct_specialized(elf)
433
+ return Symbol32 if not elf
434
+ case elf.bitsize
435
+ when 32; Symbol32
436
+ else Symbol64
437
+ end
438
+ end
439
+
440
+ attr_accessor :name_p, :value, :size, :bind, :type, :other, :shndx
441
+ attr_accessor :name, :thunk
442
+
443
+ def self.size elf
444
+ x = elf.bitsize >> 3
445
+ 8 + 2*x
446
+ end
447
+ end
448
+
449
+ class Symbol32 < Symbol
450
+ word :name_p
451
+ addr :value
452
+ xword :size
453
+ bitfield :byte, 0 => :type, 4 => :bind
454
+ fld_enum :type, SYMBOL_TYPE
455
+ fld_enum :bind, SYMBOL_BIND
456
+ byte :other
457
+ half :shndx, 0, SH_INDEX
458
+ end
459
+ class Symbol64 < Symbol
460
+ word :name_p
461
+ bitfield :byte, 0 => :type, 4 => :bind
462
+ fld_enum :type, SYMBOL_TYPE
463
+ fld_enum :bind, SYMBOL_BIND
464
+ byte :other
465
+ half :shndx, 0, SH_INDEX
466
+ addr :value
467
+ xword :size
468
+ end
469
+
470
+ class Relocation < SerialStruct
471
+ attr_accessor :offset, :type, :symbol
472
+ def struct_specialized(elf)
473
+ return Relocation32 if not elf
474
+ case elf.bitsize
475
+ when 32; Relocation32
476
+ else Relocation64
477
+ end
478
+ end
479
+
480
+ def addend ; end
481
+
482
+ def self.size elf
483
+ x = elf.bitsize >> 3
484
+ 2*x
485
+ end
486
+
487
+ end
488
+ class Relocation32 < Relocation
489
+ addr :offset
490
+ bitfield :xword, 0 => :type, 8 => :symbol
491
+ fld_enum(:type) { |elf, rel| RELOCATION_TYPE[elf.header.machine] || {} }
492
+ fld_enum(:symbol) { |elf, rel| elf.symbols }
493
+ end
494
+ class Relocation64 < Relocation
495
+ addr :offset
496
+ bitfield :xword, 0 => :type, 32 => :symbol
497
+ fld_enum(:type) { |elf, rel| RELOCATION_TYPE[elf.header.machine] || {} }
498
+ fld_enum(:symbol) { |elf, rel| elf.symbols }
499
+ end
500
+ class RelocationAddend < Relocation
501
+ attr_accessor :addend
502
+ def struct_specialized(elf)
503
+ return RelocationAddend32 if not elf
504
+ case elf.bitsize
505
+ when 32; RelocationAddend32
506
+ else RelocationAddend64
507
+ end
508
+ end
509
+ def self.size elf
510
+ x = elf.bitsize >> 3
511
+ 3*x
512
+ end
513
+
514
+ end
515
+ class RelocationAddend32 < RelocationAddend
516
+ addr :offset
517
+ bitfield :xword, 0 => :type, 8 => :symbol
518
+ fld_enum(:type) { |elf, rel| RELOCATION_TYPE[elf.header.machine] || {} }
519
+ fld_enum(:symbol) { |elf, rel| elf.symbols }
520
+ sxword :addend
521
+ end
522
+ class RelocationAddend64 < RelocationAddend
523
+ addr :offset
524
+ bitfield :xword, 0 => :type, 32 => :symbol
525
+ fld_enum(:type) { |elf, rel| RELOCATION_TYPE[elf.header.machine] || {} }
526
+ fld_enum(:symbol) { |elf, rel| elf.symbols }
527
+ sxword :addend
528
+ end
529
+
530
+ class SerialStruct
531
+ new_int_field :leb
532
+ end
533
+
534
+ # libdwarf/dwarf.h
535
+ DWARF_TAG = {
536
+ 0x01 => 'ARRAY_TYPE', 0x02 => 'CLASS_TYPE', 0x03 => 'ENTRY_POINT',
537
+ 0x04 => 'ENUMERATION_TYPE', 0x05 => 'FORMAL_PARAMETER',
538
+ 0x08 => 'IMPORTED_DECLARATION', 0x0a => 'LABEL', 0x0b => 'LEXICAL_BLOCK',
539
+ 0x0d => 'MEMBER', 0x0f => 'POINTER_TYPE',
540
+ 0x10 => 'REFERENCE_TYPE', 0x11 => 'COMPILE_UNIT', 0x12 => 'STRING_TYPE', 0x13 => 'STRUCTURE_TYPE',
541
+ 0x15 => 'SUBROUTINE_TYPE', 0x16 => 'TYPEDEF', 0x17 => 'UNION_TYPE',
542
+ 0x18 => 'UNSPECIFIED_PARAMETERS', 0x19 => 'VARIANT', 0x1a => 'COMMON_BLOCK', 0x1b => 'COMMON_INCLUSION',
543
+ 0x1c => 'INHERITANCE', 0x1d => 'INLINED_SUBROUTINE', 0x1e => 'MODULE', 0x1f => 'PTR_TO_MEMBER_TYPE',
544
+ 0x20 => 'SET_TYPE', 0x21 => 'SUBRANGE_TYPE', 0x22 => 'WITH_STMT', 0x23 => 'ACCESS_DECLARATION',
545
+ 0x24 => 'BASE_TYPE', 0x25 => 'CATCH_BLOCK', 0x26 => 'CONST_TYPE', 0x27 => 'CONSTANT',
546
+ 0x28 => 'ENUMERATOR', 0x29 => 'FILE_TYPE', 0x2a => 'FRIEND', 0x2b => 'NAMELIST',
547
+ 0x2c => 'NAMELIST_ITEM', 0x2d => 'PACKED_TYPE', 0x2e => 'SUBPROGRAM', 0x2f => 'TEMPLATE_TYPE_PARAM',
548
+ 0x30 => 'TEMPLATE_VALUE_PARAM', 0x31 => 'THROWN_TYPE', 0x32 => 'TRY_BLOCK', 0x33 => 'VARIANT_PART',
549
+ 0x34 => 'VARIABLE', 0x35 => 'VOLATILE_TYPE',
550
+ }
551
+ DWARF_FORM = {
552
+ 0x01 => 'ADDR', 0x03 => 'BLOCK2',
553
+ 0x04 => 'BLOCK4', 0x05 => 'DATA2', 0x06 => 'DATA4', 0x07 => 'DATA8',
554
+ 0x08 => 'STRING', 0x09 => 'BLOCK', 0x0a => 'BLOCK1', 0x0b => 'DATA1',
555
+ 0x0c => 'FLAG', 0x0d => 'SDATA', 0x0e => 'STRP', 0x0f => 'UDATA',
556
+ 0x10 => 'REF_ADDR', 0x11 => 'REF1', 0x12 => 'REF2', 0x13 => 'REF4',
557
+ 0x14 => 'REF8', 0x15 => 'REF_UDATA', 0x16 => 'INDIRECT',
558
+ }
559
+ DWARF_AT = {
560
+ 0x01 => 'SIBLING', 0x02 => 'LOCATION', 0x03 => 'NAME',
561
+ 0x09 => 'ORDERING', 0x0a => 'SUBSCR_DATA', 0x0b => 'BYTE_SIZE',
562
+ 0x0c => 'BIT_OFFSET', 0x0d => 'BIT_SIZE', 0x0f => 'ELEMENT_LIST',
563
+ 0x10 => 'STMT_LIST', 0x11 => 'LOW_PC', 0x12 => 'HIGH_PC', 0x13 => 'LANGUAGE',
564
+ 0x14 => 'MEMBER', 0x15 => 'DISCR', 0x16 => 'DISCR_VALUE', 0x17 => 'VISIBILITY',
565
+ 0x18 => 'IMPORT', 0x19 => 'STRING_LENGTH', 0x1a => 'COMMON_REFERENCE', 0x1b => 'COMP_DIR',
566
+ 0x1c => 'CONST_VALUE', 0x1d => 'CONTAINING_TYPE', 0x1e => 'DEFAULT_VALUE',
567
+ 0x20 => 'INLINE', 0x21 => 'IS_OPTIONAL', 0x22 => 'LOWER_BOUND',
568
+ 0x25 => 'PRODUCER', 0x27 => 'PROTOTYPED',
569
+ 0x2a => 'RETURN_ADDR',
570
+ 0x2c => 'START_SCOPE', 0x2e => 'STRIDE_SIZE', 0x2f => 'UPPER_BOUND',
571
+ 0x31 => 'ABSTRACT_ORIGIN', 0x32 => 'ACCESSIBILITY', 0x33 => 'ADDRESS_CLASS',
572
+ 0x34 => 'ARTIFICIAL', 0x35 => 'BASE_TYPES', 0x36 => 'CALLING_CONVENTION', 0x37 => 'COUNT',
573
+ 0x38 => 'DATA_MEMBER_LOCATION', 0x39 => 'DECL_COLUMN', 0x3a => 'DECL_FILE', 0x3b => 'DECL_LINE',
574
+ 0x3c => 'DECLARATION', 0x3d => 'DISCR_LIST', 0x3e => 'ENCODING', 0x3f => 'EXTERNAL',
575
+ 0x40 => 'FRAME_BASE', 0x41 => 'FRIEND', 0x42 => 'IDENTIFIER_CASE', 0x43 => 'MACRO_INFO',
576
+ 0x44 => 'NAMELIST_ITEM', 0x45 => 'PRIORITY', 0x46 => 'SEGMENT', 0x47 => 'SPECIFICATION',
577
+ 0x48 => 'STATIC_LINK', 0x49 => 'TYPE', 0x4a => 'USE_LOCATION', 0x4b => 'VARIABLE_PARAMETER',
578
+ 0x4c => 'VIRTUALITY', 0x4d => 'VTABLE_ELEM_LOCATION',
579
+ }
580
+
581
+ class DwarfDebug < SerialStruct
582
+ class Node < SerialStruct
583
+ leb :index
584
+ leb :tag, 0, DWARF_TAG
585
+ byte :has_child
586
+ attr_accessor :parent, :children, :attributes
587
+ class Attribute < SerialStruct
588
+ leb :attr, 0, DWARF_AT
589
+ leb :form, 0, DWARF_FORM
590
+ attr_accessor :data
591
+ def to_s(a); "#{@attr}=(#@form)#{dump(@data, a)}" end
592
+ end
593
+ end
594
+
595
+ word :cu_len
596
+ half :version, 2
597
+ word :abbrev_off
598
+ byte :ptr_sz
599
+ attr_accessor :tree # ary of root siblings (Node)
600
+ end
601
+
602
+ def self.hash_symbol_name(name)
603
+ name.unpack('C*').inject(0) { |hash, char|
604
+ break hash if char == 0
605
+ hash <<= 4
606
+ hash += char
607
+ hash ^= (hash >> 24) & 0xf0
608
+ hash &= 0x0fff_ffff
609
+ }
610
+ end
611
+
612
+ def self.gnu_hash_symbol_name(name)
613
+ name.unpack('C*').inject(5381) { |hash, char|
614
+ break hash if char == 0
615
+ (hash*33 + char) & 0xffff_ffff
616
+ }
617
+ end
618
+
619
+ attr_accessor :header, :segments, :sections, :tag, :symbols, :relocations, :endianness, :bitsize, :debug
620
+ def initialize(cpu=nil)
621
+ @header = Header.new
622
+ @tag = {}
623
+ @symbols = [Symbol32.new]
624
+ @symbols.first.shndx = 'UNDEF'
625
+ @relocations = []
626
+ @sections = [Section.new]
627
+ @sections.first.type = 'NULL'
628
+ @segments = []
629
+ if cpu
630
+ @endianness = cpu.endianness
631
+ @bitsize = cpu.size
632
+ else
633
+ @endianness = :little
634
+ @bitsize = 32
635
+ end
636
+ super(cpu)
637
+ end
638
+
639
+ def shortname; 'elf'; end
640
+ end
641
+
642
+ class LoadedELF < ELF
643
+ attr_accessor :load_address
644
+ def addr_to_off(addr)
645
+ @load_address ||= 0
646
+ addr >= @load_address ? addr - @load_address : addr if addr
647
+ end
648
+ end
649
+
650
+ class FatELF < ExeFormat
651
+ MAGIC = "\xfa\x70\x0e\x1f" # 0xfat..elf
652
+
653
+ class SerialStruct < Metasm::SerialStruct
654
+ new_int_field :qword
655
+ end
656
+
657
+ class Header < SerialStruct
658
+ mem :magic, 4, MAGIC
659
+ word :version, 1
660
+ byte :nfat_arch
661
+ byte :reserved
662
+
663
+ def decode(fe)
664
+ super(fe)
665
+ raise InvalidExeFormat, "Invalid FatELF signature #{@magic.unpack('H*').first.inspect}" if @magic != MAGIC
666
+ end
667
+
668
+ def set_default_values(fe)
669
+ @nfat_arch ||= fe.list.length
670
+ super(fe)
671
+ end
672
+ end
673
+ class FatArch < SerialStruct
674
+ word :machine
675
+ bytes :abi, :abi_version, :e_class, :data, :res1, :res2
676
+ qwords :offset, :size
677
+
678
+ fld_enum :machine, ELF::MACHINE
679
+ fld_enum :abi, ELF::ABI
680
+ fld_enum :e_class, ELF::CLASS
681
+ fld_enum :data, ELF::DATA
682
+
683
+ attr_accessor :encoded
684
+ end
685
+
686
+ def encode_byte(val) Expression[val].encode(:u8, @endianness) end
687
+ def encode_word(val) Expression[val].encode(:u16, @endianness) end
688
+ def encode_qword(val) Expression[val].encode(:u64, @endianness) end
689
+ def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
690
+ def decode_word(edata = @encoded) edata.decode_imm(:u16, @endianness) end
691
+ def decode_qword(edata = @encoded) edata.decode_imm(:u64, @endianness) end
692
+
693
+ attr_accessor :header, :list
694
+ def initialize
695
+ @endianness = :little
696
+ @list = []
697
+ super()
698
+ end
699
+
700
+ def decode
701
+ @header = Header.decode(self)
702
+ @list = []
703
+ @header.nfat_arch.times { @list << FatArch.decode(self) }
704
+ @list.each { |e|
705
+ e.encoded = @encoded[e.offset, e.size] || EncodedData.new
706
+ }
707
+ end
708
+
709
+ def encode
710
+ @header ||= Header.new
711
+ @encoded = @header.encode(self)
712
+ @list.map! { |f|
713
+ if f.kind_of? ExeFormat
714
+ e = f
715
+ f = FatArch.new
716
+ f.encoded = e.encode_string
717
+ h = e.header
718
+ f.machine, f.abi, f.abi_version, f.e_class, f.data =
719
+ h.machine, h.abi, h.abi_version, h.e_class, h.data
720
+ end
721
+ f.offset = new_label('fat_off')
722
+ f.size = f.encoded.size
723
+ @encoded << f.encode(self)
724
+ f
725
+ }
726
+ bd = {}
727
+ @list.each { |f|
728
+ @encoded.align 4096
729
+ bd[f.offset] = @encoded.length if f.offset.kind_of? String
730
+ @encoded << f.encoded
731
+ }
732
+ @encoded.fixup! bd
733
+ end
734
+
735
+ def [](i) AutoExe.decode(@list[i].encoded) if @list[i] end
736
+ def <<(exe) @list << exe ; self end
737
+
738
+ def self.autoexe_load(*a)
739
+ fe = super(*a)
740
+ fe.decode
741
+ # TODO have a global callback or whatever to prompt the user
742
+ # which file he wants to load in the dasm
743
+ puts "FatELF: using 1st archive member" if $VERBOSE
744
+ fe[0]
745
+ end
746
+
747
+ def shortname; 'fatelf'; end
748
+ end
749
+ end
750
+
751
+ require 'metasm/exe_format/elf_encode'
752
+ require 'metasm/exe_format/elf_decode'
753
+
754
+ # TODO symbol version info
755
+ __END__
756
+ /*
757
+ * Version structures. There are three types of version structure:
758
+ *
759
+ * o A definition of the versions within the image itself.
760
+ * Each version definition is assigned a unique index (starting from
761
+ * VER_NDX_BGNDEF) which is used to cross-reference symbols associated to
762
+ * the version. Each version can have one or more dependencies on other
763
+ * version definitions within the image. The version name, and any
764
+ * dependency names, are specified in the version definition auxiliary
765
+ * array. Version definition entries require a version symbol index table.
766
+ *
767
+ * o A version requirement on a needed dependency. Each needed entry
768
+ * specifies the shared object dependency (as specified in DT_NEEDED).
769
+ * One or more versions required from this dependency are specified in the
770
+ * version needed auxiliary array.
771
+ *
772
+ * o A version symbol index table. Each symbol indexes into this array
773
+ * to determine its version index. Index values of VER_NDX_BGNDEF or
774
+ * greater indicate the version definition to which a symbol is associated.
775
+ * (the size of a symbol index entry is recorded in the sh_info field).
776
+ */
777
+ #ifndef _ASM
778
+
779
+ typedef struct { /* Version Definition Structure. */
780
+ Elf32_Half vd_version; /* this structures version revision */
781
+ Elf32_Half vd_flags; /* version information */
782
+ Elf32_Half vd_ndx; /* version index */
783
+ Elf32_Half vd_cnt; /* no. of associated aux entries */
784
+ Elf32_Word vd_hash; /* version name hash value */
785
+ Elf32_Word vd_aux; /* no. of bytes from start of this */
786
+ /* verdef to verdaux array */
787
+ Elf32_Word vd_next; /* no. of bytes from start of this */
788
+ } Elf32_Verdef; /* verdef to next verdef entry */
789
+
790
+ typedef struct { /* Verdef Auxiliary Structure. */
791
+ Elf32_Word vda_name; /* first element defines the version */
792
+ /* name. Additional entries */
793
+ /* define dependency names. */
794
+ Elf32_Word vda_next; /* no. of bytes from start of this */
795
+ } Elf32_Verdaux; /* verdaux to next verdaux entry */
796
+
797
+
798
+ typedef struct { /* Version Requirement Structure. */
799
+ Elf32_Half vn_version; /* this structures version revision */
800
+ Elf32_Half vn_cnt; /* no. of associated aux entries */
801
+ Elf32_Word vn_file; /* name of needed dependency (file) */
802
+ Elf32_Word vn_aux; /* no. of bytes from start of this */
803
+ /* verneed to vernaux array */
804
+ Elf32_Word vn_next; /* no. of bytes from start of this */
805
+ } Elf32_Verneed; /* verneed to next verneed entry */
806
+
807
+ typedef struct { /* Verneed Auxiliary Structure. */
808
+ Elf32_Word vna_hash; /* version name hash value */
809
+ Elf32_Half vna_flags; /* version information */
810
+ Elf32_Half vna_other;
811
+ Elf32_Word vna_name; /* version name */
812
+ Elf32_Word vna_next; /* no. of bytes from start of this */
813
+ } Elf32_Vernaux; /* vernaux to next vernaux entry */
814
+
815
+ typedef Elf32_Half Elf32_Versym; /* Version symbol index array */
816
+
817
+ typedef struct {
818
+ Elf32_Half si_boundto; /* direct bindings - symbol bound to */
819
+ Elf32_Half si_flags; /* per symbol flags */
820
+ } Elf32_Syminfo;
821
+
822
+
823
+ #if (defined(_LP64) || ((__STDC__ - 0 == 0) && (!defined(_NO_LONGLONG))))
824
+ typedef struct {
825
+ Elf64_Half vd_version; /* this structures version revision */
826
+ Elf64_Half vd_flags; /* version information */
827
+ Elf64_Half vd_ndx; /* version index */
828
+ Elf64_Half vd_cnt; /* no. of associated aux entries */
829
+ Elf64_Word vd_hash; /* version name hash value */
830
+ Elf64_Word vd_aux; /* no. of bytes from start of this */
831
+ /* verdef to verdaux array */
832
+ Elf64_Word vd_next; /* no. of bytes from start of this */
833
+ } Elf64_Verdef; /* verdef to next verdef entry */
834
+
835
+ typedef struct {
836
+ Elf64_Word vda_name; /* first element defines the version */
837
+ /* name. Additional entries */
838
+ /* define dependency names. */
839
+ Elf64_Word vda_next; /* no. of bytes from start of this */
840
+ } Elf64_Verdaux; /* verdaux to next verdaux entry */
841
+
842
+ typedef struct {
843
+ Elf64_Half vn_version; /* this structures version revision */
844
+ Elf64_Half vn_cnt; /* no. of associated aux entries */
845
+ Elf64_Word vn_file; /* name of needed dependency (file) */
846
+ Elf64_Word vn_aux; /* no. of bytes from start of this */
847
+ /* verneed to vernaux array */
848
+ Elf64_Word vn_next; /* no. of bytes from start of this */
849
+ } Elf64_Verneed; /* verneed to next verneed entry */
850
+
851
+ typedef struct {
852
+ Elf64_Word vna_hash; /* version name hash value */
853
+ Elf64_Half vna_flags; /* version information */
854
+ Elf64_Half vna_other;
855
+ Elf64_Word vna_name; /* version name */
856
+ Elf64_Word vna_next; /* no. of bytes from start of this */
857
+ } Elf64_Vernaux; /* vernaux to next vernaux entry */
858
+
859
+ typedef Elf64_Half Elf64_Versym;
860
+
861
+ typedef struct {
862
+ Elf64_Half si_boundto; /* direct bindings - symbol bound to */
863
+ Elf64_Half si_flags; /* per symbol flags */
864
+ } Elf64_Syminfo;
865
+ #endif /* (defined(_LP64) || ((__STDC__ - 0 == 0) ... */
866
+
867
+ #endif
868
+
869
+ /*
870
+ * Versym symbol index values. Values greater than VER_NDX_GLOBAL
871
+ * and less then VER_NDX_LORESERVE associate symbols with user
872
+ * specified version descriptors.
873
+ */
874
+ #define VER_NDX_LOCAL 0 /* symbol is local */
875
+ #define VER_NDX_GLOBAL 1 /* symbol is global and assigned to */
876
+ /* the base version */
877
+ #define VER_NDX_LORESERVE 0xff00 /* beginning of RESERVED entries */
878
+ #define VER_NDX_ELIMINATE 0xff01 /* symbol is to be eliminated */
879
+
880
+ /*
881
+ * Verdef and Verneed (via Veraux) flags values.
882
+ */
883
+ #define VER_FLG_BASE 0x1 /* version definition of file itself */
884
+ #define VER_FLG_WEAK 0x2 /* weak version identifier */
885
+
886
+ /*
887
+ * Verdef version values.
888
+ */
889
+ #define VER_DEF_NONE 0 /* Ver_def version */
890
+ #define VER_DEF_CURRENT 1
891
+ #define VER_DEF_NUM 2
892
+
893
+ /*
894
+ * Verneed version values.
895
+ */
896
+ #define VER_NEED_NONE 0 /* Ver_need version */
897
+ #define VER_NEED_CURRENT 1
898
+ #define VER_NEED_NUM 2
899
+
900
+
901
+ /*
902
+ * Syminfo flag values
903
+ */
904
+ #define SYMINFO_FLG_DIRECT 0x0001 /* direct bound symbol */
905
+ #define SYMINFO_FLG_PASSTHRU 0x0002 /* pass-thru symbol for translator */
906
+ #define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
907
+ #define SYMINFO_FLG_LAZYLOAD 0x0008 /* symbol bound to object to be lazy */
908
+ /* loaded */
909
+
910
+ /*
911
+ * key values for Syminfo.si_boundto
912
+ */
913
+ #define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
914
+ #define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
915
+ #define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */
916
+
917
+ /*
918
+ * Syminfo version values.
919
+ */
920
+ #define SYMINFO_NONE 0 /* Syminfo version */
921
+ #define SYMINFO_CURRENT 1
922
+ #define SYMINFO_NUM 2
923
+