2009-05-31 15 views
6

Z początku brzmi to jak głupkowate pytanie, ale pamiętajcie o mnie.Która część (w szczególności) natywnego pliku wykonywalnego czyni go nieprzenośnym?

Powszechnie wiadomo, że pliki binarne dla jednej architektury procesora nie działają na innych. Na przykład niemożliwe jest uruchomienie (bez warstwy kompatybilności), pliku binarnego x86 na układzie sparc64. Zestawy instrukcji są różne, więc wyraźnie nie będą działać.

Ale gdy plik binarny jest dla tego samego procesora, ale dla innego systemu operacyjnego, to która część kodu uniemożliwia wykonanie. Na przykład, uruchomienie binarnego systemu Solaris x86 na pudełku Linuxa x86. Zakładam, że istnieje pewien rodzaj specyficznego dla platformy kodu pośredniczącego, który dotyczy łącznika wykonawczego lub harmonogramu procesu?

Chciałbym wiedzieć. Dzięki.

Odpowiedz

12

Istnieje wiele powodów. Głównymi zamówieniami w "odległości od metalu" są:

  1. Systemy operacyjne mogą mieć różne formaty binarne dla plików wykonywalnych. W tym przypadku nie będzie możliwe załadowanie pliku binarnego w pierwszej kolejności.
  2. Program może wykorzystywać inną metodę do wskazania, że ​​chce umieścić wywołanie systemowe (np. INT21 vs INT80).
  3. Program może polegać na wywołaniach systemowych, które nie są obecne w innym systemie operacyjnym (na przykład dlopen()).
  4. Program może polegać na standardowej bibliotece nieobecnej w innym systemie operacyjnym.
  5. Program może polegać na innych bibliotekach, które nie są dostępne w innym systemie operacyjnym.

Oczywiście istnieje wiele innych sposobów, w których program uruchomiony w nieoczekiwanym otoczeniu może się nie udać.

+1

Przyczyny 1, 2 i 3 są bardzo łatwe do naprawienia. Linux już obsługuje dużą liczbę formatów wykonywalnych. Nowe przerwań można utworzyć za pomocą ładowalnego modułu jądra. A wywołania systemowe zazwyczaj dobrze korespondują między różnymi systemami operacyjnymi. – Zifre

+0

Powinienem był powiedzieć, że zakładamy ELF :) Dzięki za odpowiedź. –

1

To biblioteki specyficzne dla systemu, które nie zawsze są przenośne. Na przykład, nie możesz użyć api win32 na aperitze vanilla (i tak, zdaję sobie sprawę, że są takie warunki pracy jak wino, nie jest to najlepszy przykład).

3

To głównie interfejsy API. Na przykład Win32 API nie są naprawdę dostępne w systemie Linux. Możliwe jest obejście tego, patrz: Wine. Format pliku wykonywalnego może być różny (ELF/PE), ale można go naprawić dość łatwo (Wine to robi, umożliwia wykonywanie plików PE w systemie Linux).

Twój przykład mieszania plików wykonywalnych Solaris i Linux byłby dość łatwy do wdrożenia, ponieważ systemy operacyjne są tak podobne (ELF dla formatu wykonywalnego, POSIX API, X Window, itp.). FreeBSD może już uruchamiać pliki wykonywalne Linux. Powodem, dla którego nie jest to tak powszechne, jest po prostu to, że nie ma na nie dużego popytu. Istnieje o wiele więcej programów dla systemu Windows niż programy * NIX, więc stworzono Wine. Istnieje znacznie więcej programów Linux niż FreeBSD, więc FreeBSD zaimplementowało warstwę kompatybilności z Linuxem. Solaris może w końcu zaimplementować coś podobnego. Jednak nie oczekuj odwrotności (pliki wykonywalne Solaris/BSD w systemie Linux), ponieważ nie ma po prostu popytu na to.

1

Biblioteki systemowe i interfejsy API. Rzeczywisty prosty kod powinien zadziałać. Właśnie dlatego warstwy takie jak Wine nie wykonują żadnej emulacji procesora, po prostu ponownie implementują interfejs API systemu Windows.

0

Jak już wskazano, niekompatybilność ma mniej wspólnego z formatami wykonywalnymi, a nie z bibliotekami, do których odwołuje się plik wykonywalny.

wierzę Linux jest rzeczywiście zgodny z wieloma różnymi formatami wykonywalnych chociaż mogę się mylić tutaj

5

Istnieją cztery problemy:

  1. Różne systemy operacyjne Pakiety binarne pliki wykonywalne ich inaczej (np Linux ELF vs formacie Windows);
  2. Różne zestawy instrukcji na różnych architekturach procesorów;
  3. Różne systemy operacyjne mają różne wywołania systemowe (np. CreateProcess() w systemie Win32 vs fork() w systemie Linux/Unix);
  4. Różnice, takie jak ścieżki, znaki prawne, separatory katalogów i tak dalej.

Biblioteki niesystemowe są obecne na obu, w przeciwnym razie jest to kolejna różnica.

1

Oprócz tego, co powiedzieli inni, rzeczywisty format pliku wykonywalnego może być inny. Tak więc, gdy system operacyjny przychodzi, aby załadować go, nie znajdzie wartości, które oczekuje na kod, segmenty danych itp. W odpowiednich miejscach w pliku.

+1

Ponownie, można to naprawić dość łatwo. Linux obsługuje już wiele formatów wykonywalnych. Wino też to robi. Biblioteki są * znacznie * większym czynnikiem niż format pliku wykonywalnego. – Zifre

2

Poza formatem binarnym i innymi funkcjami "opakowania" (które mogą nie być dokładnie banalne) Istnieją również konsekwencje, które można znaleźć w prawie każdym fragmencie kodu. Rzeczy takie jak

  1. PIC może spowodować, że każdy globalny dostęp będzie polegał na założeniach specyficznych dla systemu przy ponownym ładowaniu wskaźnika GOT i założeniach na dodatkowych przesunięciach.
  2. Wiele systemów posiada specyficzną ABI, mijając małe konstrukcjom w rejestrach, omijając rejestrów dla celów wyrównania, zastrzegając rejestrów do celów specjalnych Niektóre mają kilka (jak ARM EABI i OABI) zagadnień związanych
  3. pamięć lokalna wątku, zmiennych, które są instancja na jeden wątek są ściśle powiązane z obiektami określonymi przez system operacyjny. Zarejestruj wybór, przesunięcia itp.
  4. Niektóre okna systemu operacyjnego (przede wszystkim) obsługują określony format obsługi wyjątków, umożliwiając obsługę wyjątków między językami a nawet między maszynami (przez DCOM).
  5. Systemy międzyoperacyjne o wyższym poziomie (takie jak COM, ale także np. Współpraca z systemem Objective C na komputerach Mac lub zgodność z niektórymi wersjami komend KDE-gcc) również mogą mieć pewne wymagania dotyczące układu VMT.
  6. Niektóre łączniki i formaty obsługują przesunięcia ujemne do sekcji, niektóre nie.

Zauważ, że to tylko braindump rzeczy, które mogą być interesujące do zaglądania. Prawdopodobnie nie jest kompletny i nie wszystkie mogą mieć zastosowanie. Niektóre z powyższych punktów mogą się pokrywać (np. Rezerwowanie rejestru dla TLS lub PIC to także zmiana ABI)

Powiązane problemy