33module 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
0 commit comments