📄 ieee.c
字号:
IEEE_DATA (abfd)->h.first_byte = (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1); if (!IEEE_DATA (abfd)->h.first_byte) goto fail; if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) goto fail; /* FIXME: Check return value. I'm not sure whether it needs to read the entire buffer or not. */ bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1, ieee->w.r.me_record + 1, abfd); ieee_slurp_sections (abfd); if (! ieee_slurp_debug (abfd)) goto fail; /* Parse section data to activate file and section flags implied by section contents. */ if (! ieee_slurp_section_data (abfd)) goto fail; return abfd->xvec;got_wrong_format: bfd_set_error (bfd_error_wrong_format);fail: (void) bfd_release (abfd, ieee); abfd->tdata.ieee_data = save; return (const bfd_target *) NULL;}voidieee_get_symbol_info (ignore_abfd, symbol, ret) bfd *ignore_abfd ATTRIBUTE_UNUSED; asymbol *symbol; symbol_info *ret;{ bfd_symbol_info (symbol, ret); if (symbol->name[0] == ' ') ret->name = "* empty table entry "; if (!symbol->section) ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';}voidieee_print_symbol (ignore_abfd, afile, symbol, how) bfd *ignore_abfd ATTRIBUTE_UNUSED; PTR afile; asymbol *symbol; 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_all: { const char *section_name = (symbol->section == (asection *) NULL ? "*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, symbol->name); } } break; }}static booleando_one (ieee, current_map, location_ptr, s, iterations) ieee_data_type *ieee; ieee_per_section_type *current_map; unsigned char *location_ptr; asection *s; int iterations;{ 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)); if (!r) return false; *(current_map->reloc_tail_ptr) = r; current_map->reloc_tail_ptr = &r->next; r->next = (ieee_reloc_type *) NULL; next_byte (&(ieee->h));/* abort();*/ r->relent.sym_ptr_ptr = 0; parse_expression (ieee, &r->relent.addend, &r->symbol, &pcrel, &extra, §ion); r->relent.address = current_map->pc; s->flags |= SEC_RELOC; s->owner->flags |= HAS_RELOC; s->reloc_count++; if (r->relent.sym_ptr_ptr == NULL && section != NULL) 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 (); return false; } } 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; } } } /* Prevent more than the first load-item of an LR record from being repeated (MRI convention). */ if (iterations != 1) loop = false; } } } return true;}/* Read in all the section data and relocation stuff too */static booleanieee_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; if ((s->flags & SEC_DEBUGGING) != 0) continue; per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size); if (!per->data) return false; /*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]; s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; 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; 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: next_byte (&(ieee->h)); if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum) next_byte (&(ieee->h)); abfd->start_address = must_parse_int (&(ieee->h)); /* We've got to the end of the data now - */ return true; default: BFD_FAIL (); return false; } 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; unsigned char *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; if (!do_one (ieee, current_map, location_ptr, s, iterations)) return false; iterations--; } } } break; case ieee_load_constant_bytes_enum: case ieee_load_with_relocation_enum: { if (!do_one (ieee, current_map, location_ptr, s, 1)) return false; } } }}booleanieee_new_section_hook (abfd, newsect) bfd *abfd; asection *newsect;{ newsect->used_by_bfd = (PTR) bfd_alloc (abfd, sizeof (ieee_per_section_type)); if (!newsect->used_by_bfd) return false; ieee_per_section (newsect)->data = (bfd_byte *) NULL; ieee_per_section (newsect)->section = newsect; return true;}longieee_get_reloc_upper_bound (abfd, asect) bfd *abfd; sec_ptr asect;{ if ((asect->flags & SEC_DEBUGGING) != 0) return 0; if (! ieee_slurp_section_data (abfd)) return -1; return (asect->reloc_count + 1) * sizeof (arelent *);}static booleanieee_get_section_contents (abfd, section, location, offset, count) bfd *abfd; sec_ptr section; PTR location; file_ptr offset; bfd_size_type count;{ ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd; if ((section->flags & SEC_DEBUGGING) != 0) return _bfd_generic_get_section_contents (abfd, section, location, offset, count); ieee_slurp_section_data (abfd); (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count); return true;}longieee_canonicalize_reloc (abfd, section, relptr, symbols) bfd *abfd; sec_ptr section; arelent **relptr; 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); if ((section->flags & SEC_DEBUGGING) != 0) return 0; while (src != (ieee_reloc_type *) NULL) { /* Work out which symbol to attach it this reloc to */ switch (src->symbol.letter) { case 'I': src->relent.sym_ptr_ptr = symbols + src->symbol.index + ieee->external_symbol_base_offset; break; case 'X': src->relent.sym_ptr_ptr = symbols + src->symbol.index + ieee->external_reference_base_offset; break; case 0: if (src->relent.sym_ptr_ptr != NULL) src->relent.sym_ptr_ptr = src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr; break; default: BFD_FAIL (); } *relptr++ = &src->relent; src = src->next; } *relptr = (arelent *) NULL; return section->reloc_count;}static intcomp (ap, bp) CONST PTR ap; CONST PTR bp;{ arelent *a = *((arelent **) ap); arelent *b = *((arelent **) bp); return a->address - b->address;}/* Write the section headers. */static booleanieee_write_section_part (abfd) bfd *abfd;{ ieee_data_type *ieee = IEEE_DATA (abfd); asection *s; ieee->w.r.section_part = bfd_tell (abfd); for (s = abfd->sections; s != (asection *) NULL; s = s->next) { if (! bfd_is_abs_section (s) && (s->flags & SEC_DEBUGGING) == 0) { if (! ieee_write_byte (abfd, ieee_section_type_enum) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) return false; if (abfd->flags & EXEC_P) { /* This image is executable, so output absolute sections */ if (! ieee_write_byte (abfd, ieee_variable_A_enum) || ! ieee_write_byte (abfd, ieee_variable_S_enum)) return false; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -