2013-07-03 3 views
4

Учитывая программуСтатические местные жители в методах и ELF OS ABI

$ cat main.cpp 
#ifndef WITH_LOCAL_STATIC 
static int y = 0; 
#endif 

class X { 
    public: 
    void foo() { 
#ifdef WITH_LOCAL_STATIC 
     static int y = 0; 
#endif 
     ++y; 
    } 
}; 

int main() { 
    X().foo(); 
    return 0; 
} 

Составитель двумя различными способами:

$ g++ main.cpp -o global 
$ g++ main.cpp -DWITH_LOCAL_STATIC -o local 

я получаю два различных бинарных форматов:

$ file local 
local: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x8d8e998601e44115b5fa6c0e71f3ed97cb13a0bd, not stripped 
$ file global 
global: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x3481ba7c6969ed9d1bd1c8ce0f052d574023d488, not stripped 
Может

кого-нибудь объясните, почему я получаю ELFOSABI_LINUX в одном случае, но ELFOSABI_NONE в другом? Компилятор - gcc 4.7.2

Фон в том, что в моей среде загрузчик отклоняет исполняемые файлы, которые не являются ELFOSABI_NONE.

ответ

0

Формат GNU/Linux заменил формат файла объекта System V, и ваш gcc полагает, что минимальная OS/ABI, в которой исполняемый файл может быть запущен, - это GNU/Linux.

Это обычно происходит, когда ваша программа имеет символы, тип которых STT_GNU_IFUNC (гну расширений, что обозначает косвенную функцию), и эти символы, как правило, приходят из Glibc. Когда вы ввели локальную статическую переменную gcc, добавленную (более) код в блок перевода, чтобы обрабатывать ее инициализацию и уничтожение (по строкам _ZZZ__static_initialization_and_destruction_iii), и именно здесь были задействованы соответствующие части glibc.

Прежде всего, вам лучше следовать советам в этом вопросе: How to avoid STT_GNU_IFUNC symbols in your binary?

Во-вторых, я должен сказать, что на моей машине, как старый GCC 4.4 и новый лязг 3,4 генерировать глобальный и местные двоичные файлы как Стандартные ELF SYSV, так что на вашем тестовом примере отсутствует больше соответствующих битов и частей, или вы, возможно, используете настраиваемый и встроенный gcc, нестандартный линкер или нестандартный glibc.

Больше путей, которые вы можете продолжить исследовать, как вы в конечном итоге с этими косвенными функциями GNU в бинарном:

  • Run nm на бинарный файле и определить косвенные символы, они должны иметь i типа. (См. Ниже.)
  • Создайте карту ссылок и/или сборку и проведите эти косвенные символы с особенностями вашего кода.
  • Кроме того, проверьте, если местонахождение Glibc с ldd -v $(type -p gcc) точек вам нестандартным LibC

я - Для файлов формата PE это указывает на то, что символ находится в разделе специфичны для реализации библиотек DLL , Для файлов формата ELF это означает, что символ является косвенной функцией. Это расширение GNU для стандартного набора типов символов ELF. Он указывает символ>, который, если ссылка на перемещение не оценивается по его адресу, но должна быть вызвана во время выполнения. Выполнение во время выполнения вернет значение, которое будет использоваться при перемещении.

https://sourceware.org/binutils/docs/binutils/nm.html

Смежные вопросы