📄 ieee.c
字号:
static booleanDEFUN(ieee_mkobject,(abfd), bfd *abfd){ abfd->tdata.ieee_data = (ieee_data_type *)bfd_zalloc(abfd,sizeof(ieee_data_type)); return true;}bfd_target *DEFUN(ieee_object_p,(abfd), bfd *abfd){ char *processor; unsigned int part; ieee_data_type *ieee; uint8e_type buffer[300]; ieee_data_type *save = IEEE_DATA(abfd); abfd->tdata.ieee_data = 0; ieee_mkobject(abfd); ieee = IEEE_DATA(abfd); bfd_seek(abfd, (file_ptr) 0, SEEK_SET); /* Read the first few bytes in to see if it makes sense */ bfd_read((PTR)buffer, 1, sizeof(buffer), abfd); ieee->h.input_p = buffer; if (this_byte_and_next(&(ieee->h)) != Module_Beginning) goto fail; ieee->read_symbols= false; ieee->read_data= false; ieee->section_count = 0; ieee->external_symbol_max_index = 0; ieee->external_symbol_min_index = IEEE_PUBLIC_BASE; ieee->external_reference_min_index =IEEE_REFERENCE_BASE; ieee->external_reference_max_index = 0; ieee->h.abfd = abfd; memset((PTR)ieee->section_table, 0, sizeof(ieee->section_table)); processor = ieee->mb.processor = read_id(&(ieee->h)); if (strcmp(processor,"LIBRARY") == 0) goto fail; ieee->mb.module_name = read_id(&(ieee->h)); if (abfd->filename == (CONST char *)NULL) { abfd->filename = ieee->mb.module_name; } /* Determine the architecture and machine type of the object file. */ { bfd_arch_info_type *arch = bfd_scan_arch(processor); if (arch == 0) goto fail; abfd->arch_info = arch; } if (this_byte(&(ieee->h)) != (int)ieee_address_descriptor_enum) { goto fail; } next_byte(&(ieee->h)); if (parse_int(&(ieee->h), &ieee->ad.number_of_bits_mau) == false) { goto fail; } if(parse_int(&(ieee->h), &ieee->ad.number_of_maus_in_address) == false) { goto fail; } /* If there is a byte order info, take it */ if (this_byte(&(ieee->h)) == (int)ieee_variable_L_enum || this_byte(&(ieee->h)) == (int)ieee_variable_M_enum) next_byte(&(ieee->h)); for (part = 0; part < N_W_VARIABLES; part++) { boolean ok; if (read_2bytes(&(ieee->h)) != (int) ieee_assign_value_to_variable_enum) { goto fail; } if (this_byte_and_next(&(ieee->h)) != part) { goto fail; } ieee->w.offset[part] = parse_i(&(ieee->h), &ok); if (ok==false) { goto fail; } } abfd->flags = HAS_SYMS;/* By now we know that this is a real IEEE file, we're going to read the whole thing into memory so that we can run up and down it quickly. We can work out how big the file is from the trailer record */ IEEE_DATA(abfd)->h.first_byte = (uint8e_type *) bfd_alloc(ieee->h.abfd, ieee->w.r.me_record + 50); bfd_seek(abfd, (file_ptr) 0, SEEK_SET); bfd_read((PTR)(IEEE_DATA(abfd)->h.first_byte), 1, ieee->w.r.me_record+50, abfd); ieee_slurp_sections(abfd); return abfd->xvec; fail: (void) bfd_release(abfd, ieee);abfd->tdata.ieee_data = save; return (bfd_target *)NULL;}void DEFUN(ieee_print_symbol,(ignore_abfd, afile, symbol, how), bfd *ignore_abfd AND PTR afile AND asymbol *symbol AND bfd_print_symbol_type how){ FILE *file = (FILE *)afile; switch (how) { case bfd_print_symbol_name: fprintf(file,"%s", symbol->name); break; case bfd_print_symbol_more:#if 0 fprintf(file,"%4x %2x",aout_symbol(symbol)->desc & 0xffff, aout_symbol(symbol)->other & 0xff);#endif BFD_FAIL(); break; case bfd_print_symbol_nm: case bfd_print_symbol_all: { CONST char *section_name = symbol->section == (asection *)NULL ? (CONST char *)"*abs" : symbol->section->name; if (symbol->name[0] == ' ') { fprintf(file,"* empty table entry "); } else { bfd_print_symbol_vandf((PTR)file,symbol); fprintf(file," %-5s %04x %02x %s", section_name, (unsigned) ieee_symbol(symbol)->index, (unsigned) 0, /* aout_symbol(symbol)->desc & 0xffff, aout_symbol(symbol)->other & 0xff,*/ symbol->name); } } break; }}static voidDEFUN(do_one,(ieee, current_map, location_ptr,s), ieee_data_type *ieee AND ieee_per_section_type *current_map AND uint8e_type *location_ptr AND asection *s){ switch (this_byte(&(ieee->h))) { case ieee_load_constant_bytes_enum: { unsigned int number_of_maus; unsigned int i; next_byte(&(ieee->h)); number_of_maus = must_parse_int(&(ieee->h)); for (i = 0; i < number_of_maus; i++) { location_ptr[current_map->pc++]= this_byte(&(ieee->h)); next_byte(&(ieee->h)); } } break; case ieee_load_with_relocation_enum: { boolean loop = true; next_byte(&(ieee->h)); while (loop) { switch (this_byte(&(ieee->h))) { case ieee_variable_R_enum: case ieee_function_signed_open_b_enum: case ieee_function_unsigned_open_b_enum: case ieee_function_either_open_b_enum: { unsigned int extra = 4; boolean pcrel = false;asection *section; ieee_reloc_type *r = (ieee_reloc_type *) bfd_alloc(ieee->h.abfd, sizeof(ieee_reloc_type)); *(current_map->reloc_tail_ptr) = r; current_map->reloc_tail_ptr= &r->next; r->next = (ieee_reloc_type *)NULL; next_byte(&(ieee->h));/* abort();*/ parse_expression(ieee, &r->relent.addend, &r->symbol, &pcrel, &extra, §ion); r->relent.address = current_map->pc; s->reloc_count++;if (r->relent.sym_ptr_ptr == 0) { r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;} if (this_byte(&(ieee->h)) == (int)ieee_comma) { next_byte(&(ieee->h)); /* Fetch number of bytes to pad */ extra = must_parse_int(&(ieee->h)); }; switch (this_byte(&(ieee->h))) { case ieee_function_signed_close_b_enum: next_byte(&(ieee->h)); break; case ieee_function_unsigned_close_b_enum: next_byte(&(ieee->h)); break; case ieee_function_either_close_b_enum: next_byte(&(ieee->h)); break; default: break; } /* Build a relocation entry for this type */ /* If pc rel then stick -ve pc into instruction and take out of reloc .. I've changed this. It's all too complicated. I keep 0 in the instruction now. */ switch (extra) { case 0: case 4: if (pcrel == true) {#if KEEPMINUSPCININST bfd_put_32(ieee->h.abfd, -current_map->pc, location_ptr + current_map->pc); r->relent.howto = &rel32_howto; r->relent.addend -= current_map->pc;#else bfd_put_32(ieee->h.abfd,0, location_ptr + current_map->pc); r->relent.howto = &rel32_howto;#endif } else { bfd_put_32(ieee->h.abfd, 0, location_ptr + current_map->pc); r->relent.howto = &abs32_howto; } current_map->pc +=4; break; case 2: if (pcrel == true) {#if KEEPMINUSPCININST bfd_put_16(ieee->h.abfd, (int)(-current_map->pc), location_ptr +current_map->pc); r->relent.addend -= current_map->pc; r->relent.howto = &rel16_howto;#else bfd_put_16(ieee->h.abfd, 0, location_ptr +current_map->pc); r->relent.howto = &rel16_howto;#endif } else { bfd_put_16(ieee->h.abfd, 0, location_ptr +current_map->pc); r->relent.howto = &abs16_howto; } current_map->pc +=2; break; case 1: if (pcrel == true) {#if KEEPMINUSPCININST bfd_put_8(ieee->h.abfd, (int)(-current_map->pc), location_ptr +current_map->pc); r->relent.addend -= current_map->pc; r->relent.howto = &rel8_howto;#else bfd_put_8(ieee->h.abfd,0, location_ptr +current_map->pc); r->relent.howto = &rel8_howto;#endif } else { bfd_put_8(ieee->h.abfd, 0, location_ptr +current_map->pc); r->relent.howto = &abs8_howto; } current_map->pc +=1; break; default: BFD_FAIL(); break; } } break; default: { bfd_vma this_size ; if (parse_int(&(ieee->h), &this_size) == true) { unsigned int i; for (i = 0; i < this_size; i++) { location_ptr[current_map->pc ++] = this_byte(&(ieee->h)); next_byte(&(ieee->h)); } } else { loop = false; } } } } } }}/* Read in all the section data and relocation stuff too */static boolean DEFUN(ieee_slurp_section_data,(abfd), bfd *abfd){ bfd_byte *location_ptr = (bfd_byte *)NULL; ieee_data_type *ieee = IEEE_DATA(abfd); unsigned int section_number ; ieee_per_section_type *current_map = (ieee_per_section_type *)NULL; asection *s; /* Seek to the start of the data area */ if (ieee->read_data== true) return true; ieee->read_data = true; ieee_seek(abfd, ieee->w.r.data_part); /* Allocate enough space for all the section contents */ for (s = abfd->sections; s != (asection *)NULL; s = s->next) { ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd; per->data = (bfd_byte *) bfd_alloc(ieee->h.abfd, s->_raw_size); /*SUPPRESS 68*/ per->reloc_tail_ptr = (ieee_reloc_type **)&(s->relocation); } while (true) { switch (this_byte(&(ieee->h))) { /* IF we see anything strange then quit */ default: return true; case ieee_set_current_section_enum: next_byte(&(ieee->h)); section_number = must_parse_int(&(ieee->h)); s = ieee->section_table[section_number]; current_map = (ieee_per_section_type *) s->used_by_bfd; location_ptr = current_map->data - s->vma; /* The document I have says that Microtec's compilers reset */ /* this after a sec section, even though the standard says not */ /* to. SO .. */ current_map->pc =s->vma; break; case ieee_e2_first_byte_enum: next_byte(&(ieee->h)); switch (this_byte(&(ieee->h))) { case ieee_set_current_pc_enum & 0xff: { bfd_vma value; asection *dsection; ieee_symbol_index_type symbol; unsigned int extra; boolean pcrel; next_byte(&(ieee->h)); must_parse_int(&(ieee->h)); /* Thow away section #*/ parse_expression(ieee, &value, &symbol, &pcrel, &extra, 0); current_map->pc = value; BFD_ASSERT((unsigned)(value - s->vma) <= s->_raw_size); } break; case ieee_value_starting_address_enum & 0xff: /* We've got to the end of the data now - */ return true; default: BFD_FAIL(); return true; } break; case ieee_repeat_data_enum: { /* Repeat the following LD or LR n times - we do this by remembering the stream pointer before running it and resetting it and running it n times. We special case the repetition of a repeat_data/load_constant */ unsigned int iterations ; uint8e_type *start ; next_byte(&(ieee->h)); iterations = must_parse_int(&(ieee->h)); start = ieee->h.input_p; if (start[0] == (int)ieee_load_constant_bytes_enum && start[1] == 1) { while (iterations != 0) { location_ptr[current_map->pc++] = start[2]; iterations--; } next_byte(&(ieee->h)); next_byte(&(ieee->h)); next_byte(&(ieee->h)); } else { while (iterations != 0) { ieee->h.input_p = start; do_one(ieee, current_map, location_ptr,s); iterations --; } } } break; case ieee_load_constant_bytes_enum: case ieee_load_with_relocation_enum: { do_one(ieee, current_map, location_ptr,s); } } }}booleanDEFUN(ieee_new_section_hook,(abfd, newsect), bfd *abfd AND asection *newsect){ newsect->used_by_bfd = (PTR) bfd_alloc(abfd, sizeof(ieee_per_section_type)); ieee_per_section( newsect)->data = (bfd_byte *)NULL; ieee_per_section(newsect)->section = newsect; return true;}unsigned intDEFUN(ieee_get_reloc_upper_bound,(abfd, asect), bfd *abfd AND sec_ptr asect){ ieee_slurp_section_data(abfd); return (asect->reloc_count+1) * sizeof(arelent *);}static booleanDEFUN(ieee_get_section_contents,(abfd, section, location, offset, count), bfd *abfd AND sec_ptr section AND PTR location AND file_ptr offset AND bfd_size_type count){ ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd; ieee_slurp_section_data(abfd); (void) memcpy((PTR)location, (PTR)(p->data + offset), (unsigned)count); return true;}unsigned intDEFUN(ieee_canonicalize_reloc,(abfd, section, relptr, symbols), bfd *abfd AND sec_ptr section AND arelent **relptr AND asymbol **symbols){/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/ ieee_reloc_type *src = (ieee_reloc_type *)(section->relocation); ieee_data_type *ieee = IEEE_DATA(abfd); while (src != (ieee_reloc_type *)NULL) { /* Work out which symbol to attach it this reloc to */ switch (src->symbol.letter) { case 'X': src->relent.sym_ptr_ptr = symbols + src->symbol.index + ieee->external_reference_base_offset; break; case 0: src->relent.sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; break; default: BFD_FAIL(); } *relptr++ = &src->relent; src = src->next; } *relptr = (arelent *)NULL; return section->reloc_count;}static int DEFUN(comp,(ap, bp), CONST PTR ap AND CONST PTR bp){ arelent *a = *((arelent **)ap); arelent *b = *((arelent **)bp); return a->address - b->address;}/*Write the section headers*/static voidDEFUN(ieee_write_section_part,(abfd), bfd *abfd){ ieee_data_type *ieee = IEEE_DATA(abfd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -