Board.KolibriOS.org
http://board.kolibrios.org/

Помогите новичку
http://board.kolibrios.org/viewtopic.php?f=2&t=684
Page 15 of 76

Author:  SoUrcerer [ Tue Feb 15, 2011 10:36 am ]
Post subject:  Re: Помогите новичку

Собираю lua 5.1.4 для Колибри. Проблема, с которой не могу пока что справиться, такая:
lua.o: In function `docall':
lua.c:(.text+0x15e): undefined reference to `signal'

Кажется, в libc не хватает чего-то (сигналов, угу). Подскажите, что с этим можно сделать, пожалуйста.
Помогут в том числе любые полезные ссылки.

upd: код вот такой... может быть, его как-то поправить можно, чтобы обойтись без сигналов?
Code:
static int docall (lua_State *L, int narg, int clear) {
  int status;
  int base = lua_gettop(L) - narg;  /* function index */
  lua_pushcfunction(L, traceback);  /* push traceback function */
  lua_insert(L, base);  /* put it under chunk and args */
  signal(SIGINT, laction);
  status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
  signal(SIGINT, SIG_DFL);
  lua_remove(L, base);  /* remove traceback function */
  /* force a complete garbage collection in case of errors */
  if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
  return status;
}

Author:  SoUrcerer [ Tue Feb 15, 2011 10:56 am ]
Post subject:  Re: Помогите новичку

Вдобавок очень нехватает макросов va_start и va_end.
Посмотрю в коде libc для open watcom, но не уверен, что даже если они там есть, то смогу их перенести в libc :(
Тоже буду рад подсказкам и умным мыслям.

Author:  CleverMouse [ Tue Feb 15, 2011 1:07 pm ]
Post subject:  Re: Помогите новичку

Макросы va_start и va_end в menuetlibc есть, #include <stdarg.h>.

Author:  SoUrcerer [ Tue Feb 15, 2011 1:19 pm ]
Post subject:  Re: Помогите новичку

Действительно, есть. Почему ж тогда в printf и sprintf на них выдается undefined refernce :(

Author:  CleverMouse [ Tue Feb 15, 2011 1:23 pm ]
Post subject:  Re: Помогите новичку

В языке Си (не C++) необъявленные сущности, обращение к которым выглядит как вызов функции, считаются внешними функциями, возвращающими int. va_start/va_end - не функции, а макросы, для них это не подходит, и их нужно объявлять. #include <stdarg.h>

Author:  SoUrcerer [ Tue Feb 15, 2011 1:28 pm ]
Post subject:  Re: Помогите новичку

Есть в lua.h этот самый include <stdarg.h>, пробовал подключить к lua.с - результат один. :(

Author:  CleverMouse [ Tue Feb 15, 2011 1:58 pm ]
Post subject:  Re: Помогите новичку

При имеющейся информации я могу посоветовать только писать на ассемблере.

Author:  XVilka [ Tue Feb 15, 2011 2:43 pm ]
Post subject:  Re: Помогите новичку

могу посоветовать реализацию, на ассемблере (большей частью) http://luajit.org/

Author:  Jaeger [ Fri Mar 25, 2011 11:31 am ]
Post subject:  Re: Помогите новичку

Подскажите, как реализовать на FASM структуру, содержащую в качестве одного из полей массив структур?
Т.е. хочется перевести с C код наподобие этого:
Code:
struct tp_frame {
...
};
struct tp_vm {
...
struct tp_frame frames[256];
...
};

Author:  IgorA [ Fri Mar 25, 2011 5:35 pm ]
Post subject:  Re: Помогите новичку

можно перевести вот так :
Code:
struct tp_frame
;...
ends

struct tp_vm
;...
frames rb 256*sizeof.tp_frame
;...
ends

для массивов есть еще инструкция times, но с ней я не смог заставить файл компилироваться :(

Author:  Jaeger [ Sun Mar 27, 2011 5:41 am ]
Post subject:  Re: Помогите новичку

Спасибо! Я пытался сделать то же с помощью макроса struc, но FASM ругался, что не знает символа sizeof.tp_obj (tp_obj - одна из структур, входящих в tp_frame).

Ещё вопрос. Есть функция на C:
Code:
tp_obj tp_dict(tp_vm *tp){...};

принимающая 1 параметр - указатель на структуру tp_vm.
Я её вызываю следующим образом:

Code:
extrn tp_dict
public testmod_init

testmod_str     rd 1

testmod_init:
     push ebp
     mov ebp, esp
     ; Create module dictionary and store its address in testmod_str
     mov eax,dword [ebp + 8]
     ;push eax
     push eax
     call tp_dict
     ...
     pop ebp
     ret


и в tp_dict передаётся что-то совсем не то. А если раскомментировать дублирующий "push eax", то всё работает как надо. Почему так?

Author:  IgorA [ Sun Mar 27, 2011 9:37 pm ]
Post subject:  Re: Помогите новичку

Jaeger wrote:
А если раскомментировать дублирующий "push eax", то всё работает как надо. Почему так?

Ошибок пока не вижу, может внутри функции tp_dict не правильное считывание параметров? Например там может стоять dword [ebp + 12] вместо dword [ebp + 8] и тогда входной параметр будет браться из 1-го push eax, а 2-й ни на что не будет влиять.
Кроме того если функция возвращает параметр, как здесь:
Code:
tp_obj tp_dict(tp_vm *tp){...};

то после ее вызова обязательно нужно делать вызов pop для считывания параметра, или если возвращаемый параметр не нужен то можно изменить значение регистра esp на 4. В указанном примере после вызова функции сразу идет многоточие, потому не понятно есть ли там обработка возвращаемого результата.

Author:  CleverMouse [ Mon Mar 28, 2011 12:26 pm ]
Post subject:  Re: Помогите новичку

Jaeger, если тип возвращаемого значения tp_obj - это сложная структура, не умещающаяся в регистре, то код из
Code:
tp_obj func(arg1)
{ tp_obj result; result.field_1 = arg1; return result; }

компилируется примерно в
Code:
void func(tp_obj* hidden, arg1)
{ hidden->field_1 = arg1; }

Возможны варианты - компилятор может не решиться делать все действия прямо с hidden, а честно заполнять локальную переменную и потом её копировать в *hidden; компилятор может возвращать не void, а сам указатель hidden для удобства, - но суть такая: если возвращаемое значение не умещается в регистр, то функция имеет неявный первый параметр, являющийся указателем на результат.

Author:  SoUrcerer [ Mon Mar 28, 2011 8:53 pm ]
Post subject:  Re: Помогите новичку

Spoiler: Show
Хочу сделать coff-библиотеку freetype, но для этого сначала нужно понять, как нужно делать coff-библиотеки. Код получился такой:
Code:
#include <stdio.h>



int __stdcall start() {return 1;
};



typedef struct

{

  char *name;

  void *f;

}export_t;



char szStart[]           = "START";

char szVersion[]         = "version";



export_t EXPORTS[] __asm__("EXPORTS") =

         {

           { szStart,           start },

           { szVersion,         (void*)0x00010001 },


           { NULL, NULL },

         };




Компилировал так:
i586-mingw32msvc-gcc -c lib.c -fomit-frame-pointer -I include/ -D__DYNAMIC_REENT__ -O2 -combine
Получившийся obj-файл имеет в таблице экспорта START и version (так пишет cObj), но при попытке загрузить библиотеку через kol_cofflib_load из kolibri.c на доску выводится несколько сообщений навроде "unresolved (". Другие библиотеки отлично загружаются. Что я неправильно делаю? (Ой, а их еще и линковать надо? :oops: )

Упс, всё работает как нужно... Ура

UPD:и всё же, что делать с unresolved? В библиотеке freetype используются например memcpy, malloc, fseek, fread (правда, не знаю, откуда они вызываются).

Author:  SoUrcerer [ Mon Mar 28, 2011 10:48 pm ]
Post subject:  Re: Помогите новичку

Добавляю в freetype.c следующий код:
Spoiler: Show
Code:
void main(){
int major;
int minor;
TT_FreeType_Version(&major,&minor);
printf ("%d .. %d \n",major,minor);}

Получаю в результате вывод на доску отладки 1.3 - номер версии.

Теперь делаю coff, добавляя вместо main к freetype.c следующий код:
Spoiler: Show
Code:
int __stdcall start()
{
     return 1;
};

typedef struct
{
  char *name;
  void *f;
}export_t;

char szStart[]           = "START";
char szVersion[]         = "version";

export_t EXPORTS[] __asm__("EXPORTS") =
         {
           { szStart,           start },
           { szVersion,         TT_FreeType_Version },
          { NULL, NULL },
         };


cObj показывает START и version в таблице экспорта.

Тестовая программка:
Spoiler: Show
Code:
#include <stdlib.h>
#include <stdio.h>
#include <kolibri.h>


 int (* __stdcall start)(void);

 int (* __stdcall version)(int* major, int* minor);





///===========================



void INIT()

{

kol_struct_import *imp;



imp = kol_cofflib_load("/sys/lib/freetype.obj");

if (imp == NULL)

   kol_exit();

printf("Library found\n");



start = ( _stdcall int (*)(void))

      kol_cofflib_procload (imp, "START");

if (start == NULL)

   kol_exit();



printf("start loaded\n");



version = ( _stdcall int (*)(int* major, int* minor))

      kol_cofflib_procload (imp, "version");

if (version == NULL)

   kol_exit();

printf("version loaded\n");



}

int main()
{
   int major;
   int minor;
        INIT();
        printf("Yep!\n");
   version(&major, &minor);
        printf("Version .. %d .. %d .. \n",major,minor);
        return 1;
}

Библиотеку вроде загружает, функции импортирует, но выдает версию 0.47.
Если не трудно, расскажите, как нужно делать, чтобы работало? Причина в stdcall?

UPD: сделал примитивную обертку, чтобы передавала значения от TT_FreeType_Version через stdcall. Неужели так для всех функций делать придется? Или есть более простой способ?

Page 15 of 76 All times are UTC+03:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/