Compilação do GCC - de onde vem o símbolo __stack_chk_fail@GLIBC_2.4?

1

Estou usando o GCC 4.7.2 do pacote devtoolset no CentOS 5 (CentOS 5 porque precisamos compatibilidade com antigos Linuxes e GCC 4.7 porque otimiza melhor que 4.4).

Há um símbolo que impede que meus binários sejam executados no RHEL4: __stack_chk_fail@GLIBC_2.4 . Está incluído apenas em alguns programas C ++ e o sinalizador -fno-stack-protector não ajuda.

Aqui está o programa mínimo que reproduz o problema (mas o mesmo usando stdio.h funciona):

#include <iostream>
int main(int argc, char *argv[]) {
    for(int i=0; i < argc; i++)
        std::cout << " " << argv[i];
    return 0;
}

Quando compilado com otimização ( -O / -O2 ), ele referencia __stack_chk_fail .

$ g++ -fno-stack-protector -O2 foo.cc
$ readelf -s a.out | grep chk
    15: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@GLIBC_2.4 (5)
   105: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@@GLIBC_2

Alguma idéia de por que esse símbolo chegou aqui e como se livrar dele?

Apenas no caso, readelf de saída total e gcc -v são aqui .

Editar: Esse problema pode ser específico do Red Hat Developer Toolset 1.1. Com o compilador padrão do CentOS __stack_chk_fail não é referenciado.

    
por marcin 12.09.2013 / 01:48

2 respostas

2

Este símbolo vem de libstdc++_nonshared.a .

Diferente do GCC da distro, o GCC do devtoolset possui uma parte não compartilhada do libstdc ++. libstdc ++. portanto, o GCC 4.7 é um script de vinculador que usa libstdc ++ do GCC 4.1 e funções extras vinculadas estaticamente:

$ cat /opt/centos/devtoolset-1.1/root/usr/lib/gcc/i386-CentOS-linux/4.7.2/libstdc++.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-i386)
INPUT ( /usr/lib/libstdc++.so.6 -lstdc++_nonshared )

Depois de recompilar libstdc++_nonshared.a com o protetor de pilha desativado, o programa final pode ser executado no RHEL4.

    
por 28.09.2013 / 21:14
0

Ele vem com o GLibC. Construa contra um GLibC mais antigo.

Você pode dizer ao GCC 4.7 para emitir código de montagem otimizado e depois montar e vincular isso em um sistema antigo

    
por 12.09.2013 / 01:56