📄 bout.c
字号:
int incode_mask; int size_mask; bfd_vma prev_addr = 0; unsigned int count; size_t reloc_size; struct relocation_info *relocs; arelent *reloc_cache; if (asect->relocation) return true; if (!aout_32_slurp_symbol_table (abfd)) return false; 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_error = invalid_operation; return false; doit: bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET); count = reloc_size / sizeof (struct relocation_info); relocs = (struct relocation_info *) bfd_xmalloc (reloc_size); if (!relocs) { bfd_error = no_memory; return false; } reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent)); if (!reloc_cache) { free ((char*)relocs); bfd_error = no_memory; return false; } if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) { bfd_error = system_call_error; free (reloc_cache); free (relocs); return false; } if (abfd->xvec->header_byteorder_big_p) { /* big-endian bit field allocation order */ pcrel_mask = 0x80; extern_mask = 0x10; incode_mask = 0x08; callj_mask = 0x02; size_mask = 0x20; length_shift = 5; } else { /* little-endian bit field allocation order */ pcrel_mask = 0x01; extern_mask = 0x08; incode_mask = 0x10; callj_mask = 0x40; size_mask = 0x02; length_shift = 1; } for (rptr = relocs, cache_ptr = reloc_cache, counter = 0; counter < count; counter++, rptr++, cache_ptr++) { unsigned char *raw = (unsigned char *)rptr; unsigned int symnum; cache_ptr->address = bfd_h_get_32 (abfd, raw + 0); cache_ptr->howto = 0; if (abfd->xvec->header_byteorder_big_p) { symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6]; } else { symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4]; } if (raw[7] & extern_mask) { /* if this is set then the r_index is a index into the symbol table; * if the bit is not set then r_index contains a section map. * we either fill in the sym entry with a pointer to the symbol, * or point to the correct section */ cache_ptr->sym_ptr_ptr = symbols + symnum; cache_ptr->addend = 0; } else { /* in a.out symbols are relative to the beginning of the * file rather than sections ? * (look in translate_from_native_sym_flags) * the reloc entry addend has added to it the offset into the * file of the data, so subtract the base to make the reloc * section relative */ int s; { /* sign-extend symnum from 24 bits to whatever host uses */ s = symnum; if (s & (1 << 23)) s |= (~0) << 24; } cache_ptr->sym_ptr_ptr = (asymbol **)NULL; switch (s) { case N_TEXT: case N_TEXT | N_EXT: cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; cache_ptr->addend = - obj_textsec(abfd)->vma; break; case N_DATA: case N_DATA | N_EXT: cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; cache_ptr->addend = - obj_datasec(abfd)->vma; break; case N_BSS: case N_BSS | N_EXT: cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; cache_ptr->addend = - obj_bsssec(abfd)->vma; break; case N_ABS: case N_ABS | N_EXT: cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; cache_ptr->addend = 0; break; case -2: /* .align */ if (raw[7] & pcrel_mask) { cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3]; cache_ptr->sym_ptr_ptr = &bfd_abs_symbol; } else { /* .org? */ abort (); } cache_ptr->addend = 0; break; default: BFD_ASSERT(0); break; } } /* the i960 only has a few relocation types: abs 32-bit and pcrel 24bit. except for callj's! */ if (cache_ptr->howto != 0) ; else if (raw[7] & callj_mask) { cache_ptr->howto = &howto_reloc_callj; } else if ( raw[7] & pcrel_mask) { if (raw[7] & size_mask) cache_ptr->howto = &howto_reloc_pcrel13; else cache_ptr->howto = &howto_reloc_pcrel24; } else { if (raw[7] & incode_mask) { cache_ptr->howto = &howto_reloc_abs32code; } else { cache_ptr->howto = &howto_reloc_abs32; } } if (cache_ptr->address < prev_addr) { /* Ouch! this reloc is out of order, insert into the right place */ arelent tmp; arelent *cursor = cache_ptr-1; bfd_vma stop = cache_ptr->address; tmp = *cache_ptr; while (cursor->address > stop && cursor >= reloc_cache) { cursor[1] = cursor[0]; cursor--; } cursor[1] = tmp; } else { prev_addr = cache_ptr->address; } } free (relocs); asect->relocation = reloc_cache; asect->reloc_count = count; return true;}static booleanb_out_squirt_out_relocs (abfd, section) bfd *abfd; asection *section;{ arelent **generic; int r_extern; int r_idx; int incode_mask; int len_1; unsigned int count = section->reloc_count; struct relocation_info *native, *natptr; size_t natsize = count * sizeof (struct relocation_info); int extern_mask, pcrel_mask, len_2, callj_mask; if (count == 0) return true; generic = section->orelocation; native = ((struct relocation_info *) bfd_xmalloc (natsize)); if (!native) { bfd_error = no_memory; return false; } if (abfd->xvec->header_byteorder_big_p) { /* Big-endian bit field allocation order */ pcrel_mask = 0x80; extern_mask = 0x10; len_2 = 0x40; len_1 = 0x20; callj_mask = 0x02; incode_mask = 0x08; } else { /* Little-endian bit field allocation order */ pcrel_mask = 0x01; extern_mask = 0x08; len_2 = 0x04; len_1 = 0x02; callj_mask = 0x40; incode_mask = 0x10; } for (natptr = native; count > 0; --count, ++natptr, ++generic) { arelent *g = *generic; unsigned char *raw = (unsigned char *)natptr; asymbol *sym = *(g->sym_ptr_ptr); asection *output_section = sym->section->output_section; bfd_h_put_32(abfd, g->address, raw); /* Find a type in the output format which matches the input howto - * at the moment we assume input format == output format FIXME!! */ /* FIXME: Need callj stuff here, and to check the howto entries to be sure they are real for this architecture. */ if (g->howto== &howto_reloc_callj) { raw[7] = callj_mask + pcrel_mask + len_2; } else if (g->howto == &howto_reloc_pcrel24) { raw[7] = pcrel_mask + len_2; } else if (g->howto == &howto_reloc_pcrel13) { raw[7] = pcrel_mask + len_1; } else if (g->howto == &howto_reloc_abs32code) { raw[7] = len_2 + incode_mask; } else { raw[7] = len_2; } if (output_section == &bfd_com_section || output_section == &bfd_abs_section || output_section == &bfd_und_section) { if (bfd_abs_section.symbol == sym) { /* Whoops, looked like an abs symbol, but is really an offset from the abs section */ r_idx = 0; r_extern = 0; } else { /* Fill in symbol */ r_extern = 1; r_idx = stoi((*(g->sym_ptr_ptr))->flags); } } else { /* Just an ordinary section */ r_extern = 0; r_idx = output_section->target_index; } if (abfd->xvec->header_byteorder_big_p) { raw[4] = (unsigned char) (r_idx >> 16); raw[5] = (unsigned char) (r_idx >> 8); raw[6] = (unsigned char) (r_idx ); } else { raw[6] = (unsigned char) (r_idx >> 16); raw[5] = (unsigned char) (r_idx>> 8); raw[4] = (unsigned char) (r_idx ); } if (r_extern) raw[7] |= extern_mask; } if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { free((PTR)native); return false; } free ((PTR)native); return true;}/* This is stupid. This function should be a boolean predicate */static unsigned intb_out_canonicalize_reloc (abfd, section, relptr, symbols) bfd *abfd; sec_ptr section; arelent **relptr; asymbol **symbols;{ arelent *tblptr = section->relocation; unsigned int count = 0; if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0; tblptr = section->relocation; if (!tblptr) return 0; for (; count++ < section->reloc_count;) *relptr++ = tblptr++; *relptr = 0; return section->reloc_count;}static unsigned intb_out_get_reloc_upper_bound (abfd, asect) bfd *abfd; sec_ptr asect;{ if (bfd_get_format (abfd) != bfd_object) { bfd_error = invalid_operation; return 0; } if (asect == obj_datasec (abfd)) return (sizeof (arelent *) * ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info)) +1)); if (asect == obj_textsec (abfd)) return (sizeof (arelent *) * ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info)) +1)); bfd_error = invalid_operation; return 0;}static booleanb_out_set_section_contents (abfd, section, location, offset, count) bfd *abfd; sec_ptr section; unsigned char *location; file_ptr offset; int count;{ if (abfd->output_has_begun == false) { /* set by bfd.c handler */ if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*|| (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) { bfd_error = invalid_operation; return false; } obj_textsec (abfd)->filepos = sizeof(struct internal_exec); obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos + obj_textsec (abfd)->_raw_size; } /* regardless, once we know what we're doing, we might as well get going */ bfd_seek (abfd, section->filepos + offset, SEEK_SET); if (count != 0) { return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false; } return true;}static booleanb_out_set_arch_mach (abfd, arch, machine) bfd *abfd; enum bfd_architecture arch; unsigned long machine;{ bfd_default_set_arch_mach(abfd, arch, machine); if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */ return true; if (arch == bfd_arch_i960) /* i960 default is OK */ switch (machine) { case bfd_mach_i960_core: case bfd_mach_i960_kb_sb: case bfd_mach_i960_mc: case bfd_mach_i960_xa: case bfd_mach_i960_ca: case bfd_mach_i960_ka_sa: case 0: return true; default: return false; } return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -