Sorcerer
stdcall только для START - точка входа для библиотеки если требуется выполнить статические конструкторы. Формат остальных вызовов на усмотрение программиста.
Я бы советовал делать PE длл. Для подгруженного coff надо все функции переобъявлять из
retval function(<args>) в указатели на функцию retval (*function)(<args>). Это правка всех include, то есть для ассемблера и маленьких демок годится, а для портирования чего-нибудь большого на С уже нет. Проще статически слинковать.
Помогите новичку
Пробую сделать PE dll по инструкции, не линкуется в dll-ку, потому что требует некоторые функции из libc, а если подключать libc, то ругается на отсутствие main, __cmdline и __pgmname. Проще заменить функции, используемые freetype, на аналоги, или есть другие методы?
upd: Нет функций printf, ftell, fread, fseek, fclose, fopen, memmove. С printf я разберусь, файловые операции есть в libio - можно ли использовать coff-библиотеки из dll, и если да, то как? Что делать с memmove?
upd: Нет функций printf, ftell, fread, fseek, fclose, fopen, memmove. С printf я разберусь, файловые операции есть в libio - можно ли использовать coff-библиотеки из dll, и если да, то как? Что делать с memmove?
Sorcerer
Bce функции есть, надо линковать не со статической libc, а с библиотеками импорта. Посмотри svn://kolibrios.org/programs/develop/libraries/libmpg123 Библиотеки импорта и длл http://code.google.com/p/kolibri-pe/downloads/list
Bce функции есть, надо линковать не со статической libc, а с библиотеками импорта. Посмотри svn://kolibrios.org/programs/develop/libraries/libmpg123 Библиотеки импорта и длл http://code.google.com/p/kolibri-pe/downloads/list
Угу, собралось. Заголовок у библиотеки MZ, так и должно быть? Как проверить, что все правильно собралось (т.е. как подключать pe-библиотеки к Си-программам)? Я правильно понял, что нужно все делать, как и при статической линковке, но линковать с libfreetypeimp.a?
Sorcerer
1. Пишешь обычную программу на С.
2. Линкуешь с ключами -nostdlib -pie -s -T pe_app.lds --image-base 0 --stack 0x100000 -Map test.map -lamz -lgcc -lcimp + остальные библиотеки импорта.
3. Получившийся екзешник встраиваешь в demo.asm (он есть amz-dev.12.03.11.7z)
Для проверки PE екзешников и ддлок рекомендую pedump:
pedump моя_программа_или_длл >dump.txt
File Header
Machine: 014C (i386)
Number of Sections: 0007
TimeDateStamp: 4D7A75F9
PointerToSymbolTable: 00000000
NumberOfSymbols: 00000000
SizeOfOptionalHeader: 00E0
Characteristics: 230E
EXECUTABLE_IMAGE
LINE_NUMS_STRIPPED
LOCAL_SYMS_STRIPPED
32BIT_MACHINE
DLL
Optional Header
Magic 010B
linker version 2.21
size of code F600
size of initialized data 6000
size of uninitialized data 10000
entrypoint RVA 1000
base of code 1000
base of data 15000
image base 0
section align 1000
file align 200
required OS version 4.00
image version 1.00
subsystem version 4.00
Reserved1 0
size of image 2A000
size of headers 400
checksum 1D4B2
Subsystem 0003 (Windows character)
DLL flags 0000
stack reserve size 200000
stack commit size 1000
heap reserve size 100000
heap commit size 1000
loader flags 00000000
RVAs & sizes 10
Data Directory
EXPORT rva: 00027000 size: 00000706
IMPORT rva: 00028000 size: 00000118
RESOURCE rva: 00000000 size: 00000000
EXCEPTION rva: 00000000 size: 00000000
SECURITY rva: 00000000 size: 00000000
BASERELOC rva: 00029000 size: 000005B8
DEBUG rva: 00000000 size: 00000000
COPYRIGHT rva: 00000000 size: 00000000
GLOBALPTR rva: 00000000 size: 00000000
TLS rva: 00000000 size: 00000000
LOAD_CONFIG rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
Section Table
01 .text VirtSize: 0000F59C VirtAddr: 00001000
raw data offs: 00000400 raw data size: 0000F600
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 60600020
CODE MEM_EXECUTE MEM_READ
02 .rdata VirtSize: 00003260 VirtAddr: 00011000
raw data offs: 0000FA00 raw data size: 00003400
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 40600040
INITIALIZED_DATA MEM_READ
03 .data VirtSize: 00001AA4 VirtAddr: 00015000
raw data offs: 00012E00 raw data size: 00001C00
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: C0600040
INITIALIZED_DATA MEM_READ MEM_WRITE
04 .bss VirtSize: 0000FF84 VirtAddr: 00017000
raw data offs: 00000000 raw data size: 00000000
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: C0600080
UNINITIALIZED_DATA MEM_READ MEM_WRITE
05 .edata VirtSize: 00000706 VirtAddr: 00027000
raw data offs: 00014A00 raw data size: 00000800
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 40300040
INITIALIZED_DATA MEM_READ
06 .idata VirtSize: 00000118 VirtAddr: 00028000
raw data offs: 00015200 raw data size: 00000200
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: C0300040
INITIALIZED_DATA MEM_READ MEM_WRITE
07 .reloc VirtSize: 000005B8 VirtAddr: 00029000
raw data offs: 00015400 raw data size: 00000600
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 42300040
INITIALIZED_DATA MEM_DISCARDABLE MEM_READ
Imports Table:
libc.dll
Hint/Name Table: 00028028
TimeDateStamp: 00000000
ForwarderChain: 00000000
First thunk RVA: 00028054
Ordn Name
306 close
378 free
465 lseek
466 malloc
473 memmove
490 open
492 pow
503 read
505 realloc
548 strcasecmp
exports table:
Name: libmpg123.dll
Characteristics: 00000000
TimeDateStamp: 4D7A75F9
Version: 0.00
Ordinal base: 00000001
# of functions: 00000044
# of Names: 00000044
Entry Pt Ordn Name
00001EE4 1 mpg123_clip
00002B88 2 mpg123_close
00003FF4 3 mpg123_current_decoder
00001D1C 4 mpg123_decode
00001BC4 5 mpg123_decode_frame
00001A28 6 mpg123_decoder
00004010 7 mpg123_decoders
00002CC8 8 mpg123_delete
0000DC70 9 mpg123_delete_pars
00002B14 10 mpg123_enc_from_id3
0000F310 11 mpg123_encodings
000015C4 12 mpg123_eq
00002D24 13 mpg123_errcode
0000110C 14 mpg123_exit
00001CC4 15 mpg123_feed
00002124 16 mpg123_feedseek
0000F660 17 mpg123_fmt
0000F5B8 18 mpg123_fmt_all
0000F558 19 mpg123_fmt_none
0000F7A4 20 mpg123_fmt_support
0000F750 21 mpg123_format
0000F624 22 mpg123_format_all
0000F57C 23 mpg123_format_none
0000F810 24 mpg123_format_support
00001650 25 mpg123_geteq
00001F04 26 mpg123_getformat
000013CC 27 mpg123_getpar
00001518 28 mpg123_getparam
0000156C 29 mpg123_getstate
0000F094 30 mpg123_getvolume
00002AF8 31 mpg123_icy
00002B10 32 mpg123_icy2utf8
00002A84 33 mpg123_id3
00002B2C 34 mpg123_index
0000E48C 35 mpg123_info
000010D8 36 mpg123_init
00002508 37 mpg123_length
00002A70 38 mpg123_meta_check
000011D0 39 mpg123_new
0000DBC4 40 mpg123_new_pars
00002C7C 41 mpg123_open
00002C30 42 mpg123_open_fd
00002BF4 43 mpg123_open_feed
00001AF8 44 mpg123_outblock
000011F8 45 mpg123_par
00001348 46 mpg123_param
00001110 47 mpg123_parnew
00002CF8 48 mpg123_plain_strerror
0000CE60 49 mpg123_position
0000F2F0 50 mpg123_rates
00001EA8 51 mpg123_read
0000DF24 52 mpg123_replace_buffer
000016B0 53 mpg123_replace_reader
0000DC8C 54 mpg123_reset_eq
00001AF0 55 mpg123_safe_buffer
000026A0 56 mpg123_scan
0000283C 57 mpg123_seek
00002350 58 mpg123_seek_frame
000024E8 59 mpg123_set_filesize
00002D3C 60 mpg123_strerror
00004018 61 mpg123_supported_decoders
0000200C 62 mpg123_tell
000020FC 63 mpg123_tell_stream
000020C0 64 mpg123_tellframe
00001F88 65 mpg123_timeframe
0000CE1C 66 mpg123_tpf
0000EE44 67 mpg123_volume
0000EF84 68 mpg123_volume_change Для запуска понадобятся libc.obj system.env из последней демки Cairo (amz-12.03.11.7z)
Почти. Надо собирать PE приложение.Я правильно понял, что нужно все делать, как и при статической линковке, но линковать с libfreetypeimp.a?
1. Пишешь обычную программу на С.
2. Линкуешь с ключами -nostdlib -pie -s -T pe_app.lds --image-base 0 --stack 0x100000 -Map test.map -lamz -lgcc -lcimp + остальные библиотеки импорта.
3. Получившийся екзешник встраиваешь в demo.asm (он есть amz-dev.12.03.11.7z)
Для проверки PE екзешников и ддлок рекомендую pedump:
pedump моя_программа_или_длл >dump.txt
Spoiler:
Dump of file LIBMPG123.DLLFile Header
Machine: 014C (i386)
Number of Sections: 0007
TimeDateStamp: 4D7A75F9
PointerToSymbolTable: 00000000
NumberOfSymbols: 00000000
SizeOfOptionalHeader: 00E0
Characteristics: 230E
EXECUTABLE_IMAGE
LINE_NUMS_STRIPPED
LOCAL_SYMS_STRIPPED
32BIT_MACHINE
DLL
Optional Header
Magic 010B
linker version 2.21
size of code F600
size of initialized data 6000
size of uninitialized data 10000
entrypoint RVA 1000
base of code 1000
base of data 15000
image base 0
section align 1000
file align 200
required OS version 4.00
image version 1.00
subsystem version 4.00
Reserved1 0
size of image 2A000
size of headers 400
checksum 1D4B2
Subsystem 0003 (Windows character)
DLL flags 0000
stack reserve size 200000
stack commit size 1000
heap reserve size 100000
heap commit size 1000
loader flags 00000000
RVAs & sizes 10
Data Directory
EXPORT rva: 00027000 size: 00000706
IMPORT rva: 00028000 size: 00000118
RESOURCE rva: 00000000 size: 00000000
EXCEPTION rva: 00000000 size: 00000000
SECURITY rva: 00000000 size: 00000000
BASERELOC rva: 00029000 size: 000005B8
DEBUG rva: 00000000 size: 00000000
COPYRIGHT rva: 00000000 size: 00000000
GLOBALPTR rva: 00000000 size: 00000000
TLS rva: 00000000 size: 00000000
LOAD_CONFIG rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
unused rva: 00000000 size: 00000000
Section Table
01 .text VirtSize: 0000F59C VirtAddr: 00001000
raw data offs: 00000400 raw data size: 0000F600
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 60600020
CODE MEM_EXECUTE MEM_READ
02 .rdata VirtSize: 00003260 VirtAddr: 00011000
raw data offs: 0000FA00 raw data size: 00003400
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 40600040
INITIALIZED_DATA MEM_READ
03 .data VirtSize: 00001AA4 VirtAddr: 00015000
raw data offs: 00012E00 raw data size: 00001C00
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: C0600040
INITIALIZED_DATA MEM_READ MEM_WRITE
04 .bss VirtSize: 0000FF84 VirtAddr: 00017000
raw data offs: 00000000 raw data size: 00000000
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: C0600080
UNINITIALIZED_DATA MEM_READ MEM_WRITE
05 .edata VirtSize: 00000706 VirtAddr: 00027000
raw data offs: 00014A00 raw data size: 00000800
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 40300040
INITIALIZED_DATA MEM_READ
06 .idata VirtSize: 00000118 VirtAddr: 00028000
raw data offs: 00015200 raw data size: 00000200
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: C0300040
INITIALIZED_DATA MEM_READ MEM_WRITE
07 .reloc VirtSize: 000005B8 VirtAddr: 00029000
raw data offs: 00015400 raw data size: 00000600
relocation offs: 00000000 relocations: 00000000
line # offs: 00000000 line #'s: 00000000
characteristics: 42300040
INITIALIZED_DATA MEM_DISCARDABLE MEM_READ
Imports Table:
libc.dll
Hint/Name Table: 00028028
TimeDateStamp: 00000000
ForwarderChain: 00000000
First thunk RVA: 00028054
Ordn Name
306 close
378 free
465 lseek
466 malloc
473 memmove
490 open
492 pow
503 read
505 realloc
548 strcasecmp
exports table:
Name: libmpg123.dll
Characteristics: 00000000
TimeDateStamp: 4D7A75F9
Version: 0.00
Ordinal base: 00000001
# of functions: 00000044
# of Names: 00000044
Entry Pt Ordn Name
00001EE4 1 mpg123_clip
00002B88 2 mpg123_close
00003FF4 3 mpg123_current_decoder
00001D1C 4 mpg123_decode
00001BC4 5 mpg123_decode_frame
00001A28 6 mpg123_decoder
00004010 7 mpg123_decoders
00002CC8 8 mpg123_delete
0000DC70 9 mpg123_delete_pars
00002B14 10 mpg123_enc_from_id3
0000F310 11 mpg123_encodings
000015C4 12 mpg123_eq
00002D24 13 mpg123_errcode
0000110C 14 mpg123_exit
00001CC4 15 mpg123_feed
00002124 16 mpg123_feedseek
0000F660 17 mpg123_fmt
0000F5B8 18 mpg123_fmt_all
0000F558 19 mpg123_fmt_none
0000F7A4 20 mpg123_fmt_support
0000F750 21 mpg123_format
0000F624 22 mpg123_format_all
0000F57C 23 mpg123_format_none
0000F810 24 mpg123_format_support
00001650 25 mpg123_geteq
00001F04 26 mpg123_getformat
000013CC 27 mpg123_getpar
00001518 28 mpg123_getparam
0000156C 29 mpg123_getstate
0000F094 30 mpg123_getvolume
00002AF8 31 mpg123_icy
00002B10 32 mpg123_icy2utf8
00002A84 33 mpg123_id3
00002B2C 34 mpg123_index
0000E48C 35 mpg123_info
000010D8 36 mpg123_init
00002508 37 mpg123_length
00002A70 38 mpg123_meta_check
000011D0 39 mpg123_new
0000DBC4 40 mpg123_new_pars
00002C7C 41 mpg123_open
00002C30 42 mpg123_open_fd
00002BF4 43 mpg123_open_feed
00001AF8 44 mpg123_outblock
000011F8 45 mpg123_par
00001348 46 mpg123_param
00001110 47 mpg123_parnew
00002CF8 48 mpg123_plain_strerror
0000CE60 49 mpg123_position
0000F2F0 50 mpg123_rates
00001EA8 51 mpg123_read
0000DF24 52 mpg123_replace_buffer
000016B0 53 mpg123_replace_reader
0000DC8C 54 mpg123_reset_eq
00001AF0 55 mpg123_safe_buffer
000026A0 56 mpg123_scan
0000283C 57 mpg123_seek
00002350 58 mpg123_seek_frame
000024E8 59 mpg123_set_filesize
00002D3C 60 mpg123_strerror
00004018 61 mpg123_supported_decoders
0000200C 62 mpg123_tell
000020FC 63 mpg123_tell_stream
000020C0 64 mpg123_tellframe
00001F88 65 mpg123_timeframe
0000CE1C 66 mpg123_tpf
0000EE44 67 mpg123_volume
0000EF84 68 mpg123_volume_change
- Attachments
-
-
pedump.zip (16.61 KiB)
- Matt Pietrek's PE dump
Downloaded 144 times
-
Update.
В system.env надо прописать путь к PE ддлкам.
В system.env надо прописать путь к PE ддлкам.
Спасибо! Вечером попробую.
Обидно, что тяжеловаты бинарники получаются - непакованный freetype.dll занимает 97 килобайт (а ему еще libc.obj будет нужен, верно?). Хм, а в запакованном - всего 37 килобайт.
И как это - "встроить экзешник в demo.asm"?
Обидно, что тяжеловаты бинарники получаются - непакованный freetype.dll занимает 97 килобайт (а ему еще libc.obj будет нужен, верно?). Хм, а в запакованном - всего 37 килобайт.
И как это - "встроить экзешник в demo.asm"?
Sorcerer
в demo.asm есть строчки
в demo.asm есть строчки
фактически это контейнер для PE приложения. DLL можно сжимать kpack, хотя и не рекомендуется. Вообще всё это больше рассчитано за работу с винта или LiveCD. Пишешь в system.env свой путь к длл и их размер больше не волнует. Опция ld -s удаляет отладочную информацию. -file-alignment 32 --section-alignment 32 помогают уменьшить размер.my_app:
file 'my_app.exe'
Имею всевозможные инклуды в подпапке include, компилирую библиотеку, всё хорошо.
Затем в другой папке с теми же инклудами компилирую common.c и ftstrpnm.c в объектники. Копирую в папку к o-файлам все imp-библиотеки, libamz и свежесобранную freetype. Пытаюсь слинковать:
i586-mingw32msvc-ld -nostdlib -pie -s -T pe_app.lds --image-base 0 --stack 0x100000 -Map test.map -L ./ -lamz -lcimp -lgcc -lfreetypeimp -o ftpnm.exe *.o
Получаю undefinded reference на все функции libc и freetype, используемые в программе.
Если вместо библиотек указывать напрямую a и o файлы, то остается undefined reference только на __getreent.
И всё же хотя PE-библиотеки более перспективны, их нельзя так же легко использовать, как COFF-библиотеки Колибри, верно?
Затем в другой папке с теми же инклудами компилирую common.c и ftstrpnm.c в объектники. Копирую в папку к o-файлам все imp-библиотеки, libamz и свежесобранную freetype. Пытаюсь слинковать:
i586-mingw32msvc-ld -nostdlib -pie -s -T pe_app.lds --image-base 0 --stack 0x100000 -Map test.map -L ./ -lamz -lcimp -lgcc -lfreetypeimp -o ftpnm.exe *.o
Получаю undefinded reference на все функции libc и freetype, используемые в программе.
Если вместо библиотек указывать напрямую a и o файлы, то остается undefined reference только на __getreent.
И всё же хотя PE-библиотеки более перспективны, их нельзя так же легко использовать, как COFF-библиотеки Колибри, верно?
Sorcerer
Mingw ld чувствителен к порядку в котором перечисляются библиотеки. Почему так не знаю. Попробуй поставить -lcimp после -lfreetypeimp и все либы после объектников. __getreent - это что-то компилировал без -D__DYNAMIC_REENT__.
Тут ещё один момент. Для отладки и поиска ошибок лучше линковать со статическими библиотеками, легче найти по map где вылетает. В случае PE это совсем не требует модификации исходного кода.
Mingw ld чувствителен к порядку в котором перечисляются библиотеки. Почему так не знаю. Попробуй поставить -lcimp после -lfreetypeimp и все либы после объектников. __getreent - это что-то компилировал без -D__DYNAMIC_REENT__.
Не думаю что с COFF легче. Для COFF библиотек надо всё вручную импортировать или писать таблицы импорта. Для PE всё делается автоматически. Единственная сложность то, что ядро пока не умеет грузить PE приложения.И всё же хотя PE-библиотеки более перспективны, их нельзя так же легко использовать, как COFF-библиотеки Колибри, верно?
Тут ещё один момент. Для отладки и поиска ошибок лучше линковать со статическими библиотеками, легче найти по map где вылетает. В случае PE это совсем не требует модификации исходного кода.
Code: Select all
sourcerer@sourcerer-laptop ~/projects/libc/ftdemo $ i586-mingw32msvc-gcc -c *.c -fomit-frame-pointer -I include/ -D__DYNAMIC_REENT__ -O2
In file included from common.c:34:
include/stdlib.h:110: предупреждение: директива описания атрибутов ‘__warning__’ проигнорирована
include/stdlib.h:117: предупреждение: директива описания атрибутов ‘__warning__’ проигнорирована
In file included from ftstrpnm.c:18:
include/stdlib.h:110: предупреждение: директива описания атрибутов ‘__warning__’ проигнорирована
include/stdlib.h:117: предупреждение: директива описания атрибутов ‘__warning__’ проигнорирована
sourcerer@sourcerer-laptop ~/projects/libc/ftdemo $ i586-mingw32msvc-ld -nostdlib -pie -s -T pe_app.lds --image-base 0 --stack 0x100000 -Map test.map ftstrpnm.o common.o -L ./ -lfreetypeimp -lamz -lcimp -o ftpnm.exe
ftstrpnm.o:ftstrpnm.c:(.text+0x75f): undefined reference to `__getreent'
common.o:common.c:(.text+0x2ad): undefined reference to `__getreent'
common.o:common.c:(.text+0x2e9): undefined reference to `__getreent'
Sorcerer
Проверь заголовочные файлы newlib на svn. Там лежит самая последняя версия. __getreent определена в include/sys/reent.h
Проверь заголовочные файлы newlib на svn. Там лежит самая последняя версия. __getreent определена в include/sys/reent.h
Code: Select all
static inline struct _reent *__getreent(void)
{
struct _reent *ent;
__asm__ __volatile__(
"movl %%fs:12, %0"
:"=r"(ent));
return ent;
};