: Sized_relobj<32, big_endian>(name, input_file, offset, ehdr),
       stub_tables_(), local_symbol_is_thumb_function_(),
       attributes_section_data_(NULL), mapping_symbols_info_(),
-      section_has_cortex_a8_workaround_(NULL), exidx_section_map_()
+      section_has_cortex_a8_workaround_(NULL), exidx_section_map_(),
+      output_local_symbol_count_needs_update_(false)
   { }
 
   ~Arm_relobj()
            : NULL);
   }
 
+  // Whether output local symbol count needs updating.
+  bool
+  output_local_symbol_count_needs_update() const
+  { return this->output_local_symbol_count_needs_update_; }
+
+  // Set output_local_symbol_count_needs_update flag to be true.
+  void
+  set_output_local_symbol_count_needs_update()
+  { this->output_local_symbol_count_needs_update_ = true; }
+  
+  // Update output local symbol count at the end of relaxation.
+  void
+  update_output_local_symbol_count();
+
  protected:
   // Post constructor setup.
   void
   std::vector<bool>* section_has_cortex_a8_workaround_;
   // Map a text section to its associated .ARM.exidx section, if there is one.
   Exidx_section_map exidx_section_map_;
+  // Whether output local symbol count needs updating.
+  bool output_local_symbol_count_needs_update_;
 };
 
 // Arm_dynobj class.
   // Write out the entry.  The first word either points to the beginning
   // or after the end of a text section.  The second word is the special
   // EXIDX_CANTUNWIND value.
-  elfcpp::Swap<32, big_endian>::writeval(wv, output_address);
+  uint32_t prel31_offset = output_address - this->address();
+  if (utils::has_overflow<31>(offset))
+    gold_error(_("PREL31 overflow in EXIDX_CANTUNWIND entry"));
+  elfcpp::Swap<32, big_endian>::writeval(wv, prel31_offset & 0x7fffffffU);
   elfcpp::Swap<32, big_endian>::writeval(wv + 1, elfcpp::EXIDX_CANTUNWIND);
 
   of->write_output_view(this->offset(), oview_size, oview);
          // The whole EXIDX section got merged.  Remove it from output.
          gold_assert(section_offset_map == NULL);
          exidx_relobj->set_output_section(exidx_shndx, NULL);
+
+         // All local symbols defined in this input section will be dropped.
+         // We need to adjust output local symbol count.
+         arm_relobj->set_output_local_symbol_count_needs_update();
        }
       else if (deleted_bytes > 0)
        {
                                         *section_offset_map, deleted_bytes);
          this->add_relaxed_input_section(merged_section);
          arm_relobj->convert_input_section_to_relaxed_section(exidx_shndx);
+
+         // All local symbols defined in discarded portions of this input
+         // section will be dropped.  We need to adjust output local symbol
+         // count.
+         arm_relobj->set_output_local_symbol_count_needs_update();
        }
       else
        {
     }
 }
 
+// Update output local symbol count.  Owing to EXIDX entry merging, some local
+// symbols  will be removed in output.  Adjust output local symbol count
+// accordingly.  We can only changed the static output local symbol count.  It
+// is too late to change the dynamic symbols.
+
+template<bool big_endian>
+void
+Arm_relobj<big_endian>::update_output_local_symbol_count()
+{
+  // Caller should check that this needs updating.  We want caller checking
+  // because output_local_symbol_count_needs_update() is most likely inlined.
+  gold_assert(this->output_local_symbol_count_needs_update_);
+
+  gold_assert(this->symtab_shndx() != -1U);
+  if (this->symtab_shndx() == 0)
+    {
+      // This object has no symbols.  Weird but legal.
+      return;
+    }
+
+  // Read the symbol table section header.
+  const unsigned int symtab_shndx = this->symtab_shndx();
+  elfcpp::Shdr<32, big_endian>
+    symtabshdr(this, this->elf_file()->section_header(symtab_shndx));
+  gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
+
+  // Read the local symbols.
+  const int sym_size = elfcpp::Elf_sizes<32>::sym_size;
+  const unsigned int loccount = this->local_symbol_count();
+  gold_assert(loccount == symtabshdr.get_sh_info());
+  off_t locsize = loccount * sym_size;
+  const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
+                                             locsize, true, true);
+
+  // Loop over the local symbols.
+
+  typedef typename Sized_relobj<32, big_endian>::Output_sections
+     Output_sections;
+  const Output_sections& out_sections(this->output_sections());
+  unsigned int shnum = this->shnum();
+  unsigned int count = 0;
+  // Skip the first, dummy, symbol.
+  psyms += sym_size;
+  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
+    {
+      elfcpp::Sym<32, big_endian> sym(psyms);
+
+      Symbol_value<32>& lv((*this->local_values())[i]);
+
+      // This local symbol was already discarded by do_count_local_symbols.
+      if (!lv.needs_output_symtab_entry())
+       continue;
+
+      bool is_ordinary;
+      unsigned int shndx = this->adjust_sym_shndx(i, sym.get_st_shndx(),
+                                                 &is_ordinary);
+
+      if (shndx < shnum)
+       {
+         Output_section* os = out_sections[shndx];
+
+         // This local symbol no longer has an output section.  Discard it.
+         if (os == NULL)
+           {
+             lv.set_no_output_symtab_entry();
+             continue;
+           }
+
+         // Currently we only discard parts of EXIDX input sections.
+         // We explicitly check for a merged EXIDX input section to avoid
+         // calling Output_section_data::output_offset unless necessary.
+         if ((this->get_output_section_offset(shndx) == invalid_address)
+             && (this->exidx_input_section_by_shndx(shndx) != NULL))
+           {
+             section_offset_type output_offset =
+               os->output_offset(this, shndx, lv.input_value());
+             if (output_offset == -1)
+               {
+                 // This symbol is defined in a part of an EXIDX input section
+                 // that is discarded due to entry merging.
+                 lv.set_no_output_symtab_entry();
+                 continue;
+               }       
+           }
+       }
+
+      ++count;
+    }
+
+  this->set_output_local_symbol_count(count);
+  this->output_local_symbol_count_needs_update_ = false;
+}
+
 // Arm_dynobj methods.
 
 // Read the symbol information.
       break;
 
     case elfcpp::R_ARM_REL32:
+      break;
+
     case elfcpp::R_ARM_PREL31:
       {
        // Make a dynamic relocation if necessary.
 
   // Finalize the stubs in the last relaxation pass.
   if (!continue_relaxation)
-    for (Stub_table_iterator sp = this->stub_tables_.begin();
-        (sp != this->stub_tables_.end()) && !any_stub_table_changed;
-        ++sp)
-      (*sp)->finalize_stubs();
+    {
+      for (Stub_table_iterator sp = this->stub_tables_.begin();
+          (sp != this->stub_tables_.end()) && !any_stub_table_changed;
+           ++sp)
+       (*sp)->finalize_stubs();
+
+      // Update output local symbol counts of objects if necessary.
+      for (Input_objects::Relobj_iterator op = input_objects->relobj_begin();
+          op != input_objects->relobj_end();
+          ++op)
+       {
+         Arm_relobj<big_endian>* arm_relobj =
+           Arm_relobj<big_endian>::as_arm_relobj(*op);
+
+         // Update output local symbol counts.  We need to discard local
+         // symbols defined in parts of input sections that are discarded by
+         // relaxation.
+         if (arm_relobj->output_local_symbol_count_needs_update())
+           arm_relobj->update_output_local_symbol_count();
+       }
+    }
 
   return continue_relaxation;
 }