Optimize Memory::ReadString

This function is responsible for majority of CPU time in prefetto.

Reduce the number of memory reads (don't read strings byte-by-byte).

Update all calls of ReadString to include the third parameter to have
a max read.

Add an Elf creation benchmark since this function is on the elf
creation path.

Test: libunwindstack_unit_test
Change-Id: Ia36e1f1a5ba76c9e9f13c43fb9e3691dde7897f2
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 821e042..17470fd 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -371,7 +371,7 @@
       // Look for the .debug_frame and .gnu_debugdata.
       if (shdr.sh_name < sec_size) {
         std::string name;
-        if (memory_->ReadString(sec_offset + shdr.sh_name, &name)) {
+        if (memory_->ReadString(sec_offset + shdr.sh_name, &name, sec_size - shdr.sh_name)) {
           if (name == ".debug_frame") {
             debug_frame_offset_ = shdr.sh_offset;
             debug_frame_size_ = shdr.sh_size;
@@ -405,7 +405,7 @@
     } else if (shdr.sh_type == SHT_NOTE) {
       if (shdr.sh_name < sec_size) {
         std::string name;
-        if (memory_->ReadString(sec_offset + shdr.sh_name, &name) &&
+        if (memory_->ReadString(sec_offset + shdr.sh_name, &name, sec_size - shdr.sh_name) &&
             name == ".note.gnu.build-id") {
           gnu_build_id_offset_ = shdr.sh_offset;
           gnu_build_id_size_ = shdr.sh_size;
@@ -456,10 +456,11 @@
   for (const auto& entry : strtabs_) {
     if (entry.first == strtab_addr) {
       soname_offset = entry.second + soname_offset;
-      if (soname_offset >= entry.second + strtab_size) {
+      uint64_t soname_max = entry.second + strtab_size;
+      if (soname_offset >= soname_max) {
         return "";
       }
-      if (!memory_->ReadString(soname_offset, &soname_)) {
+      if (!memory_->ReadString(soname_offset, &soname_, soname_max - soname_offset)) {
         return "";
       }
       soname_type_ = SONAME_VALID;
@@ -608,7 +609,8 @@
     }
     std::string name;
     if (shdr.sh_type == SHT_NOTE && shdr.sh_name < sec_size &&
-        memory->ReadString(sec_offset + shdr.sh_name, &name) && name == ".note.gnu.build-id") {
+        memory->ReadString(sec_offset + shdr.sh_name, &name, sec_size - shdr.sh_name) &&
+        name == ".note.gnu.build-id") {
       *build_id_offset = shdr.sh_offset;
       *build_id_size = shdr.sh_size;
       return true;