i386lynx.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 564 行 · 第 1/2 页
C
564 行
Aout keeps all it's symbols based from zero, so the symbol would contain 60. This macro subs the base of each section from the value to give the true offset from the section */#define MOVE_ADDRESS(ad) \ if (r_extern) { \ /* undefined symbol */ \ cache_ptr->sym_ptr_ptr = symbols + r_index; \ cache_ptr->addend = ad; \ } else { \ /* defined, section relative. replace symbol with pointer to \ symbol which points to section */ \ switch (r_index) { \ case N_TEXT: \ case N_TEXT | N_EXT: \ cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ cache_ptr->addend = ad - su->textsec->vma; \ break; \ case N_DATA: \ case N_DATA | N_EXT: \ cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ cache_ptr->addend = ad - su->datasec->vma; \ break; \ case N_BSS: \ case N_BSS | N_EXT: \ cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ cache_ptr->addend = ad - su->bsssec->vma; \ break; \ default: \ case N_ABS: \ case N_ABS | N_EXT: \ cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ cache_ptr->addend = ad; \ break; \ } \ } \voidNAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) bfd *abfd; struct reloc_ext_external *bytes; arelent *cache_ptr; asymbol **symbols; bfd_size_type symcount ATTRIBUTE_UNUSED;{ int r_index; int r_extern; unsigned int r_type; struct aoutdata *su = &(abfd->tdata.aout_data->a); cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); r_index = bytes->r_index[1]; r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG)); r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG) >> RELOC_EXT_BITS_TYPE_SH_BIG; cache_ptr->howto = aout_32_ext_howto_table + r_type; MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));}voidNAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) bfd *abfd; struct reloc_std_external *bytes; arelent *cache_ptr; asymbol **symbols; bfd_size_type symcount ATTRIBUTE_UNUSED;{ int r_index; int r_extern; unsigned int r_length; int r_pcrel; int r_baserel, r_jmptable, r_relative; struct aoutdata *su = &(abfd->tdata.aout_data->a); cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); r_index = bytes->r_index[1]; r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG)); r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG)); r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG)); r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG)); r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG)); r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG; cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel; /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ MOVE_ADDRESS (0);}/* Reloc hackery */booleanNAME(lynx,slurp_reloc_table) (abfd, asect, symbols) bfd *abfd; sec_ptr asect; asymbol **symbols;{ unsigned int count; bfd_size_type reloc_size; PTR relocs; arelent *reloc_cache; size_t each_size; if (asect->relocation) return true; if (asect->flags & SEC_CONSTRUCTOR) return true; if (asect == obj_datasec (abfd)) { reloc_size = exec_hdr (abfd)->a_drsize; goto doit; } if (asect == obj_textsec (abfd)) { reloc_size = exec_hdr (abfd)->a_trsize; goto doit; } bfd_set_error (bfd_error_invalid_operation); return false;doit: if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) return false; each_size = obj_reloc_entry_size (abfd); count = reloc_size / each_size; reloc_cache = (arelent *) bfd_malloc (count * sizeof (arelent)); if (!reloc_cache && count != 0) return false; memset (reloc_cache, 0, count * sizeof (arelent)); relocs = (PTR) bfd_alloc (abfd, reloc_size); if (!relocs && reloc_size != 0) { free (reloc_cache); return false; } if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) { bfd_release (abfd, relocs); free (reloc_cache); return false; } if (each_size == RELOC_EXT_SIZE) { register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; unsigned int counter = 0; arelent *cache_ptr = reloc_cache; for (; counter < count; counter++, rptr++, cache_ptr++) { NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols, bfd_get_symcount (abfd)); } } else { register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; unsigned int counter = 0; arelent *cache_ptr = reloc_cache; for (; counter < count; counter++, rptr++, cache_ptr++) { NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, bfd_get_symcount (abfd)); } } bfd_release (abfd, relocs); asect->relocation = reloc_cache; asect->reloc_count = count; return true;}/* Write out a relocation section into an object file. */booleanNAME(lynx,squirt_out_relocs) (abfd, section) bfd *abfd; asection *section;{ arelent **generic; unsigned char *native, *natptr; size_t each_size; unsigned int count = section->reloc_count; size_t natsize; if (count == 0) return true; each_size = obj_reloc_entry_size (abfd); natsize = each_size * count; native = (unsigned char *) bfd_zalloc (abfd, natsize); if (!native) return false; generic = section->orelocation; if (each_size == RELOC_EXT_SIZE) { for (natptr = native; count != 0; --count, natptr += each_size, ++generic) NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr); } else { for (natptr = native; count != 0; --count, natptr += each_size, ++generic) NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr); } if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { bfd_release (abfd, native); return false; } bfd_release (abfd, native); return true;}/* This is stupid. This function should be a boolean predicate */longNAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols) bfd *abfd; sec_ptr section; arelent **relptr; asymbol **symbols;{ arelent *tblptr = section->relocation; unsigned int count; if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols))) return -1; if (section->flags & SEC_CONSTRUCTOR) { arelent_chain *chain = section->constructor_chain; for (count = 0; count < section->reloc_count; count++) { *relptr++ = &chain->relent; chain = chain->next; } } else { tblptr = section->relocation; for (count = 0; count++ < section->reloc_count;) { *relptr++ = tblptr++; } } *relptr = 0; return section->reloc_count;}#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)#include "aout-target.h"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?