Breakpad Dumper: Move CFI register names to DwarfCFIToModule class.

At the moment, the mappings from register numbers appearing in DWARF CFI
and .eh_frame exception handling sections to the appropriate
processor-specific names are in src/common/linux/dump_syms.cc. However, the
numberings are (for the most part) the same on all platforms using DWARF,
so there's no reason those tables shouldn't be shared between the Linux and
Mac symbol dumpers.

This patch moves the tables into a nested class of DwarfCFIToModule, so
they the Mac dumper can use them when it is changed to use
DwarfCFIToModule.

a=jimblandy, r=thestig


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@575 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
jimblandy 2010-04-28 18:14:59 +00:00
parent 865df5af57
commit 504280af60
4 changed files with 110 additions and 46 deletions

View file

@ -42,6 +42,59 @@ namespace google_breakpad {
using std::ostringstream; using std::ostringstream;
vector<string> DwarfCFIToModule::RegisterNames::MakeVector(
const char * const *strings,
size_t size) {
vector<string> names(strings, strings + size);
return names;
}
vector<string> DwarfCFIToModule::RegisterNames::I386() {
static const char *const names[] = {
"$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi",
"$eip", "$eflags", "$unused1",
"$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
"$unused2", "$unused3",
"$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
"$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
"$fcw", "$fsw", "$mxcsr",
"$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5",
"$tr", "$ldtr"
};
return MakeVector(names, sizeof(names) / sizeof(names[0]));
}
vector<string> DwarfCFIToModule::RegisterNames::X86_64() {
static const char *const names[] = {
"$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp",
"$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
"$rip",
"$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
"$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15",
"$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
"$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
"$rflags",
"$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused1", "$unused2",
"$fs.base", "$gs.base", "$unused3", "$unused4",
"$tr", "$ldtr",
"$mxcsr", "$fcw", "$fsw"
};
return MakeVector(names, sizeof(names) / sizeof(names[0]));
}
vector<string> DwarfCFIToModule::RegisterNames::ARM() {
static const char *const names[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"fps", "cpsr"
};
return MakeVector(names, sizeof(names) / sizeof(names[0]));
}
bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length, bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length,
uint8 version, const string &augmentation, uint8 version, const string &augmentation,
unsigned return_address) { unsigned return_address) {

View file

@ -91,6 +91,26 @@ class DwarfCFIToModule: public CallFrameInfo::Handler {
string file_, section_; string file_, section_;
}; };
// Register name tables. If TABLE is a vector returned by one of these
// functions, then TABLE[R] is the name of the register numbered R in
// DWARF call frame information.
class RegisterNames {
public:
// Intel's "x86" or IA-32.
static vector<string> I386();
// AMD x86_64, AMD64, Intel EM64T, or Intel 64
static vector<string> X86_64();
// ARM.
static vector<string> ARM();
private:
// Given STRINGS, an array of C strings with SIZE elements, return an
// equivalent vector<string>.
static vector<string> MakeVector(const char * const *strings, size_t size);
};
// Create a handler for the dwarf2reader::CallFrameInfo parser that // Create a handler for the dwarf2reader::CallFrameInfo parser that
// records the stack unwinding information it receives in MODULE. // records the stack unwinding information it receives in MODULE.
// //

View file

@ -258,3 +258,31 @@ TEST_F(Rule, DefaultReturnAddressRuleLater) {
EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes));
} }
TEST(RegisterNames, I386) {
vector<string> names = DwarfCFIToModule::RegisterNames::I386();
EXPECT_EQ("$eax", names[0]);
EXPECT_EQ("$ecx", names[1]);
EXPECT_EQ("$esp", names[4]);
EXPECT_EQ("$eip", names[8]);
}
TEST(RegisterNames, ARM) {
vector<string> names = DwarfCFIToModule::RegisterNames::ARM();
EXPECT_EQ("r0", names[0]);
EXPECT_EQ("r10", names[10]);
EXPECT_EQ("sp", names[13]);
EXPECT_EQ("lr", names[14]);
EXPECT_EQ("pc", names[15]);
}
TEST(RegisterNames, X86_64) {
vector<string> names = DwarfCFIToModule::RegisterNames::X86_64();
EXPECT_EQ("$rax", names[0]);
EXPECT_EQ("$rdx", names[1]);
EXPECT_EQ("$rbp", names[6]);
EXPECT_EQ("$rsp", names[7]);
EXPECT_EQ("$rip", names[16]);
}

View file

@ -226,56 +226,19 @@ static bool LoadDwarf(const string &dwarf_filename,
static bool DwarfCFIRegisterNames(const ElfW(Ehdr) *elf_header, static bool DwarfCFIRegisterNames(const ElfW(Ehdr) *elf_header,
vector<string> *register_names) vector<string> *register_names)
{ {
static const char *const i386_names[] = {
"$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi",
"$eip", "$eflags", "$unused1",
"$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
"$unused2", "$unused3",
"$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
"$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
"$fcw", "$fsw", "$mxcsr",
"$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5",
"$tr", "$ldtr",
NULL
};
static const char *const x86_64_names[] = {
"$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp",
"$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
"$rip",
"$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
"$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15",
"$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
"$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
"$rflags",
"$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused1", "$unused2",
"$fs.base", "$gs.base", "$unused3", "$unused4",
"$tr", "$ldtr",
"$mxcsr", "$fcw", "$fsw",
NULL
};
static const char *const arm_names[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"fps", "cpsr",
NULL
};
const char * const *name_table;
switch (elf_header->e_machine) { switch (elf_header->e_machine) {
case EM_386: name_table = i386_names; break; case EM_386:
case EM_ARM: name_table = arm_names; break; *register_names = DwarfCFIToModule::RegisterNames::I386();
case EM_X86_64: name_table = x86_64_names; break; return true;
case EM_ARM:
*register_names = DwarfCFIToModule::RegisterNames::ARM();
return true;
case EM_X86_64:
*register_names = DwarfCFIToModule::RegisterNames::X86_64();
return true;
default: default:
return false; return false;
} }
register_names->clear();
for (int i = 0; name_table[i]; i++)
register_names->push_back(name_table[i]);
return true;
} }
static bool LoadDwarfCFI(const string &dwarf_filename, static bool LoadDwarfCFI(const string &dwarf_filename,