aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-04-28 18:14:59 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-04-28 18:14:59 +0000
commit504280af60e3052d2ecaa9e003818886e651310f (patch)
tree89cbeedd14326076ef0f2e2d3d4e0a3bd0264e2b /src
parentBreakpad test support: Move test_assembler.{h,cc} from src/processor to src/c... (diff)
downloadbreakpad-504280af60e3052d2ecaa9e003818886e651310f.tar.xz
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
Diffstat (limited to 'src')
-rw-r--r--src/common/dwarf_cfi_to_module.cc53
-rw-r--r--src/common/dwarf_cfi_to_module.h20
-rw-r--r--src/common/dwarf_cfi_to_module_unittest.cc28
-rw-r--r--src/common/linux/dump_symbols.cc55
4 files changed, 110 insertions, 46 deletions
diff --git a/src/common/dwarf_cfi_to_module.cc b/src/common/dwarf_cfi_to_module.cc
index 49a6d852..611cecd5 100644
--- a/src/common/dwarf_cfi_to_module.cc
+++ b/src/common/dwarf_cfi_to_module.cc
@@ -42,6 +42,59 @@ namespace google_breakpad {
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,
uint8 version, const string &augmentation,
unsigned return_address) {
diff --git a/src/common/dwarf_cfi_to_module.h b/src/common/dwarf_cfi_to_module.h
index 002fc90f..4f4ce0a2 100644
--- a/src/common/dwarf_cfi_to_module.h
+++ b/src/common/dwarf_cfi_to_module.h
@@ -91,6 +91,26 @@ class DwarfCFIToModule: public CallFrameInfo::Handler {
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
// records the stack unwinding information it receives in MODULE.
//
diff --git a/src/common/dwarf_cfi_to_module_unittest.cc b/src/common/dwarf_cfi_to_module_unittest.cc
index 516b9784..9477296d 100644
--- a/src/common/dwarf_cfi_to_module_unittest.cc
+++ b/src/common/dwarf_cfi_to_module_unittest.cc
@@ -258,3 +258,31 @@ TEST_F(Rule, DefaultReturnAddressRuleLater) {
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]);
+}
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index ea55cc7b..c3648e9a 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -226,56 +226,19 @@ static bool LoadDwarf(const string &dwarf_filename,
static bool DwarfCFIRegisterNames(const ElfW(Ehdr) *elf_header,
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) {
- case EM_386: name_table = i386_names; break;
- case EM_ARM: name_table = arm_names; break;
- case EM_X86_64: name_table = x86_64_names; break;
+ case EM_386:
+ *register_names = DwarfCFIToModule::RegisterNames::I386();
+ 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:
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,