Имена функций в библиотеках

Тема в разделе "WASM.UNIX", создана пользователем Zlyden, 4 июл 2010.

  1. Zlyden

    Zlyden New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    49
    Как сделать так, чтобы компилятор не оставлял имена функций в библиотеке, если это не нужно? Недавно скомпилировал библиотеку для серверной защиты и вскрыл ее текстовым редактором, и сразу нашел имена всех используемых функций. Проблема в том, что их в релизе быть не должно. Почему-то компилятор оставляет имена функций, несмотря на отсутствие отладочной информации и то, что эти функции не выставлены в экспорт.
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Это информация о символах из секции '.symtab'. Удаляется командой strip filename.
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Zlyden
    Динамический импорт используйте.
     
  4. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Clerk
    это unix, у них там нет API функций )
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    K10
    Аа точно, раздел не посмотрел. Тогда не знаю.
     
  6. Zlyden

    Zlyden New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    49
    Mika0x65
    Не помогло. Применял strip со всеми возможными параметрами, бесполезно.
    В итоге в .so остается перечень функций и глобальных переменных, в той же секции, что и расшаренные функции, при этом имена расшаренных хранятся в обычном формате, а нерасшаренных - _ZX$name$v, где X - цифра от 1 до 16, может повторяться, как в _Z4ratev
     
  7. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    запакуйте
     
  8. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Zlyden
    А эти переменные объявлены как static? В Linux все, что не static попадает в секции '.symtab'/'.dynsym'.
     
  9. Zlyden

    Zlyden New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    49
    Нет, не статичные. Объявил static, и они из списка пропали. А вот с функциями мне пока ничего не удалось, пробовал по-разному.
    Если это поможет:
    .o компилируются с параметрами -pipe -m32 -O2 -fPIC -fomit-frame-pointer -ffast-math -falign-loops=2 -falign-jumps=2 -falign-functions=2 -fno-strict-aliasing -fstrength-reduce -I../sdks
    .so компилируются с параметрами -pipe -m32 -O2 -fPIC -fomit-frame-pointer -ffast-math -falign-loops=2 -falign-jumps=2 -falign-functions=2 -fno-strict-aliasing -fstrength-reduce -shared -m32
     
  10. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Zlyden
    С -фиями static не работает? Должен быть тот же эффект:

    //Not visible
    static int f()
    {
    return 0;
    }

    //Visible
    int g()
    {
    return 0;
    }

    И где именно видны эти ф-ии? В таблице символов после strip?
     
  11. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    Тоже недавно разбирался с этой проблемой, только как я понял надо убрать лишнее из so ака dll, а не либы (.a \ .lib в винде).
    Чтобы экспортировать только нужные символы в шаред либу (и отбрасывался мертвый код) длжны соблюдаться несколько условий, если одно не выполнено - молча не заработает, делается примерно так:
    g++ -O2 -Wl,-x,-gc-sections,-retain-symbols-file=syms -fpic -shared -fdata-sections -ffunction-sections -o out.so input.cpp
    где syms - файл в котором через строчку указываются экспортируемые символы (аналог .def в винде)
    если линковать другие либы, то как они собраны тоже будет влиять и может навалиться мусора от них (причем даже если их не видно в экспорте не значит что их нет)
    Вобщем все это крайне не порадовало, весь линукс (все дистрибутивы) собран фактически криво и мертвый код не удаляется. Сам линкер мутный и добиться результата было сложно и до конца так и не добился.
     
  12. Zlyden

    Zlyden New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    49
    Mika0x65
    Пробовал объявлять функции со static, единственное отличие - вместо _ZX$name$v теперь пишется _ZLX$name$v.
    Натравил на него readelf, выяснил, что это секция .dynstr (естественно, ее удаление при помощи strip ни к чему хорошему не приведет). Что меня удивило, так обнаружение в том же файле восьми секций debug_*, хотя компилировал без -g (осмотрел Makefile). Сейчас попробовал отладить с этой "релизной" библиотекой - все признаки дебаг-информации, даже бряки на нерасшаренные функции ставятся.
    Все перепроверил, скомпилировал вручную (обычно компилировал при помощи make) командами без необязательных параметров, дебаг информация пропала, имена остались. Опытным путем нашел, что дебаг-информация появляется от параметра -ffast-math.
    semen
    Спасибо, но ваш метод не помог
     
  13. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    гцц такой гцц
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну dlopen, dlsym и проч у них есть) Правда, не знаю, поддерижвается ли импорт по номеру.
     
  15. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Zlyden
    Странно, только что собрал delme.c:
    Код (Text):
    1. int f()
    2. {
    3.         return 0;
    4. }
    5.  
    6. static int g()
    7. {
    8.         return 0;
    9. }
    Собирал вот так: 'cc delme.c -ffast-math -shared', затем 'strip a.out'. objdump -T:
    Код (Text):
    1. a.out:     file format elf32-i386
    2.  
    3. DYNAMIC SYMBOL TABLE:
    4. 00000000  w   DF *UND*  00000023  GLIBC_2.0   __deregister_frame_info
    5. 00000000  w   D  *UND*  00000000              __gmon_start__
    6. 000004cc g    DF .fini  00000000  Base        _fini
    7. 00000000  w   DF *UND*  0000003a  GLIBC_2.0   __register_frame_info
    8. 000015f4 g    D  *ABS*  00000000  Base        __bss_start
    9. 0000160c g    D  *ABS*  00000000  Base        _end
    10. 0000046c g    DF .text  0000000a  Base        f
    11. 000015f4 g    D  *ABS*  00000000  Base        _edata
    12. 00000000  w   DF *UND*  0000015a  GLIBC_2.1.3 __cxa_finalize
    13. 000002d0 g    DF .init  00000000  Base        _init
    Т.е. ф-ия g() в .dynsym не попала.
    Код (Text):
    1. $ cc -v
    2. Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.6/specs
    3. Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,f77 --disable-libgcj --host=i386-redhat-linux
    4. Thread model: posix
    5. gcc version 3.4.6 20060404 (Red Hat 3.4.6-4)
    А если собрать минимальный тестовый пример, то g() все равно остается?
     
  16. Zlyden

    Zlyden New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    49
    gcc предустановленный.
    Код (Text):
    1. Using built-in specs.
    2. Target: x86_64-linux-gnu
    3. Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    4. Thread model: posix
    5. gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
    Mika0x65
    В .dynsym у меня ее и так нет, она присутствует в .dynstr. Скомпилировал пример через gcc, все как положено, g на выходе в .dynstr отсутствует. Забыл сказать, что я собираю через g++.
     
  17. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Zlyden
    .dynstr -- просто секция, куда скидываются все строки, принадлежащие .dynsym (может не только ей, точно не знаю). Т.е. какой-то символ из .dynsym ссылается на эту строку. Вопрос в том, почему он туда вообще попал, если ф-ия объявлена как static.

    Не понял два момента:
    1. Это происходит всегда, если собирать с помощью g++ (и на тестовом примере тоже)?
    2. Это происходит и в случае gcc, но не происходит на тестовом примере?
     
  18. Zlyden

    Zlyden New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    49
    Mika0x65
    Большое спасибо, разобрался. Дело в том, все эти функции были в отдельном .cpp, а когда я их перебросил в main, они сразу из списка исчезли (естественно, при помощи static).

    А что касается вопросов, то всегда итог одинаковый, хоть с gcc, хоть g++. Единственная разница - формат имен этих функций разный (при gcc $name$, а g++ _ZX$name$v)
     
  19. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Zlyden
    Странно, что оно вообще собралось -- static также ограничивает область видимости ф-ии файлом, в котором она определена. Т.е. если main находится в другом файле, то эти ф-ии просто не будут видны из него. Поэтому подозреваю, что в .dynsym символ попадал как неопределенный.