Liaison de symboles à des adresses fixes sous Linux
Question
Comment peut-on relier (certains) symboles à des adresses fixes spécifiques à l’aide de GNU ld afin que le fichier binaire puisse toujours être exécuté normalement sous Linux (x86)? Il n’y aura pas d’accès à ces symboles, mais leurs adresses sont importantes.
Par exemple, j'aurais la structure suivante:
struct FooBar {
Register32 field_1;
Register32 field_2;
//...
};
struct FooBar foobar;
J'aimerais lier foobar
l'adresse 0x76543210, mais liez normalement les bibliothèques standard et le reste de l'application. L’application utilisera alors l’adresse de foobar, mais ne fera pas référence à la mémoire (éventuellement non existante) située derrière elle.
La raison de cette demande est que cette même source peut être utilisée sur deux plates-formes: Register32
sur la plate-forme native, il peut simplement s'agir d'un volatile uint32_t
, mais sous Linux uint32_t
, il s'agit d'un objet C ++ de même taille. comme operator=
qui définit par exemple <=>, qui utilisera ensuite l'adresse de l'objet et enverra une requête à un cadre de communication avec cette adresse (et les données) pour effectuer l'accès effectif sur un matériel distant. L'éditeur de liens s'assurerait ainsi que les <=> champs de la structure font référence aux & Adresses & Quot; & Quot;.
La solution
La suggestion de litb d'utiliser --defsym symbol=address
fonctionne, mais est un peu lourde lorsque vous avez quelques dizaines d'instances similaires à mapper. Cependant, --just-symbols=symbolfile
fait juste l'affaire. Il m'a fallu un certain temps pour connaître la syntaxe de symbolfile
, qui est
symbolname1 = address;
symbolname2 = address;
...
Les espaces semblent être nécessaires, sinon ld
rapports file format not recognized; treating as linker script
.
Autres conseils
Essayez-le avec
--defsym symbol=expression
Comme avec ceci:
gcc -Wl,--defsym,foobar=0x76543210 file.c
Et faites de foobar dans votre code une déclaration extern:
extern struct FooBar foobar;
Cela semble prometteur. Cependant, c’est une mauvaise idée de faire une telle chose (à moins que vous sachiez vraiment ce que vous faites). Pourquoi en avez-vous besoin?
Je vais vous donner le conseil ... GNU LD peut le faire (en supposant que les bibliothèques système n’aient pas besoin de l’adresse que vous voulez). Il vous suffit de créer votre propre script de l'éditeur de liens au lieu d'utiliser celui généré automatiquement par le compilateur. Lisez la page de manuel de ld. En outre, la création d’un script d’éditeur de liens pour un logiciel complexe n’est pas une tâche facile lorsque vous impliquez également le GLIBC.