diff --git a/lib/vaporware/compiler/assembler.rb b/lib/vaporware/compiler/assembler.rb index fdd7c6e..3675cf2 100644 --- a/lib/vaporware/compiler/assembler.rb +++ b/lib/vaporware/compiler/assembler.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true require_relative "assembler/elf" +require_relative "assembler/elf/utils" require_relative "assembler/elf/header" require_relative "assembler/elf/sections" require_relative "assembler/elf/section_header" diff --git a/lib/vaporware/compiler/assembler/elf.rb b/lib/vaporware/compiler/assembler/elf.rb index 4dfe014..3040799 100644 --- a/lib/vaporware/compiler/assembler/elf.rb +++ b/lib/vaporware/compiler/assembler/elf.rb @@ -2,7 +2,7 @@ module Vaporware class Compiler class Assembler class ELF - class ERROR < StandardError; end + class Error < StandardError; end class Section; end class SectionHeader; end module Utils; end diff --git a/lib/vaporware/compiler/assembler/elf/section/shstrtab.rb b/lib/vaporware/compiler/assembler/elf/section/shstrtab.rb index a4d5700..20a3300 100644 --- a/lib/vaporware/compiler/assembler/elf/section/shstrtab.rb +++ b/lib/vaporware/compiler/assembler/elf/section/shstrtab.rb @@ -1,8 +1,27 @@ class Vaporware::Compiler::Assembler::ELF::Section::Shstrtab include Vaporware::Compiler::Assembler::ELF::Utils - def initialize = @strtab = [] + def initialize = @name = [] def build = bytes.flatten.pack("C*") - def set!(name:) = @strtab << name + def set!(name:) + @name << set(name) + self + end + + def set(name:) = name!(name) + private - def bytes = [@strtab] + def bytes = [@name] + def name!(name) + case name + when String + (name.match(/\A\0.+\0\z/) ? name : "\0#{name}\0").bytes + when Array + raise Vaporware::Compiler::Assembler::ELF::Error, "unaccepted type in Array" unless name.all? { |elem| elem.is_a?(Integer) } + n = name + n.unshift(0) && n.push(0) unless n.first == 0 && n.last == 0 + n + else + raise Vaporware::Compiler::Assembler::ELF::Error, "unsupported type" unless name.then { |elem| [Integer, Array].map.all? { |c| elem.is_a?(c) } } + end + end end diff --git a/lib/vaporware/compiler/assembler/elf/section_header.rb b/lib/vaporware/compiler/assembler/elf/section_header.rb index 727dce8..f5b366f 100644 --- a/lib/vaporware/compiler/assembler/elf/section_header.rb +++ b/lib/vaporware/compiler/assembler/elf/section_header.rb @@ -38,5 +38,5 @@ def data! = set!() def symtab! = set! def strtab! = set! def bss! = set! - def shsymtab! = set! + def shstrtab! = set! end diff --git a/lib/vaporware/compiler/assembler/elf/sections.rb b/lib/vaporware/compiler/assembler/elf/sections.rb index 293f93e..8ee288d 100644 --- a/lib/vaporware/compiler/assembler/elf/sections.rb +++ b/lib/vaporware/compiler/assembler/elf/sections.rb @@ -4,14 +4,14 @@ class Vaporware::Compiler::Assembler::ELF::Sections ATTRIBUTES = %i|null text data bss note symtab strtab shstrtab| attr_reader *ATTRIBUTES def initialize - @null = Section.new(type: :null) - @text = Section.new(type: :text) - @data = Section.new(type: :data) - @bss = Section.new(type: :bss) - @note = Section.new(type: :note) - @symtab = Section.new(type: :symtab) - @strtab = Section.new(type: :strtab) - @shstrtab = Section.new(type: :shstrtab) + @null = Vaporware::Compiler::Assembler::ELF::Section.new(type: :null) + @text = Vaporware::Compiler::Assembler::ELF::Section.new(type: :text) + @data = Vaporware::Compiler::Assembler::ELF::Section.new(type: :data) + @bss = Vaporware::Compiler::Assembler::ELF::Section.new(type: :bss) + @note = Vaporware::Compiler::Assembler::ELF::Section.new(type: :note) + @symtab = Vaporware::Compiler::Assembler::ELF::Section.new(type: :symtab) + @strtab = Vaporware::Compiler::Assembler::ELF::Section.new(type: :strtab) + @shstrtab = Vaporware::Compiler::Assembler::ELF::Section.new(type: :shstrtab) end def each(&block) diff --git a/sig/vaporware/compiler/assembler/elf.rbs b/sig/vaporware/compiler/assembler/elf.rbs index 3c7d856..ba3e3cb 100644 --- a/sig/vaporware/compiler/assembler/elf.rbs +++ b/sig/vaporware/compiler/assembler/elf.rbs @@ -1,2 +1,4 @@ class Vaporware::Compiler::Assembler::ELF + class Error + end end diff --git a/sig/vaporware/compiler/assembler/elf/section/shstrtab.rbs b/sig/vaporware/compiler/assembler/elf/section/shstrtab.rbs index def9aee..f37a41e 100644 --- a/sig/vaporware/compiler/assembler/elf/section/shstrtab.rbs +++ b/sig/vaporware/compiler/assembler/elf/section/shstrtab.rbs @@ -3,6 +3,7 @@ class Vaporware::Compiler::Assembler::ELF::Section::Shstrtab def build: () -> String def set!: (name: String | Array[Integer]) -> self + def set: (name: String | Array[Integer]) -> Array[Integer]? private def bytes: () -> Array[Array[Integer]?] - private def set_name: (String | Array[Integer]) -> Array[Integer]? + private def name!: (String | Array[Integer]) -> Array[Integer]? end diff --git a/sig/vaporware/compiler/assembler/elf/utils.rbs b/sig/vaporware/compiler/assembler/elf/utils.rbs index bb49b94..8f123e9 100644 --- a/sig/vaporware/compiler/assembler/elf/utils.rbs +++ b/sig/vaporware/compiler/assembler/elf/utils.rbs @@ -1,4 +1,4 @@ -module Vaporware::Utils +module Vaporware::Compiler::Assembler::ELF::Utils def build: () -> String private def align: (Array[Integer], Integer) -> void private def check: (Array[Integer]?, Integer) -> bool diff --git a/test/vaporware/compiler/assembler/elf/section/test_shstrtab.rb b/test/vaporware/compiler/assembler/elf/section/test_shstrtab.rb new file mode 100644 index 0000000..ce55bd3 --- /dev/null +++ b/test/vaporware/compiler/assembler/elf/section/test_shstrtab.rb @@ -0,0 +1,14 @@ +require "vaporware" +require "test/unit" + +class Vaporware::Compiler::Assembler::ELF::Section::TestShstrtab < Test::Unit::TestCase + def setup = @shstrtab = Vaporware::Compiler::Assembler::ELF::Section::Shstrtab.new + def test_set_values + assert_equal(@shstrtab.set(name: "main"), [0, 109, 97, 105, 110, 0]) + assert_equal(@shstrtab.set(name: [0, 109, 97, 105, 110, 0]), [0, 109, 97, 105, 110, 0]) + end + def test_alert_values + assert_raise(Vaporware::Compiler::Assembler::ELF::Error) { @shstrtab.set(name: :main) } + assert_raise(Vaporware::Compiler::Assembler::ELF::Error) { @shstrtab.set(name: 123) } + end +end