📄 elf-m10200.c
字号:
code = 0xc8 + (code & 0x03); else if ((code & 0xfc) == 0x40) code = 0xc0 + (code & 0x03); else if ((code & 0xfc) == 0x44) code = 0xc4 + (code & 0x03); else if ((code & 0xfc) == 0xc8) code = 0xcc + (code & 0x03); /* Fix the opcode. */ bfd_put_8 (abfd, code, contents + irel->r_offset - 2); /* Fix the relocation's type. */ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_MN10200_16); /* The opcode got shorter too, so we have to fix the offset. */ irel->r_offset -= 1; /* Delete two bytes of data. */ if (!mn10200_elf_relax_delete_bytes (abfd, sec, irel->r_offset + 1, 2)) goto error_return; /* That will change things, so, we should relax again. Note that this is not required, and it may be slow. */ *again = true; break; /* cmp imm24,dn -> cmp imm16,dn mov (abs24),an -> mov (abs16),an mov an,(abs24) -> mov an,(abs16) add imm24,dn -> add imm16,dn add imm24,an -> add imm16,an sub imm24,dn -> sub imm16,dn sub imm24,an -> sub imm16,an And all d24->d16 in memory ops. */ case 0x78: case 0xd0: case 0x50: case 0x60: case 0x64: case 0x68: case 0x6c: case 0x80: case 0xf0: case 0x00: case 0x10: case 0xb0: case 0x30: case 0xa0: case 0x20: case 0x90: /* Not safe if the high bit is on as relaxing may move the value out of high mem and thus not fit in a signed 16bit value. */ if (((code & 0xfc) == 0x78 || (code & 0xfc) == 0x60 || (code & 0xfc) == 0x64 || (code & 0xfc) == 0x68 || (code & 0xfc) == 0x6c || (code & 0xfc) == 0x80 || (code & 0xfc) == 0xf0 || (code & 0xfc) == 0x00 || (code & 0xfc) == 0x10 || (code & 0xfc) == 0xb0 || (code & 0xfc) == 0x30 || (code & 0xfc) == 0xa0 || (code & 0xfc) == 0x20 || (code & 0xfc) == 0x90) && (value & 0x8000) != 0) continue; /* Note that we've changed the reldection contents, etc. */ elf_section_data (sec)->relocs = internal_relocs; free_relocs = NULL; elf_section_data (sec)->this_hdr.contents = contents; free_contents = NULL; symtab_hdr->contents = (bfd_byte *) extsyms; free_extsyms = NULL; /* Fix the opcode. */ bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2); if ((code & 0xfc) == 0x78) code = 0x48 + (code & 0x03); else if ((code & 0xfc) == 0xd0) code = 0x30 + (code & 0x03); else if ((code & 0xfc) == 0x50) code = 0x20 + (code & 0x03); else if ((code & 0xfc) == 0x60) code = 0x18 + (code & 0x03); else if ((code & 0xfc) == 0x64) code = 0x08 + (code & 0x03); else if ((code & 0xfc) == 0x68) code = 0x1c + (code & 0x03); else if ((code & 0xfc) == 0x6c) code = 0x0c + (code & 0x03); else if ((code & 0xfc) == 0x80) code = 0xc0 + (code & 0x07); else if ((code & 0xfc) == 0xf0) code = 0xb0 + (code & 0x07); else if ((code & 0xfc) == 0x00) code = 0x80 + (code & 0x07); else if ((code & 0xfc) == 0x10) code = 0xa0 + (code & 0x07); else if ((code & 0xfc) == 0xb0) code = 0x70 + (code & 0x07); else if ((code & 0xfc) == 0x30) code = 0x60 + (code & 0x07); else if ((code & 0xfc) == 0xa0) code = 0xd0 + (code & 0x07); else if ((code & 0xfc) == 0x20) code = 0x90 + (code & 0x07); else if ((code & 0xfc) == 0x90) code = 0x50 + (code & 0x07); bfd_put_8 (abfd, code, contents + irel->r_offset - 1); /* Fix the relocation's type. */ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_MN10200_16); /* Delete one bytes of data. */ if (!mn10200_elf_relax_delete_bytes (abfd, sec, irel->r_offset + 2, 1)) goto error_return; /* That will change things, so, we should relax again. Note that this is not required, and it may be slow. */ *again = true; break; /* movb (abs24),dn ->movbu (abs16),dn extxb bn */ case 0xc4: /* Note that we've changed the reldection contents, etc. */ elf_section_data (sec)->relocs = internal_relocs; free_relocs = NULL; elf_section_data (sec)->this_hdr.contents = contents; free_contents = NULL; symtab_hdr->contents = (bfd_byte *) extsyms; free_extsyms = NULL; bfd_put_8 (abfd, 0xcc + (code & 0x03), contents + irel->r_offset - 2); bfd_put_8 (abfd, 0xb8 + (code & 0x03), contents + irel->r_offset - 1); /* Fix the relocation's type. */ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_MN10200_16); /* The reloc will be applied one byte in front of its current location. */ irel->r_offset -= 1; /* Delete one bytes of data. */ if (!mn10200_elf_relax_delete_bytes (abfd, sec, irel->r_offset + 2, 1)) goto error_return; /* That will change things, so, we should relax again. Note that this is not required, and it may be slow. */ *again = true; break; } } } } if (free_relocs != NULL) { free (free_relocs); free_relocs = NULL; } if (free_contents != NULL) { if (! link_info->keep_memory) free (free_contents); else { /* Cache the section contents for elf_link_input_bfd. */ elf_section_data (sec)->this_hdr.contents = contents; } free_contents = NULL; } if (free_extsyms != NULL) { if (! link_info->keep_memory) free (free_extsyms); else { /* Cache the symbols for elf_link_input_bfd. */ symtab_hdr->contents = extsyms; } free_extsyms = NULL; } return true; error_return: if (free_relocs != NULL) free (free_relocs); if (free_contents != NULL) free (free_contents); if (free_extsyms != NULL) free (free_extsyms); return false;}/* Delete some bytes from a section while relaxing. */static booleanmn10200_elf_relax_delete_bytes (abfd, sec, addr, count) bfd *abfd; asection *sec; bfd_vma addr; int count;{ Elf_Internal_Shdr *symtab_hdr; Elf32_External_Sym *extsyms; int shndx, index; bfd_byte *contents; Elf_Internal_Rela *irel, *irelend; Elf_Internal_Rela *irelalign; bfd_vma toaddr; Elf32_External_Sym *esym, *esymend; struct elf_link_hash_entry *sym_hash; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; extsyms = (Elf32_External_Sym *) symtab_hdr->contents; shndx = _bfd_elf_section_from_bfd_section (abfd, sec); contents = elf_section_data (sec)->this_hdr.contents; /* The deletion must stop at the next ALIGN reloc for an aligment power larger than the number of bytes we are deleting. */ irelalign = NULL; toaddr = sec->_cooked_size; irel = elf_section_data (sec)->relocs; irelend = irel + sec->reloc_count; /* Actually delete the bytes. */ memmove (contents + addr, contents + addr + count, toaddr - addr - count); sec->_cooked_size -= count; /* Adjust all the relocs. */ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) { /* Get the new reloc address. */ if ((irel->r_offset > addr && irel->r_offset < toaddr)) irel->r_offset -= count; } /* Adjust the local symbols defined in this section. */ esym = extsyms; esymend = esym + symtab_hdr->sh_info; for (; esym < esymend; esym++) { Elf_Internal_Sym isym; bfd_elf32_swap_symbol_in (abfd, esym, &isym); if (isym.st_shndx == shndx && isym.st_value > addr && isym.st_value < toaddr) { isym.st_value -= count; bfd_elf32_swap_symbol_out (abfd, &isym, esym); } } /* Now adjust the global symbols defined in this section. */ esym = extsyms + symtab_hdr->sh_info; esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)); for (index = 0; esym < esymend; esym++, index++) { Elf_Internal_Sym isym; bfd_elf32_swap_symbol_in (abfd, esym, &isym); sym_hash = elf_sym_hashes (abfd)[index]; if (isym.st_shndx == shndx && ((sym_hash)->root.type == bfd_link_hash_defined || (sym_hash)->root.type == bfd_link_hash_defweak) && (sym_hash)->root.u.def.section == sec && (sym_hash)->root.u.def.value > addr && (sym_hash)->root.u.def.value < toaddr) { (sym_hash)->root.u.def.value -= count; } } return true;}/* Return true if a symbol exists at the given address, else return false. */static booleanmn10200_elf_symbol_address_p (abfd, sec, extsyms, addr) bfd *abfd; asection *sec; Elf32_External_Sym *extsyms; bfd_vma addr;{ Elf_Internal_Shdr *symtab_hdr; int shndx; Elf32_External_Sym *esym, *esymend; struct elf_link_hash_entry **sym_hash, **sym_hash_end; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; shndx = _bfd_elf_section_from_bfd_section (abfd, sec); /* Examine all the symbols. */ esym = extsyms; esymend = esym + symtab_hdr->sh_info; for (; esym < esymend; esym++) { Elf_Internal_Sym isym; bfd_elf32_swap_symbol_in (abfd, esym, &isym); if (isym.st_shndx == shndx && isym.st_value == addr) return true; } sym_hash = elf_sym_hashes (abfd); sym_hash_end = (sym_hash + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) - symtab_hdr->sh_info)); for (; sym_hash < sym_hash_end; sym_hash++) { if (((*sym_hash)->root.type == bfd_link_hash_defined || (*sym_hash)->root.type == bfd_link_hash_defweak) && (*sym_hash)->root.u.def.section == sec && (*sym_hash)->root.u.def.value == addr) return true; } return false;}/* This is a version of bfd_generic_get_relocated_section_contents which uses mn10200_elf_relocate_section. */static bfd_byte *mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order, data, relocateable, symbols) bfd *output_bfd; struct bfd_link_info *link_info; struct bfd_link_order *link_order; bfd_byte *data; boolean relocateable; asymbol **symbols;{ Elf_Internal_Shdr *symtab_hdr; asection *input_section = link_order->u.indirect.section; bfd *input_bfd = input_section->owner; asection **sections = NULL; Elf_Internal_Rela *internal_relocs = NULL; Elf32_External_Sym *external_syms = NULL; Elf_Internal_Sym *internal_syms = NULL; /* We only need to handle the case of relaxing, or of having a particular set of section contents, specially. */ if (relocateable || elf_section_data (input_section)->this_hdr.contents == NULL) return bfd_generic_get_relocated_section_contents (output_bfd, link_info, link_order, data, relocateable, symbols); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; memcpy (data, elf_section_data (input_section)->this_hdr.contents, input_section->_raw_size); if ((input_section->flags & SEC_RELOC) != 0 && input_section->reloc_count > 0) { Elf_Internal_Sym *isymp; asection **secpp; Elf32_External_Sym *esym, *esymend; if (symtab_hdr->contents != NULL) external_syms = (Elf32_External_Sym *) symtab_hdr->contents; else { external_syms = ((Elf32_External_Sym *) bfd_malloc (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))); if (external_syms == NULL && symtab_hdr->sh_info > 0) goto error_return; if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 || (bfd_read (external_syms, sizeof (Elf32_External_Sym), symtab_hdr->sh_info, input_bfd) != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym)))) goto error_return; } internal_relocs = (_bfd_elf32_link_read_relocs (input_bfd, input_section, (PTR) NULL, (Elf_Internal_Rela *) NULL, false)); if (internal_relocs == NULL) goto error_return; internal_syms = ((Elf_Internal_Sym *) bfd_malloc (symtab_hdr->sh_info * sizeof (Elf_Internal_Sym))); if (internal_syms == NULL && symtab_hdr->sh_info > 0) goto error_return; sections = (asection **) bfd_malloc (symtab_hdr->sh_info * sizeof (asection *)); if (sections == NULL && symtab_hdr->sh_info > 0) goto error_return; isymp = internal_syms; secpp = sections; esym = external_syms; esymend = esym + symtab_hdr->sh_info; for (; esym < esymend; ++esym, ++isymp, ++secpp) { asection *isec; bfd_elf32_swap_symbol_in (input_bfd, esym, isymp); if (isymp->st_shndx == SHN_UNDEF) isec = bfd_und_section_ptr; else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE) isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx); else if (isymp->st_shndx == SHN_ABS) isec = bfd_abs_section_ptr; else if (isymp->st_shndx == SHN_COMMON) isec = bfd_com_section_ptr; else { /* Who knows? */ isec = NULL; } *secpp = isec; } if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd, input_section, data, internal_relocs, internal_syms, sections)) goto error_return; if (sections != NULL) free (sections); sections = NULL; if (internal_syms != NULL) free (internal_syms); internal_syms = NULL; if (external_syms != NULL && symtab_hdr->contents == NULL) free (external_syms); external_syms = NULL; if (internal_relocs != elf_section_data (input_section)->relocs) free (internal_relocs); internal_relocs = NULL; } return data; error_return: if (internal_relocs != NULL && internal_relocs != elf_section_data (input_section)->relocs) free (internal_relocs); if (external_syms != NULL && symtab_hdr->contents == NULL) free (external_syms); if (internal_syms != NULL) free (internal_syms); if (sections != NULL) free (sections); return NULL;}#define TARGET_LITTLE_SYM bfd_elf32_mn10200_vec#define TARGET_LITTLE_NAME "elf32-mn10200"#define ELF_ARCH bfd_arch_mn10200#define ELF_MACHINE_CODE EM_CYGNUS_MN10200#define ELF_MAXPAGESIZE 0x1000#define elf_info_to_howto mn10200_info_to_howto#define elf_info_to_howto_rel 0#define elf_backend_relocate_section mn10200_elf_relocate_section#define bfd_elf32_bfd_relax_section mn10200_elf_relax_section#define bfd_elf32_bfd_get_relocated_section_contents \ mn10200_elf_get_relocated_section_contents#define elf_symbol_leading_char '_'#include "elf32-target.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -