// tilegx.cc -- tilegx target support for gold.
-// Copyright 2012 Free Software Foundation, Inc.
+// Copyright 2012, 2013 Free Software Foundation, Inc.
// Written by Jiong Wang (jiwang@tilera.com)
// This file is part of gold.
got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
global_offset_table_(NULL), tilegx_dynamic_(NULL), rela_dyn_(NULL),
rela_irelative_(NULL), copy_relocs_(elfcpp::R_TILEGX_COPY),
- dynbss_(NULL), got_mod_index_offset_(-1U),
+ got_mod_index_offset_(-1U),
tls_get_addr_sym_defined_(false)
{ }
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
- off_t offset_in_output_section,
+ typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
Reloc_section* rela_irelative_;
// Relocs saved to avoid a COPY reloc.
Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
- // Space for variables copied with a COPY reloc.
- Output_data_space* dynbss_;
// Offset of the GOT entry for the TLS module index.
unsigned int got_mod_index_offset_;
// True if the _tls_get_addr symbol has been defined.
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
- NULL // attributes_vendor
+ NULL, // attributes_vendor
+ "_start" // entry_symbol_name
};
template<>
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
- NULL // attributes_vendor
+ NULL, // attributes_vendor
+ "_start" // entry_symbol_name
};
template<>
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
- NULL // attributes_vendor
+ NULL, // attributes_vendor
+ "_start" // entry_symbol_name
};
template<>
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
- NULL // attributes_vendor
+ NULL, // attributes_vendor
+ "_start" // entry_symbol_name
};
// tilegx relocation handlers
// right shift operand by this number of bits.
unsigned char srshift;
- // the offset to apply relocation.
+ // the offset to apply relocation.
unsigned char doffset;
// set to 1 for pc-relative relocation.
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
Valtype reloc = 0;
- if (size == 32)
+ if (size == 32)
reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
>> srshift;
else
Valtype;
unsigned char* wv = view;
Valtype reloc = 0;
- if (size == 32)
+ if (size == 32)
reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
>> srshift;
else
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
Valtype reloc = 0;
- if (size == 32)
+ if (size == 32)
reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
>> srshift;
else
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
Tilegx_howto &r_howto)
- {
+ {
This::template rela<64>(view, object, psymval, addend,
(elfcpp::Elf_Xword)(r_howto.srshift),
(elfcpp::Elf_Xword)(r_howto.doffset),
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address,
Tilegx_howto &r_howto)
- {
+ {
This::template pcrela<64>(view, object, psymval, addend, address,
(elfcpp::Elf_Xword)(r_howto.srshift),
(elfcpp::Elf_Xword)(r_howto.doffset),
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address,
unsigned int r_type)
- {
+ {
elfcpp::Elf_Xword doffset1 = 0llu;
elfcpp::Elf_Xword doffset2 = 0llu;
static inline void
tls_relax(unsigned char* view, unsigned int r_type,
tls::Tls_optimization opt_t)
- {
-
+ {
+
const uint64_t TILEGX_X_MOVE_R0_R0 = 0x283bf8005107f000llu;
const uint64_t TILEGX_Y_MOVE_R0_R0 = 0xae05f800540bf000llu;
const uint64_t TILEGX_X_LD = 0x286ae80000000000llu;
// LE: 1. copy dest operand into the first source operand
// 2. change the opcode to "move"
reloc = (val & 0x3Fllu) << 6;
- reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK);
+ reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK);
val &= ~R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK;
} else
gold_unreachable();
break;
case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
if (opt_t == tls::TLSOPT_NONE) {
- // GD see comments for optimize_tls_reloc
+ // GD see comments for optimize_tls_reloc
reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK;
val &= ~TILEGX_X0_RRR_SRCB_MASK;
} else if (opt_t == tls::TLSOPT_TO_IE
false, false);
this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD);
- } else
+ } else
// for executable, just set the first entry to zero.
this->got_->set_current_data_size(size / 8);
plt_index = *pcount;
// TILEGX .plt section layout
- //
+ //
// ----
// plt_header
// ----
// ----
// ...
// ----
- //
+ //
// TILEGX .got.plt section layout
- //
+ //
// ----
// reserv1
// ----
// entries for normal function
// ----
// ...
- // ----
+ // ----
// entries for ifunc
// ----
// ...
// move r0, r0 Y0/Y1/X0/X1
// move r0, r0 Y0/Y1/X0/X1
// add adr, r0, tp Y0/Y1/X0/X1
-//
-//
+//
+//
// compiler IE reference
// |
// V
}
// We are about to emit a dynamic relocation of type R_TYPE. If the
-// dynamic linker does not support it, issue an error.
+// dynamic linker does not support it, issue an error.
template<int size, bool big_endian>
void
Target_tilegx<size, big_endian>::Scan::check_non_pic(Relobj* object,
data_shndx,
reloc.get_r_offset(),
reloc.get_r_addend());
-
+
}
}
break;
break;
// GD: requires two GOT entry for module index and offset
- // IE: requires one GOT entry for tp-relative offset
+ // IE: requires one GOT entry for tp-relative offset
// LE: shouldn't happen for global symbol
case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
r_sym, shndx);
else
got->add_local_pair_with_rel(object, r_sym, shndx,
- GOT_TYPE_TLS_PAIR,
+ GOT_TYPE_TLS_PAIR,
target->rela_dyn_section(layout),
size == 32
? elfcpp::R_TILEGX_TLS_DTPMOD32
? elfcpp::R_TILEGX_TLS_TPOFF32
: elfcpp::R_TILEGX_TLS_TPOFF64,
got, off, 0);
- } else if (opt_t != tls::TLSOPT_TO_LE)
+ } else if (opt_t != tls::TLSOPT_TO_LE)
// only TO_LE is allowed for local symbol
unsupported_reloc_local(object, r_type);
}
symtab->lookup("__tls_get_addr"));
}
break;
-
+
// only make effect when applying relocation
case elfcpp::R_TILEGX_TLS_IE_LOAD:
case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
break;
-
+
// GD: requires two GOT entry for module index and offset
- // IE: requires one GOT entry for tp-relative offset
+ // IE: requires one GOT entry for tp-relative offset
// LE: shouldn't happen for global symbol
case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
unsupported_reloc_global(object, r_type, gsym);
}
break;
-
+
// IE
case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
unsupported_reloc_global(object, r_type, gsym);
}
break;
-
+
// LE
case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
typename elfcpp::Elf_types<size>::Elf_Addr address,
section_size_type)
{
+ if (view == NULL)
+ return true;
+
typedef Tilegx_relocate_functions<size, big_endian> TilegxReloc;
typename TilegxReloc::Tilegx_howto r_howto;
} // else if (opt_t == tls::TLSOPT_TO_LE)
// both GD/IE are turned into LE, which
// is absolute relocation.
- //
+ //
// | go through
- // |
+ // |
// V
// LE
- //
+ //
// tp
// |
// V
- // t_var1 | t_var2 | t_var3 | ...
+ // t_var1 | t_var2 | t_var3 | ...
// --------------------------------------------------
//
// so offset to tp should be negative, we get offset
|| issue_undefined_symbol_error(gsym));
return false;
}
-
+
typename elfcpp::Elf_types<size>::Elf_Addr value
= psymval->value(relinfo->object, 0);
symval.set_output_value(value);
gold_assert(sh_type == elfcpp::SHT_RELA);
- gold::relocate_section<size, big_endian, Tilegx,
- elfcpp::SHT_RELA, Tilegx_relocate>(
+ gold::relocate_section<size, big_endian, Tilegx, elfcpp::SHT_RELA,
+ Tilegx_relocate, gold::Default_comdat_behavior>(
relinfo,
this,
prelocs,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
- off_t offset_in_output_section,
+ typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
const Relocatable_relocs* rr,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
return ssym->value();
}
-// The selector for tilegx object files.
+// The selector for tilegx object files.
template<int size, bool big_endian>
class Target_selector_tilegx : public Target_selector