6.10. De gereedschapsketen aanpassen
Nu de laatste C-bibliotheken zijn geïnstalleerd, is het tijd om de toolchain aan te passen zodat deze elk nieuw gecompileerd programma zal koppelen aan deze nieuwe bibliotheken.
/tools/bin/{ld,ld-oud}
/tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-oud}
/tools/bin/{ld-nieuw,ld}
/tools/bin/{ld,ld-oud}
/tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-oud}
/tools/bin/{ld-nieuw,ld}
Maak eerst een back-up van de /gereedschap linker, en vervang deze door de aangepaste linker die we in hoofdstuk 5 hebben gemaakt. We zullen ook een link maken naar zijn tegenhanger in /tools/$(uname -m)-pc-linux-gnu/bin:
mv mv mv
ln
-v
-v
-v
mv mv mv
ln
-sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld
-sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld
Wijzig vervolgens het GCC-specificatiebestand zodat het naar de nieuwe dynamische linker verwijst. Door simpelweg alle instanties van "/tools" te verwijderen, zouden we het juiste pad naar de dynamische linker moeten hebben. Pas ook het specs-bestand aan zodat GCC weet waar de juiste headers en Glibc-startbestanden te vinden zijn. A dorst opdracht bereikt dit:
gcc-dumpspecificaties | sed -e 's@/tools@@g' \
-e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
-e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
`dirname $(gcc --print-libgcc-bestandsnaam)`/specs
gcc-dumpspecificaties | sed -e 's@/tools@@g' \
-e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
-e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
`dirname $(gcc --print-libgcc-bestandsnaam)`/specs
Het is een goed idee om het specificatiebestand visueel te inspecteren om te controleren of de beoogde wijziging daadwerkelijk is aangebracht.
Het is op dit punt absoluut noodzakelijk om ervoor te zorgen dat de basisfuncties (compileren en koppelen) van de aangepaste toolchain werken zoals verwacht. Voer hiervoor de volgende gezondheidscontroles uit:
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log readelf -l a.out | grep ': /lib'
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log readelf -l a.out | grep ': /lib'
Er mogen geen fouten zijn en de uitvoer van de laatste opdracht is (rekening houdend met platformspecifieke verschillen in dynamische linkernaam):
[Programma-interpreter aanvragen: /lib64/ld-linux-x86-64.so.2]
[Programma-interpreter aanvragen: /lib64/ld-linux-x86-64.so.2]
Merk op dat op 64-bits systemen / lib is de locatie van onze dynamische linker, maar is toegankelijk via een symbolische link in /lib64.
Note
Op 32-bits systemen zou de interpreter /lib/ld-linux.so.2 moeten zijn.
Note
Op 32-bits systemen zou de interpreter /lib/ld-linux.so.2 moeten zijn.
Zorg er nu voor dat we zijn ingesteld om de juiste startbestanden te gebruiken:
grep -o '/usr/lib.*/crt[1in].*geslaagd' dummy.log
grep -o '/usr/lib.*/crt[1in].*geslaagd' dummy.log
De uitvoer van het laatste commando zou moeten zijn:
/usr/lib/../lib/crt1.o geslaagd
/usr/lib/../lib/crti.o geslaagd
/usr/lib/../lib/crtn.o geslaagd
/usr/lib/../lib/crt1.o geslaagd
/usr/lib/../lib/crti.o geslaagd
/usr/lib/../lib/crtn.o geslaagd
Controleer of de compiler naar de juiste headerbestanden zoekt:
grep -B1 '^ /usr/include' dummy.log
grep -B1 '^ /usr/include' dummy.log
Deze opdracht zou de volgende uitvoer moeten retourneren:
#include <...> zoeken begint hier:
/ Usr / include
#include <...> zoeken begint hier:
/ Usr / include
Controleer vervolgens of de nieuwe linker wordt gebruikt met de juiste zoekpaden:
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
Verwijzingen naar paden met componenten met '-linux-gnu' moeten worden genegeerd, maar anders zou de uitvoer van het laatste commando moeten zijn:
ZOEK_DIR("/usr/lib") ZOEK_DIR("/lib")
ZOEK_DIR("/usr/lib") ZOEK_DIR("/lib")
Zorg er vervolgens voor dat we de juiste libc gebruiken:
grep "/lib.*/libc.so.6 " dummy.log
grep "/lib.*/libc.so.6 " dummy.log
De uitvoer van het laatste commando zou moeten zijn:
poging om /lib/libc.so.6 te openen is gelukt
poging om /lib/libc.so.6 te openen is gelukt
Zorg er ten slotte voor dat GCC de juiste dynamische linker gebruikt:
grep vond dummy.log
grep vond dummy.log
De uitvoer van de laatste opdracht zou moeten zijn (rekening houdend met platformspecifieke verschillen in dynamische linkernaam):
gevonden ld-linux-x86-64.so.2 op /lib/ld-linux-x86-64.so.2
gevonden ld-linux-x86-64.so.2 op /lib/ld-linux-x86-64.so.2
Als de uitvoer niet verschijnt zoals hierboven weergegeven of helemaal niet wordt ontvangen, is er iets ernstig mis. Onderzoek en herhaal de stappen om erachter te komen waar het probleem zit en corrigeer het. De meest waarschijnlijke reden is dat er iets mis is gegaan met de aanpassing van het specificatiebestand. Eventuele problemen moeten worden opgelost voordat u doorgaat met het proces.
Zodra alles correct werkt, ruimt u de testbestanden op:
rm -v dummy.c a.out dummy.log
rm -v dummy.c a.out dummy.log