📄 oasys.c
字号:
return abfd->xvec; fail: (void) bfd_release(abfd, oasys); abfd->tdata.oasys_obj_data = save; return (bfd_target *)NULL;}static void DEFUN(oasys_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: case bfd_print_symbol_more: fprintf(file,"%s", symbol->name); break; case bfd_print_symbol_all: case bfd_print_symbol_nm: { 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, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)};/* Read in all the section data and relocation stuff too */static boolean DEFUN(oasys_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; bfd_seek(abfd, data->first_data_record, SEEK_SET); while (loop) { oasys_read_record(abfd, &record); switch (record.header.type) { case oasys_record_is_header_enum: break; case oasys_record_is_data_enum: { uint8e_type *src = record.data.data; uint8e_type *end_src = ((uint8e_type *)&record) + record.header.length; unsigned int relbit; bfd_byte *dst_ptr ; bfd_byte *dst_base_ptr ; 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); 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) { uint8e_type mod_byte = *src++; uint32_type 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) { uint8e_type 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)); *(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)); *(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;}bfd_error_vector_type bfd_error_vector;static booleanDEFUN(oasys_new_section_hook,(abfd, newsect), bfd *abfd AND asection *newsect){ newsect->used_by_bfd = (PTR) bfd_alloc(abfd, sizeof(oasys_per_section_type)); 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 unsigned intDEFUN(oasys_get_reloc_upper_bound, (abfd, asect), bfd *abfd AND sec_ptr asect){ oasys_slurp_section_data(abfd); return (asect->reloc_count+1) * sizeof(arelent *);}static booleanDEFUN(oasys_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){ 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;}unsigned intDEFUN(oasys_canonicalize_reloc,(ignore_abfd, section, relptr, symbols), bfd *ignore_abfd AND sec_ptr section AND arelent **relptr AND asymbol **symbols){ 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 void DEFUN(oasys_write_record,(abfd, type, record, size), bfd *CONST abfd AND CONST oasys_record_enum_type type AND oasys_record_union_type *record AND CONST size_t size){ int checksum; size_t i; uint8e_type *ptr; record->header.length = size; record->header.type = (int)type; record->header.check_sum = 0; record->header.fill = 0; ptr = &record->pad[0]; checksum = 0; for (i = 0; i < size; i++) { checksum += *ptr++; } record->header.check_sum = 0xff & (- checksum); bfd_write((PTR)record, 1, size, abfd);}/* Write out all the symbols */static void DEFUN(oasys_write_syms, (abfd), bfd * CONST 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 (g->section == & bfd_com_section) { symbol.relb = RELOCATION_TYPE_COM; bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0])); index++; } else if (g->section == & bfd_abs_section) { symbol.relb = RELOCATION_TYPE_ABS; bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0])); } else if (g->section == &bfd_und_section) { symbol.relb = RELOCATION_TYPE_UND ; bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0])); /* 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, (uint8e_type *)(&symbol.refno[0])); }#ifdef UNDERSCORE_HACK if (src[l] == '_') dst[l++] = '.';#endif while (src[l]) { dst[l] = src[l]; l++; } bfd_h_put_32(abfd, g->value, (bfd_byte*) symbol.value); if (g->flags & BSF_LOCAL) { oasys_write_record(abfd, oasys_record_is_local_enum, (oasys_record_union_type *) &symbol, offsetof(oasys_symbol_record_type, name[0]) + l); } else { oasys_write_record(abfd, oasys_record_is_symbol_enum, (oasys_record_union_type *) &symbol, offsetof(oasys_symbol_record_type, name[0]) + l); } g->value = index-1; }} /* Write a section header for each section */static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -