Page 15 of 77

Re: Помогите новичку

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

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

upd: код вот такой... может быть, его как-то поправить можно, чтобы обойтись без сигналов?

Code: Select all

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;
}

Re: Помогите новичку

Posted: Tue Feb 15, 2011 10:56 am
by SoUrcerer
Вдобавок очень нехватает макросов va_start и va_end.
Посмотрю в коде libc для open watcom, но не уверен, что даже если они там есть, то смогу их перенести в libc :(
Тоже буду рад подсказкам и умным мыслям.

Re: Помогите новичку

Posted: Tue Feb 15, 2011 1:07 pm
by CleverMouse
Макросы va_start и va_end в menuetlibc есть, #include <stdarg.h>.

Re: Помогите новичку

Posted: Tue Feb 15, 2011 1:19 pm
by SoUrcerer
Действительно, есть. Почему ж тогда в printf и sprintf на них выдается undefined refernce :(

Re: Помогите новичку

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

Re: Помогите новичку

Posted: Tue Feb 15, 2011 1:28 pm
by SoUrcerer
Есть в lua.h этот самый include <stdarg.h>, пробовал подключить к lua.с - результат один. :(

Re: Помогите новичку

Posted: Tue Feb 15, 2011 1:58 pm
by CleverMouse
При имеющейся информации я могу посоветовать только писать на ассемблере.

Re: Помогите новичку

Posted: Tue Feb 15, 2011 2:43 pm
by XVilka
могу посоветовать реализацию, на ассемблере (большей частью) http://luajit.org/

Re: Помогите новичку

Posted: Fri Mar 25, 2011 11:31 am
by Jaeger
Подскажите, как реализовать на FASM структуру, содержащую в качестве одного из полей массив структур?
Т.е. хочется перевести с C код наподобие этого:

Code: Select all

struct tp_frame {
...
};
struct tp_vm {
...
struct tp_frame frames[256];
...
};

Re: Помогите новичку

Posted: Fri Mar 25, 2011 5:35 pm
by IgorA
можно перевести вот так :

Code: Select all

struct tp_frame
;...
ends

struct tp_vm
;...
frames rb 256*sizeof.tp_frame
;...
ends
для массивов есть еще инструкция times, но с ней я не смог заставить файл компилироваться :(

Re: Помогите новичку

Posted: Sun Mar 27, 2011 5:41 am
by Jaeger
Спасибо! Я пытался сделать то же с помощью макроса struc, но FASM ругался, что не знает символа sizeof.tp_obj (tp_obj - одна из структур, входящих в tp_frame).

Ещё вопрос. Есть функция на C:

Code: Select all

tp_obj tp_dict(tp_vm *tp){...};
принимающая 1 параметр - указатель на структуру tp_vm.
Я её вызываю следующим образом:

Code: Select all

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", то всё работает как надо. Почему так?

Re: Помогите новичку

Posted: Sun Mar 27, 2011 9:37 pm
by IgorA
Jaeger wrote:А если раскомментировать дублирующий "push eax", то всё работает как надо. Почему так?
Ошибок пока не вижу, может внутри функции tp_dict не правильное считывание параметров? Например там может стоять dword [ebp + 12] вместо dword [ebp + 8] и тогда входной параметр будет браться из 1-го push eax, а 2-й ни на что не будет влиять.
Кроме того если функция возвращает параметр, как здесь:

Code: Select all

tp_obj tp_dict(tp_vm *tp){...};
то после ее вызова обязательно нужно делать вызов pop для считывания параметра, или если возвращаемый параметр не нужен то можно изменить значение регистра esp на 4. В указанном примере после вызова функции сразу идет многоточие, потому не понятно есть ли там обработка возвращаемого результата.

Re: Помогите новичку

Posted: Mon Mar 28, 2011 12:26 pm
by CleverMouse
Jaeger, если тип возвращаемого значения tp_obj - это сложная структура, не умещающаяся в регистре, то код из

Code: Select all

tp_obj func(arg1)
{ tp_obj result; result.field_1 = arg1; return result; }
компилируется примерно в

Code: Select all

void func(tp_obj* hidden, arg1)
{ hidden->field_1 = arg1; }
Возможны варианты - компилятор может не решиться делать все действия прямо с hidden, а честно заполнять локальную переменную и потом её копировать в *hidden; компилятор может возвращать не void, а сам указатель hidden для удобства, - но суть такая: если возвращаемое значение не умещается в регистр, то функция имеет неявный первый параметр, являющийся указателем на результат.

Re: Помогите новичку

Posted: Mon Mar 28, 2011 8:53 pm
by SoUrcerer
Spoiler:Хочу сделать coff-библиотеку freetype, но для этого сначала нужно понять, как нужно делать coff-библиотеки. Код получился такой:

Code: Select all

#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 (правда, не знаю, откуда они вызываются).

Re: Помогите новичку

Posted: Mon Mar 28, 2011 10:48 pm
by SoUrcerer
Добавляю в freetype.c следующий код:
Spoiler:

Code: Select all

void main(){
int major;
int minor;
TT_FreeType_Version(&major,&minor);
printf ("%d .. %d \n",major,minor);}
Получаю в результате вывод на доску отладки 1.3 - номер версии.

Теперь делаю coff, добавляя вместо main к freetype.c следующий код:
Spoiler:

Code: Select all

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:

Code: Select all

#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. Неужели так для всех функций делать придется? Или есть более простой способ?