Has anybody come across a list of ARM & THUMB instructions that cause deviation from the linear instruction stream?
I've been trying to figure out gdb-stub single stepping using software interrupts, and in single stepping you need to find
the next instruction(s) where the next breakpoint instruction needs to be set.
There are three cases:
1) current instruction doesn't change the execution path. Next instruction is the next word.
2) current instruction is a jump. The operand defines the next instruction address
3) current instruction is conditional branch. One possible next instruction is the next word, the other possible
instruction address is defined by the operand. (That includes conditional add with PC as the target, and the like).
To implement single stepping, I need to tell those cases apart and figure out how to find out the possible branching address.
I could go through manuals of numerous processors instruction by instruction and maybe I'd be done within the next couple of years,
or I could find a list of instructions to check, or a paper that explains how to "decode" the instructions in a useful way.
Also, there doesn't seem to be lots of sources of ARM gdb servers or stubs around that use software breakpoints.
I think a good way might be:
check condition code
if it's 1 1 1 1 then specials
else normal
check bits 27 -25 (with both specials and normal)
then apply table if instruction subset contains several instructions
This way the huge amount of instructions is split into 16 subsets some of them only having a couple of instructions.
(NOTE: the floating point and vector instructions are in the special instructions - and there are lots of them.)
And if that's still far too much, I'll put them in a hash-table! That should, frigging, do it!
It would really be excellent, if ARM provided the instruction set as an XML file.
No matter which path you take, make sure you create some kind of automation script; it's tedious to do the actual code and table by hand.
Perl is very good for processing text-files (because of the excellent RegEx). It's currently my preferred choice, especially because you don't have to wait forever for it to compile.
I've been using awk, sed, sort and geany's regex + hand editing first. Then I load the file as CSV into LibreOffice Calc and do some editing there too. It's also tedious to go through the instructions (499 ARM instructions, I don't dare to think about Thumb instructions yet) and assign a handler to them - what handlers do I need and which handler to which instruction.
I'm not eager to crash-learn Perl at this point.
Oh, and I committed new versions of the text file and spreadsheet of the ARM instructions.
All the instructions are (I really hope) there.
The 16-bit thumb would be fairly short. I don't know how many instructions the 32-bit thumb provides.
There's a picture in this document, which gives you a quick overview: http://community.arm.com/docs/DOC-7034
Perl is very much C-like, but you don't have to learn it if the other tools can do what you need.
The hard part in Perl is probably the RegEx. The rest looks very much like C.
Generated 'raw' thumb instruction file the same way I created the ARM instruction file (all thumb instructions
should be there - both 16- and 32-bit) and it has 521 instructions.
And there are still 13 'V<op>'-kind of instructions. When they are expanded to real instructions, I guess 20 - 30 instructions more giving about 550 Thumb instructions.
Wish me luck and long life.
That's a lot more than I expected; but don't the thumb2 instructions share space with the instructions you already processed?
(I always had the impression that the Cortex-A7 was using the Thumb2 architecture, but I most likely need some correction here).
Oh, and ... of course: "Good Health, Strong Body, Clear Mind and Many Years".
I'm not sure what you mean by "...share space with the instructions you already processed".
They are re-using the instruction bits. You can't tell if it's ARM instruction or thumb instruction without checking the 'T'-bit in the CPSR.
VST1<c>.<size> <list>, [<Rn>{:<align>}]{!}
VST1<c>.<size> <list>, [<Rn>{:<align>}], <Rm>
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
(The site does something funny to the hand-formatted text. The editor seems to treat some stuff as tables - although misformatted.)
I think, for a bit pattern of the thumb instruction, there is an ARM instruction to match it that has nothing to do with the thumb instruction, and vice versa.
That is: a separate table is needed for Thumbs.
From the manual:
ARMv7 contains two main instruction sets, the ARM and Thumb instruction sets. The two instruction sets differ in how instructions are encoded: • Thumb instructions are either 16-bit or 32-bit, and are aligned on a two-byte boundary. 16-bit and 32-bit instructions can be intermixed freely.
ARMv7 contains two main instruction sets, the ARM and Thumb instruction sets.
The two instruction sets differ in how instructions are encoded:
• Thumb instructions are either 16-bit or 32-bit, and are aligned on a two-byte boundary. 16-bit and 32-bit
instructions can be intermixed freely.
Alright, you gave me excellent news today.
I did not expect the Cortex-A7 to support the ARM instruction set. I was only expecting it to support Thumb2.
So this day just got better.
... Yes, I know that there's a table-bug, but I've found out if paste the text into my text-editor (eg. text-only, no formatting), then re-copy and finally paste it into one of the JIVE-editors, it works better.
Each of the JIVE editors have several bugs. Some won't let the caret move past the # symbol, some will not let the caret move past an empty line, some does not recognize the Delete key, and some finds it amusing to remove a space now and then.
I know this has been reported to the authors, but I'm not sure they're able to fix it, so I've chosen to live with it and re-edit until my documents look the way I want them. Hey, we've got more than 80 characters per line.
And I've seen the train coming ... hey wait, it's some other light at the end of the tunnel...
It looks like the chapter 4 of the ARMv7-A/R ARM gives a good starting point for figuring out about the handler functions.
This is getting "interesting".
I generated the masks and data from the excel, then I exported the data (only mask data, no instruction names) as .csv.
Then I run sort and then uniq.
The result was 475 lines. The data before uniq was 498 lines.
=> there are 23 lines (instructions) dropped.
Run uniq -cd and searched the non-unique instruction data (added the instructions at the ends of lines):
I hope it's not very complicated to tell apart the instructions with the same data.
There sure will be the same number of masks or more data than masks. If you had more masks than data, you would have a problem.
It's expected that you have shared masks as well. For instance, if you take the 'singles' instruction group, you'd have something like WFI and WFE sharing the same mask, but they have different data. These instructions do not take any parameters.
Those are the data bits. And they are shared.
I managed to find the instructions and the way to tell them apart though, so all's well now.
I just noticed that I've been struggling with the ARM instruction set for a month!
And now I think I've finally tamed the ARM instruction set. (Although surprises have appeared before...)
Back to C-coding.
I think I'll return to the Thumb-instruction set later, and see if I get at least something working with the ARM instruction set first.
Also updates to github can wait a while.
Uhm, I was about to object.
But I believe that you split WFE and WFI for instance and handle them as one "kind" of instruction, then test their bit in the handler (if necessary).
-Actually WFE and WFI should of course be treated the same way (they're almost identical in behaviour from a debugger's point of view), so no need to do special checking there.
Writing a debugger gives you a good solid foundation in an instruction set / assembly language. It forces you through each instruction and you'll know much better what each instruction is capable of and not capable of.
I think that you may quickly become more experienced with some of the instructions, than programmers that have worked with the instructions for a while.
Yes, my lazy nature...
If I do a full decoding and then still handle instructions in groups, I'll have a decoder "sceleton" that I can use for something else if I happen to need to.
case arm_xtra_hint:
// WFE,WFI
// neither changes the program flow
retval = set_addr_lin();
break;
Then again:
case arm_xtra_cmode:
// Check cmode to see if it's VBIC (imm) or VMVN (imm)
if (bitrng(instr, 11,9) != 7)
{
// either VBIC or VMVN
if (bitrng(instr, 11, 10) == 3)
// VMVN
}
else if (bit(instr, 8))
// VBIC
else
// else UNDEFINED
Well, haven't got too far in this yet.
(And I need to change the enums used for the switch-cases here.