Simpleperf: parse prefixed symbol of linker.

Bug: 19483574
Change-Id: I2597d4a91fd9a6cfc5c15c8b637dc4ba5213ee56
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp
index 7d4671c..b5880ca 100644
--- a/simpleperf/dso.cpp
+++ b/simpleperf/dso.cpp
@@ -135,10 +135,22 @@
 
 static void DemangleInPlace(std::string* name) {
   int status;
-  char* demangled_name = __cxa_demangle(name->c_str(), nullptr, nullptr, &status);
+  bool is_linker_symbol = (name->find(linker_prefix) == 0);
+  const char* mangled_str = name->c_str();
+  if (is_linker_symbol) {
+    mangled_str += linker_prefix.size();
+  }
+  char* demangled_name = __cxa_demangle(mangled_str, nullptr, nullptr, &status);
   if (status == 0) {
-    *name = demangled_name;
+    if (is_linker_symbol) {
+      *name = std::string("[linker]") + demangled_name;
+    } else {
+      *name = demangled_name;
+    }
     free(demangled_name);
+  } else if (is_linker_symbol) {
+    std::string temp = std::string("[linker]") + mangled_str;
+    *name = std::move(temp);
   }
 }
 
diff --git a/simpleperf/read_elf.cpp b/simpleperf/read_elf.cpp
index a56a4b2..a600fc9 100644
--- a/simpleperf/read_elf.cpp
+++ b/simpleperf/read_elf.cpp
@@ -163,9 +163,13 @@
     } else if (type == STT_NOTYPE) {
       if (symbol.is_in_text_section) {
         symbol.is_label = true;
-        // Arm has meaningless labels like $t, $d, $x.
-        if (is_arm && symbol.name.size() == 2 && symbol.name[0] == '$') {
-          symbol.is_label = false;
+
+        // Arm has meaningless labels like $t, $d, $x, exclude them.
+        if (is_arm) {
+          size_t test_pos = (symbol.name.find(linker_prefix) == 0) ? linker_prefix.size() : 0;
+          if (test_pos + 2 == symbol.name.size() && symbol.name[test_pos] == '$') {
+            symbol.is_label = false;
+          }
         }
       }
     }
diff --git a/simpleperf/read_elf.h b/simpleperf/read_elf.h
index e21add4..487fc28 100644
--- a/simpleperf/read_elf.h
+++ b/simpleperf/read_elf.h
@@ -24,6 +24,9 @@
 bool GetBuildIdFromNoteFile(const std::string& filename, BuildId* build_id);
 bool GetBuildIdFromElfFile(const std::string& filename, BuildId* build_id);
 
+// The symbol prefix used to indicate that the symbol belongs to android linker.
+static const std::string linker_prefix = "__dl_";
+
 struct ElfFileSymbol {
   uint64_t start_in_file;
   uint64_t len;