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
diff --git a/src/common/dwarf_cfi_to_module.cc b/src/common/dwarf_cfi_to_module.cc
index 49a6d85..611cecd 100644
--- a/src/common/dwarf_cfi_to_module.cc
+++ b/src/common/dwarf_cfi_to_module.cc
@@ -42,6 +42,59 @@
 
 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 002fc90..4f4ce0a 100644
--- a/src/common/dwarf_cfi_to_module.h
+++ b/src/common/dwarf_cfi_to_module.h
@@ -91,6 +91,26 @@
     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 516b978..9477296 100644
--- a/src/common/dwarf_cfi_to_module_unittest.cc
+++ b/src/common/dwarf_cfi_to_module_unittest.cc
@@ -258,3 +258,31 @@
   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 ea55cc7..c3648e9 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -226,56 +226,19 @@
 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,