2009-10-19 7 views
26

Przynajmniej w systemach Linux i Solaris, statyczne biblioteki są tak naprawdę tylko zbiorem skompilowanych plików .o umieszczonych w jednym dużym pliku. Podczas kompilowania biblioteki statycznej zwykle flaga -fpic jest pomijana, więc wygenerowany kod zależy od pozycji.Łączenie biblioteki współużytkowanej z biblioteką statyczną: czy biblioteka statyczna musi być kompilowana inaczej niż w przypadku, gdy aplikacja łączyła tę bibliotekę?

Teraz mówię, że moja biblioteka statyczna to B. Zbudowałem ją i otrzymuję wynikowy plik .a, który jest tak naprawdę tylko globusem wszystkich zależnych od pozycji plików .o. Teraz mam wspólną bibliotekę, którą chciałbym zbudować, A, i chcę, żeby statycznie łączyła B. Kiedy buduję A, oczywiście użyję flagi -fpic, aby wygenerować niezależną pozycję kodu. Ale jeśli łączę się z B, czy nie łączę zależne od pozycji i niezależne od pozycji pliki obiektów?

Otrzymuję wiele błędów związanych z relokacją tekstu, chyba że określę również -przypisywanie tekstu i myślę, że to może być przyczyną. Wydaje się, że kiedy kompiluję bibliotekę, naprawdę muszę ją skompilować: razy, wersję wspólną, wersję statyczną i wersję statyczną, która może być używana przez współdzieloną bibliotekę. Czy mam rację? Mógłbym dalej używać -mimpure-text, ale strona man w g ++ mówi, że jeśli to zrobisz, obiekt nie zostanie w końcu udostępniony (nie jest jasne, czy to wszystko jest nieautoryzowane, czy tylko statycznie połączone części, czy ktoś to wie?) .

+0

Pytanie jest poprawnie napisane, "pomija" -fpic w pierwszym akapicie, prowadząc do kodu zależnego od pozycji, a następnie używa go w drugim akapicie, prowadząc do kodu niezależnego od pozycji. –

Odpowiedz

24

Nie musisz używać kodu PIC w obiektach udostępnionych (ponieważ odkryłeś, że możesz użyć opcji -mimpure-text, aby na to zezwolić).

Powiedział, że kod non-PIC we wspólnych obiektach jest bardziej waga ciężka. Z kodem PIC, strony tekstowe w pamięci są po prostu mapowaniem pamięci stron tekstowych na dysku. Oznacza to, że jeśli wiele obiektów korzysta z udostępnionego obiektu, mogą one współużytkować stronę pamięci.

Ale jeśli nie masz kodu PIC, gdy linker ładujący obiekt udostępniony, będzie musiał zastosować poprawki do stron tekstowych. Oznacza to, że każdy proces, który korzysta z udostępnionego obiektu, będzie miał własną unikalną wersję dowolnej strony tekstowej, która ma na sobie poprawkę (nawet jeśli obiekt udostępniony jest ładowany pod tym samym adresem, co kopiowanie przy zapisie, zauważa tylko, że strona była zmodyfikowane, a nie to, że zostało zmodyfikowane w ten sam sposób).

Dla mnie istotną kwestią jest to, czy jednocześnie będzie uruchomionych wiele procesów, które będą ładować obiekt udostępniony. Jeśli tak, to na pewno warto upewnić się, że cały kod w SO jest PIC.

Ale jeśli tak nie jest i tylko jeden proces ma załadowany obiekt wspólny, to nie jest aż tak krytyczny.

+0

Właściwie, jeśli wiesz, że załaduje go tylko jeden proces, czy kompilacja bez użycia picu może przynieść korzyść z wydajności? Z powodu zapisania rejestru. –

+1

@JosephGarvin PIC zużywa rejestr w kodzie 32-bitowym x86, ale nie w kodzie 64-bitowym. Zestaw instrukcji x64 obsługuje adresowanie względne adresowania programu - dane obciążenia, które są bajtami NNNN, są przesunięte względem adresu pamięci instrukcji następnej instrukcji (następnej instrukcji następującej po).Kod PIC w x64 nie wymaga rejestru wskaźnika GOT. – dthorpe

+0

Dzięki za wspaniałe wyjaśnienie! – rkellerm

1

Jako alternatywne podejście, wysyłaj dwie biblioteki: swoją wspólną i statyczne, z którymi łączysz się obok. Powinny poprawnie łączyć się z ostatecznym plikiem wykonywalnym.

3

Wykonuję następujące czynności na etapie łączenia biblioteki wersji wspólnej bibliotekę statyczną: g ++ -shared -o libshared.so -Wl, - whole-archive -fPIC -lstatic -Wl, - no- całe archiwum. Ponieważ -whole-archive łączy każdy obiekt w (liście) statycznych bibliotekach (w postaci libstatic.a). Uważam, że poprzedzanie tego (listą) z -fPIC jest wszystkim, co należy zrobić w OP.

+0

Czy mógłbyś wyjaśnić to dokładniej? – gyro

Powiązane problemy