es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

molde y lld no vinculando correctamente con libc

He estado escribiendo algo de ensamblador x64 en Linux, exactamente lo que es no es relevante, y me he encontrado con un problema extraño. En mi código ensamblador, he declarado “printf” como una etiqueta externa, y lo llamo utilizando la Convención de Llamada en C de Linux x64. Las partes relevantes se ven así:

extern printf

segment .rodata
    fmt db "%lld", 0x0a, 0x00

segment .text

mov     rsi, rax ; i64 que quiero imprimir
mov     rdi, fmt ; puntero a la cadena de formato
call    printf

Ensamblado usando “nasm -f elf64 file.asm”, obtengo un archivo objeto correcto. Al enlazar con GNU ld, “ld -o file -lc file.o”, obtengo un ejecutable que funciona correctamente y produce la salida esperada. Hasta aquí todo bien.

La parte extraña viene cuando intento hacer lo mismo con mold y lld. Para empezar, ninguno sabe dónde encontrar libc de antemano. Esto está bien; pregunté a GCC dónde encontrar libc (“gcc –print-file-name libc.so” – o “libc.a”, mi sistema tiene ambos y ambos en el mismo directorio), la respuesta es “/usr/lib”. Así que intento enlazar de nuevo mis archivos objeto con mold y lld, de esta manera.. “mold/ld.lld -o file -L/usr/lib -lc file.o”.. y ambos enlazan sin reportar errores. Pero cuando ejecuto los binarios generados, ambos provocan un segfault. Aún no he investigado la versión de ld de LLVM, pero metí la versión de mold en gdb y descubrí que el segfault ocurre porque el código “dentro de la implementación printf de libc” realiza un salto a “0x00…00”.

Mi pregunta es simple: ¿qué está saliendo mal y cómo lo arreglo? Ambos son enlazadores muy reputados, así que estoy seguro de que el problema soy yo, pero no está claro qué es lo que estoy haciendo mal. He intentado investigar este problema, pero en mi investigación algo superficial, no pude encontrar ningún caso de alguien más que haya tenido un problema similar, o al menos ninguno en el que lo hayan resuelto públicamente. ¿Hay algunas banderas que me falten? ¿No es “/usr/lib” el lugar correcto para buscar? Agradecería cualquier ayuda.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí probablemente esté relacionado con la forma en que mold y lld manejan la vinculación con libc. Específicamente, parece que estos enlazadores pueden estar utilizando una versión o implementación diferente de libc a la que estás utilizando con GNU ld. Esto podría explicar por qué el código dentro de la implementación printf de libc está saltando a la dirección 0x00…00, ya que podría estar tratando de acceder a datos o funciones que no están presentes en la versión de libc que están utilizando mold o lld.

    Para solucionar este problema, es posible que debas asegurarte de que mold y lld estén enlazando con la misma versión de libc que estabas utilizando con GNU ld. Puedes hacer esto especificando la ruta completa hacia la versión de libc que deseas utilizar, en lugar de confiar en la versión predeterminada del sistema. Por ejemplo:

    mold/ld.lld -o archivo /usr/lib/libc.so.6 archivo.o
    

    Esto enlazará con la versión específica de libc ubicada en /usr/lib/libc.so.6, en lugar de confiar en la versión predeterminada proporcionada por el sistema. Es posible que también debas especificar opciones o indicadores adicionales del enlazador para asegurarte de que los símbolos y funciones correctos estén siendo enlazados.

    También es posible que haya otros problemas con tu código ensamblador o configuración del enlazador que estén causando problemas. Para solucionarlos, es posible que desees intentar utilizar un depurador como gdb para examinar el código ensamblador generado o el ejecutable y buscar errores o comportamientos inesperados. Además, podría ser útil consultar documentación o buscar ayuda de otros expertos en el campo para ayudar a diagnosticar y resolver cualquier problema.

Comments are closed.