Показать сообщение отдельно
Старый 25.09.2008, 15:21   #35
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

вот сбрал приблизительную модель загрузки clsass-файлов, но после считывания константного пула, где-то рвет в размерах считываемых байтов, соответственно неверно заполняются поля размера ниже-следующих структур, посмотрите кто-нить в чем здесь неправ.

формат и доку брал из предоставленной информации.

Программу можно компилировать как и в TurboPascal 7.0, так и Delphi 7.0
только после создания .exe-файла в Delphi антивирус кричит на него что это вирус...


{$R+,S+}
const
  CONSTANT_Class              = 7;
  CONSTANT_Fieldref           = 9;
  CONSTANT_Methodref          = 10;
  CONSTANT_InterfaceMethodref = 11;
  CONSTANT_String             = 8;
  CONSTANT_Integer            = 3;
  CONSTANT_Float              = 4;
  CONSTANT_Long               = 5;
  CONSTANT_Double             = 6;
  CONSTANT_NameAndType        = 12;
  CONSTANT_Utf8               = 1;
  CONSTANT_Unicode            = 2;
  {------------------------------}
  ACC_PUBLIC = 1;
  ACC_PRIVATE = 2;
  ACC_PROTECTED = 4;
  ACC_STATIC = 8;
  ACC_FINAL = 16;
  ACC_SYNCHRONIZED = 32;
  ACC_SUPER = 32;
  ACC_VOLATILE = 64;
  ACC_TRANSIENT = 128;
  ACC_NATIVE = 256;
  ACC_INTERFACE = 512;
  ACC_ABSTRACT = 1024;
{}
type
  tfield_info = record
    access_flags : word;
    name_index : word;
    signature_index : word;
    attributes_count : word;
    {attributes[attribute_count]}
  end;
{}
  tmethod_info = record
    access_flags : word;
    name_index : word;
    signature_index : word;
    attributes_count : word;
    {attributes[attribute_count]}
  end;
  {--атрибуты--}
  tGenericAttribute_info = record
    attribute_name : word;
    attribute_length : longInt;
    {info[attribute_length] of byte}
  end;
  {}
  tSourceFile_attribute = record
    attribute_name_index : word;
    attribute_length : longInt;
    sourcefile_index : word;
  end;
  {}
  tLineNumberTable_attribute = record
    attribute_name_index : word;
    attribute_length : longInt;
    line_number_table_length : word;
    {line_number_table[line_number_table_length] of record start_pc,line_number:word;}
  end;
  {}
  tConstantValue_attribute = record
    attribute_name_index : word;
    attribute_length : longInt;
    constantvalue_index : word;
  end;
  {}
  tLocalVariableTable_attribute = record
    attribute_name_index : word;
    attribute_length : longInt;
    local_variable_table_length : word;
    {local_variable_table[local_variable_table_length]}
  end;
  tLocal_variable_table = record
    start_pc   : word;
    length     : word;
    name_index : word;
    signature_index : word;
    slot       : word;
  end;
  {}
  tCode_attribute = record
    attribute_name_index : word;
    attribute_length : longInt;
    max_stack : word;
    max_locals : word;
    code_length : longInt;
  end;
  {code[code_length]}
  {exception_table_length : word;{***}
  {exception_table[exception_table_length]}
  {attributes_count : word;{***}
  {attribute_info[attribute_count]}
  tException_table = record
    start_pc : word;
    end_pc : word;
    handler_pc : word;
    catch_type : word;
  end;
  {--------------------------}
var
  cf : record      {ClassFile}
    magic               : longInt;
    minor_version       : word;
    major_version       : word;
    constant_pool_count : word;
    cp_info             : pointer; {constant_pool[constant_pool_count - 1];}
    access_flags        : word;
    this_class          : word;
    super_class         : word;
    interfaces_count    : word;
    interfaces          : pointer; {[interfaces_count];}
    fields_count        : word;
    field_info          : pointer; {fields[fields_count];}
    methods_count       : word;
    method_info         : pointer; {methods[methods_count];}
    attributes_count    : word;
    attribute_info      : pointer; {attributes[attribute_count];}
  end;
var
  f                     : file;
  i,j,n,rc              : integer;{longInt;}
  s                     : string;
  tag                   : byte;
  p                     :^byte;
  pfield_info           :^tfield_info;
  pmethod_info          :^tmethod_info;
  pGenericAttribute_info:^tGenericAttribute_info;
  pCode_attribute       :^tCode_attribute;
  pException_table      :^tException_table;
  pexception_table_length:^word;
  pattributes_count      :^word;
  pLocalVariableTable_attribute:^tLocalVariableTable_attribute;
  pLocal_variable_table :^tLocal_variable_table;


function hex(b:byte) : string;
const
  h : array[0..$F] of char = '0123456789ABCDEF';
begin
  hex := h[b shr 4]+h[b and $F];
end;


function hexw(w:word) : string;
begin
  hexw:=hex(hi(w))+hex(lo(w));
end;


function get(p : pointer;  count : integer) : pointer;
var
  n : integer;
begin
  blockRead(f,p^,count,n);
  inc(longInt(p),n); {pasc}
  inc(rc,n);
  get := p;  {get := ptr(cardinal(p)+count);  //delphi}
end;

function swap2(p:pointer; offs:integer) : pointer;
var
  b1,b2 :^byte;
  b     : byte;
begin
  dec(longInt(p),offs+1);
  b1:=p;
  dec(longInt(p));
  b2:=p;
  b:=b1^;b1^:=b2^;b2^:=b;
  swap2 := p;
end;


function swap4(p:pointer; offs:integer) : pointer;
var
  b1,b2,b3,b4 :^byte;
  b           : byte;
begin
  dec(longInt(p),offs+1);
  b1:=p;
  dec(longInt(p));
  b2:=p;
  dec(longInt(p));
  b3:=p;
  dec(longInt(p));
  b4:=p;
  b:=b1^;b1^:=b4^;b4^:=b;
  b:=b2^;b2^:=b3^;b3^:=b;
  swap4 := p;
end;


function getConstStr(index : word) : string;
var
  s     : string;
  i,j,w : word;
  p     :^byte;
begin
  s:='';
  p:=cf.cp_info;
  for i := 1 to cf.constant_pool_count-1 do  {цикл начинается именно с 1, а не 0}
  begin
    if i=index then if (p^ in [CONSTANT_Utf8, CONSTANT_Unicode]) then
    begin
      w:=p^;
      inc(p,2);
      for j := 0 to w-1 do
      begin
        s := s+chr(p^);
        inc(p);
      end;
      getConstStr := s;
      break;
    end;
    case p^ of
      CONSTANT_Class: inc(p,2);
      CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_InterfaceMethodref: inc(p,4);
      CONSTANT_String: inc(p,2);
      CONSTANT_Integer,CONSTANT_Float: inc(p,4);
      CONSTANT_Long: inc(p,8);
      CONSTANT_NameAndType: inc(p,4);
      CONSTANT_Utf8, CONSTANT_Unicode:
      begin      {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{}
        w:=p^;
        inc(p,2);
        inc(p,w)
      end;
    end;
    getConstStr := s;
  end;
end;

{-------------------}

procedure load_const;
begin
  get(p,1);
  tag:=p^;
  inc(p);
  write(tag:2,' ');
  case tag of
    CONSTANT_Class:
    begin
      p:=get(p,2);
      write('CONSTANT_Class:',word(swap2(p,0)^));
    end;
    CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_InterfaceMethodref:
    begin
      case tag of
        CONSTANT_Fieldref: write('CONSTANT_Fieldref:');
        CONSTANT_Methodref: write('CONSTANT_Methodref:');
        CONSTANT_InterfaceMethodref: write('CONSTANT_InterfaceMethodref:');
      end;
      p:=get(p,4);
      write(word(swap2(p,2)^),'  ',word(swap2(p,0)^));
    end;
    CONSTANT_String:
    begin
      p:=get(p,2);
      write('CONSTANT_String:',word(swap2(p,0)^));
    end;
    CONSTANT_Integer,CONSTANT_Float:
    begin
      case tag of
        CONSTANT_Integer: write('CONSTANT_Integer:');
        CONSTANT_Float: write('CONSTANT_Float:');
      end;
      p:=get(p,4);
      write(longInt(swap4(p,0)^));
    end;
    CONSTANT_Long,CONSTANT_Double:
    begin
      case tag of
        CONSTANT_Long: write('CONSTANT_Integer:');
        CONSTANT_Double: write('CONSTANT_Double:');
      end;
      p:=get(p,8);
      write('_hi_',longInt(swap4(p,4)^),'_lo_',longInt(swap4(p,0)^));
    end;
    CONSTANT_NameAndType:
    begin
      p:=get(p,4);
      write('CONSTANT_NameAndType:',word(swap2(p,2)^),' ',word(swap2(p,0)^));
    end;
    CONSTANT_Utf8, CONSTANT_Unicode:
    begin        {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{}
      p:=get(p,2);       {length}
      n:=word(swap2(p,0)^);
      write('CONSTANT_Utf8-Unicode [',n,']=');
      for j := 0 to n-1 do
      begin
        get(p,1);
        write(chr(p^));
        inc(p);
      end;
    end;
    else
    if tag<>0 then
    begin
      write('error:',tag);
      halt;
    end;
  end;
  writeln;
end;


procedure load_attribute_info;
begin
  writeln(hexw(rc), 'h  GenericAttribute_info');
  p:=get(p,sizeof(pGenericAttribute_info^));
  pGenericAttribute_info:=swap2(swap2{4}(p,0),0);
  writeln('attribute_name:',pGenericAttribute_info^.attribute_name);
  writeln('attribute_length:',pGenericAttribute_info^.attribute_length);
  s := getConstStr(pGenericAttribute_info^.attribute_name);
  if s='Code' then
  begin
    writeln(hexw(rc), 'h  Code');
    p:=get(p,sizeof(pCode_attribute^));
    pCode_attribute := swap2(swap4(swap2(swap2(swap4(p,0),0),0),0),0);
    writeln(hexw(rc-sizeof(pCode_attribute^.attribute_name_index)),
      ' attribute_name_index:',pCode_attribute^.attribute_name_index);
    writeln(hexw(rc-sizeof(pCode_attribute^.attribute_length)),
      ' attribute_length:',pCode_attribute^.attribute_length);
    writeln(hexw(rc-sizeof(pCode_attribute^.max_stack)),
      ' max_stack:',pCode_attribute^.max_stack);
    writeln(hexw(rc-sizeof(pCode_attribute^.max_locals)),
      ' max_locals:',pCode_attribute^.max_locals);
    writeln(hexw(rc-sizeof(pCode_attribute^.code_length)),
      ' code_length:',pCode_attribute^.code_length);
    for j := 0 to pCode_attribute^.code_length-1 do  p:=get(p,1);
    p:=get(p,sizeof(pexception_table_length^));
    pexception_table_length:=swap2(p,0);
    for j := 0 to pexception_table_length^-1 do
    begin
      p := get(p,sizeof(pException_table^));
      pException_table := swap2(swap2(swap2(swap2(p,0),0),0),0);
    end;
    p:=get(p,sizeof(pattributes_count^));
    pattributes_count :=swap2(p,0);
    for j := 0 to pattributes_count^-1 do p:=get(p,1);
  end
  else if s='LocalVariableTable' then
  begin
    writeln(hexw(rc), 'h  LocalVariableTable');
    p := get(p,sizeof(pLocalVariableTable_attribute^));
    pLocalVariableTable_attribute := swap2(swap4(swap2(p,0),0),0);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_name_index)),
      ' attribute_name_index:',pLocalVariableTable_attribute^.attribute_name_index);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_length)),
      ' attribute_length:',pLocalVariableTable_attribute^.attribute_length);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.local_variable_table_length)),
      ' local_variable_table_length:',pLocalVariableTable_attribute^.local_variable_table_length);
    for j := 0 to pLocalVariableTable_attribute^.local_variable_table_length-1 do
    begin
      p := get(p,sizeof(pLocal_variable_table^));
      pLocal_variable_table := swap2(swap2(swap2(swap2(swap2(p,0),0),0),0),0);
      writeln('start_pc:',pLocal_variable_table^.start_pc);
      writeln('length:',pLocal_variable_table^.length);
      writeln('name_index:',pLocal_variable_table^.name_index);
      writeln('signature_index:',pLocal_variable_table^.signature_index);
      writeln('slot:',pLocal_variable_table^.slot);
    end;
  end
  {if s='SourceFile' then
  begin
  end
  else if s='LineNumberTable' then
  begin
  end{}
  else  {don't know... skip atributes}
  begin
    for j := 0 to pGenericAttribute_info^.attribute_length-1 do
    begin
      get(p,1);
      write(hex(byte(p^)),' ');
      inc(p);
    end;
  end;
  writeln;
end;


procedure load_interfaces;
begin
  p:=get(p,2);
  write(word(swap2(p,0)^),',');
end;


procedure load_field_info;
begin
  p := get(p,sizeof(pfield_info^));
  pfield_info := swap2(swap2(swap2(swap2(p,0),0),0),0);
  writeln('access_flags:',pfield_info^.access_flags);
  writeln('name_index:',pfield_info^.name_index);
  writeln('signature_index:',pfield_info^.signature_index);
  writeln('attributes_count:',pfield_info^.attributes_count, ' offs:[',hexw(rc), 'h]');
  for j := 0 to pfield_info^.attributes_count-1 do
    load_attribute_info;
end;


procedure method_info;
begin
  p := get(p,sizeof(pmethod_info^));
  pmethod_info := swap2(swap2(swap2(swap2(p,0),0),0),0);
  writeln('access_flags:',pmethod_info^.access_flags);
  writeln('name_index:',pmethod_info^.name_index);
  writeln('signature_index:',pmethod_info^.signature_index);
  writeln('attributes_count:',pmethod_info^.attributes_count, ' offs:[',hexw(rc), 'h]' );
  for j := 0 to pmethod_info^.attributes_count-1 do
    load_attribute_info;
end;


begin
  getMem(cf.cp_info,$FFFF);
  getMem(cf.interfaces,$7FFF);
  getMem(cf.field_info,$FFFF);
  getMem(cf.method_info,$FFFF);
  getMem(cf.attribute_info,$FFFF);
  fillChar(cf.cp_info^, $FFFF, 0);
  fillChar(cf.interfaces^, $7FFF, 0);
  fillChar(cf.field_info^, $FFFF, 0);
  fillChar(cf.method_info^, $FFFF, 0);
  fillChar(cf.attribute_info^, $FFFF, 0);
  assign(f,'fw.cla');
  {cf.magic := $CAFEBABE; cf.minor_version := $0000; cf.major_version := $002E;
  rewrite(f,1);
  blockWrite(f,cf.magic,sizeof(cf.magic),n);
  blockWrite(f,cf.minor_version,sizeof(cf.minor_version),n);
  blockWrite(f,cf.major_version,sizeof(cf.major_version),n);{...}
  reset(f,1);
  rc:=0;
  swap4(get(@cf.magic,sizeof(cf.magic)),0);
  swap2(get(@cf.minor_version,sizeof(cf.minor_version)),0);
  swap2(get(@cf.major_version,sizeof(cf.major_version)),0);
  swap2(get(@cf.constant_pool_count,sizeof(cf.constant_pool_count)),0);
  p:=cf.cp_info;
  for i := 1 to cf.constant_pool_count-1 do {цикл начинается именно с 1, а не 0}
  begin
    write(hexw(rc-1),'h ',i:3,' ');
    load_const;
  end;
  writeln('__________________________');
  swap2(get(@cf.access_flags,sizeof(cf.access_flags)),0);
  writeln(hexw(rc-sizeof(cf.access_flags)),'h access_flags:',cf.access_flags);
  swap2(get(@cf.this_class,sizeof(cf.this_class)),0);
  writeln(hexw(rc-sizeof(cf.this_class)),'h this_class:',cf.this_class);
  swap2(get(@cf.super_class,sizeof(cf.super_class)),0);
  writeln(hexw(rc-sizeof(cf.super_class)),'h super_class:',cf.super_class);
  writeln(#13#10'-----load_interfaces----');
  swap2(get(@cf.interfaces_count,sizeof(cf.interfaces_count)),0);
  writeln(hexw(rc-sizeof(cf.interfaces_count)),'h interfaces[',cf.interfaces_count,']=');
  p := cf.interfaces;
  for i := 0 to cf.interfaces_count-1 do
    load_interfaces;
  writeln(#13#10'__________________________');
  writeln(#13#10'-----load_field_info----');
  swap2(get(@cf.fields_count,sizeof(cf.fields_count)),0);
  writeln(hexw(rc-sizeof(cf.fields_count)),'h field_info[',cf.fields_count,']=');
  p := cf.field_info;
  for i:=0 to cf.fields_count-1 do
  begin
    writeln(hexw(rc), 'h  field_info:',i:3,'---------');
    load_field_info;
  end;
  writeln('__________________________');
  writeln(#13#10'-----method_info----');
  swap2(get(@cf.methods_count,sizeof(cf.methods_count)),0);
  writeln(hexw(rc-sizeof(cf.methods_count)), 'h  method_info [',cf.methods_count,']=');
  p := cf.method_info;
  for i:=0 to cf.methods_count-1 do
  begin
    writeln(hexw(rc),'h  method_info:',i:3,'---------');
    method_info;
  end;
  writeln('__________________________');
  writeln('OFFSET:',hexw(rc));
  swap2(get(@cf.attributes_count,sizeof(cf.attributes_count)),0);
  writeln(hexw(rc-sizeof(cf.attributes_count)),'h  attribute_info [',cf.attributes_count,']=');
  p:=cf.attribute_info;
  for i:=0 to cf.attributes_count-1 do
  begin
    load_attribute_info;
    writeln('-');
  end;
  close(f);
  freeMem(cf.attribute_info,$FFFF);
  freeMem(cf.method_info,$FFFF);
  freeMem(cf.field_info,$FFFF);
  freeMem(cf.interfaces,$7FFF);
  freeMem(cf.cp_info,$FFFF);
end.

Последний раз редактировалось Piligrim, 26.09.2008 в 14:09. Причина: Используйте пожалуйста нормальное форматирование!
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Piligrim (26.09.2008)