📄 oasys.c
字号:
static voidoasys_get_symbol_info (ignore_abfd, symbol, ret) bfd *ignore_abfd ATTRIBUTE_UNUSED; asymbol *symbol; symbol_info *ret;{ bfd_symbol_info (symbol, ret); if (!symbol->section) ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';}static voidoasys_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: case bfd_print_symbol_more: fprintf (file, "%s", symbol->name); break; case bfd_print_symbol_all: { CONST char *section_name = symbol->section == (asection *) NULL ? (CONST char *) "*abs" : symbol->section->name; bfd_print_symbol_vandf ((PTR) file, symbol); fprintf (file, " %-5s %s", section_name, symbol->name); } break; }}/* The howto table is build using the top two bits of a reloc byte to index into it. The bits are PCREL,WORD/LONG*/static reloc_howto_type howto_table[] ={ HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false), HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false), HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false), HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false)};/* Read in all the section data and relocation stuff too */static booleanoasys_slurp_section_data (abfd) bfd *CONST abfd;{ oasys_record_union_type record; oasys_data_type *data = OASYS_DATA (abfd); boolean loop = true; oasys_per_section_type *per; asection *s; /* See if the data has been slurped already .. */ for (s = abfd->sections; s != (asection *) NULL; s = s->next) { per = oasys_per_section (s); if (per->initialized == true) return true; } if (data->first_data_record == 0) return true; if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) return false; while (loop) { if (! oasys_read_record (abfd, &record)) return false; switch (record.header.type) { case oasys_record_is_header_enum: break; case oasys_record_is_data_enum: { bfd_byte *src = record.data.data; bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length; bfd_byte *dst_ptr; bfd_byte *dst_base_ptr; unsigned int relbit; unsigned int count; asection *section = data->sections[record.data.relb & RELOCATION_SECT_BITS]; bfd_vma dst_offset; per = oasys_per_section (section); if (per->initialized == false) { per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size); if (!per->data) return false; per->reloc_tail_ptr = (oasys_reloc_type **) & (section->relocation); per->had_vma = false; per->initialized = true; section->reloc_count = 0; section->flags = SEC_ALLOC; } dst_offset = bfd_h_get_32 (abfd, record.data.addr); if (per->had_vma == false) { /* Take the first vma we see as the base */ section->vma = dst_offset; per->had_vma = true; } dst_offset -= section->vma; dst_base_ptr = oasys_per_section (section)->data; dst_ptr = oasys_per_section (section)->data + dst_offset; if (src < end_src) { section->flags |= SEC_LOAD | SEC_HAS_CONTENTS; } while (src < end_src) { unsigned char mod_byte = *src++; size_t gap = end_src - src; count = 8; if (mod_byte == 0 && gap >= 8) { dst_ptr[0] = src[0]; dst_ptr[1] = src[1]; dst_ptr[2] = src[2]; dst_ptr[3] = src[3]; dst_ptr[4] = src[4]; dst_ptr[5] = src[5]; dst_ptr[6] = src[6]; dst_ptr[7] = src[7]; dst_ptr += 8; src += 8; } else { for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1) { if (relbit & mod_byte) { unsigned char reloc = *src; /* This item needs to be relocated */ switch (reloc & RELOCATION_TYPE_BITS) { case RELOCATION_TYPE_ABS: break; case RELOCATION_TYPE_REL: { /* Relocate the item relative to the section */ oasys_reloc_type *r = (oasys_reloc_type *) bfd_alloc (abfd, sizeof (oasys_reloc_type)); if (!r) return false; *(per->reloc_tail_ptr) = r; per->reloc_tail_ptr = &r->next; r->next = (oasys_reloc_type *) NULL; /* Reference to undefined symbol */ src++; /* There is no symbol */ r->symbol = 0; /* Work out the howto */ abort ();#if 0 r->relent.section = data->sections[reloc & RELOCATION_SECT_BITS]; r->relent.addend = - r->relent.section->vma;#endif r->relent.address = dst_ptr - dst_base_ptr; r->relent.howto = &howto_table[reloc >> 6]; r->relent.sym_ptr_ptr = (asymbol **) NULL; section->reloc_count++; /* Fake up the data to look like it's got the -ve pc in it, this makes it much easier to convert into other formats. This is done by hitting the addend. */ if (r->relent.howto->pc_relative == true) { r->relent.addend -= dst_ptr - dst_base_ptr; } } break; case RELOCATION_TYPE_UND: { oasys_reloc_type *r = (oasys_reloc_type *) bfd_alloc (abfd, sizeof (oasys_reloc_type)); if (!r) return false; *(per->reloc_tail_ptr) = r; per->reloc_tail_ptr = &r->next; r->next = (oasys_reloc_type *) NULL; /* Reference to undefined symbol */ src++; /* Get symbol number */ r->symbol = (src[0] << 8) | src[1]; /* Work out the howto */ abort ();#if 0 r->relent.section = (asection *) NULL;#endif r->relent.addend = 0; r->relent.address = dst_ptr - dst_base_ptr; r->relent.howto = &howto_table[reloc >> 6]; r->relent.sym_ptr_ptr = (asymbol **) NULL; section->reloc_count++; src += 2; /* Fake up the data to look like it's got the -ve pc in it, this makes it much easier to convert into other formats. This is done by hitting the addend. */ if (r->relent.howto->pc_relative == true) { r->relent.addend -= dst_ptr - dst_base_ptr; } } break; case RELOCATION_TYPE_COM: BFD_FAIL (); } } *dst_ptr++ = *src++; } } } } break; case oasys_record_is_local_enum: case oasys_record_is_symbol_enum: case oasys_record_is_section_enum: break; default: loop = false; } } return true;}static booleanoasys_new_section_hook (abfd, newsect) bfd *abfd; asection *newsect;{ newsect->used_by_bfd = (PTR) bfd_alloc (abfd, sizeof (oasys_per_section_type)); if (!newsect->used_by_bfd) return false; oasys_per_section (newsect)->data = (bfd_byte *) NULL; oasys_per_section (newsect)->section = newsect; oasys_per_section (newsect)->offset = 0; oasys_per_section (newsect)->initialized = false; newsect->alignment_power = 1; /* Turn the section string into an index */ sscanf (newsect->name, "%u", &newsect->target_index); return true;}static longoasys_get_reloc_upper_bound (abfd, asect) bfd *abfd; sec_ptr asect;{ if (! oasys_slurp_section_data (abfd)) return -1; return (asect->reloc_count + 1) * sizeof (arelent *);}static booleanoasys_get_section_contents (abfd, section, location, offset, count) bfd *abfd; sec_ptr section; PTR location; file_ptr offset; bfd_size_type count;{ oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd; oasys_slurp_section_data (abfd); if (p->initialized == false) { (void) memset (location, 0, (int) count); } else { (void) memcpy (location, (PTR) (p->data + offset), (int) count); } return true;}longoasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols) bfd *ignore_abfd ATTRIBUTE_UNUSED; sec_ptr section; arelent **relptr; asymbol **symbols ATTRIBUTE_UNUSED;{ unsigned int reloc_count = 0; oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation); while (src != (oasys_reloc_type *) NULL) { abort ();#if 0 if (src->relent.section == (asection *) NULL) { src->relent.sym_ptr_ptr = symbols + src->symbol; }#endif *relptr++ = &src->relent; src = src->next; reloc_count++; } *relptr = (arelent *) NULL; return section->reloc_count = reloc_count;}/* Writing *//* Calculate the checksum and write one record */static booleanoasys_write_record (abfd, type, record, size) bfd *abfd; oasys_record_enum_type type; oasys_record_union_type *record; size_t size;{ int checksum; size_t i; unsigned char *ptr; record->header.length = size; record->header.type = (int) type; record->header.check_sum = 0; record->header.fill = 0; ptr = (unsigned char *) &record->pad[0]; checksum = 0; for (i = 0; i < size; i++) { checksum += *ptr++; } record->header.check_sum = 0xff & (-checksum); if (bfd_write ((PTR) record, 1, size, abfd) != size) return false; return true;}/* Write out all the symbols */static booleanoasys_write_syms (abfd) bfd *abfd;{ unsigned int count; asymbol **generic = bfd_get_outsymbols (abfd); unsigned int index = 0; for (count = 0; count < bfd_get_symcount (abfd); count++) { oasys_symbol_record_type symbol; asymbol *CONST g = generic[count]; CONST char *src = g->name; char *dst = symbol.name; unsigned int l = 0; if (bfd_is_com_section (g->section)) { symbol.relb = RELOCATION_TYPE_COM; bfd_h_put_16 (abfd, index, symbol.refno); index++; } else if (bfd_is_abs_section (g->section)) { symbol.relb = RELOCATION_TYPE_ABS; bfd_h_put_16 (abfd, 0, symbol.refno); } else if (bfd_is_und_section (g->section)) { symbol.relb = RELOCATION_TYPE_UND; bfd_h_put_16 (abfd, index, symbol.refno); /* Overload the value field with the output index number */ index++; } else if (g->flags & BSF_DEBUGGING) { /* throw it away */ continue; } else { if (g->section == (asection *) NULL) { /* Sometime, the oasys tools give out a symbol with illegal bits in it, we'll output it in the same broken way */ symbol.relb = RELOCATION_TYPE_REL | 0; } else { symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index; } bfd_h_put_16 (abfd, 0, symbol.refno); }#ifdef UNDERSCORE_HACK if (src[l] == '_') dst[l++] = '.';#endif while (src[l]) { dst[l] = src[l]; l++; } bfd_h_put_32 (abfd, g->value, symbol.value); if (g->flags & BSF_LOCAL) { if (! oasys_write_record (abfd, oasys_record_is_local_enum, (oasys_record_union_type *) & symbol, offsetof (oasys_symbol_record_type, name[0]) + l)) return false; } else { if (! oasys_write_record (abfd, oasys_record_is_symbol_enum, (oasys_record_union_type *) & symbol, offsetof (oasys_symbol_record_type, name[0]) + l)) return false; } g->value = index - 1; } return true;} /* Write a section header for each section */static booleanoasys_write_sections (abfd) bfd *abfd;{ asection *s; static oasys_section_record_type out; for (s = abfd->sections; s != (asection *) NULL; s = s->next) { if (!isdigit ((unsigned char) s->name[0])) { (*_bfd_error_handler) (_("%s: can not represent section `%s' in oasys"), bfd_get_filename (abfd), s->name); bfd_set_error (bfd_error_nonrepresentable_section); return false; } out.relb = RELOCATION_TYPE_REL | s->target_index; bfd_h_put_32 (abfd, s->_cooked_size, out.value); bfd_h_put_32 (abfd, s->vma, out.vma); if (! oasys_write_record (abfd, oasys_record_is_section_enum,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -