node/lib/metasm/metasm/exe_format/elf_encode.rb
def encode_segments_relocs
		return if not @relocations or @relocations.empty?

		arch_preencode_reloc_func = "arch_#{@header.machine.downcase}_preencode_reloc"
		send arch_preencode_reloc_func if respond_to? arch_preencode_reloc_func

		list = @relocations.find_all { |r| r.type == 'JMP_SLOT' }
		if not list.empty? or @relocations.empty?
			if list.find { |r| r.addend }
				stype = 'RELA'
				sname = '.rela.plt'
			else
				stype = 'REL'
				sname = '.rel.plt'
			end

			if not relplt = @sections.find { |s| s.type == stype and s.name == sname }
				relplt = Section.new
				relplt.name = sname
				relplt.flags = ['ALLOC']
				encode_add_section relplt
			end
			relplt.encoded = EncodedData.new('', :export => {'_REL_PLT' => 0})
			list.each { |r| relplt.encoded << r.encode(self) }
			@tag['JMPREL'] = label_at(relplt.encoded, 0)
			@tag['PLTRELSZ'] = relplt.encoded.virtsize
			@tag['PLTREL'] = relplt.type = stype
			@tag[stype + 'ENT']  = relplt.entsize = relplt.addralign = (stype == 'REL' ? Relocation.size(self) : RelocationAddend.size(self))
			encode_check_section_size relplt
		end

		list = @relocations.find_all { |r| r.type != 'JMP_SLOT' and not r.addend }
		if not list.empty?
			if not @tag['TEXTREL'] and @sections.find { |s_|
				s_.encoded and e = s_.encoded.inv_export[0] and not s_.flags.include? 'WRITE' and
				list.find { |r| Expression[r.offset, :-, e].reduce.kind_of? ::Integer }
				# TODO need to check with r.offset.bind(elf_binding)
			}
				@tag['TEXTREL'] = 0
			end
			if not rel = @sections.find { |s_| s_.type == 'REL' and s_.name == '.rel.dyn' }
				rel = Section.new
				rel.name = '.rel.dyn'
				rel.type = 'REL'
				rel.flags = ['ALLOC']
				rel.entsize = rel.addralign = Relocation.size(self)
				encode_add_section rel
			end
			rel.encoded = EncodedData.new
			list.each { |r| rel.encoded << r.encode(self) }
			@tag['REL'] = label_at(rel.encoded, 0)
			@tag['RELENT'] = Relocation.size(self)
			@tag['RELSZ'] = rel.encoded.virtsize
			encode_check_section_size rel
		end

		list = @relocations.find_all { |r| r.type != 'JMP_SLOT' and r.addend }
		if not list.empty?
			if not rela = @sections.find { |s_| s_.type == 'RELA' and s_.name == '.rela.dyn' }
				rela = Section.new
				rela.name = '.rela.dyn'
				rela.type = 'RELA'
				rela.flags = ['ALLOC']
				rela.entsize = rela.addralign = RelocationAddend.size(self)
				encode_add_section rela
			end
			rela.encoded = EncodedData.new
			list.each { |r| rela.encoded << r.encode(self) }
			@tag['RELA'] = label_at(rela.encoded, 0)
			@tag['RELAENT'] = RelocationAddend.size(self)
			@tag['RELASZ'] = rela.encoded.virtsize
			encode_check_section_size rela
		end
	end
# encodes the relocation tables
# needs a complete self.symbols array
encodes the relocation tables
needs a complete self.symbols array
encodes the relocation tables needs a complete self . symbols array
def encode_segments_relocs
		return if not @relocations or @relocations.empty?
		arch_preencode_reloc_func = "arch_#{@header.machine.downcase}_preencode_reloc"
		send arch_preencode_reloc_func if respond_to? arch_preencode_reloc_func
		list = @relocations.find_all { |r| r.type == 'JMP_SLOT' }
		if not list.empty? or @relocations.empty?
			if list.find { |r| r.addend }
				stype = 'RELA'
				sname = '.rela.plt'
			else
				stype = 'REL'
				sname = '.rel.plt'
			end
			if not relplt = @sections.find { |s| s.type == stype and s.name == sname }
				relplt = Section.new
				relplt.name = sname
				relplt.flags = ['ALLOC']
				encode_add_section relplt
			end
			relplt.encoded = EncodedData.new('', :export => {'_REL_PLT' => 0})
			list.each { |r| relplt.encoded << r.encode(self) }
			@tag['JMPREL'] = label_at(relplt.encoded, 0)
			@tag['PLTRELSZ'] = relplt.encoded.virtsize
			@tag['PLTREL'] = relplt.type = stype
			@tag[stype + 'ENT']  = relplt.entsize = relplt.addralign = (stype == 'REL' ? Relocation.size(self) : RelocationAddend.size(self))
			encode_check_section_size relplt
		end
		list = @relocations.find_all { |r| r.type != 'JMP_SLOT' and not r.addend }
		if not list.empty?
			if not @tag['TEXTREL'] and @sections.find { |s_|
				s_.encoded and e = s_.encoded.inv_export[0] and not s_.flags.include? 'WRITE' and
				list.find { |r| Expression[r.offset, :-, e].reduce.kind_of? ::Integer }
			}
				@tag['TEXTREL'] = 0
			end
			if not rel = @sections.find { |s_| s_.type == 'REL' and s_.name == '.rel.dyn' }
				rel = Section.new
				rel.name = '.rel.dyn'
				rel.type = 'REL'
				rel.flags = ['ALLOC']
				rel.entsize = rel.addralign = Relocation.size(self)
				encode_add_section rel
			end
			rel.encoded = EncodedData.new
			list.each { |r| rel.encoded << r.encode(self) }
			@tag['REL'] = label_at(rel.encoded, 0)
			@tag['RELENT'] = Relocation.size(self)
			@tag['RELSZ'] = rel.encoded.virtsize
			encode_check_section_size rel
		end
		list = @relocations.find_all { |r| r.type != 'JMP_SLOT' and r.addend }
		if not list.empty?
			if not rela = @sections.find { |s_| s_.type == 'RELA' and s_.name == '.rela.dyn' }
				rela = Section.new
				rela.name = '.rela.dyn'
				rela.type = 'RELA'
				rela.flags = ['ALLOC']
				rela.entsize = rela.addralign = RelocationAddend.size(self)
				encode_add_section rela
			end
			rela.encoded = EncodedData.new
			list.each { |r| rela.encoded << r.encode(self) }
			@tag['RELA'] = label_at(rela.encoded, 0)
			@tag['RELAENT'] = RelocationAddend.size(self)
			@tag['RELASZ'] = rela.encoded.virtsize
			encode_check_section_size rela
		end
	end
def encode_segments_relocs return if not @relocations or @relocations . empty? arch_preencode_reloc_func = "arch_#{@header.machine.downcase}_preencode_reloc" send arch_preencode_reloc_func if respond_to? arch_preencode_reloc_func list = @relocations . find_all { | r | r . type == 'JMP_SLOT' } if not list . empty? or @relocations . empty? if list . find { | r | r . addend } stype = 'RELA' sname = '.rela.plt' else stype = 'REL' sname = '.rel.plt' end if not relplt = @sections . find { | s | s . type == stype and s . name == sname } relplt = Section . new relplt . name = sname relplt . flags = [ 'ALLOC' ] encode_add_section relplt end relplt . encoded = EncodedData . new ( '' , :export => { '_REL_PLT' => 0 } ) list . each { | r | relplt . encoded << r . encode ( self ) } @tag [ 'JMPREL' ] = label_at ( relplt . encoded , 0 ) @tag [ 'PLTRELSZ' ] = relplt . encoded . virtsize @tag [ 'PLTREL' ] = relplt . type = stype @tag [ stype + 'ENT' ] = relplt . entsize = relplt . addralign = ( stype == 'REL' ? Relocation . size ( self ) : RelocationAddend . size ( self ) ) encode_check_section_size relplt end list = @relocations . find_all { | r | r . type != 'JMP_SLOT' and not r . addend } if not list . empty? if not @tag [ 'TEXTREL' ] and @sections . find { | s_ | s_ . encoded and e = s_ . encoded . inv_export [ 0 ] and not s_ . flags . include? 'WRITE' and list . find { | r | Expression [ r . offset , :- , e ] . reduce . kind_of? :: Integer } } @tag [ 'TEXTREL' ] = 0 end if not rel = @sections . find { | s_ | s_ . type == 'REL' and s_ . name == '.rel.dyn' } rel = Section . new rel . name = '.rel.dyn' rel . type = 'REL' rel . flags = [ 'ALLOC' ] rel . entsize = rel . addralign = Relocation . size ( self ) encode_add_section rel end rel . encoded = EncodedData . new list . each { | r | rel . encoded << r . encode ( self ) } @tag [ 'REL' ] = label_at ( rel . encoded , 0 ) @tag [ 'RELENT' ] = Relocation . size ( self ) @tag [ 'RELSZ' ] = rel . encoded . virtsize encode_check_section_size rel end list = @relocations . find_all { | r | r . type != 'JMP_SLOT' and r . addend } if not list . empty? if not rela = @sections . find { | s_ | s_ . type == 'RELA' and s_ . name == '.rela.dyn' } rela = Section . new rela . name = '.rela.dyn' rela . type = 'RELA' rela . flags = [ 'ALLOC' ] rela . entsize = rela . addralign = RelocationAddend . size ( self ) encode_add_section rela end rela . encoded = EncodedData . new list . each { | r | rela . encoded << r . encode ( self ) } @tag [ 'RELA' ] = label_at ( rela . encoded , 0 ) @tag [ 'RELAENT' ] = RelocationAddend . size ( self ) @tag [ 'RELASZ' ] = rela . encoded . virtsize encode_check_section_size rela end end
encodes the relocation tables
needs a complete self.symbols array
encodes the relocation tables needs a complete self . symbols array
# TODO need to check with r.offset.bind(elf_binding)