Skip to content

Commit b5d5c8d

Browse files
authored
Merge pull request #30 from katsyoshi/assembler-writer-align
set assembler section header fields
2 parents 57071ec + 8a69e05 commit b5d5c8d

File tree

7 files changed

+70
-21
lines changed

7 files changed

+70
-21
lines changed

lib/caotral/assembler/writer.rb

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
module Caotral
44
class Assembler
55
class Writer
6+
SECTION_TYPE_BY_NAME = {
7+
nil => :null,
8+
".symtab" => :symtab,
9+
".shstrtab" => :strtab,
10+
".strtab" => :strtab,
11+
".text" => :progbits,
12+
}.freeze
13+
614
def self.write!(elf_obj:, output:, debug: false) = new(elf_obj:, output:, debug:).write
715
def initialize(elf_obj:, output:, debug: false)
816
@elf_obj = elf_obj
@@ -56,14 +64,10 @@ def write(output: @output)
5664
body.build.size
5765
end
5866
offset = section.section_name.nil? ? 0 : offsets[section_name]
59-
type = decide_type(section)
60-
if ".symtab" == section.section_name
61-
link = @elf_obj.index(".strtab")
62-
info = 1
63-
header.set!(name:, offset:, size:, type:, info:, link:)
64-
else
65-
header.set!(name:, offset:, size:, type:)
66-
end
67+
link = 0
68+
type, flags, addralign, info, entsize = [*decide(section)]
69+
link = @elf_obj.index(".strtab") if ".symtab" == section.section_name
70+
header.set!(name:, flags:, offset:, size:, type:, info:, link:, entsize:, addralign:)
6771
f.write(header.build)
6872
end
6973
@elf_obj.header.set!(shoffset:, shnum:, shstrndx:)
@@ -72,15 +76,62 @@ def write(output: @output)
7276
end
7377
output
7478
end
79+
private_constant :SECTION_TYPE_BY_NAME
80+
81+
private
82+
def decide(section)
83+
type = SECTION_TYPE_BY_NAME[section.section_name]
84+
[
85+
_type(type),
86+
_flag(type),
87+
_addralign(type, section.section_name),
88+
_info(type),
89+
_entsize(type),
90+
]
91+
end
92+
93+
def _type(type_name) = Caotral::Binary::ELF::SectionHeader::SHT[type_name]
94+
95+
def _flag(section_type)
96+
case section_type
97+
when :progbits
98+
6
99+
when :symtab, :strtab, :null
100+
0
101+
else
102+
0
103+
end
104+
end
75105

76-
private def decide_type(section)
77-
case section.section_name
78-
when ".text"
106+
def _addralign(type, section_name)
107+
case
108+
when (type == :progbits && section_name == ".text") || type == :strtab
79109
1
80-
when ".symtab"
81-
2
82-
when ".shstrtab", ".strtab"
83-
3
110+
when type == :symtab
111+
8
112+
when type == :null
113+
0
114+
else
115+
0
116+
end
117+
end
118+
119+
def _info(section_type)
120+
case section_type
121+
when :symtab
122+
1
123+
when :progbits, :strtab, :null
124+
0
125+
else
126+
0
127+
end
128+
end
129+
def _entsize(section_type)
130+
case section_type
131+
when :symtab
132+
24
133+
when :progbits, :strtab, :null
134+
0
84135
else
85136
0
86137
end

lib/caotral/binary/elf/reader.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def read
4040
info = sh_entry[44, 4].unpack("L<").first
4141
addralign = sh_entry[48, 8].unpack("Q<").first
4242
entsize = sh_entry[56, 8].unpack("Q<").first
43-
type_sym = type(type_val)
4443
section_header = Caotral::Binary::ELF::SectionHeader.new
4544
section_header.set!(name:, type: type_val, flags:, addr:, offset:, size:, link:, info:, addralign:, entsize:)
4645
section_name = i == shstrndx ? ".shstrtab" : nil

lib/caotral/compiler.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require_relative "compiler/generator"
44

55
class Caotral::Compiler
6-
attr_reader *%i(generator assembler linker)
6+
attr_reader :generator, :assembler, :linker
77

88
def self.compile!(input:, output: "tmp.s", debug: false, compiler_options: ["-O0"], shared: false)
99
compiler = new(input:, output:, debug:, shared:,)

lib/caotral/linker/writer.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ def write
3434
vaddr = base_addr + text_offset
3535
paddr = base_addr + text_offset
3636
start_len = start_bytes.length
37-
start_addr = base_addr + text_offset
3837
main_offset = main_sym.value + start_len
3938
start_bytes[1, 4] = num2bytes((main_offset - 5), 4)
4039
start_bytestring = start_bytes.pack("C*")

test/caotral/assembler/writer_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def test_write
88
output = "amd64.o"
99
instructions = Caotral::Assembler::Reader.new(input:).read
1010
elf_obj = Caotral::Assembler::Builder.new(instructions:).build
11-
writer = Caotral::Assembler::Writer.new(elf_obj:, output:).write
11+
Caotral::Assembler::Writer.new(elf_obj:, output:).write
1212
results = Caotral::Binary::ELF::Reader.new(input: output).read
1313
shstrtab = results.find_by_name(".shstrtab")
1414
text = results.find_by_name(".text")

test/caotral/compiler_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def test_sample_plus
1919

2020
def test_sample_variable
2121
@file = "sample/variable.rb"
22-
@caotral = Caotral.compile!(input: @file, assembler: "self")
22+
@caotral = Caotral.compile!(input: @file, assembler: "self", linker: "self")
2323
File.chmod(755, "tmp")
2424
IO.popen("./tmp").close
2525
exit_code, handle_code = check_process($?.to_i)

test/caotral/linker/writer_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def test_write
2121
end
2222

2323
def test_execute_written
24-
written_output = Caotral::Linker::Writer.write!(elf_obj: @elf_obj, output: "write", debug: false)
24+
Caotral::Linker::Writer.write!(elf_obj: @elf_obj, output: "write", debug: false)
2525
File.chmod(0755, "./write")
2626
IO.popen("./write").close
2727
exit_code, handle_code = check_process($?.to_i)

0 commit comments

Comments
 (0)