Lo que hago
Cuando escribo bibliotecas compartidas para Linux, tiendo a prestar atención a las reubicaciones, la visibilidad de los símbolos, GOT/PLT, etc.
Cuando corresponde, estoy tratando de evitar llamar a los stubs PLT cuando las funciones de la misma biblioteca se llaman entre sí. Por ejemplo, supongamos que un objeto compartido proporciona dos funciones públicas: foo()
y bar()
(Cualquiera de los dos puede ser llamado por el usuario). los bar()
función, sin embargo, también llama foo()
. Así que lo que hago en este caso es esto:
- Definir
_foo()
y_bar()
funciones que tienen visibilidad privada. - Definir
foo()
ybar()
alias débiles para_foo()
y_bar()
respectivamente.
De esa forma, el código en el objeto compartido nunca usa símbolos débiles. Solo invoca funciones locales, directamente. por ejemplo, cuando _bar()
es invocado, llama _foo()
directamente.
Pero los usuarios no son conscientes de _*
funciones y utilice siempre los alias débiles correspondientes.
Cómo lo hago
En Linux, esto se logra usando la siguiente construcción:
extern __typeof (_NAME) NAME __attribute__(weak, alias("_NAME"));
El problema
Desafortunadamente, esto no funciona para OS X. No tengo un conocimiento profundo de OS X o sus formatos binarios, así que investigué un poco y encontré algunos ejemplos de funciones débiles (como esta), pero esas no funcionan del todo. lo mismo que puede tener un símbolo débil, pero no un símbolo débil que sea un alias para la función local de DSO.
Solución posible…
Por ahora, acabo de desactivar esta función (que se implementa mediante macros) para que todos los símbolos sean globales y tengan visibilidad predeterminada. La única manera que se me ocurre para lograr lo mismo por ahora es tener todos _foo
funciones con visibilidad privada y tienen correspondiente foo
funciones con visibilidad predeterminada y llamando a sus contrapartes “ocultas”.
¿Una mejor manera?
Eso, sin embargo, requiere que se cambie una buena parte del código. Por lo tanto, preferiría no ir allí a menos que realmente no haya otra manera.
Entonces, ¿cuál es la alternativa más cercana a OS X o la forma más fácil de obtener la misma semántica/comportamiento?
Rob_vH
En OS X, las llamadas realizadas dentro de la biblioteca son automáticamente llamadas directas y no pasan por el stub dyld. La evidencia del hecho es que si desea poder inyectar funciones alternativas para atender una llamada, deberá usar interponible para forzar el acceso indirecto a los símbolos y forzar la ejecución de la llamada a través de los stubs de dyld. De lo contrario, de manera predeterminada, las llamadas locales serán directas y no incurrirán en la sobrecarga de ejecutarse a través de dyld.
Por lo tanto, su optimización en Linux ya es el comportamiento predeterminado y no se necesita el alias.
Aún así, si desea hacer esto solo para simplificar el código compatible con su plataforma, aún puede crear los alias. Solo necesita usar “weak_import” o “weak” (si desea combinar) como su nombre de atributo.
externo tipo de (_NOMBRE) NOMBRE __atributo(importación_débil, alias(“_NOMBRE”));
Referencia de Apple sobre enlaces débiles: Símbolos de marcado para enlaces débiles
Referencia de Apple sobre el enlace de tiempo de ejecución de Mach-O: Alcance y Tratamiento de las Definiciones de Símbolos
¿Su objetivo es simplemente evitar la sobrecarga de llamar a través de stubs PLT cuando realiza una llamada a un símbolo dentro de la misma biblioteca? ¿Has confirmado que el enlazador no se está ocupando de esto por ti?
– bdash
20 de septiembre de 2013 a las 9:54
Tengo entendido que lo que busca es el comportamiento predeterminado para las bibliotecas compartidas en OS X. La única documentación que he encontrado que se acerca a hacer esto explícito es el
ld
sección de la página del manual sobre el-interposable_list
argumento. Establece que las llamadas a los símbolos dentro de un módulo serán llamadas directas a menos que ese símbolo esté marcado como interponible, en cuyo caso se haría a través de un stub dyld.– bdash
20/09/2013 a las 18:32
Deberías leer esto: glandium.org/blog/?p=2764
– aet
6 de marzo de 2014 a las 2:42
Suena como una optimización prematura para mí.
– jcoffland
17/04/2014 a las 23:19
@NigelNquande No, ese sitio no es para programación a nivel de código a menos que sea Automator, Applescript, etc. Principalmente solo ayuda para el uso de Mac. Fuente: Su recorrido de 2 minutos dice esto.
– sudo
27 de mayo de 2014 a las 3:41