Kirov OpenSolaris User Group > Разработки Kirov OSUG

Программа для преобразования исполняемого файла Linux для запуска в OpenSolaris

(1/3) > >>

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, тем более эта процедура была достаточно затруднительной.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии