util: disassembler register/address mapping fix

For def/use pruning, the linear address mapping of the x86
sub-registers (e.g., AX represents the lower 16 bits of EAX) must
overlap.  If it doesn't, e.g., AX and EAX are considered separate
registers by def/use pruning, resulting in a failure to correlate an
EAX def with a subsequent AX use.

The only user of this mapping up to now, RegisterImporter, forced all
register widths to 8 bits, thereby fortunately canceling out this
problem.  Nevertheless it makes no sense to continue encoding a
constant width in these virtual addresses.

Existing trace, fspgroup, fsppilot and result tables may be converted
to the new encoding by using this query:

UPDATE <tablename> SET data_address = ((data_address >> 4) & ~0xf) | data_address & 0xf;

Change-Id: I7a942b78c34f6140803a86af639eeedef3550f34
This commit is contained in:
Horst Schirmeier
2013-08-30 17:03:37 +02:00
parent 4115de91aa
commit 2108c8932f
2 changed files with 15 additions and 11 deletions

View File

@ -13,6 +13,12 @@ namespace fail {
*/
class LLVMtoFailTranslator {
public:
/**
* Maps registers to/from linear addresses usable for def/use-pruning
* purposes and storage in the database. Takes care that the linear
* addresses of x86 subregisters (e.g., AX represents the lower 16 bits of
* EAX) overlap with their siblings.
*/
struct reginfo_t {
int id;
regwidth_t width;
@ -20,18 +26,17 @@ public:
byte_t offset;
int toDataAddress() const {
// .. 5 4 | 7 6 5 4 | 3 2 1 0
// <reg> | <width> | <offset>
return (id << 8) | ((width/8) << 4) | (offset / 8);
// .. 5 4 | 3 2 1 0
// <reg> | <offset>
return (id << 4) | (offset / 8);
}
// does not recreate width or mask
static reginfo_t fromDataAddress(int addr) {
int id = addr >> 8;
regwidth_t width = ((addr >> 4) & 0xf) * 8;
byte_t offset = (addr & 0xf) * 8;
return reginfo_t(id, width, offset);
int id = addr >> 4;
byte_t offset = (addr & 0xf) * 8;
return reginfo_t(id, 0, offset);
}
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
: id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {};
};