Append [DEDUPED] suffix to all deduped methods in the symbol table.

This resolves old TODO in the code.  The first method was never
marked as deduped and only the subsequent copies were recognised.
Therefore the suffix might have been missing in backtraces.

Change-Id: I4882d90f3049f7e196cd38c8987ba02960dab338
diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index f7811dd..6fe05a4 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -16,6 +16,8 @@
 
 #include "elf_writer_debug.h"
 
+#include <unordered_set>
+
 #include "compiled_method.h"
 #include "driver/compiler_driver.h"
 #include "dex_file-inl.h"
@@ -193,6 +195,15 @@
     cunit_high_pc = std::max(cunit_high_pc, method_info.high_pc_);
   }
 
+  // Find all addresses (low_pc) which contain deduped methods.
+  // The first instance of method is not marked deduped_, but the rest is.
+  std::unordered_set<uint32_t> deduped_addresses;
+  for (auto it = method_infos.begin(); it != method_infos.end(); ++it) {
+    if (it->deduped_) {
+      deduped_addresses.insert(it->low_pc_);
+    }
+  }
+
   // Write .debug_info section.
   size_t debug_abbrev_offset = debug_abbrev->size();
   DebugInfoEntryWriter<> info(false /* 32 bit */, debug_abbrev);
@@ -205,10 +216,8 @@
   for (auto method_info : method_infos) {
     std::string method_name = PrettyMethod(method_info.dex_method_index_,
                                            *method_info.dex_file_, true);
-    if (method_info.deduped_) {
-      // TODO We should place the DEDUPED tag on the first instance of a deduplicated symbol
-      // so that it will show up in a debuggerd crash report.
-      method_name += " [ DEDUPED ]";
+    if (deduped_addresses.find(method_info.low_pc_) != deduped_addresses.end()) {
+      method_name += " [DEDUPED]";
     }
     info.StartTag(DW_TAG_subprogram, DW_CHILDREN_no);
     info.WriteStrp(DW_AT_name, method_name.data(), debug_str);
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 737b9d6..429cd85 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -17,6 +17,7 @@
 #include "elf_writer_quick.h"
 
 #include <unordered_map>
+#include <unordered_set>
 
 #include "base/logging.h"
 #include "base/unix_file/fd_file.h"
@@ -181,16 +182,23 @@
                               ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
                                          Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
                               OatWriter* oat_writer) {
-  // Iterate over the compiled methods.
   const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetMethodDebugInfo();
+
+  // Find all addresses (low_pc) which contain deduped methods.
+  // The first instance of method is not marked deduped_, but the rest is.
+  std::unordered_set<uint32_t> deduped_addresses;
+  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
+    if (it->deduped_) {
+      deduped_addresses.insert(it->low_pc_);
+    }
+  }
+
   ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
       builder->GetSymtabBuilder();
   for (auto it = method_info.begin(); it != method_info.end(); ++it) {
     std::string name = PrettyMethod(it->dex_method_index_, *it->dex_file_, true);
-    if (it->deduped_) {
-      // TODO We should place the DEDUPED tag on the first instance of a deduplicated symbol
-      // so that it will show up in a debuggerd crash report.
-      name += " [ DEDUPED ]";
+    if (deduped_addresses.find(it->low_pc_) != deduped_addresses.end()) {
+      name += " [DEDUPED]";
     }
 
     uint32_t low_pc = it->low_pc_;