1// target-reloc.h -- target specific relocation support  -*- C++ -*-
2
3// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4// Written by Ian Lance Taylor <iant@google.com>.
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23#ifndef GOLD_TARGET_RELOC_H
24#define GOLD_TARGET_RELOC_H
25
26#include "elfcpp.h"
27#include "symtab.h"
28#include "object.h"
29#include "reloc.h"
30#include "reloc-types.h"
31
32namespace gold
33{
34
35// This function implements the generic part of reloc scanning.  The
36// template parameter Scan must be a class type which provides two
37// functions: local() and global().  Those functions implement the
38// machine specific part of scanning.  We do it this way to
39// avoidmaking a function call for each relocation, and to avoid
40// repeating the generic code for each target.
41
42template<int size, bool big_endian, typename Target_type, int sh_type,
43	 typename Scan>
44inline void
45scan_relocs(
46    Symbol_table* symtab,
47    Layout* layout,
48    Target_type* target,
49    Sized_relobj<size, big_endian>* object,
50    unsigned int data_shndx,
51    const unsigned char* prelocs,
52    size_t reloc_count,
53    Output_section* output_section,
54    bool needs_special_offset_handling,
55    size_t local_count,
56    const unsigned char* plocal_syms)
57{
58  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
59  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
60  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
61  Scan scan;
62
63  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
64    {
65      Reltype reloc(prelocs);
66
67      if (needs_special_offset_handling
68	  && !output_section->is_input_address_mapped(object, data_shndx,
69						      reloc.get_r_offset()))
70	continue;
71
72      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
73      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
74      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
75
76      if (r_sym < local_count)
77	{
78	  gold_assert(plocal_syms != NULL);
79	  typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
80						      + r_sym * sym_size);
81	  unsigned int shndx = lsym.get_st_shndx();
82	  bool is_ordinary;
83	  shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
84	  if (is_ordinary
85	      && shndx != elfcpp::SHN_UNDEF
86	      && !object->is_section_included(shndx)
87              && !symtab->is_section_folded(object, shndx))
88	    {
89	      // RELOC is a relocation against a local symbol in a
90	      // section we are discarding.  We can ignore this
91	      // relocation.  It will eventually become a reloc
92	      // against the value zero.
93	      //
94	      // FIXME: We should issue a warning if this is an
95	      // allocated section; is this the best place to do it?
96	      //
97	      // FIXME: The old GNU linker would in some cases look
98	      // for the linkonce section which caused this section to
99	      // be discarded, and, if the other section was the same
100	      // size, change the reloc to refer to the other section.
101	      // That seems risky and weird to me, and I don't know of
102	      // any case where it is actually required.
103
104	      continue;
105	    }
106	  scan.local(symtab, layout, target, object, data_shndx,
107		     output_section, reloc, r_type, lsym);
108	}
109      else
110	{
111	  Symbol* gsym = object->global_symbol(r_sym);
112	  gold_assert(gsym != NULL);
113	  if (gsym->is_forwarder())
114	    gsym = symtab->resolve_forwards(gsym);
115
116	  scan.global(symtab, layout, target, object, data_shndx,
117		      output_section, reloc, r_type, gsym);
118	}
119    }
120}
121
122// Behavior for relocations to discarded comdat sections.
123
124enum Comdat_behavior
125{
126  CB_UNDETERMINED,   // Not yet determined -- need to look at section name.
127  CB_PRETEND,        // Attempt to map to the corresponding kept section.
128  CB_IGNORE,         // Ignore the relocation.
129  CB_WARNING         // Print a warning.
130};
131
132// Decide what the linker should do for relocations that refer to discarded
133// comdat sections.  This decision is based on the name of the section being
134// relocated.
135
136inline Comdat_behavior
137get_comdat_behavior(const char* name)
138{
139  if (Layout::is_debug_info_section(name))
140    return CB_PRETEND;
141  if (strcmp(name, ".eh_frame") == 0
142      || strcmp(name, ".gcc_except_table") == 0)
143    return CB_IGNORE;
144  return CB_WARNING;
145}
146
147// Give an error for a symbol with non-default visibility which is not
148// defined locally.
149
150inline void
151visibility_error(const Symbol* sym)
152{
153  const char* v;
154  switch (sym->visibility())
155    {
156    case elfcpp::STV_INTERNAL:
157      v = _("internal");
158      break;
159    case elfcpp::STV_HIDDEN:
160      v = _("hidden");
161      break;
162    case elfcpp::STV_PROTECTED:
163      v = _("protected");
164      break;
165    default:
166      gold_unreachable();
167    }
168  gold_error(_("%s symbol '%s' is not defined locally"),
169	     v, sym->name());
170}
171
172// This function implements the generic part of relocation processing.
173// The template parameter Relocate must be a class type which provides
174// a single function, relocate(), which implements the machine
175// specific part of a relocation.
176
177// SIZE is the ELF size: 32 or 64.  BIG_ENDIAN is the endianness of
178// the data.  SH_TYPE is the section type: SHT_REL or SHT_RELA.
179// RELOCATE implements operator() to do a relocation.
180
181// PRELOCS points to the relocation data.  RELOC_COUNT is the number
182// of relocs.  OUTPUT_SECTION is the output section.
183// NEEDS_SPECIAL_OFFSET_HANDLING is true if input offsets need to be
184// mapped to output offsets.
185
186// VIEW is the section data, VIEW_ADDRESS is its memory address, and
187// VIEW_SIZE is the size.  These refer to the input section, unless
188// NEEDS_SPECIAL_OFFSET_HANDLING is true, in which case they refer to
189// the output section.
190
191// RELOC_SYMBOL_CHANGES is used for -fsplit-stack support.  If it is
192// not NULL, it is a vector indexed by relocation index.  If that
193// entry is not NULL, it points to a global symbol which used as the
194// symbol for the relocation, ignoring the symbol index in the
195// relocation.
196
197template<int size, bool big_endian, typename Target_type, int sh_type,
198	 typename Relocate>
199inline void
200relocate_section(
201    const Relocate_info<size, big_endian>* relinfo,
202    Target_type* target,
203    const unsigned char* prelocs,
204    size_t reloc_count,
205    Output_section* output_section,
206    bool needs_special_offset_handling,
207    unsigned char* view,
208    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
209    section_size_type view_size,
210    const Reloc_symbol_changes* reloc_symbol_changes)
211{
212  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
213  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
214  Relocate relocate;
215
216  Sized_relobj<size, big_endian>* object = relinfo->object;
217  unsigned int local_count = object->local_symbol_count();
218
219  Comdat_behavior comdat_behavior = CB_UNDETERMINED;
220
221  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
222    {
223      Reltype reloc(prelocs);
224
225      section_offset_type offset =
226	convert_to_section_size_type(reloc.get_r_offset());
227
228      if (needs_special_offset_handling)
229	{
230	  offset = output_section->output_offset(relinfo->object,
231						 relinfo->data_shndx,
232						 offset);
233	  if (offset == -1)
234	    continue;
235	}
236
237      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
238      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
239      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
240
241      const Sized_symbol<size>* sym;
242
243      Symbol_value<size> symval;
244      const Symbol_value<size> *psymval;
245      bool is_defined_in_discarded_section;
246      unsigned int shndx;
247      if (r_sym < local_count
248	  && (reloc_symbol_changes == NULL
249	      || (*reloc_symbol_changes)[i] == NULL))
250	{
251	  sym = NULL;
252	  psymval = object->local_symbol(r_sym);
253
254          // If the local symbol belongs to a section we are discarding,
255          // and that section is a debug section, try to find the
256          // corresponding kept section and map this symbol to its
257          // counterpart in the kept section.  The symbol must not
258          // correspond to a section we are folding.
259	  bool is_ordinary;
260	  shndx = psymval->input_shndx(&is_ordinary);
261	  is_defined_in_discarded_section =
262	    (is_ordinary
263	     && shndx != elfcpp::SHN_UNDEF
264	     && !object->is_section_included(shndx)
265	     && !relinfo->symtab->is_section_folded(object, shndx));
266	}
267      else
268	{
269	  const Symbol* gsym;
270	  if (reloc_symbol_changes != NULL
271	      && (*reloc_symbol_changes)[i] != NULL)
272	    gsym = (*reloc_symbol_changes)[i];
273	  else
274	    {
275	      gsym = object->global_symbol(r_sym);
276	      gold_assert(gsym != NULL);
277	      if (gsym->is_forwarder())
278		gsym = relinfo->symtab->resolve_forwards(gsym);
279	    }
280
281	  sym = static_cast<const Sized_symbol<size>*>(gsym);
282	  if (sym->has_symtab_index() && sym->symtab_index() != -1U)
283	    symval.set_output_symtab_index(sym->symtab_index());
284	  else
285	    symval.set_no_output_symtab_entry();
286	  symval.set_output_value(sym->value());
287	  if (gsym->type() == elfcpp::STT_TLS)
288	    symval.set_is_tls_symbol();
289	  else if (gsym->type() == elfcpp::STT_GNU_IFUNC)
290	    symval.set_is_ifunc_symbol();
291	  psymval = &symval;
292
293	  is_defined_in_discarded_section =
294	    (gsym->is_defined_in_discarded_section()
295	     && gsym->is_undefined());
296	  shndx = 0;
297	}
298
299      Symbol_value<size> symval2;
300      if (is_defined_in_discarded_section)
301	{
302	  if (comdat_behavior == CB_UNDETERMINED)
303	    {
304	      std::string name = object->section_name(relinfo->data_shndx);
305	      comdat_behavior = get_comdat_behavior(name.c_str());
306	    }
307	  if (comdat_behavior == CB_PRETEND)
308	    {
309	      // FIXME: This case does not work for global symbols.
310	      // We have no place to store the original section index.
311	      // Fortunately this does not matter for comdat sections,
312	      // only for sections explicitly discarded by a linker
313	      // script.
314	      bool found;
315	      typename elfcpp::Elf_types<size>::Elf_Addr value =
316		object->map_to_kept_section(shndx, &found);
317	      if (found)
318		symval2.set_output_value(value + psymval->input_value());
319	      else
320		symval2.set_output_value(0);
321	    }
322	  else
323	    {
324	      if (comdat_behavior == CB_WARNING)
325		gold_warning_at_location(relinfo, i, offset,
326					 _("relocation refers to discarded "
327					   "section"));
328	      symval2.set_output_value(0);
329	    }
330	  symval2.set_no_output_symtab_entry();
331	  psymval = &symval2;
332	}
333
334      if (!relocate.relocate(relinfo, target, output_section, i, reloc,
335			     r_type, sym, psymval, view + offset,
336			     view_address + offset, view_size))
337	continue;
338
339      if (offset < 0 || static_cast<section_size_type>(offset) >= view_size)
340	{
341	  gold_error_at_location(relinfo, i, offset,
342				 _("reloc has bad offset %zu"),
343				 static_cast<size_t>(offset));
344	  continue;
345	}
346
347      if (sym != NULL
348	  && (sym->is_undefined() || sym->is_placeholder())
349	  && sym->binding() != elfcpp::STB_WEAK
350	  && !is_defined_in_discarded_section
351          && !target->is_defined_by_abi(sym)
352	  && (!parameters->options().shared()       // -shared
353              || parameters->options().defs()))     // -z defs
354	gold_undefined_symbol_at_location(sym, relinfo, i, offset);
355      else if (sym != NULL
356	       && sym->visibility() != elfcpp::STV_DEFAULT
357	       && (sym->is_undefined() || sym->is_from_dynobj()))
358	visibility_error(sym);
359
360      if (sym != NULL && sym->has_warning())
361	relinfo->symtab->issue_warning(sym, relinfo, i, offset);
362    }
363}
364
365// This class may be used as a typical class for the
366// Scan_relocatable_reloc parameter to scan_relocatable_relocs.  The
367// template parameter Classify_reloc must be a class type which
368// provides a function get_size_for_reloc which returns the number of
369// bytes to which a reloc applies.  This class is intended to capture
370// the most typical target behaviour, while still permitting targets
371// to define their own independent class for Scan_relocatable_reloc.
372
373template<int sh_type, typename Classify_reloc>
374class Default_scan_relocatable_relocs
375{
376 public:
377  // Return the strategy to use for a local symbol which is not a
378  // section symbol, given the relocation type.
379  inline Relocatable_relocs::Reloc_strategy
380  local_non_section_strategy(unsigned int r_type, Relobj*, unsigned int r_sym)
381  {
382    // We assume that relocation type 0 is NONE.  Targets which are
383    // different must override.
384    if (r_type == 0 && r_sym == 0)
385      return Relocatable_relocs::RELOC_DISCARD;
386    return Relocatable_relocs::RELOC_COPY;
387  }
388
389  // Return the strategy to use for a local symbol which is a section
390  // symbol, given the relocation type.
391  inline Relocatable_relocs::Reloc_strategy
392  local_section_strategy(unsigned int r_type, Relobj* object)
393  {
394    if (sh_type == elfcpp::SHT_RELA)
395      return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
396    else
397      {
398	Classify_reloc classify;
399	switch (classify.get_size_for_reloc(r_type, object))
400	  {
401	  case 0:
402	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
403	  case 1:
404	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1;
405	  case 2:
406	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2;
407	  case 4:
408	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4;
409	  case 8:
410	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8;
411	  default:
412	    gold_unreachable();
413	  }
414      }
415  }
416
417  // Return the strategy to use for a global symbol, given the
418  // relocation type, the object, and the symbol index.
419  inline Relocatable_relocs::Reloc_strategy
420  global_strategy(unsigned int, Relobj*, unsigned int)
421  { return Relocatable_relocs::RELOC_COPY; }
422};
423
424// Scan relocs during a relocatable link.  This is a default
425// definition which should work for most targets.
426// Scan_relocatable_reloc must name a class type which provides three
427// functions which return a Relocatable_relocs::Reloc_strategy code:
428// global_strategy, local_non_section_strategy, and
429// local_section_strategy.  Most targets should be able to use
430// Default_scan_relocatable_relocs as this class.
431
432template<int size, bool big_endian, int sh_type,
433	 typename Scan_relocatable_reloc>
434void
435scan_relocatable_relocs(
436    Symbol_table*,
437    Layout*,
438    Sized_relobj<size, big_endian>* object,
439    unsigned int data_shndx,
440    const unsigned char* prelocs,
441    size_t reloc_count,
442    Output_section* output_section,
443    bool needs_special_offset_handling,
444    size_t local_symbol_count,
445    const unsigned char* plocal_syms,
446    Relocatable_relocs* rr)
447{
448  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
449  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
450  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
451  Scan_relocatable_reloc scan;
452
453  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
454    {
455      Reltype reloc(prelocs);
456
457      Relocatable_relocs::Reloc_strategy strategy;
458
459      if (needs_special_offset_handling
460	  && !output_section->is_input_address_mapped(object, data_shndx,
461						      reloc.get_r_offset()))
462	strategy = Relocatable_relocs::RELOC_DISCARD;
463      else
464	{
465	  typename elfcpp::Elf_types<size>::Elf_WXword r_info =
466	    reloc.get_r_info();
467	  const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
468	  const unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
469
470	  if (r_sym >= local_symbol_count)
471	    strategy = scan.global_strategy(r_type, object, r_sym);
472	  else
473	    {
474	      gold_assert(plocal_syms != NULL);
475	      typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
476							  + r_sym * sym_size);
477	      unsigned int shndx = lsym.get_st_shndx();
478	      bool is_ordinary;
479	      shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
480	      if (is_ordinary
481		  && shndx != elfcpp::SHN_UNDEF
482		  && !object->is_section_included(shndx))
483		{
484		  // RELOC is a relocation against a local symbol
485		  // defined in a section we are discarding.  Discard
486		  // the reloc.  FIXME: Should we issue a warning?
487		  strategy = Relocatable_relocs::RELOC_DISCARD;
488		}
489	      else if (lsym.get_st_type() != elfcpp::STT_SECTION)
490		strategy = scan.local_non_section_strategy(r_type, object,
491							   r_sym);
492	      else
493		{
494		  strategy = scan.local_section_strategy(r_type, object);
495		  if (strategy != Relocatable_relocs::RELOC_DISCARD)
496                    object->output_section(shndx)->set_needs_symtab_index();
497		}
498
499	      if (strategy == Relocatable_relocs::RELOC_COPY)
500		object->set_must_have_output_symtab_entry(r_sym);
501	    }
502	}
503
504      rr->set_next_reloc_strategy(strategy);
505    }
506}
507
508// Relocate relocs during a relocatable link.  This is a default
509// definition which should work for most targets.
510
511template<int size, bool big_endian, int sh_type>
512void
513relocate_for_relocatable(
514    const Relocate_info<size, big_endian>* relinfo,
515    const unsigned char* prelocs,
516    size_t reloc_count,
517    Output_section* output_section,
518    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
519    const Relocatable_relocs* rr,
520    unsigned char* view,
521    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
522    section_size_type view_size,
523    unsigned char* reloc_view,
524    section_size_type reloc_view_size)
525{
526  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
527  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
528  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write
529    Reltype_write;
530  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
531  const Address invalid_address = static_cast<Address>(0) - 1;
532
533  Sized_relobj<size, big_endian>* const object = relinfo->object;
534  const unsigned int local_count = object->local_symbol_count();
535
536  unsigned char* pwrite = reloc_view;
537
538  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
539    {
540      Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i);
541      if (strategy == Relocatable_relocs::RELOC_DISCARD)
542	continue;
543
544      if (strategy == Relocatable_relocs::RELOC_SPECIAL)
545	{
546	  // Target wants to handle this relocation.
547	  Sized_target<size, big_endian>* target =
548	    parameters->sized_target<size, big_endian>();
549	  target->relocate_special_relocatable(relinfo, sh_type, prelocs,
550					       i, output_section,
551					       offset_in_output_section,
552					       view, view_address,
553					       view_size, pwrite);
554	  pwrite += reloc_size;
555	  continue;
556	}
557      Reltype reloc(prelocs);
558      Reltype_write reloc_write(pwrite);
559
560      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
561      const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
562      const unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
563
564      // Get the new symbol index.
565
566      unsigned int new_symndx;
567      if (r_sym < local_count)
568	{
569	  switch (strategy)
570	    {
571	    case Relocatable_relocs::RELOC_COPY:
572	      if (r_sym == 0)
573		new_symndx = 0;
574	      else
575		{
576		  new_symndx = object->symtab_index(r_sym);
577		  gold_assert(new_symndx != -1U);
578		}
579	      break;
580
581	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
582	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0:
583	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1:
584	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2:
585	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4:
586	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8:
587	      {
588		// We are adjusting a section symbol.  We need to find
589		// the symbol table index of the section symbol for
590		// the output section corresponding to input section
591		// in which this symbol is defined.
592		gold_assert(r_sym < local_count);
593		bool is_ordinary;
594		unsigned int shndx =
595		  object->local_symbol_input_shndx(r_sym, &is_ordinary);
596		gold_assert(is_ordinary);
597		Output_section* os = object->output_section(shndx);
598		gold_assert(os != NULL);
599		gold_assert(os->needs_symtab_index());
600		new_symndx = os->symtab_index();
601	      }
602	      break;
603
604	    default:
605	      gold_unreachable();
606	    }
607	}
608      else
609	{
610	  const Symbol* gsym = object->global_symbol(r_sym);
611	  gold_assert(gsym != NULL);
612	  if (gsym->is_forwarder())
613	    gsym = relinfo->symtab->resolve_forwards(gsym);
614
615	  gold_assert(gsym->has_symtab_index());
616	  new_symndx = gsym->symtab_index();
617	}
618
619      // Get the new offset--the location in the output section where
620      // this relocation should be applied.
621
622      Address offset = reloc.get_r_offset();
623      Address new_offset;
624      if (offset_in_output_section != invalid_address)
625	new_offset = offset + offset_in_output_section;
626      else
627	{
628          section_offset_type sot_offset =
629              convert_types<section_offset_type, Address>(offset);
630	  section_offset_type new_sot_offset =
631              output_section->output_offset(object, relinfo->data_shndx,
632                                            sot_offset);
633	  gold_assert(new_sot_offset != -1);
634          new_offset = new_sot_offset;
635	}
636
637      // In an object file, r_offset is an offset within the section.
638      // In an executable or dynamic object, generated by
639      // --emit-relocs, r_offset is an absolute address.
640      if (!parameters->options().relocatable())
641	{
642	  new_offset += view_address;
643	  if (offset_in_output_section != invalid_address)
644	    new_offset -= offset_in_output_section;
645	}
646
647      reloc_write.put_r_offset(new_offset);
648      reloc_write.put_r_info(elfcpp::elf_r_info<size>(new_symndx, r_type));
649
650      // Handle the reloc addend based on the strategy.
651
652      if (strategy == Relocatable_relocs::RELOC_COPY)
653	{
654	  if (sh_type == elfcpp::SHT_RELA)
655	    Reloc_types<sh_type, size, big_endian>::
656	      copy_reloc_addend(&reloc_write,
657				&reloc);
658	}
659      else
660	{
661	  // The relocation uses a section symbol in the input file.
662	  // We are adjusting it to use a section symbol in the output
663	  // file.  The input section symbol refers to some address in
664	  // the input section.  We need the relocation in the output
665	  // file to refer to that same address.  This adjustment to
666	  // the addend is the same calculation we use for a simple
667	  // absolute relocation for the input section symbol.
668
669	  const Symbol_value<size>* psymval = object->local_symbol(r_sym);
670
671	  unsigned char* padd = view + offset;
672	  switch (strategy)
673	    {
674	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
675	      {
676		typename elfcpp::Elf_types<size>::Elf_Swxword addend;
677		addend = Reloc_types<sh_type, size, big_endian>::
678			   get_reloc_addend(&reloc);
679		addend = psymval->value(object, addend);
680		Reloc_types<sh_type, size, big_endian>::
681		  set_reloc_addend(&reloc_write, addend);
682	      }
683	      break;
684
685	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0:
686	      break;
687
688	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1:
689	      Relocate_functions<size, big_endian>::rel8(padd, object,
690							 psymval);
691	      break;
692
693	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2:
694	      Relocate_functions<size, big_endian>::rel16(padd, object,
695							  psymval);
696	      break;
697
698	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4:
699	      Relocate_functions<size, big_endian>::rel32(padd, object,
700							  psymval);
701	      break;
702
703	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8:
704	      Relocate_functions<size, big_endian>::rel64(padd, object,
705							  psymval);
706	      break;
707
708	    default:
709	      gold_unreachable();
710	    }
711	}
712
713      pwrite += reloc_size;
714    }
715
716  gold_assert(static_cast<section_size_type>(pwrite - reloc_view)
717	      == reloc_view_size);
718}
719
720} // End namespace gold.
721
722#endif // !defined(GOLD_TARGET_RELOC_H)
723