Ensure local debug symbols are generated first.

This is what the spec says, and newer tools warn about it.
I expect it is of little consequence otherwise.

Test: Checkout output with readelf
Change-Id: Icd358181f41304d3121a85f87b34e563b0e59073
diff --git a/compiler/debug/elf_symtab_writer.h b/compiler/debug/elf_symtab_writer.h
index 4b19547..1310e8d 100644
--- a/compiler/debug/elf_symtab_writer.h
+++ b/compiler/debug/elf_symtab_writer.h
@@ -37,7 +37,8 @@
 // exist, but it will still work well without them.
 // However, these extra symbols take space, so let's just generate
 // one symbol which marks the whole .text section as code.
-constexpr bool kGenerateSingleArmMappingSymbol = true;
+// Note that ARM's Streamline requires it to match function symbol.
+constexpr bool kGenerateArmMappingSymbol = true;
 
 // Magic name for .symtab symbols which enumerate dex files used
 // by this ELF file (currently mmapped inside the .dex section).
@@ -48,6 +49,7 @@
                               bool mini_debug_info,
                               const DebugInfo& debug_info) {
   uint64_t mapping_symbol_address = std::numeric_limits<uint64_t>::max();
+  const auto* text = builder->GetText();
   auto* strtab = builder->GetStrTab();
   auto* symtab = builder->GetSymTab();
 
@@ -62,10 +64,19 @@
     if (info.deduped) {
       deduped_addresses.insert(info.code_address);
     }
+    if (kGenerateArmMappingSymbol && info.isa == InstructionSet::kThumb2) {
+      uint64_t address = info.code_address;
+      address += info.is_code_address_text_relative ? text->GetAddress() : 0;
+      mapping_symbol_address = std::min(mapping_symbol_address, address);
+    }
   }
 
   strtab->Start();
   strtab->Write("");  // strtab should start with empty string.
+  // Generate ARM mapping symbols. ELF local symbols must be added first.
+  if (mapping_symbol_address != std::numeric_limits<uint64_t>::max()) {
+    symtab->Add(strtab->Write("$t"), text, mapping_symbol_address, 0, STB_LOCAL, STT_NOTYPE);
+  }
   // Add symbols for compiled methods.
   for (const MethodDebugInfo& info : debug_info.compiled_methods) {
     if (info.deduped) {
@@ -83,23 +94,11 @@
       name_offset = strtab->Write(name);
     }
 
-    const auto* text = builder->GetText();
     uint64_t address = info.code_address;
     address += info.is_code_address_text_relative ? text->GetAddress() : 0;
     // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
     address += CompiledMethod::CodeDelta(info.isa);
     symtab->Add(name_offset, text, address, info.code_size, STB_GLOBAL, STT_FUNC);
-
-    // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
-    // instructions, so that disassembler tools can correctly disassemble.
-    // Note that even if we generate just a single mapping symbol, ARM's Streamline
-    // requires it to match function symbol.  Just address 0 does not work.
-    if (info.isa == InstructionSet::kThumb2) {
-      if (address < mapping_symbol_address || !kGenerateSingleArmMappingSymbol) {
-        symtab->Add(strtab->Write("$t"), text, address & ~1, 0, STB_LOCAL, STT_NOTYPE);
-        mapping_symbol_address = address;
-      }
-    }
   }
   // Add symbols for dex files.
   if (!debug_info.dex_files.empty() && builder->GetDex()->Exists()) {
diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h
index 3145497..f4fcf49 100644
--- a/compiler/linker/elf_builder.h
+++ b/compiler/linker/elf_builder.h
@@ -201,7 +201,7 @@
       return section_index_ != 0;
     }
 
-   private:
+   protected:
     // Add this section to the list of generated ELF sections (if not there already).
     // It also ensures the alignment is sufficient to generate valid program headers,
     // since that depends on the previous section. It returns the required alignment.
@@ -345,7 +345,7 @@
                   type,
                   flags,
                   strtab,
-                  /* info */ 0,
+                  /* info */ 1,
                   sizeof(Elf_Off),
                   sizeof(Elf_Sym)) {
       syms_.push_back(Elf_Sym());  // The symbol table always has to start with NULL symbol.
@@ -386,6 +386,11 @@
       sym.st_shndx = section_index;
       sym.st_info = (binding << 4) + (type & 0xf);
       syms_.push_back(sym);
+
+      // The sh_info file must be set to index one-past the last local symbol.
+      if (binding == STB_LOCAL) {
+        this->header_.sh_info = syms_.size();
+      }
     }
 
     Elf_Word GetCacheSize() { return syms_.size() * sizeof(Elf_Sym); }