📄 ieee.c
字号:
asection *s; ieee->w.r.section_part = bfd_tell(abfd); for (s = abfd->sections; s != (asection *)NULL; s=s->next) { if (s != &bfd_abs_section) { ieee_write_byte(abfd, ieee_section_type_enum); ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE); if (abfd->flags & EXEC_P) { /* This image is executable, so output absolute sections */ ieee_write_byte(abfd, ieee_variable_A_enum); ieee_write_byte(abfd, ieee_variable_S_enum); } else { ieee_write_byte(abfd, ieee_variable_C_enum); } switch (s->flags &(SEC_CODE | SEC_DATA | SEC_ROM)) { case SEC_CODE | SEC_LOAD: case SEC_CODE: ieee_write_byte(abfd, ieee_variable_P_enum); break; case SEC_DATA: default: ieee_write_byte(abfd, ieee_variable_D_enum); break; case SEC_ROM: case SEC_ROM | SEC_DATA: case SEC_ROM | SEC_LOAD: case SEC_ROM | SEC_DATA | SEC_LOAD: ieee_write_byte(abfd, ieee_variable_R_enum); } ieee_write_id(abfd, s->name);#if 0 ieee_write_int(abfd, 0); /* Parent */ ieee_write_int(abfd, 0); /* Brother */ ieee_write_int(abfd, 0); /* Context */#endif /* Alignment */ ieee_write_byte(abfd, ieee_section_alignment_enum); ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE); ieee_write_int(abfd, 1 << s->alignment_power); /* Size */ ieee_write_2bytes(abfd, ieee_section_size_enum); ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE); ieee_write_int(abfd, s->_raw_size); if (abfd->flags & EXEC_P) { /* Relocateable sections don't have asl records */ /* Vma */ ieee_write_2bytes(abfd, ieee_section_base_address_enum); ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE); ieee_write_int(abfd, s->vma); } } }}static void DEFUN(do_with_relocs,(abfd, s), bfd *abfd AND asection *s){ 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 */ ieee_write_byte(abfd, ieee_set_current_section_enum); ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE); ieee_write_twobyte(abfd, ieee_set_current_pc_enum); ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE); ieee_write_expression(abfd, 0, s->symbol, 0, 0); if (relocs_to_go == 0) { /* If there arn'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 = 32; run = MAXRUN; if (run > s->_raw_size - current_byte_index) { run = s->_raw_size - current_byte_index; } if (run != 0) { ieee_write_byte(abfd, ieee_load_constant_bytes_enum); /* Output a stream of bytes */ ieee_write_int(abfd, run); bfd_write((PTR)(stream + current_byte_index), 1, run, abfd); current_byte_index += run; } } } else { ieee_write_byte(abfd, ieee_load_with_relocation_enum); /* 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 = (uint8e_type *)(bfd_alloc(abfd, s->_raw_size)); memset((PTR)stream, 0, s->_raw_size); } while (current_byte_index < s->_raw_size) { bfd_size_type run; unsigned int MAXRUN = 32; if (relocs_to_go) { run = (*p)->address - current_byte_index; } 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 */ ieee_write_int(abfd, run); bfd_write((PTR)(stream + current_byte_index), 1, run, abfd); 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_vma ov;#if 0 if (r->howto->pc_relative) { r->addend += current_byte_index ; }#endif switch (r->howto->size) { case 2: ov = bfd_get_32(abfd, stream+current_byte_index); current_byte_index +=4; break; case 1: ov = bfd_get_16(abfd, stream+current_byte_index); current_byte_index +=2; break; case 0: ov = bfd_get_8(abfd, stream+current_byte_index); current_byte_index ++; break; default: ov = 0; BFD_FAIL(); } ieee_write_byte(abfd, ieee_function_either_open_b_enum); abort(); if (r->sym_ptr_ptr != (asymbol **)NULL) { ieee_write_expression(abfd, r->addend + ov, *(r->sym_ptr_ptr), r->howto->pc_relative, s->index); } else { ieee_write_expression(abfd, r->addend + ov, (asymbol *)NULL, r->howto->pc_relative, s->index); } if (1 || r->howto->size != 2) { ieee_write_byte(abfd, ieee_comma); ieee_write_int(abfd, 1<< r->howto->size); } ieee_write_byte(abfd, ieee_function_either_close_b_enum); relocs_to_go --; p++; } } } }}/* If there are no relocations in the output section then we canbe clever about how we write. We block items up into a max of 127bytes */static void DEFUN(do_as_repeat, (abfd, s), bfd *abfd AND asection *s){ ieee_write_byte(abfd, ieee_set_current_section_enum); ieee_write_byte(abfd, 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, s->index + IEEE_SECTION_NUMBER_BASE); ieee_write_int(abfd, s->vma ); 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);}static void DEFUN(do_without_relocs, (abfd, s), bfd *abfd AND asection *s){ bfd_byte *stream = ieee_per_section(s)->data; if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) { do_as_repeat(abfd, s); } else { unsigned int i; for (i = 0; i < s->_raw_size; i++) { if (stream[i] != 0) { do_with_relocs(abfd, s); return; } } do_as_repeat(abfd, s); } }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 void fill(){ bfd_read((PTR)input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd); input_ptr = input_ptr_start;}static void flush(){ bfd_write((PTR)(output_ptr_start),1,output_ptr - output_ptr_start, output_bfd); 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 void write_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 void copy_id() { int length = THIS(); char ch; OUT(length); NEXT(); while (length--) { ch = THIS(); OUT(ch); NEXT(); }}#define VAR(x) ((x | 0x80))static void copy_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->vma ; } 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 {unsigned char *ptrp; int buffer;} ;static voidDEFUN(fill_int,(buf), struct output_buffer_struct *buf){ if (buf->buffer == output_buffer) { /* Still a chance to output the size */ int value = output_ptr - buf->ptrp + 3; buf->ptrp[0] = value >> 24; buf->ptrp[1] = value >> 16; buf->ptrp[2] = value >> 8; buf->ptrp[3] = value >> 0; }}static voidDEFUN(drop_int,(buf), struct output_buffer_struct *buf){ int type = THIS(); int ch; if (type <= 0x84) { NEXT(); switch(type) { case 0x84: ch = THIS(); NEXT(); case 0x83: ch = THIS(); NEXT(); case 0x82: ch = THIS(); NEXT(); case 0x81: ch = THIS(); NEXT(); case 0x80: break; } } OUT(0x84); buf->ptrp = output_ptr; buf->buffer = output_buffer; OUT(0);OUT(0);OUT(0);OUT(0);}static void copy_int(){ int type = THIS(); int ch; if (type <= 0x84) { OUT(type); NEXT(); switch(type) { case 0x84: ch = THIS(); NEXT(); OUT(ch); case 0x83: ch = THIS(); NEXT(); OUT(ch); case 0x82: ch = THIS(); NEXT(); OUT(ch); case 0x81: ch = THIS(); NEXT(); OUT(ch); case 0x80: break; } }}#define ID copy_id()#define INT copy_int()#define EXP copy_expression()static void copy_till_end();#define INTn(q) copy_int()#define EXPn(q) copy_expression()static void f1_record(){ int ch; /* ATN record */ NEXT(); ch = THIS(); switch (ch) { default: OUT(0xf1); OUT(ch); break; case 0xc9: NEXT(); OUT(0xf1); OUT(0xc9); INT; INT; ch = THIS(); switch (ch) { case 0x16: NEXT();break; case 0x01: NEXT();break; case 0x00: NEXT(); INT; break; case 0x03: NEXT(); INT; break; case 0x13: EXPn(instruction address); break; default: break; } break; case 0xd8: /* EXternal ref */ NEXT(); OUT(0xf1); OUT(0xd8); EXP ; EXP; EXP; EXP; break; case 0xce: NEXT(); OUT(0xf1);OUT(0xce); INT; INT; ch = THIS(); INT; switch (ch) { case 0x01: INT; INT; break; case 0x02: INT; break; case 0x04: EXPn(external function); break; case 0x05: break; case 0x07: INTn(line number); INT; case 0x08: break; case 0x0a: INTn(locked register); INT; break; case 0x3f: copy_till_end(); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -