aboutsummaryrefslogtreecommitdiff
path: root/gold/target-reloc.h
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2006-11-03 18:26:11 +0000
committerIan Lance Taylor <iant@google.com>2006-11-03 18:26:11 +0000
commitead1e4244a55707685d105c662a9a1faf5d122fe (patch)
tree3dd8ba9d010b4241ea750f6bdab49c6f3738036a /gold/target-reloc.h
parent58ea3d6a2f4d205b86b1baeaee5f6865393a6dd6 (diff)
downloadgdb-ead1e4244a55707685d105c662a9a1faf5d122fe.zip
gdb-ead1e4244a55707685d105c662a9a1faf5d122fe.tar.gz
gdb-ead1e4244a55707685d105c662a9a1faf5d122fe.tar.bz2
Can now do a full static link of hello, world in C or C++
Diffstat (limited to 'gold/target-reloc.h')
-rw-r--r--gold/target-reloc.h53
1 files changed, 32 insertions, 21 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 2d1fe30..ebaa827 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -36,11 +36,14 @@ struct Reloc_types<elfcpp::SHT_RELA, size, big_endian>
// way to avoidmaking a function call for each relocation, and to
// avoid repeating the generic code for each target.
-template<int size, bool big_endian, int sh_type, typename Scan>
+template<int size, bool big_endian, typename Target_type, int sh_type,
+ typename Scan>
inline void
scan_relocs(
const General_options& options,
Symbol_table* symtab,
+ Layout* layout,
+ Target_type* target,
Sized_object<size, big_endian>* object,
const unsigned char* prelocs,
size_t reloc_count,
@@ -68,6 +71,7 @@ scan_relocs(
+ r_sym * sym_size);
const unsigned int shndx = lsym.get_st_shndx();
if (shndx < elfcpp::SHN_LORESERVE
+ && shndx != elfcpp::SHN_UNDEF
&& !object->is_section_included(lsym.get_st_shndx()))
{
// RELOC is a relocation against a local symbol in a
@@ -88,7 +92,8 @@ scan_relocs(
continue;
}
- scan.local(options, object, reloc, r_type, lsym);
+ scan.local(options, symtab, layout, target, object, reloc, r_type,
+ lsym);
}
else
{
@@ -97,7 +102,8 @@ scan_relocs(
if (gsym->is_forwarder())
gsym = symtab->resolve_forwards(gsym);
- scan.global(options, object, reloc, r_type, gsym);
+ scan.global(options, symtab, layout, target, object, reloc, r_type,
+ gsym);
}
}
}
@@ -117,10 +123,12 @@ scan_relocs(
// of relocs. VIEW is the section data, VIEW_ADDRESS is its memory
// address, and VIEW_SIZE is the size.
-template<int size, bool big_endian, int sh_type, typename Relocate>
+template<int size, bool big_endian, typename Target_type, int sh_type,
+ typename Relocate>
inline void
relocate_section(
const Relocate_info<size, big_endian>* relinfo,
+ Target_type* target,
const unsigned char* prelocs,
size_t reloc_count,
unsigned char* view,
@@ -140,13 +148,6 @@ relocate_section(
Reltype reloc(prelocs);
off_t offset = reloc.get_r_offset();
- if (offset < 0 || offset >= view_size)
- {
- fprintf(stderr, _("%s: %s: reloc has bad offset %zu\n"),
- program_name, relinfo->location(i, offset).c_str(),
- static_cast<size_t>(offset));
- gold_exit(false);
- }
typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
@@ -169,19 +170,29 @@ relocate_section(
sym = static_cast<Sized_symbol<size>*>(gsym);
value = sym->value();
+ }
- if (sym->shnum() == elfcpp::SHN_UNDEF
- && sym->binding() != elfcpp::STB_WEAK)
- {
- fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"),
- program_name, relinfo->location(i, offset).c_str(),
- sym->name());
- // gold_exit(false);
- }
+ if (!relocate.relocate(relinfo, target, i, reloc, r_type, sym, value,
+ view + offset, view_address + offset, view_size))
+ continue;
+
+ if (offset < 0 || offset >= view_size)
+ {
+ fprintf(stderr, _("%s: %s: reloc has bad offset %zu\n"),
+ program_name, relinfo->location(i, offset).c_str(),
+ static_cast<size_t>(offset));
+ gold_exit(false);
}
- relocate.relocate(relinfo, i, reloc, r_type, sym, value, view + offset,
- view_address + offset, view_size);
+ if (sym != NULL
+ && sym->is_undefined()
+ && sym->binding() != elfcpp::STB_WEAK)
+ {
+ fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"),
+ program_name, relinfo->location(i, offset).c_str(),
+ sym->name());
+ // gold_exit(false);
+ }
}
}