ghidra
ghidra copied to clipboard
Decompiler: Low-level Error: Could not find op at target address: (code, ...) (AVR)
I have been consistently hitting this issue while reconstructing an AVR sample manually (with 10.2.3, with the code segment "loading" emulating by copying the relevant blocks into a new codebyte segment, which is already present at program import time apparently):
Low-level Error: Could not find op at target address: (code,0x00336b)
The relevant disasm:
byte: 64 e1 ldi R22,0x14
byte: 77 e5 ldi R23,0x57
byte: 8d 5b subi R24,0xbd
byte: 9f 4f sbci R25,0xff
byte: f7 01 movw Z,R15R14
byte: 19 95 eicall
byte: d8 01 movw X,R17R16
byte: 5b 96 adiw X,0x1b
byte: 8d 93 st X+,R24
Another test case:
byte: cf 93 push Ylo
byte: 80 91 27 3a lds R24,DAT_mem_xxxx
byte: 83 30 cpi R24,0x3
byte: a1 f0 brbs FUN_code_xxxa2e,Zflg
byte: 80 91 3f 3c lds R24,BYTE_ARRAY_mem_xxx[...]
byte: 88 23 and R24,R24
byte: 81 f0 brbs LAB_code_00xxx+2,Zflg
byte: c2 e0 ldi Ylo,0x2
byte: c0 93 05 06 sts PORTA_OUTSET,Ylo = ??
byte: e0 91 c0 3c lds Zlo,DAT_mem_xxx0
byte: f0 91 c1 3c lds Zhi,DAT_mem_xxx1
byte: 04 84 ldd R0,Z+0xc
byte: f5 85 ldd Zhi,Z+0xd
byte: e0 2d mov Zlo,R0
byte: 6c e6 ldi R22,0x6c
byte: 77 e3 ldi R23=>DAT_mem_xxxc,0x37
byte: 80 e0 ldi R24,0x0
byte: 19 95 eicall
byte: c0 93 06 06 sts PORTA_OUTCLR,Ylo = ??
byte: cf 91 pop Ylo
byte: 08 95 ret
Gives: Low-level Error: Could not find op at target address: (code,0x002a2e)
Notice the eicall op (see https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/AVR-Options.html EIND handling).
My initial suspicion is that EICALL constructs are not being handled properly, or something else is amiss, since all of these have the common denominator of not being detected by auto-analysis. Many of them have proper push/pop prologues/epilogues and ret/jmp "exits", so I can easily find them manually and force a function to be created in place.
It makes RE tedious and time consuming since it just so happens to be affecting the interesting bits of my sample. The AVR capabilities have come a long way, and I'm happy with being a guinea pig for the improvements. I'm not reliant solely on the decompiler so it isn't a blocking issue per se, but it is definitely causing problems as far as references are involved.
Notes from Wikipedia (memory refresh):
(Rare) models with >128 KiB of ROM have a 3-byte program counter. Subroutine calls and returns use an additional byte of stack space, there is a new EIND register to provide additional high bits for indirect jumps and calls, and there are new extended instructions EIJMP and EICALL which use EIND:Z as the destination address. (The previous IJMP and ICALL instructions use zero-extended Z.)
(Rare) models with >64 KiB of RAM address space extend the 16-bit RAM addressing limits with RAMPX, RAMPY, RAMPZ and RAMPD registers. These provide additional high bits for addressing modes which use the X, Y, or Z register pairs, respectively, or the direct addressing instructions LDS/STS. Unlike ROM access, there are no distinct "extended" instructions; instead the RAMP registers are used unconditionally.
Now, back to Ghidra:
code: 4a 5f subi R20,250
code: 5f 4f sbci R21,0xff
code: 84 e1 ldi R24,0x14
code: 90 e0 ldi R25,0x0
code: 19 95 eicall
Yields:
puVar18 = (undefined2 *)FUN_code_xxxx();
auStack_13 = (undefined [3])0xXXX ;// code segment
(*(code *)CONCAT12(EIND,*puVar18))
(0x14,*(int *)(pbVar15 + 10),*(char *)(*(int *)(pbVar15 + 10) + 2) * 2 + 6);
Seems like this could be easily simplified... the CONCAT(EIND,puVar18) and auStack decompilation is quite obfuscated. Unfortunately I'm not yet familiar enough with the internals of the AVR processor in Ghidra and I'm still relatively new to this particular RE target, but so far it seems many functions that are apparently orphaned (no incoming references) just happen to be the side effect of some issues with call constructs not being properly handled. The segments are there, in this case I manually reconstructed most of the ".text" and I am certain 99% of the sample is both mapped, including EEPROM and memory data extracted and mapped into the right spot.
We really need a complete function sample to diagnose this kind of exception in the decompiler. Assuming the second sample is complete, I loaded it in ghidra-10.2.3 as an AVR8:LE:24:xmega:gcc at address code:2a15, but was still unable to produce the Low-level Error. It seemed to decompile just fine. Please double check that your avr8 .sinc and .slaspec files aren't modified. If that isn't the issue, you could try uploading the output from the "Debug Function Decompilation" action, which is available from a drop-down menu in the upper right corner of the decompiler window, and which will give us more information about what the decompiler is seeing. You should be able to produce this output even though the window is only displaying "Low-level Error: ...".
Do you have an e-mail address I could get back to?
I recommened creating a private GitHub repo and inviting us to it.