#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
+#include "freebsd.h"
namespace
{
// http://people.redhat.com/drepper/tls.pdf
// http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt
-class Target_i386 : public Sized_target<32, false>
+class Target_i386 : public Target_freebsd<32, false>
{
public:
typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
Target_i386()
- : Sized_target<32, false>(&i386_info),
+ : Target_freebsd<32, false>(&i386_info),
got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
copy_relocs_(elfcpp::R_386_COPY), dynbss_(NULL),
got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
inline bool
should_apply_static_reloc(const Sized_symbol<32>* gsym,
int ref_flags,
- bool is_32bit);
+ bool is_32bit,
+ Output_section* output_section);
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
- relocate(const Relocate_info<32, false>*, Target_i386*, size_t relnum,
- const elfcpp::Rel<32, false>&,
+ relocate(const Relocate_info<32, false>*, Target_i386*, Output_section*,
+ size_t relnum, const elfcpp::Rel<32, false>&,
unsigned int r_type, const Sized_symbol<32>*,
const Symbol_value<32>*,
unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
inline bool
Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
int ref_flags,
- bool is_32bit)
+ bool is_32bit,
+ Output_section* output_section)
{
+ // If the output section is not allocated, then we didn't call
+ // scan_relocs, we didn't create a dynamic reloc, and we must apply
+ // the reloc here.
+ if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
+ return true;
+
// For local symbols, we will have created a non-RELATIVE dynamic
// relocation only if (a) the output is position independent,
// (b) the relocation is absolute (not pc- or segment-relative), and
inline bool
Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
Target_i386* target,
+ Output_section *output_section,
size_t relnum,
const elfcpp::Rel<32, false>& rel,
unsigned int r_type,
break;
case elfcpp::R_386_32:
- if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true))
+ if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+ output_section))
Relocate_functions<32, false>::rel32(view, object, psymval);
break;
int ref_flags = Symbol::NON_PIC_REF;
if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
ref_flags |= Symbol::FUNCTION_CALL;
- if (should_apply_static_reloc(gsym, ref_flags, true))
+ if (should_apply_static_reloc(gsym, ref_flags, true, output_section))
Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
}
break;
case elfcpp::R_386_16:
- if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false))
+ if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
+ output_section))
Relocate_functions<32, false>::rel16(view, object, psymval);
break;
int ref_flags = Symbol::NON_PIC_REF;
if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
ref_flags |= Symbol::FUNCTION_CALL;
- if (should_apply_static_reloc(gsym, ref_flags, false))
+ if (should_apply_static_reloc(gsym, ref_flags, false, output_section))
Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
}
break;
case elfcpp::R_386_8:
- if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false))
+ if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
+ output_section))
Relocate_functions<32, false>::rel8(view, object, psymval);
break;
int ref_flags = Symbol::NON_PIC_REF;
if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
ref_flags |= Symbol::FUNCTION_CALL;
- if (should_apply_static_reloc(gsym, ref_flags, false))
+ if (should_apply_static_reloc(gsym, ref_flags, false,
+ output_section))
Relocate_functions<32, false>::pcrel8(view, object, psymval, address);
}
break;
// The selector for i386 object files.
-class Target_selector_i386 : public Target_selector
+class Target_selector_i386 : public Target_selector_freebsd
{
public:
Target_selector_i386()
- : Target_selector(elfcpp::EM_386, 32, false, "elf32-i386")
+ : Target_selector_freebsd(elfcpp::EM_386, 32, false,
+ "elf32-i386", "elf32-i386-freebsd")
{ }
Target*