coff-h8300.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,341 行 · 第 1/3 页
C
1,341 行
case 0x5c: /* bsr:16 -> bsr:8 */ bfd_put_8 (abfd, 0x55, data + dst_address - 2); break; default: abort (); } /* Output the target. */ bfd_put_8 (abfd, gap, data + dst_address - 1); /* We don't advance dst_address -- the 8bit reloc is applied at dst_address - 1, so the next insn should begin at dst_address. */ src_address += 2; break; /* Similarly for a 24bit absolute that is now 8 bits. */ case R_JMPL2: /* Get the address of the target of this branch. */ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); /* Get the address of the instruction (not the reloc). */ dot = (link_order->offset + dst_address + link_order->u.indirect.section->output_section->vma + 2); gap = value - dot; /* Fix the instruction. */ switch (data[src_address]) { case 0x5e: /* jsr -> bsr */ bfd_put_8 (abfd, 0x55, data + dst_address); break; case 0x5a: /* jmp ->bra */ bfd_put_8 (abfd, 0x40, data + dst_address); break; default: abort (); } bfd_put_8 (abfd, gap, data + dst_address + 1); dst_address += 2; src_address += 4; break; /* A 16bit absolute mov.b that is now an 8bit absolute mov.b. */ case R_MOV16B2: value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); /* Sanity check. */ if (data[dst_address - 2] != 0x6a) abort (); /* Fix up the opcode. */ switch (data[src_address - 1] & 0xf0) { case 0x00: data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20; break; case 0x80: data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30; break; default: abort (); } bfd_put_8 (abfd, value & 0xff, data + dst_address - 1); src_address += 2; break; /* Similarly for a 24bit mov.b */ case R_MOV24B2: value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); /* Sanity check. */ if (data[dst_address - 2] != 0x6a) abort (); /* Fix up the opcode. */ switch (data[src_address - 1] & 0xf0) { case 0x20: data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20; break; case 0xa0: data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30; break; default: abort (); } bfd_put_8 (abfd, value & 0xff, data + dst_address - 1); src_address += 4; break; case R_BCC_INV: /* Get the address of the target of this branch. */ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); dot = (link_order->offset + dst_address + link_order->u.indirect.section->output_section->vma) + 1; gap = value - dot; /* Sanity check. */ if (gap < -128 || gap > 126) { if (! ((*link_info->callbacks->reloc_overflow) (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), reloc->howto->name, reloc->addend, input_section->owner, input_section, reloc->address))) abort (); } /* Everything looks OK. Fix the condition in the instruction, apply the relocation, and update the src/dst address appropriately. */ bfd_put_8 (abfd, bfd_get_8 (abfd, data + dst_address - 1) ^ 1, data + dst_address - 1); bfd_put_8 (abfd, gap, data + dst_address); dst_address++; src_address++; /* All done. */ break; case R_JMP_DEL: src_address += 4; break; /* An 8bit memory indirect instruction (jmp/jsr). There's several things that need to be done to handle this relocation. If this is a reloc against the absolute symbol, then we should handle it just R_RELBYTE. Likewise if it's for a symbol with a value ge 0 and le 0xff. Otherwise it's a jump/call through the function vector, and the linker is expected to set up the function vector and put the right value into the jump/call instruction. */ case R_MEM_INDIRECT: { /* We need to find the symbol so we can determine it's address in the function vector table. */ asymbol *symbol; bfd_vma value; const char *name; struct funcvec_hash_entry *h; asection *vectors_sec = h8300_coff_hash_table (link_info)->vectors_sec; /* First see if this is a reloc against the absolute symbol or against a symbol with a nonnegative value <= 0xff. */ symbol = *(reloc->sym_ptr_ptr); value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); if (symbol == bfd_abs_section_ptr->symbol || value <= 0xff) { /* This should be handled in a manner very similar to R_RELBYTES. If the value is in range, then just slam the value into the right location. Else trigger a reloc overflow callback. */ if (value <= 0xff) { bfd_put_8 (abfd, value, data + dst_address); dst_address += 1; src_address += 1; } else { if (! ((*link_info->callbacks->reloc_overflow) (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), reloc->howto->name, reloc->addend, input_section->owner, input_section, reloc->address))) abort (); } break; } /* This is a jump/call through a function vector, and we're expected to create the function vector ourselves. First look up this symbol in the linker hash table -- we need the derived linker symbol which holds this symbol's index in the function vector. */ name = symbol->name; if (symbol->flags & BSF_LOCAL) { char *new_name = bfd_malloc (strlen (name) + 9); if (new_name == NULL) abort (); strcpy (new_name, name); sprintf (new_name + strlen (name), "_%08x", (int) symbol->section); name = new_name; } h = funcvec_hash_lookup (h8300_coff_hash_table (link_info)->funcvec_hash_table, name, false, false); /* This shouldn't ever happen. If it does that means we've got data corruption of some kind. Aborting seems like a reasonable think to do here. */ if (h == NULL || vectors_sec == NULL) abort (); /* Place the address of the function vector entry into the reloc's address. */ bfd_put_8 (abfd, vectors_sec->output_offset + h->offset, data + dst_address); dst_address++; src_address++; /* Now create an entry in the function vector itself. */ if (bfd_get_mach (input_section->owner) == bfd_mach_h8300) bfd_put_16 (abfd, bfd_coff_reloc16_get_value (reloc, link_info, input_section), vectors_sec->contents + h->offset); else if (bfd_get_mach (input_section->owner) == bfd_mach_h8300h || bfd_get_mach (input_section->owner) == bfd_mach_h8300s) bfd_put_32 (abfd, bfd_coff_reloc16_get_value (reloc, link_info, input_section), vectors_sec->contents + h->offset); else abort (); /* Gross. We've already written the contents of the vector section before we get here... So we write it again with the new data. */ bfd_set_section_contents (vectors_sec->output_section->owner, vectors_sec->output_section, vectors_sec->contents, vectors_sec->output_offset, vectors_sec->_raw_size); break; } default: abort (); break; } *src_ptr = src_address; *dst_ptr = dst_address;}/* Routine for the h8300 linker. This routine is necessary to handle the special R_MEM_INDIRECT relocs on the h8300. It's responsible for generating a vectors section and attaching it to an input bfd as well as sizing the vectors section. It also creates our vectors hash table. It uses the generic linker routines to actually add the symbols. from this BFD to the bfd linker hash table. It may add a few selected static symbols to the bfd linker hash table. */static booleanh8300_bfd_link_add_symbols (abfd, info) bfd *abfd; struct bfd_link_info *info;{ asection *sec; struct funcvec_hash_table *funcvec_hash_table; /* If we haven't created a vectors section, do so now. */ if (!h8300_coff_hash_table (info)->vectors_sec) { flagword flags; /* Make sure the appropriate flags are set, including SEC_IN_MEMORY. */ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY); h8300_coff_hash_table (info)->vectors_sec = bfd_make_section (abfd, ".vectors"); /* If the section wasn't created, or we couldn't set the flags, quit quickly now, rather than dieing a painful death later. */ if (! h8300_coff_hash_table (info)->vectors_sec || ! bfd_set_section_flags (abfd, h8300_coff_hash_table(info)->vectors_sec, flags)) return false; /* Also create the vector hash table. */ funcvec_hash_table = ((struct funcvec_hash_table *) bfd_alloc (abfd, sizeof (struct funcvec_hash_table))); if (!funcvec_hash_table) return false; /* And initialize the funcvec hash table. */ if (!funcvec_hash_table_init (funcvec_hash_table, abfd, funcvec_hash_newfunc)) { bfd_release (abfd, funcvec_hash_table); return false; } /* Store away a pointer to the funcvec hash table. */ h8300_coff_hash_table (info)->funcvec_hash_table = funcvec_hash_table; } /* Load up the function vector hash table. */ funcvec_hash_table = h8300_coff_hash_table (info)->funcvec_hash_table; /* Add the symbols using the generic code. */ _bfd_generic_link_add_symbols (abfd, info); /* Now scan the relocs for all the sections in this bfd; create additional space in the .vectors section as needed. */ for (sec = abfd->sections; sec; sec = sec->next) { long reloc_size, reloc_count, i; asymbol **symbols; arelent **relocs; /* Suck in the relocs, symbols & canonicalize them. */ reloc_size = bfd_get_reloc_upper_bound (abfd, sec); if (reloc_size <= 0) continue; relocs = (arelent **) bfd_malloc ((size_t) reloc_size); if (!relocs) return false; /* The symbols should have been read in by _bfd_generic link_add_symbols call abovec, so we can cheat and use the pointer to them that was saved in the above call. */ symbols = _bfd_generic_link_get_symbols(abfd); reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, symbols); if (reloc_count <= 0) { free (relocs); continue; } /* Now walk through all the relocations in this section. */ for (i = 0; i < reloc_count; i++) { arelent *reloc = relocs[i]; asymbol *symbol = *(reloc->sym_ptr_ptr); const char *name; /* We've got an indirect reloc. See if we need to add it to the function vector table. At this point, we have to add a new entry for each unique symbol referenced by an R_MEM_INDIRECT relocation except for a reloc against the absolute section symbol. */ if (reloc->howto->type == R_MEM_INDIRECT && symbol != bfd_abs_section_ptr->symbol) { struct funcvec_hash_entry *h; name = symbol->name; if (symbol->flags & BSF_LOCAL) { char *new_name = bfd_malloc (strlen (name) + 9); if (new_name == NULL) abort (); strcpy (new_name, name); sprintf (new_name + strlen (name), "_%08x", (int) symbol->section); name = new_name; } /* Look this symbol up in the function vector hash table. */ h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table, name, false, false); /* If this symbol isn't already in the hash table, add it and bump up the size of the hash table. */ if (h == NULL) { h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table, name, true, true); if (h == NULL) { free (relocs); return false; } /* Bump the size of the vectors section. Each vector takes 2 bytes on the h8300 and 4 bytes on the h8300h. */ if (bfd_get_mach (abfd) == bfd_mach_h8300) h8300_coff_hash_table (info)->vectors_sec->_raw_size += 2; else if (bfd_get_mach (abfd) == bfd_mach_h8300h || bfd_get_mach (abfd) == bfd_mach_h8300s) h8300_coff_hash_table (info)->vectors_sec->_raw_size += 4; } } } /* We're done with the relocations, release them. */ free (relocs); } /* Now actually allocate some space for the function vector. It's wasteful to do this more than once, but this is easier. */ if (h8300_coff_hash_table (info)->vectors_sec->_raw_size != 0) { /* Free the old contents. */ if (h8300_coff_hash_table (info)->vectors_sec->contents) free (h8300_coff_hash_table (info)->vectors_sec->contents); /* Allocate new contents. */ h8300_coff_hash_table (info)->vectors_sec->contents = bfd_malloc (h8300_coff_hash_table (info)->vectors_sec->_raw_size); } return true;}#define coff_reloc16_extra_cases h8300_reloc16_extra_cases#define coff_reloc16_estimate h8300_reloc16_estimate#define coff_bfd_link_add_symbols h8300_bfd_link_add_symbols#define coff_bfd_link_hash_table_create h8300_coff_link_hash_table_create#define COFF_LONG_FILENAMES#include "coffcode.h"#undef coff_bfd_get_relocated_section_contents#undef coff_bfd_relax_section#define coff_bfd_get_relocated_section_contents \ bfd_coff_reloc16_get_relocated_section_contents#define coff_bfd_relax_section bfd_coff_reloc16_relax_sectionCREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?