const int warn_prefix_len = sizeof warn_prefix - 1;
if (strncmp(name, warn_prefix, warn_prefix_len) == 0)
{
- symtab->add_warning(name + warn_prefix_len, this, shndx);
+ // Read the section contents to get the warning text. It would
+ // be nicer if we only did this if we have to actually issue a
+ // warning. Unfortunately, warnings are issued as we relocate
+ // sections. That means that we can not lock the object then,
+ // as we might try to issue the same warning multiple times
+ // simultaneously.
+ section_size_type len;
+ const unsigned char* contents = this->section_contents(shndx, &len,
+ false);
+ std::string warning(reinterpret_cast<const char*>(contents), len);
+ symtab->add_warning(name + warn_prefix_len, this, warning);
return true;
}
return false;
return false;
}
off_t symoff = symshdr.get_sh_offset() + shdr.get_sh_info() * This::sym_size;
- const unsigned char* psym = this->get_view(symoff, This::sym_size, true);
+ const unsigned char* psym = this->get_view(symoff, This::sym_size, false);
elfcpp::Sym<size, big_endian> sym(psym);
// Read the symbol table names.
sd->symbol_names = NULL;
}
-// Finalize the local symbols. Here we add their names to *POOL and
-// *DYNPOOL, and we add their values to THIS->LOCAL_VALUES_. This
-// function is always called from a singleton thread. The actual
-// output of the local symbols will occur in a separate task.
+// First pass over the local symbols. Here we add their names to
+// *POOL and *DYNPOOL, and we store the symbol value in
+// THIS->LOCAL_VALUES_. This function is always called from a
+// singleton thread. This is followed by a call to
+// finalize_local_symbols.
template<int size, bool big_endian>
void
this->output_local_dynsym_count_ = dyncount;
}
-// Finalize the local symbols. Here we add their values to
+// Finalize the local symbols. Here we set the final value in
// THIS->LOCAL_VALUES_ and set their output symbol table indexes.
// This function is always called from a singleton thread. The actual
// output of the local symbols will occur in a separate task.
}
else if (mo[shndx].offset == -1)
{
- // Leave the input value in place for SHF_MERGE sections.
+ // This is a SHF_MERGE section or one which otherwise
+ // requires special handling. We get the output address
+ // of the start of the merged section. If this is not a
+ // section symbol, we can then determine the final
+ // value. If it is a section symbol, we can not, as in
+ // that case we have to consider the addend to determine
+ // the value to use in a relocation.
+ if (!lv.is_section_symbol())
+ lv.set_output_value(os->output_address(this, shndx,
+ lv.input_value()));
+ else
+ {
+ section_offset_type start =
+ os->starting_output_address(this, shndx);
+ Merged_symbol_value<size>* msv =
+ new Merged_symbol_value<size>(lv.input_value(), start);
+ lv.set_merged_symbol_value(msv);
+ }
}
else if (lv.is_tls_symbol())
- lv.set_output_value(mo[shndx].output_section->tls_offset()
+ lv.set_output_value(os->tls_offset()
+ mo[shndx].offset
+ lv.input_value());
else
- lv.set_output_value(mo[shndx].output_section->address()
+ lv.set_output_value(os->address()
+ mo[shndx].offset
+ lv.input_value());
}
return lv.value(this, 0);
}
-// Return the value of a local symbol defined in input section SHNDX,
-// with value VALUE, adding addend ADDEND. IS_SECTION_SYMBOL
-// indicates whether the symbol is a section symbol. This handles
-// SHF_MERGE sections.
-template<int size, bool big_endian>
-typename elfcpp::Elf_types<size>::Elf_Addr
-Sized_relobj<size, big_endian>::local_value(unsigned int shndx,
- Address value,
- bool is_section_symbol,
- Address addend) const
-{
- const std::vector<Map_to_output>& mo(this->map_to_output());
- Output_section* os = mo[shndx].output_section;
- if (os == NULL)
- return addend;
- gold_assert(mo[shndx].offset == -1);
-
- // Do the mapping required by the output section. If this is not a
- // section symbol, then we want to map the symbol value, and then
- // include the addend. If this is a section symbol, then we need to
- // include the addend to figure out where in the section we are,
- // before we do the mapping. This will do the right thing provided
- // the assembler is careful to only convert a relocation in a merged
- // section to a section symbol if there is a zero addend. If the
- // assembler does not do this, then in general we can't know what to
- // do, because we can't distinguish the addend for the instruction
- // format from the addend for the section offset.
-
- if (is_section_symbol)
- return os->output_address(this, shndx, value + addend);
- else
- return addend + os->output_address(this, shndx, value);
-}
-
// Write out the local symbols.
template<int size, bool big_endian>
section_size_type strtab_size;
const unsigned char* pnamesu = this->section_contents(strtab_shndx,
&strtab_size,
- true);
+ false);
const char* pnames = reinterpret_cast<const char*>(pnamesu);
// Get views into the output file for the portions of the symbol table