Código de brazo / pulgar para parches de firmware ... ¿Cómo decir que el ensamblador / enlazador de GCC a BL a ADDR absoluto?

StackOverflow https://stackoverflow.com/questions/9348709

  •  27-10-2019
  •  | 
  •  

Pregunta

Estoy tratando de escribir un mod de firmware (para el firmware existente, para el cual no tengo código fuente) todo el código del pulgar.

¿Alguien tiene alguna idea de cómo hacer esto? gcc as (Gas) ensamblador:Usar BL sin tener que calcular manualmente las compensaciones, cuando BL'en alguna función existente (no en mi código ... pero sé que su dirección)

Actualmente, si quiero usar BL ... Tengo que: Volver a volver a mi código. Figurado y agregar todos los bytes que resultarían de ensamblar todas las instrucciones anteriores en la función que estoy escribiendo -Add La dirección de comienzo de mi función a eso (especifico La dirección inicial de lo que estoy escribiendo, en el script de enlazador) y luego susto la dirección de la función firmefunc que quiero llamar

Todo esto ... solo para calcular el desplazamiento ... para poder escribir unbl Offset ... ¿para llamar a una función de firmware existente? Y si cambio cualquier código antes de ese BL, ¡tengo que hacerlo de nuevo manualmente!
Ver.. esta es la razón por Quiero aprender a usar BX Bien ... en lugar de BL

Además, no entiendo del BX. Si uso BX para saltar a una dirección absoluta, ¿tengo que aumentar la dirección real en 1, cuando calaba el código del pulgar del código del pulgar (para mantener el byte LSB 1) ... y la CPU sabrá que es el código del pulgar?

¿Fue útil?

Solución

Gran edición:

Cambiar la respuesta basada en lo que he aprendido recientemente y una mejor comprensión de la pregunta

En primer lugar, no sé cómo decirle al enlazador que genere un BL en una dirección que sea una dirección codificada y que en realidad no en este código. Puede intentar acumular un archivo ELF que tenga etiquetas y tal, pero ficticio o ningún código, no sé si eso engañará al enlazador o no. Tendría que modificar el script de enlazador también. no vale la pena.

Tu otra pregunta que fue generada de este:

Brazo/pulgar: usando BX en código de pulgar, para llamar a una función de pulgar o para saltar a una instrucción de pulgar en otra función

Para ramificar esto funciona bien:

LDR R6, =0x24000
ADD R6, #1       @ (set lsb to 1)
BX R6

o guarda una instrucción y simplemente haz esto

LDR R6, =0x24001
BX R6

Si desea ramificar el enlace y sabe la dirección y está en modo pulgar y desea llegar al código del pulgar entonces

  ldr r6,=0x24001
  bl thumb_trampoline
  ;@returns here
  ...
.thumb_func
thumb_trampoline:
  bx r6

Y casi exactamente lo mismo si está comenzando en modo ARM, y desea obtener el código de pulgar en una dirección que ya conoce.

  ldr r6,=0x24001
  bl arm_trampoline
  ;@returns here
  ...
arm_trampoline:
  bx r6

Debe saber que puede destrozar R6 de esta manera (asegúrese de que R6 no esté guardando algún valor que sea utilizado por algún código que llamara este código).

Lo siento mucho engañarte con la otra respuesta, podría jurar que Mov Lr, PC atrajo el LSBIT como un modo, pero no lo hace.

Otros consejos

La respuesta aceptada logra el objetivo deseado, pero para abordar la respuesta exactamente como se le solicita, puede usar la directiva .EC para asociar un valle constante con un símbolo, que luego se puede usar como un operando para las instrucciones. Esto tiene al ensamblador sintetizar el trampolín si/cuando es necesario:

equ myFirmwareFunction, 0x12346570
.globl _start
        mov r0, #42
        b   myFirmwareFunction

Que genera el siguiente ensamblaje [1

01000000 <_start>:
 1000000:   e3a0002a    mov r0, #42 ; 0x2a
 1000004:   eaffffff    b   1000008 <__*ABS*0x12346570_veneer>

01000008 <__*ABS*0x12346570_veneer>:
__*ABS*0x12346570_veneer():
 1000008:   e51ff004    ldr pc, [pc, #-4]   ; 100000c <__*ABS*0x12346570_veneer+0x4>
 100000c:   12346570    data: #0x12345670

Si el valor inmediato está lo suficientemente cerca de la PC que el desplazamiento se ajustará en el campo inmediato, entonces se omite Verneer (Trampoline) y obtendrá una instrucción de sucursal única a la dirección constante especificada.

1] Uso de la cadena de herramientas CodeSortery (2009q1) con:arm-none-eabi-gcc -march=armv7-a -x assembler test.spp -o test.elf -Ttext=0x1000000 -nostdlib

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top