Kirov OpenSolaris User Group > Разработки Kirov OSUG
Программа для преобразования исполняемого файла Linux для запуска в OpenSolaris
keremet:
Существуют такие приложения, как например skype и некоторые фильтры печати, у которых закрыты исходники, но свободно доступны бинарники под Linux. Хотелось бы иметь программу которая преобразовывала бы эти приложения так, чтобы они могли запускаться под OpenSolaris без необходимости использования зоны или lxrun. Узнав, что формат исполняемых файлов под обеими ОС одинаковый, решил попробовать поисследовать возможность создания такой программы.
Взял самый простой пример приложения на С:
#include <stdio.h>
int main(){
printf("HW!\n");
return 0;
}
Команда gcc -O3 -S генерирует одинаковый ассемблерный код как в случае Linux (в lx-зоне), так и в случае OpenSolaris.
Сгенерированный в lx-зоне объектный файл, поданный на вход gcc в OpenSolaris, позволил без ошибок слинковать нормально работающее приложение. Таким образом, если приложение использует только libc(не исключаю, что допустимо использование и других библиотек), то если из бинарника удастся сформировать объектный файл, на основе которого он создан, то можно получить такое же приложение под OpenSolaris.
Дизассемблировать линуксовое приложение, а потом снова сассемблировать под OpenSolaris - затруднительно в виду сложности создания адекватного дизассемблера.
Зависимости приложения под Linux:
$ldd a.out
libc.so.6 => /lib/tls/libc.so.6 (0xfe776000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xfef61000)
$objdump -R a.out
a.out: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049534 R_386_GLOB_DAT __gmon_start__
0804952c R_386_JUMP_SLOT puts
08049530 R_386_JUMP_SLOT __libc_start_main
Под OpenSolaris зависимости совершенно другие. Для упрощения задачи взял еще более простой пример программы.
// Компиляция: as -o hello.o hello.s && ld -s hello.o -lc && ./a.out
.text
.globl _start
_start:
pushl $message1
call puts
popl %ebx
call exit
hlt
.data
message1:
.string "Hello world\0"
Теперь зависимости от функций совпадают.
$objdump -R a.out
a.out: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049330 R_386_JUMP_SLOT exit
08049334 R_386_JUMP_SLOT puts
Открыл файл a.out с lx-зоны в ghex2 и внес изменения:
1. Строку /usr/lib/libc.so.1 заменил на /usr/lib/ld.so.1
2. Строку libc.so.6 заменил на libc.so.1
3. Строку GLIBC_2.0 заменил на SUNW_0.8, находящуюся чуть ниже последовательность байт 10 69 69 0D, тоже задающую версию, заменил на 98 28 3d 0a
Просмотр доступных версий в libc: objdump -p /lib/libc.so.1. objdump -p a.out - просмотр используемой приложением версии.
Файл запускается и работает нормально. Это доказывает возможность с относительно небольшими изменениями модифицировать бинарники из Linux для нативного запуска под OpenSolaris.
Илья:
Было ло бы хорошо если в нашей системе такая опция будет :P
Вот этот код что означает?
class Foo
{
public:
Foo(int j) { i=new int[j]; }
~Foo() { delete i; }
private:
int* i;
};
class Bar: Foo
{
public:
Bar(int j) { i=new char[j]; }
~Bar() { delete i; }
private:
char* i;
};
void main()
{
Foo* f=new Foo(100);
Foo* b=new Bar(200);
*f=*b;
delete f;
delete b;
}
sCode:
--- Цитата: keremet от Март 05, 2011, 06:53:21 pm ---Существуют такие приложения, как например skype и некоторые фильтры печати, у которых закрыты исходники, но свободно доступны бинарники под Linux. Хотелось бы иметь программу которая преобразовывала бы эти приложения так, чтобы они могли запускаться под OpenSolaris без необходимости использования зоны или lxrun. Узнав, что формат исполняемых файлов под обеими ОС одинаковый, решил попробовать поисследовать возможность создания такой программы.
Взял самый простой пример приложения на С:
#include <stdio.h>
int main(){
printf("HW!\n");
return 0;
}
Команда gcc -O3 -S генерирует одинаковый ассемблерный код как в случае Linux (в lx-зоне), так и в случае OpenSolaris.
Сгенерированный в lx-зоне объектный файл, поданный на вход gcc в OpenSolaris, позволил без ошибок слинковать нормально работающее приложение. Таким образом, если приложение использует только libc(не исключаю, что допустимо использование и других библиотек), то если из бинарника удастся сформировать объектный файл, на основе которого он создан, то можно получить такое же приложение под OpenSolaris.
Дизассемблировать линуксовое приложение, а потом снова сассемблировать под OpenSolaris - затруднительно в виду сложности создания адекватного дизассемблера.
Зависимости приложения под Linux:
$ldd a.out
libc.so.6 => /lib/tls/libc.so.6 (0xfe776000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xfef61000)
$objdump -R a.out
a.out: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049534 R_386_GLOB_DAT __gmon_start__
0804952c R_386_JUMP_SLOT puts
08049530 R_386_JUMP_SLOT __libc_start_main
Под OpenSolaris зависимости совершенно другие. Для упрощения задачи взял еще более простой пример программы.
// Компиляция: as -o hello.o hello.s && ld -s hello.o -lc && ./a.out
.text
.globl _start
_start:
pushl $message1
call puts
popl %ebx
call exit
hlt
.data
message1:
.string "Hello world\0"
Теперь зависимости от функций совпадают.
$objdump -R a.out
a.out: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049330 R_386_JUMP_SLOT exit
08049334 R_386_JUMP_SLOT puts
Открыл файл a.out с lx-зоны в ghex2 и внес изменения:
1. Строку /usr/lib/libc.so.1 заменил на /usr/lib/ld.so.1
2. Строку libc.so.6 заменил на libc.so.1
3. Строку GLIBC_2.0 заменил на SUNW_0.8, находящуюся чуть ниже последовательность байт 10 69 69 0D, тоже задающую версию, заменил на 98 28 3d 0a
Просмотр доступных версий в libc: objdump -p /lib/libc.so.1. objdump -p a.out - просмотр используемой приложением версии.
Файл запускается и работает нормально. Это доказывает возможность с относительно небольшими изменениями модифицировать бинарники из Linux для нативного запуска под OpenSolaris.
--- Конец цитаты ---
А чем кросскомпиляторы не устраивают? Типа MinGW? Можно компилировать сразу под три платформы:
* OpenSolaris
* GNU/Linux
* Windows
keremet:
Если доступны исходники, тогда, конечно, лучше скомпилировать из них. Преобразования исполняемого файла актуальны, когда исходников нет, как например в случае со skype.
keremet:
Более правильное решение - не вносить изменения в бинарники, а создать динамический линковщик, который позволит запускаться приложениям Linux. За основу хочу взять ld.so.1 из Illumos. Скомпилировал Illumos (https://www.illumos.org/projects/illumos-gate/wiki/How_To_Build_illumos) и столкнулся с проблемой, что при повторном запуске команды компиляции (./nightly illumos.sh ) для компиляции измененного кода ld.so.1 удаляются все результаты предыдущей сборки и сборка начинается сначала (10 часов). Запуск make прямо в каталоге usr/src/cmd/sgs/rtld завершается неудачно из-за невыставленных переменных окружения.
Кривым решением проблемы является составление собственного makefile в usr/src/cmd/sgs/rtld на основе '.make.state.i386', хранящего все команды, выполненные make ранее.
Однако мне кажется, что наверняка есть более корректное решение без написания makefile, тем более эта процедура была достаточно затруднительной.
Навигация
Перейти к полной версии