Je construis une bibliothèque dans CMake qui a des constantes dans un en-tête privé. Lorsque je compile dans la configuration Release, par exemple -O3 -DNDEBUG et que je lance strings sur la sortie, ces constantes apparaissent dans la sortie. Les noms de ces constantes révèlent des détails d'implémentation que j'aimerais cacher si possible.

Voici un exemple de projet minimal qui illustre le problème:

privé.h

#pragma once

const int MY_CONSTANT = 42;

lib.c

#include "private.h"

extern int get_mask(void)
{
  return MY_CONSTANT ^ 3;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(dummylib)

add_library(mylib SHARED lib.c)

Construire et afficher la sortie des chaînes:

$ mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . --config Release -- VERBOSE=1 && strings libmylib.so | grep MY
MY_CONSTANT

Puis-je utiliser un commutateur supplémentaire pour masquer ces informations?

1
ijustlovemath 15 avril 2020 à 23:24

2 réponses

Meilleure réponse

Je viens de le comprendre. Lorsque vous ajoutez le mot clé static devant la constante, vous pouvez toujours accéder à la valeur de lib.c et des fichiers sources associés, mais son nom n'apparaît plus dans le vidage du binaire strings

privé.h

#pragma once

const int MY_CONSTANT = 42;

Résultat:

$ strings libmylib.so | grep MY
MY_CONSTANT
MY_CONSTANT

Avec le mot clé static:

privé.h

#pragma once 

static const int MY_CONSTANT = 42;

Résultat:

$ strings libmylib.so | grep MY

Dans gcc, vous pouvez également désactiver les symboles de débogage à l'aide de -g0

0
ijustlovemath 15 avril 2020 à 21:12

MY_CONSTANT est une variable qui a besoin d'une place en mémoire. Le processus de liaison de compilation pour C implique la création d'un fichier objet intermédiaire avant de le lier dans l'exécutable ELF final. La variable doit être suivie et avoir son adresse finale attribuée et les références déplacées dans la dernière étape du lien.

Comme un artefact de ceci, une table de symboles est créée pour le fichier objet qui référence MY_CONSTANT en utilisant son nom. Par défaut, cela n'est pas ignoré par l'éditeur de liens lors de la création de l'exécutable final.

Vous pouvez supprimer manuellement cette table de symboles en exécutant strip --strip-unneeded ./a.out.

Notez que cela n'a rien à voir avec la table des symboles dynamiques qui est utilisée pour la liaison lors de l'exécution. Les applications pourront toujours s'associer et appeler get_mask(void)

2
Mikel Rychliski 15 avril 2020 à 20:47