* configure.tgt (powerpc64-*): Fix targ_obj.
[binutils-gdb.git] / gold / reloc.cc
index 99a736bdc95a1933b9a4f5eaef3cae5e4869f5b2..f6bef1d973a6bb347b9a9341a2872d2ecc8cf286 100644 (file)
@@ -193,7 +193,8 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
 
   rd->relocs.reserve(shnum / 2);
 
-  std::vector<Map_to_output>& map_sections(this->map_to_output());
+  const Output_sections& out_sections(this->output_sections());
+  const std::vector<Address>& out_offsets(this->section_offsets_);
 
   const unsigned char *pshdrs = this->get_view(this->elf_file_.shoff(),
                                               shnum * This::shdr_size,
@@ -208,7 +209,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
       if (sh_type != elfcpp::SHT_REL && sh_type != elfcpp::SHT_RELA)
        continue;
 
-      unsigned int shndx = shdr.get_sh_info();
+      unsigned int shndx = this->adjust_shndx(shdr.get_sh_info());
       if (shndx >= shnum)
        {
          this->error(_("relocation section %u has bad info %u"),
@@ -216,7 +217,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
          continue;
        }
 
-      Output_section* os = map_sections[shndx].output_section;
+      Output_section* os = out_sections[shndx];
       if (os == NULL)
        continue;
 
@@ -233,11 +234,11 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
          && !parameters->options().emit_relocs())
        continue;
 
-      if (shdr.get_sh_link() != this->symtab_shndx_)
+      if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx_)
        {
          this->error(_("relocation section %u uses unexpected "
                        "symbol table %u"),
-                     i, shdr.get_sh_link());
+                     i, this->adjust_shndx(shdr.get_sh_link()));
          continue;
        }
 
@@ -273,7 +274,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
       sr.sh_type = sh_type;
       sr.reloc_count = reloc_count;
       sr.output_section = os;
-      sr.needs_special_offset_handling = map_sections[shndx].offset == -1;
+      sr.needs_special_offset_handling = out_offsets[shndx] == invalid_address;
       sr.is_data_section_allocated = is_section_allocated;
     }
 
@@ -367,7 +368,7 @@ class Emit_relocs_strategy
  public:
   // A local non-section symbol.
   inline Relocatable_relocs::Reloc_strategy
-  local_non_section_strategy(unsigned int, Relobj*)
+  local_non_section_strategy(unsigned int, Relobj*, unsigned int)
   { return Relocatable_relocs::RELOC_COPY; }
 
   // A local section symbol.
@@ -507,7 +508,8 @@ Sized_relobj<size, big_endian>::do_relocate(const General_options& options,
     }
 
   // Write out the local symbols.
-  this->write_local_symbols(of, layout->sympool(), layout->dynpool());
+  this->write_local_symbols(of, layout->sympool(), layout->dynpool(),
+                           layout->symtab_xindex(), layout->dynsym_xindex());
 
   // We should no longer need the local symbol values.
   this->clear_local_symbols();
@@ -533,7 +535,8 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
                                               Views* pviews)
 {
   unsigned int shnum = this->shnum();
-  const std::vector<Map_to_output>& map_sections(this->map_to_output());
+  const Output_sections& out_sections(this->output_sections());
+  const std::vector<Address>& out_offsets(this->section_offsets_);
 
   File_read::Read_multiple rm;
   bool is_sorted = true;
@@ -545,10 +548,10 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
 
       pvs->view = NULL;
 
-      const Output_section* os = map_sections[i].output_section;
+      const Output_section* os = out_sections[i];
       if (os == NULL)
        continue;
-      off_t output_offset = map_sections[i].offset;
+      Address output_offset = out_offsets[i];
 
       typename This::Shdr shdr(p);
 
@@ -583,8 +586,8 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
       // In the normal case, this input section is simply mapped to
       // the output section at offset OUTPUT_OFFSET.
 
-      // However, if OUTPUT_OFFSET == -1, then input data is handled
-      // specially--e.g., a .eh_frame section.  The relocation
+      // However, if OUTPUT_OFFSET == INVALID_ADDRESS, then input data is
+      // handled specially--e.g., a .eh_frame section.  The relocation
       // routines need to check for each reloc where it should be
       // applied.  For this case, we need an input/output view for the
       // entire contents of the section in the output file.  We don't
@@ -601,21 +604,22 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
       // final data to the output file.
 
       off_t output_section_offset;
-      off_t output_section_size;
+      Address output_section_size;
       if (!os->requires_postprocessing())
        {
          output_section_offset = os->offset();
-         output_section_size = os->data_size();
+         output_section_size = convert_types<Address, off_t>(os->data_size());
        }
       else
        {
          output_section_offset = 0;
-         output_section_size = os->postprocessing_buffer_size();
+         output_section_size =
+              convert_types<Address, off_t>(os->postprocessing_buffer_size());
        }
 
       off_t view_start;
       section_size_type view_size;
-      if (output_offset != -1)
+      if (output_offset != invalid_address)
        {
          view_start = output_section_offset + output_offset;
          view_size = convert_to_section_size_type(shdr.get_sh_size());
@@ -629,17 +633,15 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
       if (view_size == 0)
        continue;
 
-      gold_assert(output_offset == -1
-                 || (output_offset >= 0
-                     && (output_offset + static_cast<off_t>(view_size)
-                          <= output_section_size)));
+      gold_assert(output_offset == invalid_address
+                 || output_offset + view_size <= output_section_size);
 
       unsigned char* view;
       if (os->requires_postprocessing())
        {
          unsigned char* buffer = os->postprocessing_buffer();
          view = buffer + view_start;
-         if (output_offset != -1)
+         if (output_offset != invalid_address)
            {
              off_t sh_offset = shdr.get_sh_offset();
              if (!rm.empty() && rm.back().file_offset > sh_offset)
@@ -650,7 +652,7 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
        }
       else
        {
-         if (output_offset == -1)
+         if (output_offset == invalid_address)
            view = of->get_input_output_view(view_start, view_size);
          else
            {
@@ -665,11 +667,11 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
 
       pvs->view = view;
       pvs->address = os->address();
-      if (output_offset != -1)
+      if (output_offset != invalid_address)
        pvs->address += output_offset;
       pvs->offset = view_start;
       pvs->view_size = view_size;
-      pvs->is_input_output_view = output_offset == -1;
+      pvs->is_input_output_view = output_offset == invalid_address;
       pvs->is_postprocessing_view = os->requires_postprocessing();
     }
 
@@ -697,7 +699,8 @@ Sized_relobj<size, big_endian>::relocate_sections(
   unsigned int shnum = this->shnum();
   Sized_target<size, big_endian>* target = this->sized_target();
 
-  const std::vector<Map_to_output>& map_sections(this->map_to_output());
+  const Output_sections& out_sections(this->output_sections());
+  const std::vector<Address>& out_offsets(this->section_offsets_);
 
   Relocate_info<size, big_endian> relinfo;
   relinfo.options = &options;
@@ -714,7 +717,7 @@ Sized_relobj<size, big_endian>::relocate_sections(
       if (sh_type != elfcpp::SHT_REL && sh_type != elfcpp::SHT_RELA)
        continue;
 
-      unsigned int index = shdr.get_sh_info();
+      unsigned int index = this->adjust_shndx(shdr.get_sh_info());
       if (index >= this->shnum())
        {
          this->error(_("relocation section %u has bad info %u"),
@@ -722,24 +725,24 @@ Sized_relobj<size, big_endian>::relocate_sections(
          continue;
        }
 
-      Output_section* os = map_sections[index].output_section;
+      Output_section* os = out_sections[index];
       if (os == NULL)
        {
          // This relocation section is against a section which we
          // discarded.
          continue;
        }
-      off_t output_offset = map_sections[index].offset;
+      Address output_offset = out_offsets[index];
 
       gold_assert((*pviews)[index].view != NULL);
       if (parameters->options().relocatable())
        gold_assert((*pviews)[i].view != NULL);
 
-      if (shdr.get_sh_link() != this->symtab_shndx_)
+      if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx_)
        {
          gold_error(_("relocation section %u uses unexpected "
                       "symbol table %u"),
-                    i, shdr.get_sh_link());
+                    i, this->adjust_shndx(shdr.get_sh_link()));
          continue;
        }
 
@@ -769,7 +772,7 @@ Sized_relobj<size, big_endian>::relocate_sections(
          continue;
        }
 
-      gold_assert(output_offset != -1
+      gold_assert(output_offset != invalid_address
                  || this->relocs_must_follow_section_writes());
 
       relinfo.reloc_shndx = i;
@@ -781,7 +784,7 @@ Sized_relobj<size, big_endian>::relocate_sections(
                                   prelocs,
                                   reloc_count,
                                   os,
-                                  output_offset == -1,
+                                  output_offset == invalid_address,
                                   (*pviews)[index].view,
                                   (*pviews)[index].address,
                                   (*pviews)[index].view_size);
@@ -824,7 +827,7 @@ Sized_relobj<size, big_endian>::emit_relocs(
     const unsigned char* prelocs,
     size_t reloc_count,
     Output_section* output_section,
-    off_t offset_in_output_section,
+    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size,
@@ -860,7 +863,7 @@ Sized_relobj<size, big_endian>::emit_relocs_reltype(
     const unsigned char* prelocs,
     size_t reloc_count,
     Output_section* output_section,
-    off_t offset_in_output_section,
+    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size,