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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90ed49bc46f0641a23f0d7d561489d4ec326e8f3bb933a638ed789831e9ee362
4
- data.tar.gz: 9c0d4b1f795b9e7a2b73a145218a972854fdd8372808a6fb68b3c210899d2ad8
3
+ metadata.gz: 18cda0db09b288b5ad14ebb5feb99e13fe03ea5a7897d603285b0aab0c8bdb77
4
+ data.tar.gz: e84247276f40846adef9798d8ea6584dc3fe156caaa18495c668ee7f99506e9e
5
5
  SHA512:
6
- metadata.gz: 8a18cb49c4740e3f5d86a074c75a87c90db0de718dad6ec2547b802d1acf70dd4a726fcc163ba6bf17f83b58c91e02a0e331f48b707a2ac6d80ac331f4c852fc
7
- data.tar.gz: c54ac313fed9b03a22810678244e0809dc29f25c0974c2ded1251fac7e6d01f2c28f50a0844938532eda6d7ec90b78ddf8afb0634485662ef1246677c18bc5d5
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, machine: e_machine, elf_class: elf_class, e_shstrndx: shstrndx, e_type: 1)
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: 7, # Execute, write, read permissions
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: 4
67
+ align: align
64
68
  },
65
69
  ]
66
70
 
67
- output = build(sections: sections, segments: segments, machine: e_machine, elf_class: elf_class, e_type: 2, virtual_entry_address: vaddr, e_shstrndx: shstrndx)
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: 1, binding: 0}
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
- # machine - a raw machine ID for the ELF header
92
- # virtual_entry_address - the virtual entry address for the ELF header
93
- # elf_class - the ELF class (32 or 64)
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
- def self.build sections: [], segments: [], machine: nil, virtual_entry_address: 0, elf_class: 64, e_shstrndx: 0, e_type: 0
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.align 16, "\0"
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 machine, elf_half
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] = 0 if !segment.keys.include?(:offset)
244
- segment[:offset] += section[:offset]
245
-
246
- segment[:size] = section[:size] if !segment.keys.include?(:size)
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
- if !segment.keys.include?(:align)
260
- segment[:align] = 1
261
- end
305
+ segment[:align] ||= 1
262
306
 
263
- if !segment.keys.include?(:vaddr)
264
- segment[:vaddr] = 0
265
- end
307
+ segment[:vaddr] ||= 0
266
308
 
267
- if !segment.keys.include?(:paddr)
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
- if !segment.keys.include?(:vsize)
276
- segment[:vsize] = segment[:size]
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
- if segment.keys.include? :content_section_i
285
- next
286
- end
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
- # ELF requires file_offset and vaddr to be a multiple of the alignment value
290
-
291
- file_offset = segments_contents_offset + segments_content.result.bytesize
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[:offset] = segments_content.result.bytesize + segments_contents_offset
301
- segments_content.add segment[:content]
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
- segments.each do |segment|
328
- ph.bytes segment[:type], elf_word
329
- ph.bytes segment[:flags], elf_word
330
- ph.bytes segment[:offset], elf_off
331
- ph.bytes segment[:vaddr], elf_addr
332
- ph.bytes segment[:paddr], elf_addr
333
- ph.bytes segment[:size], elf_xword
334
- ph.bytes segment[:vsize], elf_xword
335
- ph.bytes segment[:align], elf_xword
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
- # First section is all zeros
439
- symtab.bytes [0] * symtab_ent_size
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
- symtab_string_table_content = "\0".encode("ASCII")
478
+ sections << create_strtab_section(sym_strtab_contents, name: ".strtab", elf_class: elf_class)
443
479
 
444
- symbols.each do |symbol|
480
+
481
+ sections << create_strtab_section("\0", name: ".shstrtab", elf_class: elf_class)
445
482
 
446
- if symbol.keys.include? :name
447
- name_offset = symtab_string_table_content.bytesize
448
- symtab_string_table_content << symbol[:name] + "\0"
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
- symbol_info = symbol[:type] | (symbol[:binding] << 4)
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
- # info
459
- symtab.bytes symbol_info, elf_char
533
+ # Check if the auto option was selected
534
+ if section_info == "first-non-local"
460
535
 
461
- # other (must be zero)
462
- symtab.bytes 0, elf_char
536
+ # Sort symbols for global symbols to come last
463
537
 
464
- # section index of where the symbol is located
465
- symtab.bytes progbits_section_index, elf_half
538
+ local_symbols = symbols.filter{_1[:binding] == 0}
539
+ non_local_symbols = symbols.filter{_1[:binding] != 0}
466
540
 
467
- # symbol value
468
- symtab.bytes symbol[:value], elf_addr
541
+ first_non_local_i = local_symbols.size
469
542
 
470
- # symbol size
471
- symbol_size = symbol[:size] || 0
472
- symtab.bytes symbol_size, elf_xword
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
- sections[symtab_section_index][:content] = symtab.result
476
- sections[sym_strtab_section_index][:content] = symtab_string_table_content
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
- sections_string_table_content = "\0"
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
- sections.each_with_index do |section, section_i|
482
- if section.keys.include? :name
483
- section[:name_offset] = sections_string_table_content.bytesize
484
- sections_string_table_content << section[:name] + "\0"
485
- else
486
- section[:name_offset] = 0
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
- return {sections: sections, shstrndx: sh_strtab_section_index}
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.0
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-02 00:00:00.000000000 Z
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