kompiler 0.3.0 → 0.3.1
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.
- checksums.yaml +4 -4
- data/bin/kompile +13 -2
- data/lib/kompiler/wrappers/elf_wrapper.rb +320 -122
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18cda0db09b288b5ad14ebb5feb99e13fe03ea5a7897d603285b0aab0c8bdb77
|
4
|
+
data.tar.gz: e84247276f40846adef9798d8ea6584dc3fe156caaa18495c668ee7f99506e9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d682ae38a0d09b9ca8c584de5a3687554a97962ab227fcfb1bd7f458d0f5c48ff1ca0386db8ddcd6f80832e5d94a53b12a655164a23e58bd168128dd8a05106e
|
7
|
+
data.tar.gz: 04e832aff94a2948615b3f9ca03db1cc75648673873ec9a4678aab6f09aa24b595d9a276910cf53f00de34dffebb0bfc7675b1150749bdfcbe6225bae2778401
|
data/bin/kompile
CHANGED
@@ -112,6 +112,7 @@ Available wrapping formats:
|
|
112
112
|
|
113
113
|
Additional options for wrapping are:
|
114
114
|
--elf-machine=<type> Specifies ELF header's e_machine to be the type provided (default is 0)
|
115
|
+
--elf-class=<class> Specifies the ELF file's class to either 32 or 64 (default is 64)
|
115
116
|
--mach-o-machine=<cputype.subtype> Specifies Mach-O header's cputype and subtype
|
116
117
|
to be the type provided
|
117
118
|
|
@@ -276,13 +277,23 @@ when "none"
|
|
276
277
|
when "elf.obj"
|
277
278
|
elf_machine = arg_keys.filter{_1[0] == "elf-machine"}[0]
|
278
279
|
elf_machine = (elf_machine != nil) ? elf_machine[1].to_i : 0
|
280
|
+
|
281
|
+
elf_class = arg_keys.filter{_1[0] == "elf-class"}[0]
|
282
|
+
elf_class ||= ["elf-class", "64"]
|
283
|
+
elf_class = elf_class[1].to_i
|
284
|
+
|
279
285
|
symbols = Kompiler::Wrappers::ELF.labels_to_symbols(labels)
|
280
|
-
out = Kompiler::Wrappers::ELF.wrap_obj(code, symbols, machine: elf_machine)
|
286
|
+
out = Kompiler::Wrappers::ELF.wrap_obj(code, symbols, machine: elf_machine, elf_class: elf_class)
|
281
287
|
when "elf.exec"
|
282
288
|
elf_machine = arg_keys.filter{_1[0] == "elf-machine"}[0]
|
283
289
|
elf_machine = (elf_machine != nil) ? elf_machine[1].to_i : 0
|
290
|
+
|
291
|
+
elf_class = arg_keys.filter{_1[0] == "elf-class"}[0]
|
292
|
+
elf_class ||= ["elf-class", "64"]
|
293
|
+
elf_class = elf_class[1].to_i
|
294
|
+
|
284
295
|
symbols = Kompiler::Wrappers::ELF.labels_to_symbols(labels)
|
285
|
-
out = Kompiler::Wrappers::ELF.wrap_exec(code, symbols, machine: elf_machine)
|
296
|
+
out = Kompiler::Wrappers::ELF.wrap_exec(code, symbols, machine: elf_machine, elf_class: elf_class)
|
286
297
|
when "mach-o.obj"
|
287
298
|
puts "Mach-O not yet implemented."
|
288
299
|
exit
|
@@ -28,7 +28,7 @@ module Kompiler
|
|
28
28
|
|
29
29
|
sections, shstrndx = create_default_sections(code, symbols, elf_class: elf_class).values
|
30
30
|
|
31
|
-
output = build(sections: sections,
|
31
|
+
output = build(sections: sections, e_machine: e_machine, elf_class: elf_class, e_shstrndx: shstrndx, e_type: 1)
|
32
32
|
|
33
33
|
output
|
34
34
|
end
|
@@ -40,14 +40,18 @@ module Kompiler
|
|
40
40
|
# Arguments:
|
41
41
|
# code - raw byte string
|
42
42
|
# options - a hash of configurable options:
|
43
|
+
# machine - a raw machine ID to fill in the e_machine field (default is 0)
|
43
44
|
# elf_class - 32 for ELFClass32 or 64 for ELFClass64 (default is 64)
|
44
|
-
# machine - a raw machine ID to fill in the e_machine field
|
45
45
|
# vaddr - virtual address for the program and entry (default is 0x80000)
|
46
|
+
# align - alignment value for the load segment (default is 0x1000)
|
47
|
+
# flags - segment flags (default is 0b111, bits are in form 0bRWX)
|
46
48
|
def self.wrap_exec code, symbols, **options
|
47
49
|
|
48
50
|
elf_class = options[:elf_class] || 64
|
49
|
-
e_machine = options[:machine]
|
51
|
+
e_machine = options[:machine] || 0
|
50
52
|
vaddr = options[:vaddr] || 0x80000
|
53
|
+
align = options[:align] || 0x1000
|
54
|
+
flags = options[:flags] || 0b111
|
51
55
|
|
52
56
|
sections, shstrndx = create_default_sections(code, symbols, elf_class: elf_class).values
|
53
57
|
|
@@ -56,15 +60,15 @@ module Kompiler
|
|
56
60
|
segments = [
|
57
61
|
{
|
58
62
|
type: 1, # Loadable segment
|
59
|
-
flags:
|
63
|
+
flags: flags, # Execute, write, read permissions
|
60
64
|
vaddr: vaddr, # Virtual address of segment in memory
|
61
65
|
# content: code,
|
62
66
|
content_section_i: 1,
|
63
|
-
align:
|
67
|
+
align: align
|
64
68
|
},
|
65
69
|
]
|
66
70
|
|
67
|
-
output = build(sections: sections, segments: segments,
|
71
|
+
output = build(sections: sections, segments: segments, e_machine: e_machine, elf_class: elf_class, e_type: 2, virtual_entry_address: vaddr, e_shstrndx: shstrndx)
|
68
72
|
|
69
73
|
output
|
70
74
|
end
|
@@ -76,11 +80,19 @@ module Kompiler
|
|
76
80
|
def self.labels_to_symbols labels
|
77
81
|
out = []
|
78
82
|
labels.each do |name, value|
|
79
|
-
out << {name: name, value: value, type:
|
83
|
+
out << {name: name, value: value, type: 0, binding: 0}
|
80
84
|
end
|
81
85
|
out
|
82
86
|
end
|
83
87
|
|
88
|
+
# Converts a values hash of name-value pairs into an array of symbols
|
89
|
+
def self.values_to_symbols values
|
90
|
+
out = []
|
91
|
+
values.each do |name, value|
|
92
|
+
out << {name: name, value: value, type: 0, binding: 0}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
84
96
|
|
85
97
|
# Build ELF
|
86
98
|
# Builds an ELF from provided sections, segments, and other options
|
@@ -88,15 +100,42 @@ module Kompiler
|
|
88
100
|
# Arguments:
|
89
101
|
# sections - ELF sections (structure below)
|
90
102
|
# segments - ELF segments (structure below)
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# e_shstrndx - the value for ELF header's e_shstrndx field (index of the section header string table section)
|
95
|
-
# e_type - the value for ELF header's e_type field (e.g., 1 for relocatable, 3 for executable)
|
103
|
+
# virtual_entry_address - the virtual entry address for the ELF header (default is 0)
|
104
|
+
# elf_class - the ELF class (32 or 64) (default is 0)
|
105
|
+
# e_machine - a raw machine ID for the ELF header (default is 0)
|
106
|
+
# e_shstrndx - the value for ELF header's e_shstrndx field (index of the section header string table section) (default is 0)
|
107
|
+
# e_type - the value for ELF header's e_type field (e.g., 1 for relocatable, 3 for executable) (default is 0)
|
108
|
+
# e_os_abi - the value for the ELF Identification header's osabi field (default is 0) (not used with elf_class = 32)
|
109
|
+
# e_abi_version - the value for the ELF Identification header's abiversion field (default is 0) (not used with elf_class = 32)
|
110
|
+
#
|
111
|
+
# Section structure:
|
112
|
+
# name_offset - section's name field value
|
113
|
+
# type - section's type field value
|
114
|
+
# flags - section's flags field value
|
115
|
+
# addr - section's addr field value
|
116
|
+
# link - section's link field value
|
117
|
+
# info - section's info field value
|
118
|
+
# addralign - section's addralign field value
|
119
|
+
# entsize - section's entsize field value
|
120
|
+
# content - section's content (offset and size will be computed automatically)
|
121
|
+
# segment_content_i - index of segment that contains this section's content (useful to remove repeated info and 'link' a section with a segment)
|
122
|
+
# offset - if segment_content_i is present, an optional offset can be added to take only part of the segment's content (default is 0)
|
123
|
+
# size - if segment_content_i is present, size can be provided optionally to take only part of the segment's content (default is 0)
|
96
124
|
#
|
97
|
-
|
125
|
+
# Segment structure:
|
126
|
+
# type - segment's type field value
|
127
|
+
# flags - segment's flags field value
|
128
|
+
# vaddr - segment's vaddr field value (default is 0)
|
129
|
+
# paddr - segment's paddr field value (default is value of vaddr)
|
130
|
+
# vsize - segment's memsz / vsize field value (default is same as content.size)
|
131
|
+
# align - segment's alignment value. This will also ensure that the segment's content is aligned to this boundary in the file
|
132
|
+
# content - segment's content (offset and size will be computed automatically)
|
133
|
+
# section_content_i - index of section that contaisn this segment's content (idea is same as section[:segment_content_i])
|
134
|
+
# offset - idea same as section[:offset]
|
135
|
+
# size - idea same as section[:size]
|
136
|
+
#
|
137
|
+
def self.build sections: [], segments: [], virtual_entry_address: 0, elf_class: 64, e_machine: 0, e_shstrndx: 0, e_type: 0, e_os_abi: 0, e_abi_version: 0
|
98
138
|
|
99
|
-
raise "Machine ID not specified for the ELF header." if machine == nil
|
100
139
|
|
101
140
|
case elf_class
|
102
141
|
when 64
|
@@ -158,7 +197,12 @@ module Kompiler
|
|
158
197
|
# EI_Version (current)
|
159
198
|
e_ident.bytes 1, elf_char
|
160
199
|
|
161
|
-
e_ident.
|
200
|
+
e_ident.bytes e_os_abi, 1 # OS_ABI
|
201
|
+
e_ident.bytes e_abi_version, 1 # ABI_VERSION
|
202
|
+
|
203
|
+
e_ident.bytes [0] * 6 # Pad to 15
|
204
|
+
|
205
|
+
e_ident.bytes [16] # E_Ident size
|
162
206
|
|
163
207
|
elf_header.add e_ident
|
164
208
|
|
@@ -166,7 +210,7 @@ module Kompiler
|
|
166
210
|
elf_header.bytes e_type, elf_half
|
167
211
|
|
168
212
|
# E_Machine (input)
|
169
|
-
elf_header.bytes
|
213
|
+
elf_header.bytes e_machine, elf_half
|
170
214
|
|
171
215
|
# E_version (current)
|
172
216
|
elf_header.bytes 1, elf_word
|
@@ -219,7 +263,8 @@ module Kompiler
|
|
219
263
|
|
220
264
|
sections_content = PackedBytes.new
|
221
265
|
|
222
|
-
sections.each_with_index do |section, section_i|
|
266
|
+
sections.each_with_index do |section, section_i|
|
267
|
+
|
223
268
|
if !section.keys.include?(:content)
|
224
269
|
section[:size] = 0
|
225
270
|
section[:offset] = 0
|
@@ -240,10 +285,11 @@ module Kompiler
|
|
240
285
|
section[:offset] = sections_content.result.bytesize + sections_contents_offset
|
241
286
|
|
242
287
|
matching_segments.each do |segment|
|
243
|
-
segment[:offset]
|
244
|
-
|
245
|
-
|
246
|
-
|
288
|
+
segment[:offset] ||= 0
|
289
|
+
|
290
|
+
segment[:size] ||= section[:size] - segment[:offset]
|
291
|
+
|
292
|
+
segment[:offset] += section[:offset]
|
247
293
|
end
|
248
294
|
|
249
295
|
sections_content.add section[:content]
|
@@ -256,49 +302,54 @@ module Kompiler
|
|
256
302
|
|
257
303
|
segments.each_with_index do |segment, segment_i|
|
258
304
|
|
259
|
-
|
260
|
-
segment[:align] = 1
|
261
|
-
end
|
305
|
+
segment[:align] ||= 1
|
262
306
|
|
263
|
-
|
264
|
-
segment[:vaddr] = 0
|
265
|
-
end
|
307
|
+
segment[:vaddr] ||= 0
|
266
308
|
|
267
|
-
|
268
|
-
segment[:paddr] = segment[:vaddr]
|
269
|
-
end
|
309
|
+
segment[:paddr] ||= segment[:vaddr]
|
270
310
|
|
271
311
|
if segment.keys.include?(:content)
|
272
312
|
segment[:size] = segment[:content].bytesize
|
273
313
|
end
|
274
314
|
|
275
|
-
|
276
|
-
|
277
|
-
end
|
315
|
+
segment[:vsize] ||= segment[:size]
|
316
|
+
|
278
317
|
|
279
318
|
if segment[:vaddr] % segment[:align] != 0
|
280
319
|
raise "Improper segment at index #{segment_i} - the virtual address is not aligned to the specified alignment boundary."
|
281
320
|
end
|
282
321
|
|
322
|
+
# If the segment uses :content, add the segment's content to the file and compute the offset
|
323
|
+
if !segment.keys.include?(:content_section_i)
|
283
324
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
325
|
+
# ELF requires file_offset and vaddr to be a multiple of the alignment value
|
326
|
+
|
327
|
+
file_offset = segments_contents_offset + segments_content.result.bytesize
|
288
328
|
|
289
|
-
|
290
|
-
|
291
|
-
|
329
|
+
pad_amount = 0
|
330
|
+
if file_offset % segment[:align] != 0
|
331
|
+
pad_amount = segment[:align] - (file_offset % segment[:align])
|
332
|
+
end
|
333
|
+
|
334
|
+
segments_content.bytes "\0" * pad_amount
|
335
|
+
|
336
|
+
segment[:offset] = segments_content.result.bytesize + segments_contents_offset
|
337
|
+
segments_content.add segment[:content]
|
292
338
|
|
293
|
-
pad_amount = 0
|
294
|
-
if file_offset % segment[:align] != 0
|
295
|
-
pad_amount = segment[:align] - (file_offset % segment[:align])
|
296
339
|
end
|
297
340
|
|
298
|
-
segments_content.bytes "\0" * pad_amount
|
299
341
|
|
300
|
-
segment
|
301
|
-
|
342
|
+
# If some sections depend on the segment, update their values
|
343
|
+
|
344
|
+
matching_sections = sections.filter{_1[:segment_content_i] == segment_i}
|
345
|
+
|
346
|
+
matching_sections.each do |section|
|
347
|
+
section[:offset] ||= 0
|
348
|
+
|
349
|
+
section[:size] ||= segment[:size] - section[:offset]
|
350
|
+
|
351
|
+
section[:offset] += segment[:offset]
|
352
|
+
end
|
302
353
|
|
303
354
|
end
|
304
355
|
|
@@ -324,15 +375,29 @@ module Kompiler
|
|
324
375
|
|
325
376
|
ph = PackedBytes.new
|
326
377
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
378
|
+
case elf_class
|
379
|
+
when 64
|
380
|
+
segments.each do |segment|
|
381
|
+
ph.bytes segment[:type], elf_word
|
382
|
+
ph.bytes segment[:flags], elf_word
|
383
|
+
ph.bytes segment[:offset], elf_off
|
384
|
+
ph.bytes segment[:vaddr], elf_addr
|
385
|
+
ph.bytes segment[:paddr], elf_addr
|
386
|
+
ph.bytes segment[:size], elf_xword
|
387
|
+
ph.bytes segment[:vsize], elf_xword
|
388
|
+
ph.bytes segment[:align], elf_xword
|
389
|
+
end
|
390
|
+
when 32
|
391
|
+
segments.each do |segment|
|
392
|
+
ph.bytes segment[:type], elf_word
|
393
|
+
ph.bytes segment[:offset], elf_off
|
394
|
+
ph.bytes segment[:vaddr], elf_addr
|
395
|
+
ph.bytes segment[:paddr], elf_addr
|
396
|
+
ph.bytes segment[:size], elf_word
|
397
|
+
ph.bytes segment[:vsize], elf_word
|
398
|
+
ph.bytes segment[:flags], elf_word
|
399
|
+
ph.bytes segment[:align], elf_word
|
400
|
+
end
|
336
401
|
end
|
337
402
|
|
338
403
|
file_content.add ph
|
@@ -398,101 +463,234 @@ module Kompiler
|
|
398
463
|
entsize: 0,
|
399
464
|
content: program_bytes,
|
400
465
|
},
|
401
|
-
{
|
402
|
-
name: ".symtab",
|
403
|
-
type: 2,
|
404
|
-
flags: 0,
|
405
|
-
addr: 0,
|
406
|
-
link: sym_strtab_section_index, # Index of string table used for symbol names
|
407
|
-
info: symbols.size + 1, # Index of first non-local symbol
|
408
|
-
addralign: 0,
|
409
|
-
entsize: symtab_ent_size,
|
410
|
-
content: "",
|
411
|
-
},
|
412
|
-
{
|
413
|
-
name: ".strtab",
|
414
|
-
type: 3,
|
415
|
-
flags: 0,
|
416
|
-
addr: 0,
|
417
|
-
link: 0,
|
418
|
-
info: 0,
|
419
|
-
addralign: 0,
|
420
|
-
entsize: 0,
|
421
|
-
content: "",
|
422
|
-
},
|
423
|
-
{
|
424
|
-
name: ".shstrtab",
|
425
|
-
type: 3,
|
426
|
-
flags: 0,
|
427
|
-
addr: 0,
|
428
|
-
link: 0,
|
429
|
-
info: 0,
|
430
|
-
addralign: 0,
|
431
|
-
entsize: 0,
|
432
|
-
content: "",
|
433
|
-
},
|
434
466
|
]
|
435
467
|
|
436
|
-
symtab = PackedBytes.new
|
437
468
|
|
438
|
-
|
439
|
-
|
469
|
+
symbols.map! do |sym|
|
470
|
+
sym[:section_index] = sym[:section_index] || progbits_section_index
|
471
|
+
sym
|
472
|
+
end
|
473
|
+
|
474
|
+
symtab_section, sym_strtab_contents = create_symtab_section(symbols, link: sym_strtab_section_index, info: "first-non-local", elf_class: elf_class)
|
440
475
|
|
476
|
+
sections << symtab_section
|
441
477
|
|
442
|
-
|
478
|
+
sections << create_strtab_section(sym_strtab_contents, name: ".strtab", elf_class: elf_class)
|
443
479
|
|
444
|
-
|
480
|
+
|
481
|
+
sections << create_strtab_section("\0", name: ".shstrtab", elf_class: elf_class)
|
445
482
|
|
446
|
-
|
447
|
-
|
448
|
-
|
483
|
+
|
484
|
+
sections.each_with_index do |section, section_i|
|
485
|
+
if section.keys.include? :name
|
486
|
+
section[:name_offset] = sections[sh_strtab_section_index][:content].bytesize
|
487
|
+
sections[sh_strtab_section_index][:content] << section[:name] + "\0"
|
449
488
|
else
|
450
|
-
name_offset = 0
|
489
|
+
section[:name_offset] = 0
|
451
490
|
end
|
491
|
+
end
|
492
|
+
|
493
|
+
|
494
|
+
return {sections: sections, shstrndx: sh_strtab_section_index}
|
495
|
+
|
496
|
+
end
|
497
|
+
|
452
498
|
|
453
|
-
# name
|
454
|
-
symtab.bytes name_offset, elf_word
|
455
499
|
|
456
|
-
|
500
|
+
# Creates a section structure with type symtab, builds symbol entries and symbol string table contents
|
501
|
+
# Returns [symtab_section, sym_strtab_contents]
|
502
|
+
#
|
503
|
+
# Arguments:
|
504
|
+
# symbols - an array of hashes with info about each symbol (structure below)
|
505
|
+
# **options - additional options
|
506
|
+
#
|
507
|
+
# Options are:
|
508
|
+
# elf_class - elf class, either 64 or 32 (default is 64)
|
509
|
+
# name - the symtab section's name (default is .symtab)
|
510
|
+
# link - the symtab section's link field value (default is 0)
|
511
|
+
# info - the symtab section's info field value (default is 0)
|
512
|
+
# set to "first-non-local" to auto-sort all symbols and
|
513
|
+
# set info field to the index of the first non-local symbol
|
514
|
+
# flags - the symtab section's flags field value (default is 0)
|
515
|
+
#
|
516
|
+
# Symbol hash structure:
|
517
|
+
# :name - the symbol's name (optional)
|
518
|
+
# :type - symbol type (0 - notype, 1 - object, 2 - func, 3 - section, 4 - file)
|
519
|
+
# :binding - symbol binding (0 - local, 1 - global, 2 - weak)
|
520
|
+
# :section_index - corresponding section's index (0 - undef, 0xfff1 - absolute, 0xfff2 - common block)
|
521
|
+
# :value - the symbol's value
|
522
|
+
# :size - the symbol's size (default is 0)
|
523
|
+
#
|
524
|
+
def self.create_symtab_section symbols, **options
|
525
|
+
|
526
|
+
elf_class = options[:elf_class] || 64
|
527
|
+
|
528
|
+
section_name = options[:name] || ".symtab"
|
529
|
+
section_link = options[:link] || 0
|
530
|
+
section_info = options[:info] || 0
|
531
|
+
section_flags = options[:flags] || 0
|
457
532
|
|
458
|
-
|
459
|
-
|
533
|
+
# Check if the auto option was selected
|
534
|
+
if section_info == "first-non-local"
|
460
535
|
|
461
|
-
#
|
462
|
-
symtab.bytes 0, elf_char
|
536
|
+
# Sort symbols for global symbols to come last
|
463
537
|
|
464
|
-
|
465
|
-
|
538
|
+
local_symbols = symbols.filter{_1[:binding] == 0}
|
539
|
+
non_local_symbols = symbols.filter{_1[:binding] != 0}
|
466
540
|
|
467
|
-
|
468
|
-
symtab.bytes symbol[:value], elf_addr
|
541
|
+
first_non_local_i = local_symbols.size
|
469
542
|
|
470
|
-
#
|
471
|
-
|
472
|
-
|
543
|
+
# Sort symbols for local ones to come first
|
544
|
+
symbols = local_symbols + non_local_symbols
|
545
|
+
|
546
|
+
# + 1 because the first symbol will be pre-forced to be all zeros and local
|
547
|
+
section_info = first_non_local_i + 1
|
548
|
+
end
|
549
|
+
|
550
|
+
|
551
|
+
case elf_class
|
552
|
+
when 64
|
553
|
+
elf_char = 1
|
554
|
+
elf_half = 2
|
555
|
+
elf_word = 4
|
556
|
+
elf_addr = 8
|
557
|
+
elf_xword = 8
|
558
|
+
symtab_ent_size = 24
|
559
|
+
when 32
|
560
|
+
elf_char = 1
|
561
|
+
elf_half = 2
|
562
|
+
elf_word = 4
|
563
|
+
elf_addr = 4
|
564
|
+
elf_xword = 4
|
565
|
+
symtab_ent_size = 16
|
473
566
|
end
|
474
567
|
|
475
|
-
|
476
|
-
|
568
|
+
symtab_content = PackedBytes.new
|
569
|
+
sym_strtab_contents = "\0".encode "ASCII"
|
477
570
|
|
571
|
+
# First entry must be all zeros
|
572
|
+
symtab_content.bytes [0] * symtab_ent_size
|
478
573
|
|
479
|
-
|
574
|
+
case elf_class
|
575
|
+
when 64
|
576
|
+
symbols.each do |symbol|
|
577
|
+
if symbol.keys.include? :name
|
578
|
+
name_offset = sym_strtab_contents.bytesize
|
579
|
+
sym_strtab_contents << symbol[:name] + "\0"
|
580
|
+
else
|
581
|
+
name_offset = 0
|
582
|
+
end
|
480
583
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
584
|
+
# name
|
585
|
+
symtab_content.bytes name_offset, elf_word
|
586
|
+
|
587
|
+
symbol_info = symbol[:type] | (symbol[:binding] << 4)
|
588
|
+
# info
|
589
|
+
symtab_content.bytes symbol_info, elf_char
|
590
|
+
|
591
|
+
# other
|
592
|
+
symtab_content.bytes 0, elf_char
|
593
|
+
|
594
|
+
# shndx
|
595
|
+
symtab_content.bytes symbol[:section_index], elf_half
|
596
|
+
|
597
|
+
# value
|
598
|
+
symtab_content.bytes symbol[:value], elf_addr
|
599
|
+
|
600
|
+
# size
|
601
|
+
symtab_content.bytes symbol[:size] || 0, elf_xword
|
602
|
+
end
|
603
|
+
when 32
|
604
|
+
symbols.each do |symbol|
|
605
|
+
if symbol.keys.include? :name
|
606
|
+
name_offset = sym_strtab_contents.bytesize
|
607
|
+
sym_strtab_contents << symbol[:name] + "\0"
|
608
|
+
else
|
609
|
+
name_offset = 0
|
610
|
+
end
|
611
|
+
|
612
|
+
# name
|
613
|
+
symtab_content.bytes name_offset, elf_word
|
614
|
+
|
615
|
+
# value
|
616
|
+
symtab_content.bytes symbol[:value], elf_addr
|
617
|
+
|
618
|
+
# size
|
619
|
+
symtab_content.bytes symbol[:size] || 0, elf_xword
|
620
|
+
|
621
|
+
symbol_info = symbol[:type] | (symbol[:binding] << 4)
|
622
|
+
# info
|
623
|
+
symtab_content.bytes symbol_info, elf_char
|
624
|
+
|
625
|
+
# other
|
626
|
+
symtab_content.bytes 0, elf_char
|
627
|
+
|
628
|
+
# shndx
|
629
|
+
symtab_content.bytes symbol[:section_index], elf_half
|
487
630
|
end
|
488
631
|
end
|
489
632
|
|
490
|
-
sections[sh_strtab_section_index][:content] = sections_string_table_content
|
491
633
|
|
492
|
-
|
634
|
+
symtab_section = {
|
635
|
+
name: ".symtab",
|
636
|
+
type: 2,
|
637
|
+
flags: section_flags,
|
638
|
+
addr: 0,
|
639
|
+
link: section_link,
|
640
|
+
info: section_info,
|
641
|
+
addralign: 0,
|
642
|
+
entsize: symtab_ent_size,
|
643
|
+
content: symtab_content.result,
|
644
|
+
}
|
645
|
+
|
646
|
+
return symtab_section, sym_strtab_contents
|
493
647
|
|
494
648
|
end
|
495
649
|
|
650
|
+
|
651
|
+
# Create string table section
|
652
|
+
# Creates a hash with information for a string table section
|
653
|
+
#
|
654
|
+
# Arguments:
|
655
|
+
# string_content - the string table's content
|
656
|
+
# **options - additional options
|
657
|
+
#
|
658
|
+
# Options:
|
659
|
+
# name - the section's name (default is nil)
|
660
|
+
# info - the section's info field value (default is 0)
|
661
|
+
# link - the section's link field value (default is 0)
|
662
|
+
# flags - the section's flags field value (default is 0)
|
663
|
+
# addr - the section's addr field value (default is 0)
|
664
|
+
# addralign - the section's addralign field value (default is 0)
|
665
|
+
# elf_class - ELF class 32 or 64 (not used)
|
666
|
+
#
|
667
|
+
def self.create_strtab_section string_content, **options
|
668
|
+
name = options[:name]
|
669
|
+
info = options[:info] || 0
|
670
|
+
link = options[:link] || 0
|
671
|
+
flags = options[:flags] || 0
|
672
|
+
addr = options[:addr] || 0
|
673
|
+
addralign = options[:addralign] || 0
|
674
|
+
|
675
|
+
|
676
|
+
section = {
|
677
|
+
type: 3,
|
678
|
+
info: info,
|
679
|
+
link: link,
|
680
|
+
flags: flags,
|
681
|
+
addr: addr,
|
682
|
+
addralign: addralign,
|
683
|
+
content: string_content,
|
684
|
+
entsize: 0,
|
685
|
+
}
|
686
|
+
|
687
|
+
section[:name] = name if name != nil
|
688
|
+
|
689
|
+
return section
|
690
|
+
end
|
691
|
+
|
692
|
+
|
693
|
+
|
496
694
|
end # Kompiler::ELF
|
497
695
|
end # Kompiler::Wrappers
|
498
696
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kompiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyryl Shyshko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Kompiler is a low-level, modular and extendable compiler for any architecture.
|
14
14
|
By default Kompiler supports ARMv8-a, but other architecture extensions can be downloaded
|