Почему имена констант появляются в скомпилированных двоичных файлах / общих библиотеках? - PullRequest
1 голос
/ 15 апреля 2020

Я создаю библиотеку в CMake, которая имеет некоторые константы в частном заголовке. Когда я компилирую в Release config, например, -O3 -DNDEBUG и запускаю strings на выходе, эти константы появляются на выходе. Имена этих констант раскрывают некоторые детали реализации, которые я хотел бы скрыть, если это возможно.

Вот минимальный пример проекта, который демонстрирует проблему:

private.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)

Сборка и показ вывод строки:

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

Есть ли какой-то дополнительный переключатель, который я могу использовать, чтобы скрыть эту информацию?

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

MY_CONSTANT - это переменная, которой нужно место в памяти. Процесс компиляции для C включает создание промежуточного объектного файла перед его связыванием в окончательный исполняемый файл ELF. Переменная должна отслеживаться и ей должен быть присвоен конечный адрес и ссылки перемещены на последнем этапе ссылки.

В качестве артефакта этого для файла объекта, который ссылается на MY_CONSTANT, создается таблица символов его имя. По умолчанию он не удаляется компоновщиком при создании окончательного исполняемого файла.

Вы можете вручную удалить эту таблицу символов, выполнив strip --strip-unneeded ./a.out.

Обратите внимание, что это не имеет ничего общего с dynamici c таблица символов, которая используется для связи во время выполнения. Приложения по-прежнему смогут связываться и звонить get_mask(void)

0 голосов
/ 15 апреля 2020

Я только что понял это. Когда вы добавляете ключевое слово static перед константой, вы все равно можете получить доступ к значению из lib.c и связанных с ним исходных файлов, но его имя больше не отображается в двоичном файле strings dump

* 1006. * private.h

#pragma once

const int MY_CONSTANT = 42;

Результат:

$ strings libmylib.so | grep MY
MY_CONSTANT
MY_CONSTANT

с ключевым словом static:

private.h

#pragma once 

static const int MY_CONSTANT = 42;

Результат:

$ strings libmylib.so | grep MY

В gcc вы также можете отключить символы отладки, используя -g0

...