GNU/Linux >> Tutoriels Linux >  >> Linux

Suppression des bibliothèques partagées Linux

Si vous enveloppez votre partie privée dans un espace de noms anonyme, alors ni std::abs ni private_function peut être vu dans la table des symboles :

namespace{
#include<cmath>
  float private_function(float f)
  {
    return std::abs(f);
  }
}
extern "C" float public_function(float f)
{
        return private_function(f);
}

compilation (g++ 4.3.3):

g++ -shared -o libtest.so test.cpp -s

inspection :

# nm -DC libtest.so
         w _Jv_RegisterClasses
0000200c A __bss_start
         w __cxa_finalize
         w __gmon_start__
0000200c A _edata
00002014 A _end
000004a8 T _fini
000002f4 T _init
00000445 T public_function

Juste pour noter qu'Ulrich Drepper a écrit un essai concernant (tous ?) les aspects de l'écriture de bibliothèques partagées pour Linux/Unix, qui couvre le contrôle des symboles exportés parmi de nombreux autres sujets.

C'était très pratique pour expliquer clairement comment exporter uniquement les fonctions d'une liste blanche à partir d'une bibliothèque partagée.


Votre utilisation de l'attribut de visibilité par défaut et -fvisibility=hidden doit être complétée par -fvisibility-inlines-hidden.

Vous devriez également oublier d'essayer de masquer les exportations stdlib, consultez ce bogue GCC pour savoir pourquoi.

De plus, si vous avez tous vos symboles publics dans un en-tête spécifique, vous pouvez les envelopper dans #pragma GCC visibility push(default) et #pragma GCC visibility pop au lieu d'utiliser des attributs. Cependant, si vous créez une bibliothèque multiplateforme, jetez un œil à Contrôle des symboles exportés des bibliothèques partagées pour une technique permettant d'unifier votre stratégie d'exportation DLL Windows et DSO Linux.


Donc la solution que nous avons pour l'instant est la suivante :

test.cpp

#include <cmath>
#include <vector>
#include <typeinfo>

struct private_struct
{
    float f;
};

float private_function(float f)
{
    return std::abs(f);
}

void other_private_function()
{
    std::vector<private_struct> f(1);
}

extern "C" void __attribute__ ((visibility ("default"))) public_function2()
{
    other_private_function();
}

extern "C" float __attribute__ ((visibility ("default"))) public_function1(float f)
{
    return private_function(f);
}

exporte.version

LIBTEST 
{
global:
    public*;
local:
    *;
};

compilé avec

g++ -shared test.cpp -o libtest.so -fvisibility=hidden -fvisibility-inlines-hidden -s -Wl,--version-script=exports.version

donne

00000000 A LIBTEST
         w _Jv_RegisterClasses
         U _Unwind_Resume
         U std::__throw_bad_alloc()
         U operator delete(void*)
         U operator new(unsigned int)
         w __cxa_finalize
         w __gmon_start__
         U __gxx_personality_v0
000005db T public_function1
00000676 T public_function2

Ce qui est assez proche de ce que nous recherchons. Il y a cependant quelques pièges :

  • Nous devons nous assurer que nous n'utilisons pas le préfixe "exporté" (dans cet exemple simple "public", mais évidemment quelque chose de plus utile dans notre cas) dans le code interne.
  • De nombreux noms de symboles se retrouvent toujours dans la table de chaînes, qui semble être due à RTTI, -fno-rtti les fait disparaître dans mes tests simples, mais c'est une solution plutôt nucléaire.

Je suis heureux d'accepter toutes les meilleures solutions que quelqu'un propose !


Linux
  1. Erreur lors du chargement des bibliothèques partagées libcrypto.so.1.1 – OpenSSL [Réparer]

  2. Bibliothèques graphiques Linux 3D ?

  3. Exemples de commandes ipcs sous Linux

  4. Comment afficher toutes les bibliothèques partagées utilisées par les exécutables sous Linux ?

  5. Bibliothèque partagée dynamique C++ sous Linux

Comment gérer les bibliothèques dynamiques et statiques sous Linux

Communication inter-processus sous Linux :stockage partagé

Détecter les bibliothèques partagées obsolètes en mémoire avec UChecker

Comment répertorier les bibliothèques partagées utilisées par les exécutables sous Linux

Pourquoi les bibliothèques partagées sous Linux sont-elles exécutables ?

Ubuntu Linux - VHDX partagé