2011-01-14 12 views
6

¿Hay alguna manera con gcc y binutils de GNU para marcar algunas funciones de modo que generen un error en el tiempo de enlace, si se usan? Mi situación es que tengo algunas funciones de biblioteca que no eliminé por razones de compatibilidad con los binarios existentes, pero quiero asegurarme de que ningún binario recién compilado intente hacer uso de las funciones. No puedo usar los atributos de gcc en tiempo de compilación porque el código ofensivo está ignorando mis encabezados y detectando la presencia de las funciones con un script configure y prototipando ellos mismos. Mi objetivo es generar un error de tiempo de enlace para los scripts configure incorrectos para que dejen de detectar la existencia de las funciones.Generando error de tiempo de enlace para funciones obsoletas

Editar: .. Una idea sería utilizar para especificar el montaje incorrecto .type de los puntos de entrada sea compatible con el enlazador dinámico pero generan errores de enlace cuando se trata de vincular nuevos programas?

Respuesta

0

La mejor manera de generar un error de tiempo de enlace para las funciones en desuso que no desea que las personas usen es asegurarse de que las funciones obsoletas no estén presentes en las bibliotecas, lo que las hace una etapa más allá de 'obsoleta'.

Tal vez pueda proporcionar una biblioteca auxiliar con la función en desuso; los réprobos que no prestarán atención pueden vincularse con la biblioteca auxiliar, pero las personas en general no utilizarán la biblioteca auxiliar y, por lo tanto, no usarán las funciones. Sin embargo, todavía lo está llevando más allá de la etapa 'en desuso'.

Obtener una advertencia de tiempo de enlace es complicado. Claramente, GCC lo hace para alguna función (mktemp() y otros), y Apple ha advertido a GCC si ejecuta un programa que usa gets(). No sé lo que hacen para que eso suceda.


A la luz de los comentarios, creo que es necesario ir hacia el problema fuera en tiempo de compilación, en lugar de esperar hasta el tiempo de enlace o en tiempo de ejecución.

Los atributos del CCG incluyen (en el manual de GCC 4.4.1):

error ("message") 

Si se utiliza este atributo en una declaración de función y una llamada a una función de este tipo se no eliminan a través de código muerto eliminación u otras optimizaciones, se diagnosticará un error que incluirá el mensaje. Esto es útil para el tiempo de compilación comprobando, especialmente junto con __builtin_constant_p y las funciones en línea donde no es posible verificar los argumentos de la función en línea mediante extern char [(condición)? 1: -1]; trucos. Si bien es posible dejar la función indefinida y, por lo tanto, invocar un error en el enlace, al usar este atributo se diagnosticará el problema anteriormente y con la ubicación exacta de la llamada incluso en presencia de funciones en línea o cuando no se emite información de depuración.

warning ("message") 

Si se utiliza este atributo en una declaración de función y una llamada a una función de este tipo es no se elimina a través de la eliminación de código muerto o otras optimizaciones, una advertencia que incluirá mensajes serán diagnosticados. Esto es útil para comprobar en tiempo de compilación , especialmente junto con __builtin_constant_p y las funciones en línea. Si bien es posible definir la función con un mensaje en .gnu.advertencia * sección, cuando se usa este atributo, el problema se diagnosticará antes y con la ubicación exacta de la llamada, incluso en presencia de funciones en línea o cuando no esté emitiendo información de depuración.

Si los programas de configuración ignoran los errores, simplemente se rompen. Esto significa que el nuevo código no se pudo compilar utilizando las funciones, pero el código existente puede seguir utilizando las funciones en desuso en las bibliotecas (hasta que sea necesario recompilarlo).

+0

Las advertencias se pueden hacer con el 'nota .gnu.warning', pero No conozco un equivalente para generar errores. Desafortunadamente, si bien su solución es la mejor, no satisface mis necesidades de combinar tanto un ABI en desuso como vincular nuevas aplicaciones. –

+0

@R ..: suficiente. ¿Es justo decir que desea una copia de las bibliotecas instaladas; desea que las aplicaciones compiladas previamente (que pueden estar usando la interfaz en desuso) continúen ejecutándose; ¿Desea que las nuevas aplicaciones compiladas que usan la interfaz obsoleta no se vinculen? Si es así, y si los detectores de configuración detectarán las funciones obsoletas, ¿cómo planea que la gente arregle las cosas para que el código termine enlazando con las interfaces modernas (no desaprobadas)? –

+0

No hay una nueva interfaz de reemplazo; tratar de usar estas interfaces obsoletas es simplemente dañino, y el comportamiento correcto es no usarlas en absoluto.Lamentablemente, no tengo control sobre el software defectuoso que está tratando de usarlos, y aunque probablemente logre que los mantenedores arreglen nuevas versiones, los usuarios podrían estar intentando compilar versiones antiguas por un buen tiempo. –

0

Una idea podría ser generar una biblioteca de código auxiliar que tenga estos símbolos pero con propiedades inesperadas.

  • quizás crear objetos que tienen el nombre de las funciones, por lo que el enlazador en la fase de configuración podría se quejan de que los símbolos no son compatibles
  • crear funciones que tienen una dependencia "dont_use_symbol_XXX" que nunca se resolvió
  • o falso .a un archivo con un índice global que tendría sus funciones, pero donde los miembros .o en el archivo tienen un formato incorrecto
2

FreeBSD 9.x hace algo muy cercano a lo que quiera con el ttyslot() Func ción. Esta función no tiene sentido con utmpx. El truco es que solo hay versiones no predeterminadas de este símbolo. Por lo tanto, ld no lo encontrará, pero rtld encontrará la definición versionada cuando se ejecuta un binario antiguo. No sé qué sucede si un viejo binario tiene una referencia no versionada, pero probablemente sea sensato si solo hay una definición.

Por ejemplo,

__asm__(".symver hidden_badfunc, [email protected]_1.0"); 

Normalmente, habría también una versión por defecto, como

__asm__(".symver new_badfunc, [email protected]@MYLIB_1.1"); 

oa través de una versión de scripts compatible con Solaris, pero el truco es no agregar una.

Normalmente, la directiva asm está envuelta en una macro.

El truco depende de las extensiones de GNU para definir versiones de símbolos con la directiva de ensamblador .symver, por lo que probablemente solo funcione en Linux y FreeBSD. Los scripts de versión compatibles con Solaris solo pueden expresar una definición por símbolo.

Más información: .symver Directiva en info gas, Ulrich Drepper de "Cómo escribir bibliotecas compartidas", la confirmación que ttyslot obsoleto() en http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845

+0

¿Podría explicar mejor cómo funciona esto o proporcionar un enlace? Parece que podría satisfacer mis necesidades. –

+0

@R .. Agregué más información en una edición. – jilles

Cuestiones relacionadas