procesadores procesador cortex arquitectura linux x86 arm cpu-architecture

linux - procesador - Convertir archivo de objeto a otra arquitectura



arquitectura arm pdf (7)

Estoy tratando de usar un Wifi-Dongle con una Raspberry Pi. El proveedor del dongle proporciona un controlador de Linux que puedo compilar con éxito en la arquitectura ARM, sin embargo, un archivo objeto, que viene con el controlador, fue precompilado para una arquitectura x86, lo que hace que el enlazador falle.

Sé que sería mucho más fácil compilar ese archivo (bastante grande) de nuevo, pero no tengo acceso al código fuente.

¿Es posible convertir ese archivo objeto de una arquitectura x86 a una arquitectura ARM?

¡Gracias!


¿Tal vez el archivo solo contenga un volcado binario del firmware wifi? Si es así, no necesita traducción de instrucciones y se puede realizar una conversión utilizando objcopy.

Puedes usar objdump -x file.o y ver si hay algún código ejecutable real dentro del archivo obj o si solo son datos.


En teoría, sí. Hacerlo en un controlador de kernel real sin acceso al código fuente será difícil.

Si tenía un ensamblaje de alta calidad del archivo objeto, y el código en el archivo objeto se "comportó bien" (utilizando convenciones de llamadas estándar, sin código de auto modificación), entonces podría traducir automáticamente las instrucciones X86 en instrucciones de armado. Sin embargo, es probable que no tenga un desarmado de alta calidad. En particular, puede haber partes del archivo de objeto que no podrá clasificar correctamente como código o datos que realizan el des-ensamblaje de descenso recursivo normal. Si malinterpretas datos como código, se traducirá al código ARM, en lugar de copiarse como está, y tendrá los valores incorrectos. Eso probablemente hará que el código no funcione correctamente.

Incluso si tiene suerte y puede clasificar correctamente todas las direcciones en el archivo objeto, existen varios problemas que lo harán tropezar:

  1. Las convenciones de llamada en X86 son diferentes a las convenciones de llamada en ARM. Esto significa que deberá identificar los patrones relacionados con las convenciones de llamadas X86 y cambiarlos para usar las convenciones de llamadas ARM. Esta es una reescritura no trivial.

  2. La interfaz de hardware en ARM es diferente que en X86. Deberá entender cómo funciona el controlador para traducir el código. Eso requeriría una capa sustancial de compatibilidad de hardware X86 o ingeniería inversa de cómo funciona el controlador. Si puede realizar una ingeniería inversa del controlador, entonces no necesita traducirlo. Podrías escribir una versión de brazo.

  3. El núcleo interno APIS es diferente entre ARM y X86. Deberá comprender esa diferencia y cómo traducirla. Eso probablemente no sea trivial.

  4. El núcleo de Linux utiliza un mecanismo de "alternativas", que reescribirá el código de la máquina de forma dinámica cuando el código se cargue por primera vez en el kernel. Por ejemplo, en las máquinas de procesador único, las cerraduras a menudo se reemplazan por no-operaciones para mejorar el rendimiento. Las instrucciones como "popcnt" se reemplazan con llamadas a funciones en máquinas que no lo admiten, etc. Su uso en Kernel es extremadamente común. Esto significa que hay una buena probabilidad de que el código en el objeto es "no se comporta bien", de acuerdo con la definición dada anteriormente. Tendría que verificar que el archivo objeto no usa ese mecanismo o encontrar la forma de traducir los usos del mismo.

  5. X86 usa un modelo de memoria diferente que ARM. Para traducir "de manera segura" el código X86 a ARM (sin introducir condiciones de carrera), deberá introducir vallas de memoria después de cada acceso a la memoria. Eso daría como resultado un rendimiento MUY MALO en un chip ARM. Averiguar cuándo necesita introducir vallas de memoria (sin hacerlo en todas partes) es un problema EXTREMADAMENTE difícil. Los intentos más exitosos en ese tipo de análisis requieren sistemas de tipo personalizado, que no tendrá en el archivo objeto.

Su mejor apuesta (la ruta más rápida hacia el éxito) sería intentar realizar una ingeniería inversa de lo que hace el archivo objeto en cuestión, y luego simplemente reemplazarlo.


No hay una forma razonable de hacer esto. Póngase en contacto con el fabricante y pregunte si pueden proporcionar el código correspondiente en código ARM, ya que x86 es inútil para usted. Si no pueden hacerlo, tendrá que encontrar un proveedor diferente del hardware [que tiene una versión ARM, o fuente totalmente abierta, de todos los componentes], o del proveedor del software [suponiendo que haya otro fuente de eso].


Puede traducir el ensamblaje x86 manualmente instalando binutils x86 GNU y desensamblar el archivo objeto con objdump. Probablemente, algunas direcciones diferirán pero deberían ser directas.


Sí, definitivamente podrías hacer una traducción binaria estática. El desmontaje de x86 es doloroso, aunque si se compiló desde un nivel alto, entonces no es tan malo como podría ser.

¿Realmente vale la pena el esfuerzo? Podría intentar un simulador de conjunto de instrucciones en su lugar. ¿Has hecho un análisis de la cantidad de instrucciones utilizadas? Se requieren llamadas al sistema, etc.

¿Hasta dónde has llegado tan lejos en el desmontaje?


Si tiene acceso a IDA con descompilador Hex-Rays, puede (con algo de trabajo) descompilar el archivo objeto en código C y luego tratar de recompilarlo para ARM.


Um, no, me parece una pérdida de tiempo. El controlador de Wi-Fi es complejo, y usted dice que este archivo de objeto problemático es ''grande''. Mucho dolor de traducir, y la posibilidad de depuración exitosa es delgada o nula. Además, cualquier parámetro que pase entre este archivo de objeto único y el resto del sistema no se traduciría directamente entre x86 y ARM.