@@ -41,6 +41,7 @@ def write
4141 gap = [ text_offset - f . pos , 0 ] . max
4242 f . write ( "\0 " * gap )
4343 f . write ( text_section . body )
44+ write_shared_dynamic_sections ( file : f ) if @shared
4445 symtab_offset = f . pos
4546 symtab_section . body . each { |sym | f . write ( sym . build ) }
4647 symtab_entsize = symtab_section . body . first &.build &.bytesize . to_i
@@ -67,7 +68,6 @@ def write
6768 f . write ( shstrtab_section . body . names )
6869 shoffset = f . pos
6970 shstrndx = write_section_index ( ".shstrtab" )
70- strtabndx = write_section_index ( ".strtab" )
7171 symtabndx = write_section_index ( ".symtab" )
7272 shnum = @write_sections . size
7373 @elf_obj . header . set! ( shoffset :, shnum :, shstrndx :)
@@ -78,8 +78,8 @@ def write
7878 lookup_name = section . section_name
7979 name_offset = names . offset_of ( lookup_name )
8080 name , info , entsize = ( name_offset . nil? ? 0 : name_offset ) , header . info , header . entsize
81- link = header . link
82- link = strtabndx if section . section_name == ".symtab"
81+ link = link_index ( section . section_name )
82+ link = header . link if link . nil?
8383 if [ :rel , :rela ] . include? ( header . type )
8484 link = symtabndx
8585 info = ref_index ( section . section_name )
@@ -100,13 +100,34 @@ def write_order_sections
100100 write_order = [ ]
101101 write_order << @elf_obj . sections . find { |s | s . section_name . nil? }
102102 write_order << @elf_obj . find_by_name ( ".text" )
103+ write_order << @elf_obj . find_by_name ( ".dynstr" )
104+ write_order << @elf_obj . find_by_name ( ".dynsym" )
105+ write_order << @elf_obj . find_by_name ( ".dynamic" )
103106 write_order << @elf_obj . find_by_name ( ".symtab" )
104107 write_order << @elf_obj . find_by_name ( ".strtab" )
105108 write_order . concat ( @elf_obj . select_by_names ( RELOCATION_SECTION_NAMES ) )
106109 write_order << @elf_obj . find_by_name ( ".shstrtab" )
107110 write_order . compact
108111 end
109112 def write_section_index ( section_name ) = @write_sections . index { it . section_name == section_name }
113+
114+ def write_shared_dynamic_sections ( file :)
115+ dynstr_offset = file . pos
116+ file . write ( dynstr_section . body . build )
117+ size = file . pos - dynstr_offset
118+ dynstr_section . header . set! ( offset : dynstr_offset , size :)
119+
120+ dynsym_offset = file . pos
121+ dynsym_section . body . each { |dynsym | file . write ( dynsym . build ) }
122+ size = file . pos - dynsym_offset
123+ dynsym_section . header . set! ( offset : dynsym_offset , size :)
124+
125+ dynamic_offset = file . pos
126+ dynamic_section . body . each { |dynamic | file . write ( dynamic . build ) }
127+ size = file . pos - dynamic_offset
128+ dynamic_section . header . set! ( offset : dynamic_offset , size :)
129+ end
130+
110131 def ref_index ( section_name )
111132 ref_name = section_name . split ( "." ) . filter { |sn | !sn . empty? && sn != "rel" && sn != "rela" }
112133 ref_name = "." + ref_name . join ( "." )
@@ -115,11 +136,25 @@ def ref_index(section_name)
115136 write_section_index ( ref . section_name )
116137 end
117138
139+ def link_index ( section_name )
140+ case section_name
141+ when ".symtab"
142+ write_section_index ( ".strtab" )
143+ when ".dynsym" , ".dynamic"
144+ write_section_index ( ".dynstr" )
145+ else
146+ nil
147+ end
148+ end
149+
118150 def text_section = @text_section ||= @write_sections . find { |s | ".text" === s . section_name . to_s }
119151 def rel_sections = @rel_sections ||= @write_sections . select { RELOCATION_SECTION_NAMES . include? ( it . section_name ) }
120152 def symtab_section = @symtab_section ||= @write_sections . find { |s | ".symtab" === s . section_name . to_s }
121153 def strtab_section = @strtab_section ||= @write_sections . find { |s | ".strtab" === s . section_name . to_s }
122154 def shstrtab_section = @shstrtab_section ||= @write_sections . find { |s | ".shstrtab" === s . section_name . to_s }
155+ def dynstr_section = @dynstr_section ||= @write_sections . find { |s | ".dynstr" === s . section_name . to_s }
156+ def dynsym_section = @dynsym_section ||= @write_sections . find { |s | ".dynsym" === s . section_name . to_s }
157+ def dynamic_section = @dynamic_section ||= @write_sections . find { |s | ".dynamic" === s . section_name . to_s }
123158 end
124159 end
125160end
0 commit comments