- Mon Oct 06, 2014 12:38 pm
#1320
0ff wrote:In IDA Pro, you can simply run the attached commands as python, they will automatically name the functions.
You need to load the dump at 0x40000000 and you need the IDA CPU Plugin for xtensa CPUs (which is the great work of https://github.com/themadinventor/ida-xtensa).
Have fun reading the ROM Code then
There seems to be a bug in that plugin, as it turns out. I hope the maintainer of it reads this.
As i was poking around with accessing the pin registers directly, i first went by the disassembly of the gpio_output_set() function in the ROM, as done by IDA Pro. This is what it generated:
Code: Select allROM:40004CD0 gpio_output_set: ; CODE XREF: gpio_init+26p
ROM:40004CD0 ; gpio_intr_test+17p ...
ROM:40004CD0 l32r a6, dword_40000FC4
ROM:40004CD3 memw
ROM:40004CD6 s32i a2, a6, 4
ROM:40004CD9 memw
ROM:40004CDC s32i a3, a6, 8
ROM:40004CDF memw
ROM:40004CE2 s32i a4, a6, 0x10
ROM:40004CE5 memw
ROM:40004CE8 s32i a5, a6, 0x14
ROM:40004CEB ret.n
ROM:40004CEB ; End of function gpio_output_set
Now, the dword at 0x40000FC4 holds the value 0x60000200. Therefore i was assuming that this function accesses the registers at 0x60000204, 0x60000208, 0x60000210 and 0x60000214. However, as soon as i wrote anything to it, the chip rebooted with an exception.
Then i checked eagle_soc.h, and there the base address is given as 0x60000300. And of course, using 0x60000304, 0x60000308, 0x60000310 and 0x60000314 works as expected. I then posetd in the GCC thread to ask jcmvbkbc if he sees anything wrong with the code, or if there is something going on that missed, since he seems to be the resident Xtensa expert here. He couldn't find anything wrong with the bytecode.
Now, tinhead was so kind to check what would show up in the Xtensa IDE, compared to a disassembly by IDA, when accessing stuff. So he went and compiled the following code:
Code: Select allvoid user_init(void)
{
WRITE_PERI_REG(0x60000300, 0);
WRITE_PERI_REG(0x60000200,0);
}
Now, in IDA that comes out as:
Code: Select all.text:00000004 dword_4 .int 0x60000200 ; DATA XREF: user_init+2r
.text:00000008
.text:00000008 ; =============== S U B R O U T I N E =======================================
.text:00000008
.text:00000008 ; Attributes: noreturn
.text:00000008
.text:00000008 user_init:
.text:00000008 movi.n a2, 0
.text:0000000A l32r a3, dword_4
.text:0000000D memw
.text:00000010 s32i a2, a3, 0
.text:00000013 memw
.text:00000016 s32i.n a2, a3, 0
.text:00000018 ret.n
.text:00000018 ; End of function user_init
Now, as you can see that can't be right. One is accessing 0x6000.0300, the other 0x6000.0200, but in both cases the store's are working on a 0 offset to the dword having 0x6000.0200.
Next, doing:
Code: Select all WRITE_PERI_REG(0x60000400, 0);
WRITE_PERI_REG(0x60000500,0);
produced the exact same disassembly in IDA. However, in the Xtensa IDE, the disassembly looks like this:
Code: Select allDisassembly of section .text:00000000 <user_init-0x4>:
0: 60000200 ...`00000004 <user_init>:
#include "ets_sys.h"
#include "osapi.h"
#include "user_config.h"void user_init(void)
{
4: 020c movi.n a2, 0
6: fffe31 l32r a3, 0 <user_init-0x4> (also 60000200)
WRITE_PERI_REG(0x60000400, 0);
9: 0020c0 memw
c: 806322 s32i a2, a3, 0x200
WRITE_PERI_REG(0x60000500,0);
f: 0020c0 memw
12: c06322 s32i a2, a3, 0x300
}
15: f00d ret.n
So here we have the store's using the proper offsets to get the right address. The IDA plugin disassembled them wrongly.
Would be great if that can be fixed, since that affects quite a lot of of stuff when going through a siassembly in IDA.
Greetings,
Chris