coff-m68k.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 532 行 · 第 1/2 页
C
532 行
return bfd_reloc_continue; if (bfd_is_com_section (symbol->section)) { /* We are relocating a common symbol. The current value in the object file is ORIG + OFFSET, where ORIG is the value of the common symbol as seen by the object file when it was compiled (this may be zero if the symbol was undefined) and OFFSET is the offset into the common symbol (normally zero, but may be non-zero when referring to a field in a common structure). ORIG is the negative of reloc_entry->addend, which is set by the CALC_ADDEND macro below. We want to replace the value in the object file with NEW + OFFSET, where NEW is the value of the common symbol which we are going to put in the final object file. NEW is symbol->value. */ diff = symbol->value + reloc_entry->addend; } else { /* For some reason bfd_perform_relocation always effectively ignores the addend for a COFF target when producing relocateable output. This seems to be always wrong for 386 COFF, so we handle the addend here instead. */ diff = reloc_entry->addend; }#define DOIT(x) \ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) if (diff != 0) { reloc_howto_type *howto = reloc_entry->howto; unsigned char *addr = (unsigned char *) data + reloc_entry->address; switch (howto->size) { case 0: { char x = bfd_get_8 (abfd, addr); DOIT (x); bfd_put_8 (abfd, x, addr); } break; case 1: { short x = bfd_get_16 (abfd, addr); DOIT (x); bfd_put_16 (abfd, x, addr); } break; case 2: { long x = bfd_get_32 (abfd, addr); DOIT (x); bfd_put_32 (abfd, x, addr); } break; default: abort (); } } /* Now let bfd_perform_relocation finish everything up. */ return bfd_reloc_continue;}/* Compute the addend of a reloc. If the reloc is to a common symbol, the object file contains the value of the common symbol. By the time this is called, the linker may be using a different symbol from a different object file with a different value. Therefore, we hack wildly to locate the original symbol from this file so that we can make the correct adjustment. This macro sets coffsym to the symbol from the original file, and uses it to set the addend value correctly. If this is not a common symbol, the usual addend calculation is done, except that an additional tweak is needed for PC relative relocs. FIXME: This macro refers to symbols and asect; these are from the calling function, not the macro arguments. */#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ { \ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ coffsym = (obj_symbols (abfd) \ + (cache_ptr->sym_ptr_ptr - symbols)); \ else if (ptr) \ coffsym = coff_symbol_from (abfd, ptr); \ if (coffsym != (coff_symbol_type *) NULL \ && coffsym->native->u.syment.n_scnum == 0) \ cache_ptr->addend = - coffsym->native->u.syment.n_value; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ && ptr->section != (asection *) NULL) \ cache_ptr->addend = - (ptr->section->vma + ptr->value); \ else \ cache_ptr->addend = 0; \ if (ptr && (reloc.r_type == R_PCRBYTE \ || reloc.r_type == R_PCRWORD \ || reloc.r_type == R_PCRLONG)) \ cache_ptr->addend += asect->vma; \ }#ifndef coff_rtype_to_howto/* coff-m68k.c uses the special COFF backend linker. We need to adjust common symbols. */static reloc_howto_type *m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp) bfd *abfd ATTRIBUTE_UNUSED; asection *sec; struct internal_reloc *rel; struct coff_link_hash_entry *h; struct internal_syment *sym; bfd_vma *addendp;{ arelent relent; reloc_howto_type *howto; RTYPE2HOWTO (&relent, rel); howto = relent.howto; if (howto->pc_relative) *addendp += sec->vma; if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) { /* This is a common symbol. The section contents include the size (sym->n_value) as an addend. The relocate_section function will be adding in the final value of the symbol. We need to subtract out the current size in order to get the correct result. */ BFD_ASSERT (h != NULL); *addendp -= sym->n_value; } /* If the output symbol is common (in which case this must be a relocateable link), we need to add in the final size of the common symbol. */ if (h != NULL && h->root.type == bfd_link_hash_common) *addendp += h->root.u.c.size; return howto;}#define coff_rtype_to_howto m68kcoff_common_addend_rtype_to_howto#endif /* ! defined (coff_rtype_to_howto) */#endif /* COFF_COMMON_ADDEND */#if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS/* Given a .data section and a .emreloc in-memory section, store relocation information into the .emreloc section which can be used at runtime to relocate the section. This is called by the linker when the --embedded-relocs switch is used. This is called after the add_symbols entry point has been called for all the objects, and before the final_link entry point is called. */booleanbfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) bfd *abfd; struct bfd_link_info *info; asection *datasec; asection *relsec; char **errmsg;{ char *extsyms; bfd_size_type symesz; struct internal_reloc *irel, *irelend; bfd_byte *p; BFD_ASSERT (! info->relocateable); *errmsg = NULL; if (datasec->reloc_count == 0) return true; extsyms = obj_coff_external_syms (abfd); symesz = bfd_coff_symesz (abfd); irel = _bfd_coff_read_internal_relocs (abfd, datasec, true, NULL, false, NULL); irelend = irel + datasec->reloc_count; relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 12); if (relsec->contents == NULL) return false; p = relsec->contents; for (; irel < irelend; irel++, p += 12) { asection *targetsec; /* We are going to write a four byte longword into the runtime reloc section. The longword will be the address in the data section which must be relocated. It is followed by the name of the target section NUL-padded or truncated to 8 characters. */ /* We can only relocate absolute longword relocs at run time. */ if (irel->r_type != R_RELLONG) { *errmsg = _("unsupported reloc type"); bfd_set_error (bfd_error_bad_value); return false; } if (irel->r_symndx == -1) targetsec = bfd_abs_section_ptr; else { struct coff_link_hash_entry *h; h = obj_coff_sym_hashes (abfd)[irel->r_symndx]; if (h == NULL) { struct internal_syment isym; bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx, &isym); targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum); } else if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) targetsec = h->root.u.def.section; else targetsec = NULL; } bfd_put_32 (abfd, (irel->r_vaddr - datasec->vma + datasec->output_offset), p); memset (p + 4, 0, 8); if (targetsec != NULL) strncpy (p + 4, targetsec->output_section->name, 8); } return true;}#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */#define coff_bfd_is_local_label_name m68k_coff_is_local_label_name#define coff_relocate_section _bfd_coff_generic_relocate_section#include "coffcode.h"#ifndef TARGET_SYM#define TARGET_SYM m68kcoff_vec#endif#ifndef TARGET_NAME#define TARGET_NAME "coff-m68k"#endif#ifdef NAMES_HAVE_UNDERSCORECREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL)#elseCREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL)#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?