Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

270
Vistas
Comportamiento de GCC para funciones débiles no resueltas

Considere el siguiente programa simple:

 __attribute__((weak)) void weakf(void); int main(int argc, char *argv[]) { weakf(); }

Al compilar esto con gcc y ejecutarlo en una PC con Linux, falla. Cuando se ejecuta en ARM CM0 (arm-none-eabi-gcc), el enlazador reemplaza el símbolo indefinido por un salto a la siguiente instrucción y un nop.

¿Dónde está documentado este comportamiento? ¿Hay formas posibles de cambiarlo a través de las opciones de la línea de comandos? He revisado las documentaciones de GCC y LD , no hay información al respecto.

Sin embargo, si reviso el documento del compilador ARM, esto se explica claramente .

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

man nm

Estaba leyendo algunos documentos y me encontré con una cita relacionada con esto:

 man nm

dice:

"V"
"v" El símbolo es un objeto débil. Cuando un símbolo definido débil se vincula con un símbolo definido normal, el símbolo definido normal se utiliza sin error. Cuando se vincula un símbolo indefinido débil y el símbolo no está definido, el valor del símbolo débil se convierte en cero sin error. En algunos sistemas, las mayúsculas indican que se ha especificado un valor predeterminado.

"W"
"w" El símbolo es un símbolo débil que no se ha etiquetado específicamente como un símbolo de objeto débil. Cuando un símbolo definido débil se vincula con un símbolo definido normal, el símbolo definido normal se utiliza sin error. Cuando se vincula un símbolo indefinido débil y el símbolo no está definido, el valor del símbolo se determina de manera específica del sistema sin errores. En algunos sistemas, las mayúsculas indican que se ha especificado un valor predeterminado.

nm es parte de Binutils, que GCC usa bajo el capó, por lo que debería ser lo suficientemente canónico.

Luego, ejemplo en su archivo fuente:

C Principal

 __attribute__((weak)) void weakf(void); int main(int argc, char *argv[]) { weakf(); }

hacemos:

 gcc -O0 -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c nm main.out

que contiene:

 w weakf

y por lo tanto es un valor específico del sistema. Sin embargo, no puedo encontrar dónde se define el comportamiento por sistema. No creo que puedas hacer nada mejor que leer el código fuente de Binutils aquí.

v se fijaría en 0, pero eso se usa para variables indefinidas (que son objetos): ¿Cómo hacer que los enlaces débiles funcionen con GCC?

Entonces:

 gdb -batch -ex 'disassemble/rs main' main.out

da:

 Dump of assembler code for function main: main.c: 4 { 0x0000000000001135 <+0>: 55 push %rbp 0x0000000000001136 <+1>: 48 89 e5 mov %rsp,%rbp 0x0000000000001139 <+4>: 48 83 ec 10 sub $0x10,%rsp 0x000000000000113d <+8>: 89 7d fc mov %edi,-0x4(%rbp) 0x0000000000001140 <+11>: 48 89 75 f0 mov %rsi,-0x10(%rbp) 5 weakf(); 0x0000000000001144 <+15>: e8 e7 fe ff ff callq 0x1030 <weakf@plt> 0x0000000000001149 <+20>: b8 00 00 00 00 mov $0x0,%eax 6 } 0x000000000000114e <+25>: c9 leaveq 0x000000000000114f <+26>: c3 retq End of assembler dump.

lo que significa que se resuelve en el PLT .

Luego, dado que no entiendo completamente PLT, verifico experimentalmente que se resuelve en la dirección 0 y segfaults:

 gdb -nh -ex run -ex bt main.out

Supongo que sucede lo mismo en ARM, también debe configurarlo en 0.

over 4 years ago · Santiago Trujillo Denunciar

0

En ARM con gcc este código no me funciona (prueba en armv7 con gcc Debian 4.6.3-14+rpi1). Parece que la cadena de herramientas del compilador arm tiene un comportamiento diferente.

No encontré documentación útil para este comportamiento. Parece que el valor débil es NULL si no está definido en el momento del enlace.

Así que te sugiero que lo pruebes:

 if (weakf == NULL) printf ("weakf not found\n"); else weakf();
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda