📄 ieee.c
字号:
if (! ieee_write_byte (abfd, ieee_variable_C_enum)) return false; } switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM)) { case SEC_CODE | SEC_LOAD: case SEC_CODE: if (! ieee_write_byte (abfd, ieee_variable_P_enum)) return false; break; case SEC_DATA: default: if (! ieee_write_byte (abfd, ieee_variable_D_enum)) return false; break; case SEC_ROM: case SEC_ROM | SEC_DATA: case SEC_ROM | SEC_LOAD: case SEC_ROM | SEC_DATA | SEC_LOAD: if (! ieee_write_byte (abfd, ieee_variable_R_enum)) return false; } if (! ieee_write_id (abfd, s->name)) return false;#if 0 ieee_write_int (abfd, 0); /* Parent */ ieee_write_int (abfd, 0); /* Brother */ ieee_write_int (abfd, 0); /* Context */#endif /* Alignment */ if (! ieee_write_byte (abfd, ieee_section_alignment_enum) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) || ! ieee_write_int (abfd, 1 << s->alignment_power)) return false; /* Size */ if (! ieee_write_2bytes (abfd, ieee_section_size_enum) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) || ! ieee_write_int (abfd, s->_raw_size)) return false; if (abfd->flags & EXEC_P) { /* Relocateable sections don't have asl records */ /* Vma */ if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum) || ! ieee_write_byte (abfd, ((bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) || ! ieee_write_int (abfd, s->lma)) return false; } } } return true;}static booleando_with_relocs (abfd, s) bfd *abfd; asection *s;{ unsigned int number_of_maus_in_address = bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd); unsigned int relocs_to_go = s->reloc_count; bfd_byte *stream = ieee_per_section (s)->data; arelent **p = s->orelocation; bfd_size_type current_byte_index = 0; qsort (s->orelocation, relocs_to_go, sizeof (arelent **), comp); /* Output the section preheader */ if (! ieee_write_byte (abfd, ieee_set_current_section_enum) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) return false; if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0) { if (! ieee_write_int (abfd, s->lma)) return false; } else { if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0)) return false; } if (relocs_to_go == 0) { /* If there aren't any relocations then output the load constant byte opcode rather than the load with relocation opcode */ while (current_byte_index < s->_raw_size) { bfd_size_type run; unsigned int MAXRUN = 127; run = MAXRUN; if (run > s->_raw_size - current_byte_index) { run = s->_raw_size - current_byte_index; } if (run != 0) { if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)) return false; /* Output a stream of bytes */ if (! ieee_write_int (abfd, run)) return false; if (bfd_write ((PTR) (stream + current_byte_index), 1, run, abfd) != run) return false; current_byte_index += run; } } } else { if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum)) return false; /* Output the data stream as the longest sequence of bytes possible, allowing for the a reasonable packet size and relocation stuffs. */ if ((PTR) stream == (PTR) NULL) { /* Outputting a section without data, fill it up */ stream = (unsigned char *) (bfd_alloc (abfd, s->_raw_size)); if (!stream) return false; memset ((PTR) stream, 0, (size_t) s->_raw_size); } while (current_byte_index < s->_raw_size) { bfd_size_type run; unsigned int MAXRUN = 127; if (relocs_to_go) { run = (*p)->address - current_byte_index; if (run > MAXRUN) run = MAXRUN; } else { run = MAXRUN; } if (run > s->_raw_size - current_byte_index) { run = s->_raw_size - current_byte_index; } if (run != 0) { /* Output a stream of bytes */ if (! ieee_write_int (abfd, run)) return false; if (bfd_write ((PTR) (stream + current_byte_index), 1, run, abfd) != run) return false; current_byte_index += run; } /* Output any relocations here */ if (relocs_to_go && (*p) && (*p)->address == current_byte_index) { while (relocs_to_go && (*p) && (*p)->address == current_byte_index) { arelent *r = *p; bfd_signed_vma ov;#if 0 if (r->howto->pc_relative) { r->addend += current_byte_index; }#endif switch (r->howto->size) { case 2: ov = bfd_get_signed_32 (abfd, stream + current_byte_index); current_byte_index += 4; break; case 1: ov = bfd_get_signed_16 (abfd, stream + current_byte_index); current_byte_index += 2; break; case 0: ov = bfd_get_signed_8 (abfd, stream + current_byte_index); current_byte_index++; break; default: ov = 0; BFD_FAIL (); return false; } ov &= r->howto->src_mask; if (r->howto->pc_relative && ! r->howto->pcrel_offset) ov += r->address; if (! ieee_write_byte (abfd, ieee_function_either_open_b_enum)) return false;/* abort();*/ if (r->sym_ptr_ptr != (asymbol **) NULL) { if (! ieee_write_expression (abfd, r->addend + ov, *(r->sym_ptr_ptr), r->howto->pc_relative, s->index)) return false; } else { if (! ieee_write_expression (abfd, r->addend + ov, (asymbol *) NULL, r->howto->pc_relative, s->index)) return false; } if (number_of_maus_in_address != bfd_get_reloc_size (r->howto)) { if (! ieee_write_int (abfd, bfd_get_reloc_size (r->howto))) return false; } if (! ieee_write_byte (abfd, ieee_function_either_close_b_enum)) return false; relocs_to_go--; p++; } } } } return true;}/* If there are no relocations in the output section then we can be clever about how we write. We block items up into a max of 127 bytes. */static booleando_as_repeat (abfd, s) bfd *abfd; asection *s;{ if (s->_raw_size) { if (! ieee_write_byte (abfd, ieee_set_current_section_enum) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8) || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff) || ! ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) || ! ieee_write_int (abfd, s->lma) || ! ieee_write_byte (abfd, ieee_repeat_data_enum) || ! ieee_write_int (abfd, s->_raw_size) || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum) || ! ieee_write_byte (abfd, 1) || ! ieee_write_byte (abfd, 0)) return false; } return true;}static booleando_without_relocs (abfd, s) bfd *abfd; asection *s;{ bfd_byte *stream = ieee_per_section (s)->data; if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) { if (! do_as_repeat (abfd, s)) return false; } else { unsigned int i; for (i = 0; i < s->_raw_size; i++) { if (stream[i] != 0) { if (! do_with_relocs (abfd, s)) return false; return true; } } if (! do_as_repeat (abfd, s)) return false; } return true;}static unsigned char *output_ptr_start;static unsigned char *output_ptr;static unsigned char *output_ptr_end;static unsigned char *input_ptr_start;static unsigned char *input_ptr;static unsigned char *input_ptr_end;static bfd *input_bfd;static bfd *output_bfd;static int output_buffer;static voidfill (){ /* FIXME: Check return value. I'm not sure whether it needs to read the entire buffer or not. */ bfd_read ((PTR) input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd); input_ptr = input_ptr_start;}static voidflush (){ if (bfd_write ((PTR) (output_ptr_start), 1, output_ptr - output_ptr_start, output_bfd) != (bfd_size_type) (output_ptr - output_ptr_start)) abort (); output_ptr = output_ptr_start; output_buffer++;}#define THIS() ( *input_ptr )#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); }static voidwrite_int (value) int value;{ if (value >= 0 && value <= 127) { OUT (value); } else { unsigned int length; /* How many significant bytes ? */ /* FIXME FOR LONGER INTS */ if (value & 0xff000000) { length = 4; } else if (value & 0x00ff0000) { length = 3; } else if (value & 0x0000ff00) { length = 2; } else length = 1; OUT ((int) ieee_number_repeat_start_enum + length); switch (length) { case 4: OUT (value >> 24); case 3: OUT (value >> 16); case 2: OUT (value >> 8); case 1: OUT (value); } }}static voidcopy_id (){ int length = THIS (); char ch; OUT (length); NEXT (); while (length--) { ch = THIS (); OUT (ch); NEXT (); }}#define VAR(x) ((x | 0x80))static voidcopy_expression (){ int stack[10]; int *tos = stack; int value = 0; while (1) { switch (THIS ()) { case 0x84: NEXT (); value = THIS (); NEXT (); value = (value << 8) | THIS (); NEXT (); value = (value << 8) | THIS (); NEXT (); value = (value << 8) | THIS (); NEXT (); *tos++ = value; break; case 0x83: NEXT (); value = THIS (); NEXT (); value = (value << 8) | THIS (); NEXT (); value = (value << 8) | THIS (); NEXT (); *tos++ = value; break; case 0x82: NEXT (); value = THIS (); NEXT (); value = (value << 8) | THIS (); NEXT (); *tos++ = value; break; case 0x81: NEXT (); value = THIS (); NEXT (); *tos++ = value; break; case 0x80: NEXT (); *tos++ = 0; break; default: if (THIS () > 0x84) { /* Not a number, just bug out with the answer */ write_int (*(--tos)); return; } *tos++ = THIS (); NEXT (); value = 0; break; case 0xa5: /* PLUS anything */ { int value = *(--tos); value += *(--tos); *tos++ = value; NEXT (); } break; case VAR ('R'): { int section_number; ieee_data_type *ieee; asection *s; NEXT (); section_number = THIS (); NEXT (); ieee = IEEE_DATA (input_bfd); s = ieee->section_table[section_number]; if (s->output_section) { value = s->output_section->lma; } else { value = 0; } value += s->output_offset; *tos++ = value; value = 0; } break; case 0x90: { NEXT (); write_int (*(--tos)); OUT (0x90); return; } } }}/* Drop the int in the buffer, and copy a null into the gap, which we will overwrite later */struct output_buffer_struct{ unsi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -