[exerb-dev] Re: コア / アーカイブ結合方式の変更について

Back to archive index

NAKANO Kouichi knuck****@f8*****
2002年 5月 16日 (木) 22:24:45 JST


なかのです。

> もしアーカイブのサイズが4KB以下の場合は、そのまま.rubyセク
> ションに埋め込めばいいのですが、4KBを越える場合、.rubyセク
> ションのサイズを拡大する必要があります。このセクションサイ
> ズの拡大が、面倒なのです。というか、はっきり言って無理です。

実は私はこの線で作業してます。
私としてはあと一歩の気がしてるんですが、何がそんなに面倒
なのでしょう。私が何かすごいことを見逃しているのかもしれ
ません。
要は、.rubyセクションよりも後ろに位置するセクションのヘッ
ダのVirtualSize、VirtualAdress、PointerToRawData、
SizeOfRawDataをずれた分だけインクリメントすればいいんです
よね?SectionAlignmentを考慮して。
あとは、オプショナルヘッダを書き換える必要もありそうです
が、それはこれからやろうとしてました。
まだ実行はできませんが、dumpbinやバイナリエディタで見る限
りではではセクションに関しては予期した結果を得ています。
オプショナルヘッダとはずれてるんですが...。
これだけではだめでしょうか?私も実験段階なんで自信ないで
す。
末尾にパッチ付けます。(実験段階のまとまりのないコードで非
常に恥ずかしいんですが)

> 末尾に.rubyセクションが位置していれば、そのまま拡大するこ
> ともできますが、実際には末尾に位置することはないので拡大す
> ることはできません。

同じ思考をたどりました。

> そこで、リンカによって確保された.rubyセクションは棄てるこ
> とにして、コアの末尾に領域を確保し、そこを.rubyセクション
> としようと思います。これによって4KBの制限を越えることがで
> きます。

これはこれでシンプルでいい気もします。


以下パッチ。(送ってもらったソースに対するパッチです)

Index: r2e.rb
===================================================================
RCS file: /usr/local/cvsrepos/exerb/package/r2e.rb,v
retrieving revision 1.2
diff -c -r1.2 r2e.rb
*** r2e.rb 2002/05/14 10:48:28 1.2
--- r2e.rb 2002/05/16 13:12:08
***************
*** 7,12 ****
--- 7,15 ----
  # R2E Module
  module R2E
  
+   class ExerbError < Exception
+   end
+ 
    #==================================================================#
    # Archive Class
    class Archive
***************
*** 583,589 ****
        end
  
        def output(io)
!         io.print(@binary)
        end
  
        def analyze
--- 586,592 ----
        end
  
        def output(io)
!         io.print(pack)
        end
  
        def analyze
***************
*** 604,609 ****
--- 607,629 ----
   @sections = Sections.new(@binary, @pe_header)
        end
  
+       def insert!(archive)
+  @sections.replace('.ruby', archive, @binary, section_alignment)
+       end
+ 
+       def pack
+  @binary[@pe_header.offset_to_section_headers, @pe_header.number_of_sections * 40] =****@secti*****_headers
+  return @binary
+       end
+ 
+       def section_alignment
+  @binary[offset_to_section_alignment, 4].unpack('L')[0]
+       end
+ 
+       def offset_to_section_alignment
+  @offset_to_pe + @pe_header.size_of_pe_signature + @pe_header.size + 32
+       end
+ 
      end # Core
  
  
***************
*** 611,617 ****
      # PEHeader Class
      class PEHeader
  
!       attr_accessor :number_of_sections, :size_of_optional_header
  
        def initialize(core, offset)
   @offset_to_me = offset
--- 631,637 ----
      # PEHeader Class
      class PEHeader
  
!       attr_reader :number_of_sections, :size_of_optional_header
  
        def initialize(core, offset)
   @offset_to_me = offset
***************
*** 634,639 ****
--- 654,663 ----
        def offset_to_section_headers
   return @offset_to_me + size_of_pe_signature + 20 + size_of_optional_header
        end
+ 
+       def size
+  20
+       end
      end
  
      #================================================================#
***************
*** 650,660 ****
        def size_of_section_header
   return 40
        end
  
!       def show
!  @sections.each { |section|
!    puts section.show
   }
        end
      end
  
--- 674,726 ----
        def size_of_section_header
   return 40
        end
+ 
+       def replace(section_name, archive, binary, alignment)
+  section = section_named section_name
+  if section == nil
+    raise ExerbError, "no section nemed #{section_name}"
+  end
+  increment = section.replace(archive, binary, alignment)
+  next_sections = next_section_by_pointer_of section
+  next_sections.each{ |next_section|
+    next_section.move_pointer!(increment[0])
+  }
+  next_sections = next_section_by_address_of section
+  next_sections.each{ |next_section|
+    next_section.move_address!(increment[1])
+  }
+       end
+ 
+       def section_named(section_name)
+  @sections.find { |item| item.name.index(section_name) }
+       end
+ 
+       def next_section_by_pointer_of(section)
+  retur****@secti*****_all{ |item| section.header.pointer_to_raw_data < item.header.pointer_to_raw_data }
+       end
+ 
+       def next_section_by_address_of(section)
+  retur****@secti*****_all{ |item| section.header.virtual_address < item.header.virtual_address }
+       end
+ 
+       def pack_bodies_to(binary)
+       end
+ 
+       def packed_headers
+  packed = ''
+  @sections.each{ |section|
+    packed.concat section.header.pack
+  }
+  return packed
+       end
  
!       def packed_bodies
!  sorted =****@secti*****{ |x, y| x.header.pinter_to_raw_data - y.header.pointer_to_raw_data }
!  packed = ''
!  sorted.each{ |section|
!    packed.concat section.body
   }
+  return packed
        end
      end
  
***************
*** 665,671 ****
        #================================================================#
        # a header of Section
        class Header
!  attr_accessor :name, :pointer_to_raw_data, :size_of_raw_data
   def initialize(core, offset)
     @name = core[offset, 8]
     @virtual_size = core[offset + 8, 4].unpack('L')[0]
--- 731,737 ----
        #================================================================#
        # a header of Section
        class Header
!  attr_accessor :name, :pointer_to_raw_data, :size_of_raw_data, :virtual_size, :virtual_address
   def initialize(core, offset)
     @name = core[offset, 8]
     @virtual_size = core[offset + 8, 4].unpack('L')[0]
***************
*** 678,698 ****
     @number_of_line_numbers = core[offset + 34, 2].unpack('S')[0]
     @characteristics = core[offset + 36, 4].unpack('L')[0]
   end
-       end
- 
-       #================================================================#
-       # a body of Section
-       class Body
-  attr_accessor :body
  
!  def initialize(core, header)
!    @body = core[header.pointer_to_raw_data, header.size_of_raw_data]
   end
        end
  
        def initialize(core, offset)
   @header = Header.new(core, offset)
!  @body = Body.new(core, @header)
        end
      end
  
--- 744,809 ----
     @number_of_line_numbers = core[offset + 34, 2].unpack('S')[0]
     @characteristics = core[offset + 36, 4].unpack('L')[0]
   end
  
!  def pack
!    packed = @name
!    packed.concat [@virtual_size].pack('L')
!    packed.concat [@virtual_address].pack('L')
!    packed.concat [@size_of_raw_data].pack('L')
!    packed.concat [@pointer_to_raw_data].pack('L')
!    packed.concat [@pointer_to_relocations].pack('L')
!    packed.concat [@pointer_to_line_numbers].pack('L')
!    packed.concat [@number_of_relocations].pack('S')
!    packed.concat [@number_of_line_numbers].pack('S')
!    packed.concat [@characteristics].pack('L')
!    return packed
   end
        end
  
+       attr_accessor :header
+ 
        def initialize(core, offset)
   @header = Header.new(core, offset)
!  @body = core[@header.pointer_to_raw_data, @header.size_of_raw_data]
!       end
! 
!       def name
!  retur****@heade*****
!       end
! 
!       def replace(archive, binary, alignment)
!  aligned_size = self.aligned_size(archive.size, alignment)
!  increment = aligned_size -****@heade*****_of_raw_data
!  old_size =****@body*****
!  archive.output self
!  new_size =****@body*****
!  @header.virtual_size =****@body*****
!  @body.concat("\0" * (aligned_size -****@body*****)) if aligned_size -****@body***** > 0
!  binary[@header.pointer_to_raw_data, @header.size_of_raw_data] = @body
!  if increment > 0
!    @header.size_of_raw_data = aligned_size
!  end
!  return [increment, self.aligned_size(new_size - old_size, alignment)]
!       end
! 
!       def move_pointer!(distance)
!  @header.pointer_to_raw_data += distance if distance > 0
!       end
! 
!       def move_address!(virtual_distance)
!  @header.virtual_address += virtual_distance if virtual_distance > 0
!       end
! 
!       def print(binary)
!  @body = binary
!       end
! 
!       def aligned_size(size, alignment)
!  result = (size / alignment + 1) * alignment
!  if size % alignment == 0
!    result -= alignment
!  end
!  return result
        end
      end
  
***************
*** 706,711 ****
--- 817,823 ----
        def initialize(archive, core)
          @archive = archive
          @core    = core
+  @core.insert! archive
        end
  
        #==============================================================#
***************
*** 717,726 ****
        end
  
        def output(io)
!         @core.archive_offset =****@core*****
!         @core.archive_size   =****@archi*****
          @core.output(io)
!         @archive.output(io)
        end
  
        def output_to_file(filepath)
--- 829,838 ----
        end
  
        def output(io)
!         #@core.archive_offset =****@core*****
!         #@core.archive_size   =****@archi*****
          @core.output(io)
!         #@archive.output(io)
        end
  
        def output_to_file(filepath)




exerb-developer メーリングリストの案内
Back to archive index