Le but de cette conversion est de vous offrir un système qui
puisse créer et exécuter aussi bien des programmes a.out
qu'ELF, chaque type de binaire étant capable de trouver les
ensembles de bibliothèques partagées dont il a besoin. Cela demande
par conséquent un peu plus de finesse dans la stratégie de
recherche des bibliothèques que le traditionnel "allons voir dans
/lib
, /usr/lib
et partout où cela a été indiqué par
compilation", qui suffit à beaucoup de systèmes.
Sous Linux, l'esclave responsable de la recherche des bibliothèques se
nomme /lib/ld.so
. Le compilateur et l'éditeur de liens
n'encodent pas leur chemin d'accès absolu dans le programme exécutable
; au lieu de cela, ils mettent le nom de la bibliothèque nécessaire et
le chemin absolu vers ld.so
, et laissent ce dernier terminer
le travail à l'exécution du programme. Cette méthode apporte une
caractéristique importante : les bibliothèques dont un programme a
besoin peuvent être déplacées dans d'autres répertoires sans qu'il
soit nécessaire de recompiler l'application, à condition que l'on
indique à ld.so
ce nouveau répertoire. C'est essentiel pour
l'opération d'interversion de répertoires qui va suivre.
Par corollaire, bien entendu, toute tentative de suppression ou
de déplacement de ld.so
se soldera par l'arrêt immédiat du
fonctionnement de tout programme utilisant des bibliothèques
partagées. En général, ce n'est pas bon, mais pas bon du tout...
En ce qui concerne les binaires ELF, il est fourni un éditeur de liens
dynamiques supplémentaire. Il s'agit de /lib/ld-linux.so.1
:
il effectue exactement le même travail que ld.so
, mais pour
les programmes ELF. Il utilise les mêmes fichiers de support et
outils de configuration que celui-ci (ldd
, ldconfig
, et
/etc/ld.so.conf
).
Le but de la manipulation, donc, est de faire que tous les outils de
développement ELF (compilateurs, fichiers d'en-têtes et bibliothèques)
aillent dans /usr/{bin,lib,include}
; c'est-à-dire là où se
trouvent actuellement ceux pour a.out
, et que tous les outils
a.out
soient déplacés dans /usr/i486-linuxaout/{bin, lib,
include}
. Le fichier /etc/ld.so.conf
contiendra tous les
endroits où les bibliothèques sont susceptibles d'être trouvées, et
ldconfig
est suffisamment intelligent pour faire la distinction
entre ELF et a.out
.
Toutefois, il y a des exceptions, dans quelques cas particuliers.
ld.so
.
Si leurs bibliothèques étaient déplacées, ceux-ci cesseraient
immédiatement de fonctionner. Par conséquent, libc.so*
and libm.so*
doivent rester à leur place dans /lib
, et les versions ELF
ont vues leur numéro majeur incrémenté de manière à pouvoir cohabiter
dans le même répertoire. Egalement, les anciennes bibliothèques X
(antérieures à la version 6) sont bien où elles sont, alors que les
récentes (libX*so.6
) doivent être déplacées. Le déplacement des
anciennes gênerait le fonctionnement des programmes xview
,
et les nouvelles seraient écrasées par leurs versions ELF si elles
restaient à la même place.
Si vous êtes en possession de programmes n'utilisantt pas ld.so
,
nécessitant des bibliothèques autres que celles citées ci-dessus (si
vous savez de quels logiciels il s'agit, vous pouvez les tester à
l'aide de la commande ldd
pour déterminer quelles sont les
bibliothèques nécessaires à leur fonctionnement avant de tout
casser), vous avez deux solutions. La première consiste à extraire
l'archive ELF dans un répertoire temporaire, pour vérifier si votre
précieuse bibliothèque sera écrasée ou non par la nouvelle qui
pourrait porter le même nom. Si c'est le cas, places la version ELF
dans, disons, /usr/i486-linux/lib
au lieu de /lib
.
Assurez-vous que ld.so.conf
contient bien la spécification du
chemin /usr/i486-linux/lib
, puis lancez ldconfig
et tout
ira bien. La seconde solution consiste à recompiler ou vous procurer
une copie récente du programme en question. C'est, en général, une
bonne idée, de toutes façons.
/usr
ou /usr/lib
sont
sur une partition séparée de la racine, vous devez faire
très attention. Il vous faudra peut-être déplacer certaines
bibliothèques afin qu'elles se trouvent quelque part sur la racine,
pour qu'elles puissent être utilisées lors du démarrage du système ou
en mode mono-utilisateur. Identifiez ces programmes et les bibliothèques
dont ils ont besoin (voyez ci-dessus pour les exceptions...), et placez
ces dernières par exemple dans un répertoire /lib-aout
.
mv
et ln
, ainsi que d'autres commandes
essentielles à la manipulation de fichiers (bien que ces deux-là
soient sans doute les seules dont vous pourriez avoir besoin), pourra
vous aider à vous sortir de tout mauvais pas.
/lib/elf
(probablement libc.so.4
et compagnie). Les
applications que vous avez construites avec doivent être recompilées,
et ensuite ce répertoire devra être supprimé. Il n'y a nul besoin du
répertoire /lib/elf
!
/sbin/
quelque_chose et que vous n'avez pas de
répertoire /sbin
, vous trouverez probablement le programme en
question dans /bin
ou /etc/
.
Les paquetages suivants sont disponibles dans le répertoire GCC
des sites miroirs Linux français.
ftp://ftp.ibp.fr/pub/linux/tsx-11/packages/GCC/
.
Les archives suivantes (soit les versions citées ici, soit des
versions plus récentes) sont nécessaires. Téléchargez également toutes
les notes et documentations que vous trouverez, et lisez-les. Les
fichiers s'appellent en général release.
nom_du_paquetage. Ce
conseil s'applique particulièrement si vous récupérez des versions
plus récentes que celles dont nous parlons ici, car les procédures
d'installation peuvent avoir changé.
ld.so-1.7.3.tar.gz
: l'éditeur de liens dynamiques ;
libc-5.0.9.bin.tar.gz
: les images partagées de la
bibliothèque C et sa famille (m
(math), termcap
, gdbm
,
et ainsi de suite) ; ainsi que les versions statiques correspondantes,
et les fichiers d'en-têtes nécessaires pour la compilation de
programmes. Il se pourrait que libc 5.2.quelquechose
sorte
pendant la durée de validité de ce document ; or elle est radicalement
différente de la 5.0.9
. Si vous comptez l'installer, il faudra
vous débrouiller seuls. Nous vous recommandons alors de commencer
par installer quand même la version 5.0.9
, puis l'autre par-dessus :
beaucoup de parties de la première ne sont plus fournies dans la nouvelle,
et leurs canaux de distribution sont encore très incertains...
gcc-2.7.0.bin.tar.gz
: Le compilateur C ELF. Il contient
également un compilateur a.out
qui reconnaît la nouvelle
organisation de l'arborescence ;
binutils-2.5.2l.17.bin.tar.gz
: Les GNU binutils
adaptés à Linux. Ce sont les outils comme gas
, ld
,
strings
, etc. Ils sont indispensables pour que l'environnement
de développement (à commencer par le compilateur C), fonctionne.
Bien... Notez que dans tout ce qui va suivre, lorsque nous disons
"supprimer", cela sous-entend naturellement "faire une
sauvegarde, puis supprimer" :-)
. Notez également que ces
instructions sont destinées aux personnes n'ayant jamais expérimenté
ELF. Ceux qui ont déjà essayé doivent en principe être capable de
s'adapter, le cas échéant. Allons-y !
a.out
:
mkdir -p /usr/i486-linuxaout/bin
mkdir -p /usr/i486-linuxaout/include
mkdir -p /usr/i486-linuxaout/lib
mkdir /lib-aout
ld.so-1.7.3
dans le répertoire où vous placez généralement
le code source, puis lisez le script ld.so-1.7.3/instldso.sh
qu'il contient. Si vous avez vraiment un système Linux standard,
exécutez-le en tapant "sh instldso.sh
",
mais si vous n'êtes pas certain que tout est bien où il faut,
faites l'installation à la main, on n'est jamais trop prudent. Cela
concerne aussi les cas suivants :
zsh
(certaines versions définissent
$VERSION
, ce qui semble tromper instldso.sh
) ;
/lib/elf
vers
/lib
(qui devraient être inutiles, mais vous avez le droit
d'avoir vos propres raisons d'en posséder si vous avez suivi le
développement de ELF).
/etc/ld.so.conf
afin d'y ajouter le
nouveau répertoire /usr/i486-linuxaout/lib
(ainsi que
/lib-aout
si vous en avez besoin). Puis, relancez
"/sbin/ldconfig -v
"pour vérifier qu'il prenne bien en
compte ces nouveaux chemins d'accès.
a.out
de
/usr/*/lib
dans /usr/i486-linuxaout/lib
.
Notez bien que nous avons dit "bibliothèques", et non pas
"tout". Il s'agit des fichiers correspondant aux expressions
lib*.so*
, lib*.sa*
et lib*.a
. Ne commencez pas à
déplacer /usr/lib/gcc-lib
ou faire toute autre ânerie du genre.
/lib
. Ne touchez
pas à libc.so*
, libm.so*
et libdl.so*
. Si vous avez
des liens symboliques vers des bibliothèques X (libX*.so.3*
),
laissez-les également : XView et quelques autres applications peuvent
en avoir besoin. Ne touchez pas à ld.so*
, ld-linux.so*
et
tout autre fichier dont le nom commence par ld
. En ce qui
concerne toutes les autres bibliothèques (s'il vous en reste) :
si votre partition /usr
est sur la racine, mettez-les
dans /usr/i486-linuxaout/lib
. Si /usr
est montée
séparément, mettez-les alors dans /lib-aout
. Puis, lancez
ldconfig -v
.
/usr/lib/ldscripts
s'il existe,
en vue de l'installation des binutils (ce qui le recréera).
ld
et as
(sauf ld86
et as86
) que vous trouverez dans
/usr/bin.
tar
semblent avoir des
problèmes avec les liens symboliques dans le répertoire de destination.
Vous avez alors deux options :
cpio
au lieu de tar
, il n'a pas ce problème.
L'incantation magique, à exécuter depuis le répertoire racine, est :
zcat /votre/repertoire/libc-5.0.9.tar.gz | cpio -iv
cpio
) Avant d'installer les
fichiers de la libc, vous aurez intérêt à faire un tour dans
/usr/include
pour y faire un peu de ménage.
C'est délicat, et pénible. Beaucoup de paquetages (comme
ncurses
) sont installés dans /usr/include
par les
concepteurs de distributions, et ne sont pas fournis avec la
bibliothèque C standard. Sauvegardez toute cette arborescence, et
utilisez tar tzf
pour regarder ce qui se trouve dans les
archives que vous allez installer : supprimez les répertoires qui vont
être recréés, pour partir sur des bases saines. Puis, installez
libc-5.0.9.bin.tar.gz
depuis la racine.binutils
. La commande
"tar -xvzf binutils-2.6.2l.17.bin.tar.gz -C /
" constitue
une excellente méthode pour cette opération.
gcc
que vous utilisiez
auparavant, il se peut que votre système ne soit pas en état de
compiler des programmes en a.out
avant que vous n'installiez le
nouveau compilateur.
/usr/lib/gcc-lib/{i486-linux, i486-linuxelf, i486-linuxaout}/
.
Si vous utilisez un pilote gcc
non standard (comme Gnu ADA),
copiez-le aussi dans un endroit sûr.
Installez alors le paquetage GCC, toujours depuis la racine.
/lib/cpp
, qui est en général, sous Linux, un lien
vers /usr/lib/gcc-lib/i486-linux/
version/cpp
.
Comme l'opération précédente a supprimé toute version de cpp
vers
laquelle ce lien pointait, il va vous falloir le recréer :
$ cd /lib
$ ln -s /usr/lib/gcc-lib/i486-linux/2.7.0/cpp .
utmp
et wtmp
de /var/adm
vers
/var/run
et /var/log
, respectivement. Vous devrez
ajouter quelques liens symboliques en fonction de l'endroit où ils
se trouvent sur votre système, et vous pourrez même avoir à créer
ces répertoires /var/log
et /var/adm
.
Voici la sortie donnée par ls -l
sur un système correctement
installé selon cette nouvelle arborescence :
$ ls -ld /var/adm /var/log /var/run /var/log/*tmp /var/run/*tmp
lrwxrwxrwx 1 root root 3 May 24 05:53 /var/adm -> log/
drwxr-xr-x 9 root root 1024 Aug 13 23:17 /var/log/
lrwxrwxrwx 1 root root 11 Aug 13 23:17 /var/log/utmp -> ../run/utmp
-rw-r--r-- 1 root root 451472 Aug 13 23:00 /var/log/wtmp
drwxr-xr-x 2 root root 1024 Aug 13 23:17 /var/run/
-rw-r--r-- 1 root root 448 Aug 13 23:00 /var/run/utmp
Consultez le document FSSTND pour comprendre toute l'histoire.
a.out
, il est temps
d'installer libc.so 4.7.x. Décompactez l'archive depuis la
racine, vous êtes sans doute maintenant capable d'effectuer cette
opération sans autre explication. Cette étape est bien entendu
facultative.
C'est terminé ! Vous pouvez maintenant effectuer quelques tests simples :
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.0/specs
gcc version 2.7.0
$ gcc -v -b i486-linuxaout
Reading specs from /usr/lib/gcc-lib/i486-linuxaout/2.7.0/specs
gcc version 2.7.0
$ ld -V
ld version cygnus/linux-2.5.2l.14 (with BFD cygnus/linux-2.5.2l.11)
Supported emulations:
elf_i386
i386linux
i386coff
suivis, comme il se doit, par le traditionnel programme "Hello,
world". Essayez de le compiler avec gcc
et gcc -b
i486-linuxaout
, afin de vérifier que les deux formats, ELF et
a.out
, soient correctement gérés.
Voici un vague aperçu des fichiers que vous venez d'installer, qui pourra vous servir de guide pour déterminer une éventuelle erreur, ou les fichiers que vous pouvez effacer.
/lib
ld.so
(a.out) et
ld-linux.so.1
(ELF). Ce peuvent être des liens symboliques, mais
vérifiez dans ce cas que les fichiers vers lesquels ils pointent sont
bel et bien accessibles.
libc.so.4
, libm.so.4
(a.out).
Ce sont des liens symboliques. Vérifiez leur validité.
libc.so.5
, libm.so.5
,
libdl.so.1
, libcurses.so.1
, libtermcap.so.2
, (ELF).
Ce sont, là encore, des liens symboliques.
libc.so.5.0.9
), un lien
symbolique dont le nom correspond au numéro majeur de la version
(libc.so.5
) et un lien symbolique pointant sur tout cela,
sans numéro de version (libc.so
). C'est-à-dire :
lrwxrwxrwx 1 root root 9 May 24 05:52 libc.so -> libc.so.5
lrwxrwxrwx 1 root root 13 Aug 25 12:48 libc.so.5 -> libc.so.5.0.9
-rwxr-xr-x 1 bin bin 562683 May 19 04:47 libc.so.5.0.9
/usr/lib
libbfd.so*
, libdb.so*
, libgdbm.so*
,
bibliothèques partagées ELF. Constituées par trois fichiers selon
l'organisation de liens décrite dans la section précédente.
libbsd.a
, libgmon.a
, libldso.a
, libmcheck.a
,
libieee.a
, libmcheck.a
et un fichier lib*.a
pour
chaque bibliothèque partagée ELF présente dans /lib
et /usr/lib
. Ce sont des bibliothèques statiques ELF.
Celles dupliquant les versions dynamiques ne seront sans doute
pas très utile à beaucoup d'utilisateurs : en ELF, il est possible
de compiler avec gcc -g
en employant les versions dynamiques,
il n'y a donc plus de raison de continuer à génerer des versions
statiques.
a.out
crt0.o
et
gcrt0.o
. Ce sont les premiers fichiers objets à être liés aux
programmes compilés en a.out
, à moins de spécifier une option
contraire.
crt1.o
, crtbegin.o
, crtbeginS.o
, crtend.o
,
crtendS.o
, crti.o
, crtn.o
et gcrt1.o
. Similaires
aux *crt0.o
décrits ci-dessus, mais pour les programmes ELF.
/usr/lib/ldscripts
ld
. Il doit ressembler à ceci :
$ ls /usr/lib/ldscripts/
elf_i386.x elf_i386.xs i386coff.xn i386linux.xbn
elf_i386.xbn elf_i386.xu i386coff.xr i386linux.xn
elf_i386.xn i386coff.x i386coff.xu i386linux.xr
elf_i386.xr i386coff.xbn i386linux.x i386linux.xu
/usr/i486-linux/bin
ar
, as
, gasp
, ld
, nm
, ranlib
,
strip
. Ce sont en réalité des liens symboliques vers les vrais
binutils
, situés dans le répertoire /usr/bin
./usr/i486-linuxaout/bin
as
, l'assembleur a.out
et gasp
, son préprocesseur
de macros.
ar
, ld
, nm
, ranlib
, strip
: liens vers
les binutils
situés dans /usr/bin
.
/usr/i486-linux/lib
ldscripts
est un lien symbolique vers /usr/lib/ldscripts
./usr/i486-linuxaout/lib
lib*.so*
. Images des bibliothèques partagées a.out
,
nécessaires à l'exécution des programmes dans ce format.
lib*.sa
. Ce sont les "stubs" nécessaires pour la compilation
des programmes a.out
utilisant des bibliothèques partagées. Si
vous ne comptez plus compiler de tels programmes, vous pouvez supprimer
ces fichiers.
lib*.a
. Bibliothèques a.out
statiques, nécessaires
pour la compilation de programmes statiques a.out
. Là aussi,
vous pouvez supprimer ces fichiers si vous ne comptez plus effectuer
de telles compilations./usr/lib/gcc-lib/i486-linux/2.7.0
/usr/lib/gcc-lib/i486-linuxaout/2.7.0
a.out
,
et la nouvelle organisation de l'arborescence de fichiers. Si vous
ne comptez plus réaliser de binaires à l'ancien format a.out
,
vous gagnerez environ 4 Mo en le supprimant.... avec un grand sourire.
Toutefois, vous avez encore un shell à disposition, et avec un peu
d'astuce, on peut faire énormément de choses avec ses commandes
internes. Sachez que "echo *
" peut remplacer de manière satisfaisante
ls
, et que "echo >>fichier
" peut servir à ajouter des
lignes dans un fichier. Également, n'oubliez pas que ldconfig
est compilé en statique. Si vous avez déplacé par erreur, disons,
libc.so.4
vers /lib-aout
, vous pouvez faire
"echo "
lib-aout" >>/etc/ld.so.conf ; ldconfig -v/"
pour récupérer la main. Si vous avez déplacé /lib/ld.so
,
vous pouvez peut-être faire "sln /place/idiote/ld.so /lib/ld.so
"
si vous disposez d'une version statique de la commande ln
.
no such file or directory: /usr/bin/gcc
"Fichier ou répertoire inexistant" ... alors que pourtant, vous
savez que ce programme gcc
est là. Cela signifie en général
que l'éditeur de liens dynamiques ELF /lib/ld-linux.so.1
n'est pas installé, ou est illisible pour une raison quelconque. Vous
devez l'avoir mis en place, en principe, vers l'étape 2 de la section
précédente.
not a ZMAGIC file, skipping
vous dit ldconfig
. Vous possédez une ancienne version
de l'ensemble ld.so
, procurez-vous une archive récente.
Là encore, voyez l'étape 2 de la section précédente.
bad address
"Mauvaise adresse" à chaque tentative d'exécution de n'importe quel programme ELF. Vous utilisez une version 1.3.x du noyau, où x<3. Prenez une version à jour, supérieure à 1.3.3, ou utilisez une version 1.2.
_setutent: Can't open utmp file
Ce message apparaît plusieurs fois lorsque vous lancez un xterm
.
Allez lire ce qui est dit à propos du FSSTND vers la fin de la procédure
d'installation.
gcc: installation problem, cannot exec quelque chose: No such file or directory
lors de compilations a.out
("quelque chose" correspond
généralement à cpp
ou cc1
). Soit il s'agit réellement
d'une erreur d'installation, soit vous avez tapé
$ gcc -b -i486-linuxaout
au lieu de
$ gcc -b i486-linuxaout
Notez que le "i486" ne commence pas par un tiret.
Chapitre Suivant , Chapitre Précédent
Table des matières de ce chapitre, Table des matières générale
Début du document, Début de ce chapitre