» TeamX (Архив Форума)«


Форум TeamX » Исследования » Баги в компиляторах и декомпиляторах (Обнаруженные ошибки и неточности)

Переход по темам
<< Пред. След. >>
Единственная страница этой темы

 
Alchemist
Модератор

Откуда: Арзамас-17
Регистрация: Дек. 2004

Всего: 298 сообщений

Для затравки продублирую пару из последних сообщений в тех-рассылке.


==========  О компиляторе от BIS ==========
Anchorite:
Я тут с подачи Alchemist-а нашел в BIS-овом компиляторе достаточно неприятный баг.
Компилятор ни при каких условиях не генерирует опкод O_BWXOR. Так что имейте это ввиду.

Alchemist:
Поясню, из-за этого бага во _ВСЕХ_ версиях Fallout2 сломаны скрипты dcCraps.int и zccrpdel.int.

-------- Исходник --------
   if (local_var((28)) bwand bit_32) then
   begin
     amount := local_var((28)) bwxor bit_32;
     dontbet := 1;
   end
   else
   ...  

------- Результат -------
   if (local_var(28) bwand bit_32) then
   begin
     asm_expr(local_var(28));
     amount  := bit_32;
     dontbet  := 1;
   end
   else
   ...

Если в вашем коде инструкция bwxor просто необходима, то компилятор от Iplay для этого не годится, и  следует собрать скрипт одним из альтернативных.


==========  О декомпиляторе Noid'а  ==========
Anchorite:
Чтобы декомпильнуть скрипты скомпилированные IPP с помощью декомпиля от Noid-а  нужно в файле decompile строчку

   remove_opcodes_from_tail([0xc001, 0x8003, 0xc001, 0x8004])

заменить на

   remove_opcodes_from_tail([0xc001, 0x8004])

После этого декомпилятор будет работать.

В IPP не совсем "стандартный" Startup code

Den Baster:
Ну это когда на кусок тайла ругается да.
нойд говорит:

tail does not match

-----------------------------
Alchemist:
Есть ещё такой баг: в аргументы для op_gsay_option вместо символического указателя на процедуру попадает целое, являющееся индексом в таблице процедур. И BIS'овский, и Noid'овский компиляторы это не смущает и скрипт собирается нормально. Однако, если в процессе редактирования добавится процедура, которая будет расположена перед вызываемой в gsay_option, то индексы сдвинутся, и диалог перестанет правильно работать.

Чтобы этого не происходило, лезем в decompile и в двух местах меняем строчку:

   0x811f => ["prefix", "op_gsay_option", "S", "EEEE"],

на строчку:

   0x811f => ["prefix", "op_gsay_option", "S", "EEPE"],


-----
/// What'ya be sain'? Vault 100+? We need nothing o'that!

Отправлено: 12:37 - 4 Апр., 2005
Alchemist
Модератор

Откуда: Арзамас-17
Регистрация: Дек. 2004

Всего: 298 сообщений

==========  О декомпиляторе Noid'а  ==========
Alchemist:
Декомпилятор Noid'а написан на языке Ruby, огромным достоинством которого является прозрачное преобразование типов данных "на лету". То есть, так называемая коэрция. Однако эта замечательная особенность в определённых случаях выходит боком. В декомпилированном коде в область инициализации переменных вместо отрицательного целого значения с лёгкостью может попасть его альтернативная интерпретация, выраженная зашкалившим за 31 бит положительным значением. Родной компилятор Noid'а, с таким значением справляется на ура, помещая в скрипт именно то, что нужно. Более того, даже компилятор BIS из-за одной очень распространённой ошибки в коде выдаст, как ни смешно, корректный результат. Однако, подобные вещи сильно ухудшают читабельность кода (скажем, вместо (-10) мы увидим 4294967286) и могут привести  ошибкам при использовании альтернативных компиляторов.
Лечится, как и ранее, редактированием decompile


Находим вот такой фрагмент кода:

   def exported_var_definition(var)
     raise "no exported variable #{var}" unless @exported_vars.has_key?(var)
     "export variable #{var} := #{@exported_vars[var]};"
   end
   def script_var_definition(var)
     list = @script_vars.assoc(var)
     raise "no script variable #{var}" if list.nil?
     "variable #{list[0]} := #{list[1]};"  def exported_var_definition(var)
     raise "no exported variable #{var}" unless @exported_vars.has_key?(var)
     "export variable #{var} := #{@exported_vars[var]};"
   end


И заменяем его на такой фрагмент:

   def exported_var_definition(var)
     raise "no exported variable #{var}" unless @exported_vars.has_key?(var)
     if @exported_vars[var].to_i > 0x7FFFFFFF
       @exported_vars[var] =  sprintf("%d", @exported_vars[var].to_i - 0x100000000)
     end
     "export variable #{var} := #{@exported_vars[var]};"
   end
   def script_var_definition(var)
     list = @script_vars.assoc(var)
     raise "no script variable #{var}" if list.nil?
     if list[1].to_i > 0x7FFFFFFF
       list[1] =  sprintf("%d", list[1].to_i - 0x100000000)
     end
     "variable #{list[0]} := #{list[1]};"
   end


Проверенно - мин нет. Однако я не уверен, что подобные проблемы не возникают в других местах. Если заметите - пишите.

-------- Update --------

Как всегда, поторопился. Мины есть - после доработки под компилятором Noid'а результирующий код собираться перестанет. Нужна доработка компилятора. С этим ещё предстоит разобраться.

(Отредактировал(а) Alchemist - 23:58 - 5 Апр., 2005)

-----
/// What'ya be sain'? Vault 100+? We need nothing o'that!

Отправлено: 23:22 - 5 Апр., 2005
Alchemist
Модератор

Откуда: Арзамас-17
Регистрация: Дек. 2004

Всего: 298 сообщений

Обнаружен новый баг. И SSLC by Anchorite, и compile by Interplay, так же как в случае с O_BWXOR, отказываются генерировать опкод O_BWNOT (0x8043). Визуально это выглядит так, будто оператор побитовой инверсии bwnot, будучи использованным в коде, просто не работает. Декомпиляция показывает, что в бинарном скрипте его нет вообще.
В качестве обхода бага можно вместо bwnot X использовать  (-1) bwxor X. Но это сработает только на SSLC, так как в компиляторе Interplay операция bwxor тоже "сломана".

-----
/// What'ya be sain'? Vault 100+? We need nothing o'that!

Отправлено: 0:52 - 8 Апр., 2007 | ИСПРАВЛЕНО: Alchemist - 11:20 - 8 Апр., 2007
Wasteland Ghost
Маленькое Злое Привидение

Откуда: Россия, Самара
Регистрация: Дек. 2002

Всего: 2251 сообщение

Баг исправлен, новые версии компилера и декомпилера доступны в файловом разделе по старым ссылкам. Сырца тоже обновлены.

Отправлено: 13:56 - 3 Мая, 2007
Jordan 63
Пользователь

Откуда: Россия, Самара
Регистрация: Июль 2007

Всего: 228 сообщений

При декомпилировании скриптов fallout1 программами int2ssl или noid_compiler1.01 заменяет названия импортируемых переменных  

пример скрипт killian

заменяет
import variable rndx;

на
variable SVar01 := 0;

Таких замен я обнаружил в 35 скриптах

Можно ли исправить этот баг в noid_compiler1.01

Отправлено: 20:55 - 19 Сент., 2007
Anchorite
Пользователь

Откуда: Не здесь
Регистрация: Янв. 2003

Всего: 283 сообщения

Закинь этот скрипт мне на мыло.  И "сырец" от него если есть

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

Отправлено: 20:42 - 21 Сент., 2007 | ИСПРАВЛЕНО: Anchorite - 20:54 - 21 Сент., 2007
Jordan 63
Пользователь

Откуда: Россия, Самара
Регистрация: Июль 2007

Всего: 228 сообщений

Вот скрипт
http://jordan631.narod.ru/Killian.rar

Отправлено: 21:05 - 21 Сент., 2007
Anchorite
Пользователь

Откуда: Не здесь
Регистрация: Янв. 2003

Всего: 283 сообщения

Как я и говорил - импортированные переменные без ссылок на них. И как соотнести большее количество имен с меньшим числом переменных?

Отправлено: 21:19 - 21 Сент., 2007 | ИСПРАВЛЕНО: Anchorite - 21:23 - 21 Сент., 2007
Jordan 63
Пользователь

Откуда: Россия, Самара
Регистрация: Июль 2007

Всего: 228 сообщений

Anchorite

То есть невозможно узнать какая это переменная export или import?

Отправлено: 14:21 - 22 Сент., 2007
Anchorite
Пользователь

Откуда: Не здесь
Регистрация: Янв. 2003

Всего: 283 сообщения

Вопрос не совсем корректен. Попробую разъяснить.

Если в скрипте происходит ИМПОРТ переменной, но НЕ ПРОИСХОДИТ ОБРАЩЕНИЕ к ней их процедур этого скрипта,
и в этом скрипте есть ГЛОБАЛЬНЫЕ переменные,
то при декомпиляции такого скрипта будет НЕВОЗМОЖНО ОПРЕДЕЛИТЬ ИМЕНА импортированных и глобальных переменных.

С экспорированными переменными как раз никаких проблем нету. Там все четко и однозначно.
Если переменная экспортирована, то ее имя всегда можно определить.

Отправлено: 19:51 - 22 Сент., 2007 | ИСПРАВЛЕНО: Anchorite - 19:52 - 22 Сент., 2007
Jordan 63
Пользователь

Откуда: Россия, Самара
Регистрация: Июль 2007

Всего: 228 сообщений

Anchorite

Прога sslc не хочет компилировать  town_map выдает на этой строчке ошибку

Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.

c:\Евгений\SSL\COMPILER>compile

c:\Евгений\SSL\COMPILER>call 1 Acklint
Скопировано файлов:         1.
Скопировано файлов:         1.
Compiling temp.ssl
temp.ssl(10039): Error! Undefined symbol town_map.

*** THERE WERE ERRORS (1 of them)
c:\Евгений\SSL\COMPILER>

А вот часть скрипта

procedure map_enter_p_proc begin
  variable pole;

  Only_Once:=0;
  critter_add_trait(self_obj,TRAIT_OBJECT,OBJECT_TEAM_NUM,TEAM_ARROYO);
  critter_add_trait(self_obj,TRAIT_OBJECT,OBJECT_AI_PACKET,AI_ARROYO_WARRIOR);

  if ((tile_contains_obj_pid(21303,0,PID_TEMPLE_SKULL_POLE)) and (global_var(GVAR_START_ARROYO_TRIAL) != 0)) then begin
      pole:=tile_contains_pid_obj(21303,0,PID_TEMPLE_SKULL_POLE);
      move_to(pole,19698,0);
  end
  town_map;
end

Отправлено: 11:04 - 4 Янв., 2008
Alchemist
Модератор

Откуда: Арзамас-17
Регистрация: Дек. 2004

Всего: 298 сообщений

Даже скажу точно в чём дело. В opextra.h есть define c проверкой на номер игры.
Код:
#if (FALLOUT_VERSION == 2) 
O_INVEN_CMDS,
#else
O_TOWN_MAP,
#endif


Только при сборке проекта что-то было напутано и опкод O_TOWN_MAP вместо бинарника для F2 попал в бинарник для F1. А опкод O_INVEN_CMDS, соотвественно, наоборот. Нужно просто корректно пересобрать проект.

-----
/// What'ya be sain'? Vault 100+? We need nothing o'that!

Отправлено: 21:06 - 5 Янв., 2008 | ИСПРАВЛЕНО: Alchemist - 21:13 - 5 Янв., 2008
Anchorite
Пользователь

Откуда: Не здесь
Регистрация: Янв. 2003

Всего: 283 сообщения

Смотрим сюда http://www.teamx.ru/cgi-bin/ikonboard/topic.cgi?forum=14&topic=37

town_map  инструкция СПЕЦИФИЧНАЯ для FO1. Естественно, что компилятор для FO2 ее просто не переварит.

Отправлено: 13:29 - 6 Янв., 2008 | ИСПРАВЛЕНО: Anchorite - 13:59 - 6 Янв., 2008
Alchemist
Модератор

Откуда: Арзамас-17
Регистрация: Дек. 2004

Всего: 298 сообщений

Ох. Пардону прошу. Обнаружив town_map в интерплейевской доке по скриптам и решил, что -- наоборот. А про нюансы опкодов уже успел забыть...

-----
/// What'ya be sain'? Vault 100+? We need nothing o'that!

Отправлено: 17:40 - 15 Янв., 2008
 

Переход по темам
<< Пред. След. >>
Единственная страница этой темы


Powered by Ikonboard 2.1.9 RUS
Modified by RU.Board Team
© 2000 Ikonboard.com