diff options
author | Steve Chamberlain <steve@cygnus> | 1991-04-17 00:54:03 +0000 |
---|---|---|
committer | Steve Chamberlain <steve@cygnus> | 1991-04-17 00:54:03 +0000 |
commit | 3e9aade18314dd24fd88abe28b0b1b9c1d1a1828 (patch) | |
tree | e4452df782a6a84b3cd6f61c2b0f32ca8524c9c2 /bfd/oasys.c | |
parent | 4432f8ad291038bda65a79d02a7deaa57479e7d2 (diff) | |
download | gdb-3e9aade18314dd24fd88abe28b0b1b9c1d1a1828.zip gdb-3e9aade18314dd24fd88abe28b0b1b9c1d1a1828.tar.gz gdb-3e9aade18314dd24fd88abe28b0b1b9c1d1a1828.tar.bz2 |
Lots of fixes to make it work
Diffstat (limited to 'bfd/oasys.c')
-rw-r--r-- | bfd/oasys.c | 831 |
1 files changed, 516 insertions, 315 deletions
diff --git a/bfd/oasys.c b/bfd/oasys.c index 4d57116..cb40750 100644 --- a/bfd/oasys.c +++ b/bfd/oasys.c @@ -1,23 +1,14 @@ -/*#define UNDERSCORE_HACK 0*/ +#define UNDERSCORE_HACK 1 +#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier) /* bfd backend for oasys objects. - Object files contain records in order: - - optional header - symbol records - section records - data records - debugging records - end record - - - - Written by Steve Chamberlain - steve@cygnus.com + Written by Steve Chamberlain + steve@cygnus.com + $Id$ */ @@ -36,11 +27,15 @@ #define obstack_chunk_alloc malloc #define obstack_chunk_free free +#define oasys_malloc(abfd,size) \ + obstack_alloc( &( oasys_data(abfd)->oasys_obstack), (size)) + typedef void generic_symbol_type; -void DEFUN(oasys_read_record,(abfd, record), - bfd *abfd AND +static void +DEFUN(oasys_read_record,(abfd, record), + bfd *CONST abfd AND oasys_record_union_type *record) { @@ -51,8 +46,8 @@ void DEFUN(oasys_read_record,(abfd, record), abfd); } static size_t -oasys_string_length(record) -oasys_record_union_type *record; +DEFUN(oasys_string_length,(record), + oasys_record_union_type *record) { return record->header.length - ((char *)record->symbol.name - (char *)record); @@ -65,16 +60,18 @@ return record->header.length Slurp the symbol table by reading in all the records at the start file till we get to the first section record. -We'll sort the symbols into two lists, defined and undefined. The -undefined symbols will also be sorted by refno. We do this by placing -all undefined symbols at the front of the table moving in, and the -defined symbols at the end of the table moving back. +We'll sort the symbolss into two lists, defined and undefined. The +undefined symbols will be placed into the table according to their +refno. + +We do this by placing all undefined symbols at the front of the table +moving in, and the defined symbols at the end of the table moving back. */ static boolean -oasys_slurp_symbol_table(abfd) -bfd *abfd; +DEFUN(oasys_slurp_symbol_table,(abfd), + bfd * CONST abfd) { oasys_record_union_type record; oasys_data_type *data = oasys_data(abfd); @@ -90,13 +87,13 @@ bfd *abfd; } /* Buy enough memory for all the symbols and all the names */ data->symbols = - (asymbol *)malloc(sizeof(asymbol) * abfd->symcount); + (asymbol *)oasys_malloc(abfd, sizeof(asymbol) * abfd->symcount); #ifdef UNDERSCORE_HACK /* buy 1 more char for each symbol to keep the underscore in*/ - data->strings = malloc(data->symbol_string_length + - abfd->symcount); + data->strings = oasys_malloc(abfd, data->symbol_string_length + + abfd->symcount); #else - data->strings = malloc(data->symbol_string_length); + data->strings = oasys_malloc(abfd, data->symbol_string_length); #endif dest_undefined = data->symbols; @@ -113,12 +110,12 @@ bfd *abfd; case oasys_record_is_local_enum: case oasys_record_is_symbol_enum: { -int flag = record.header.type == oasys_record_is_local_enum ? + int flag = record.header.type == oasys_record_is_local_enum ? (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT); size_t length = oasys_string_length(&record); - switch (record.symbol.relb[0] & RELOCATION_TYPE_BITS) { + switch (record.symbol.relb & RELOCATION_TYPE_BITS) { case RELOCATION_TYPE_ABS: dest = dest_defined--; dest->section = 0; @@ -127,7 +124,7 @@ int flag = record.header.type == oasys_record_is_local_enum ? case RELOCATION_TYPE_REL: dest = dest_defined--; dest->section = - oasys_data(abfd)->sections[record.symbol.relb[0] & + oasys_data(abfd)->sections[record.symbol.relb & RELOCATION_SECT_BITS]; if (record.header.type == oasys_record_is_local_enum) { @@ -139,7 +136,7 @@ int flag = record.header.type == oasys_record_is_local_enum ? } break; case RELOCATION_TYPE_UND: - dest = dest_undefined++; + dest = data->symbols + bfd_h_getshort(abfd, &record.symbol.refno[0]); dest->section = (asection *)NULL; dest->flags = BSF_UNDEFINED; break; @@ -154,11 +151,14 @@ int flag = record.header.type == oasys_record_is_local_enum ? } dest->name = string_ptr; dest->the_bfd = abfd; - dest->udata = (void *)NULL; - dest->value = bfd_h_getlong(abfd, &record.symbol.value); -#if UNDERSCORE_HACK - string_ptr[0] = '_'; - string_ptr++; + dest->udata = (PTR)NULL; + dest->value = bfd_h_getlong(abfd, &record.symbol.value[0]); + +#ifdef UNDERSCORE_HACK + if (record.symbol.name[0] != '_') { + string_ptr[0] = '_'; + string_ptr++; + } #endif memcpy(string_ptr, record.symbol.name, length); @@ -175,9 +175,9 @@ int flag = record.header.type == oasys_record_is_local_enum ? } -size_t -oasys_get_symtab_upper_bound (abfd) -bfd *abfd; +static size_t +DEFUN(oasys_get_symtab_upper_bound,(abfd), + bfd *CONST abfd) { oasys_slurp_symbol_table (abfd); @@ -190,9 +190,9 @@ bfd *abfd; extern bfd_target oasys_vec; unsigned int -oasys_get_symtab (abfd, location) -bfd *abfd; -asymbol **location; +DEFUN(oasys_get_symtab,(abfd, location), + bfd *abfd AND + asymbol **location) { asymbol *symbase ; unsigned int counter ; @@ -211,9 +211,9 @@ asymbol **location; * archive stuff */ #define swap(x) x = bfd_h_get_x(abfd, &x); -bfd_target * -oasys_archive_p(abfd) -bfd *abfd; +static bfd_target * +DEFUN(oasys_archive_p,(abfd), + bfd *abfd) { oasys_archive_header_type header; unsigned int i; @@ -250,12 +250,12 @@ bfd *abfd; */ { oasys_ar_data_type *ar = - (oasys_ar_data_type*) malloc(sizeof(oasys_ar_data_type)); + (oasys_ar_data_type*) oasys_malloc(abfd, sizeof(oasys_ar_data_type)); oasys_module_info_type *module = (oasys_module_info_type*) - malloc(sizeof(oasys_module_info_type) * header.mod_count); + oasys_malloc(abfd, sizeof(oasys_module_info_type) * header.mod_count); oasys_module_table_type record; @@ -270,7 +270,7 @@ bfd *abfd; swap(record.mod_size); swap(record.file_offset); swap(record.mod_name_length); - module[i].name = malloc(record.mod_name_length+1); + module[i].name = oasys_malloc(abfd,record.mod_name_length+1); bfd_read(module[i].name, 1, record.mod_name_length +1, abfd); /* SKip some stuff */ @@ -285,34 +285,47 @@ bfd *abfd; return abfd->xvec; } -#define MAX_SECS 16 -bfd_target * -oasys_object_p (abfd) -bfd *abfd; +static boolean +DEFUN(oasys_mkobject,(abfd), + bfd *abfd) { + struct obstack tmp_obstack; oasys_data_type *oasys; - oasys_data_type static_data; + obstack_init(&tmp_obstack); + BFD_ASSERT(oasys_data(abfd) == 0); + oasys_data(abfd) = + (oasys_data_type*)obstack_alloc(&tmp_obstack,sizeof(oasys_data_type)); + oasys = oasys_data(abfd); + oasys->oasys_obstack = tmp_obstack; + return true; +} +#define MAX_SECS 16 +static bfd_target * +DEFUN(oasys_object_p,(abfd), + bfd *abfd) +{ + oasys_data_type *oasys; boolean loop = true; - - boolean had_usefull = false; - - memset((PTR)static_data.sections, 0xff, sizeof(static_data.sections)); + oasys_data(abfd) = 0; + oasys_mkobject(abfd); + oasys = oasys_data(abfd); + memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections)); /* Point to the start of the file */ bfd_seek(abfd, (file_ptr)0, SEEK_SET); - static_data.symbol_string_length = 0; + oasys->symbol_string_length = 0; /* Inspect the records, but only keep the section info - remember the size of the symbols */ - static_data.first_data_record = 0; + oasys->first_data_record = 0; while (loop) { - oasys_record_union_type record; oasys_read_record(abfd, &record); - if (record.header.length < sizeof(record.header)) - return (bfd_target *)NULL; + if (record.header.length < sizeof(record.header)) + goto fail; + switch ((oasys_record_enum_type)(record.header.type)) { case oasys_record_is_header_enum: @@ -322,77 +335,75 @@ bfd *abfd; case oasys_record_is_local_enum: /* Count symbols and remember their size for a future malloc */ abfd->symcount++; - static_data.symbol_string_length += 1 + oasys_string_length(&record); + oasys->symbol_string_length += 1 + oasys_string_length(&record); had_usefull = true; break; case oasys_record_is_section_enum: - { - asection *s; - char *buffer; - unsigned int section_number; - if (record.section.header.length != sizeof(record.section)) - { - return (bfd_target *)NULL; + { + asection *s; + char *buffer; + unsigned int section_number; + if (record.section.header.length != sizeof(record.section)) + { + goto fail; + } + buffer = oasys_malloc(abfd, 3); + section_number= record.section.relb & RELOCATION_SECT_BITS; + sprintf(buffer,"%u", section_number); + s = bfd_make_section(abfd,buffer); + oasys->sections[section_number] = s; + switch (record.section.relb & RELOCATION_TYPE_BITS) { + case RELOCATION_TYPE_ABS: + case RELOCATION_TYPE_REL: + break; + case RELOCATION_TYPE_UND: + case RELOCATION_TYPE_COM: + BFD_FAIL(); } - buffer = malloc(3); - section_number= record.section.relb & RELOCATION_SECT_BITS; - sprintf(buffer,"%u", section_number); - s = bfd_make_section(abfd,buffer); - static_data.sections[section_number] = s; - switch (record.section.relb & RELOCATION_TYPE_BITS) { - case RELOCATION_TYPE_ABS: - case RELOCATION_TYPE_REL: - break; - case RELOCATION_TYPE_UND: - case RELOCATION_TYPE_COM: - BFD_FAIL(); - } - - s->size = bfd_h_getlong(abfd, & record.section.value) ; - s->vma = bfd_h_getlong(abfd, &record.section.vma); - s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; - had_usefull = true; - } + s->size = bfd_h_getlong(abfd, & record.section.value[0]) ; + s->vma = bfd_h_getlong(abfd, &record.section.vma[0]); + s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; + had_usefull = true; + } break; case oasys_record_is_data_enum: - static_data.first_data_record = bfd_tell(abfd) - record.header.length; + oasys->first_data_record = bfd_tell(abfd) - record.header.length; case oasys_record_is_debug_enum: case oasys_record_is_module_enum: case oasys_record_is_named_section_enum: case oasys_record_is_end_enum: - if (had_usefull == false) return (bfd_target *)NULL; + if (had_usefull == false) goto fail; loop = false; break; default: - return (bfd_target *)NULL; + goto fail; } } - oasys_data(abfd) = (oasys_data_type - *)malloc(sizeof(oasys_data_type)); - oasys = oasys_data(abfd); - * oasys = static_data; - oasys->symbols = (asymbol *)NULL; /* - Oasys support several architectures, but I can't see a simple way - to discover which one is in a particular file - we'll guess - */ + Oasys support several architectures, but I can't see a simple way + to discover which one is in a particular file - we'll guess + */ abfd->obj_arch = bfd_arch_m68k; abfd->obj_machine =0; if (abfd->symcount != 0) { abfd->flags |= HAS_SYMS; } return abfd->xvec; + + fail: + (void) obstack_finish(&oasys->oasys_obstack); + return (bfd_target *)NULL; } -void -oasys_print_symbol(ignore_abfd, file, symbol, how) -bfd *ignore_abfd; -FILE *file; -asymbol *symbol; -bfd_print_symbol_enum_type how; +static void +DEFUN(oasys_print_symbol,(ignore_abfd, file, symbol, how), + bfd *ignore_abfd AND + FILE *file AND + asymbol *symbol AND + bfd_print_symbol_enum_type how) { switch (how) { case bfd_print_symbol_name_enum: @@ -401,10 +412,10 @@ bfd_print_symbol_enum_type how; break; case bfd_print_symbol_all_enum: { - char *section_name = symbol->section == (asection *)NULL ? +CONST char *section_name = symbol->section == (asection *)NULL ? "*abs" : symbol->section->name; - bfd_print_symbol_vandf((void *)file,symbol); + bfd_print_symbol_vandf((PTR)file,symbol); fprintf(file," %-5s %s", section_name, @@ -421,15 +432,16 @@ static reloc_howto_type howto_table[]= { /* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */ -{ 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff}, -{ 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff}, -{ 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff}, -{ 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff} +{ 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff}, +{ 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff}, +{ 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff}, +{ 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff} }; /* Read in all the section data and relocation stuff too */ -static boolean oasys_slurp_section_data(abfd) -bfd *abfd; +static boolean +DEFUN(oasys_slurp_section_data,(abfd), + bfd *CONST abfd) { oasys_record_union_type record; oasys_data_type *data = oasys_data(abfd); @@ -443,9 +455,10 @@ bfd *abfd; for (s = abfd->sections; s != (asection *)NULL; s= s->next) { per = oasys_per_section(s); if (per->data != (bfd_byte*)NULL) return true; - per->data = (bfd_byte *) malloc(s->size); - obstack_init(&per->reloc_obstack); + per->data = (bfd_byte *) oasys_malloc(abfd, s->size); per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation); + per->had_vma = false; + s->reloc_count = 0; } if (data->first_data_record == 0) return true; @@ -464,12 +477,23 @@ bfd *abfd; unsigned int relbit; bfd_byte *dst_ptr ; bfd_byte *dst_base_ptr ; - asection *section; unsigned int count; - - bfd_vma dst_offset = bfd_h_getlong(abfd, record.data.addr); - section = data->sections[record.data.relb & RELOCATION_SECT_BITS]; + asection * section = + data->sections[record.data.relb & RELOCATION_SECT_BITS]; + bfd_vma dst_offset ; per = oasys_per_section(section); + dst_offset = bfd_h_getlong(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; @@ -507,8 +531,8 @@ bfd *abfd; /* Relocate the item relative to the section */ oasys_reloc_type *r = (oasys_reloc_type *) - obstack_alloc(&per->reloc_obstack, - sizeof(oasys_reloc_type)); + oasys_malloc(abfd, + sizeof(oasys_reloc_type)); *(per->reloc_tail_ptr) = r; per->reloc_tail_ptr = &r->next; r->next= (oasys_reloc_type *)NULL; @@ -519,12 +543,11 @@ bfd *abfd; /* Work out the howto */ r->relent.section = data->sections[reloc & RELOCATION_SECT_BITS]; - r->relent.addend = 0; + r->relent.addend = - r->relent.section->vma; 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++; - } break; @@ -533,8 +556,8 @@ bfd *abfd; { oasys_reloc_type *r = (oasys_reloc_type *) - obstack_alloc(&per->reloc_obstack, - sizeof(oasys_reloc_type)); + oasys_malloc(abfd, + sizeof(oasys_reloc_type)); *(per->reloc_tail_ptr) = r; per->reloc_tail_ptr = &r->next; r->next= (oasys_reloc_type *)NULL; @@ -548,8 +571,8 @@ bfd *abfd; 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; } break; @@ -577,38 +600,43 @@ bfd *abfd; +bfd_error_vector_type bfd_error_vector; - -boolean -oasys_new_section_hook (abfd, newsect) -bfd *abfd; -asection *newsect; +static boolean +DEFUN(oasys_new_section_hook,(abfd, newsect), + bfd *abfd AND + asection *newsect) { newsect->used_by_bfd = (oasys_per_section_type *) - malloc(sizeof(oasys_per_section_type)); + oasys_malloc(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; + newsect->alignment_power = 3; + /* Turn the section string into an index */ + + sscanf(newsect->name,"%u", &newsect->target_index); + return true; } -unsigned int -oasys_get_reloc_upper_bound (abfd, asect) -bfd *abfd; -sec_ptr asect; +static unsigned int +DEFUN(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 boolean -oasys_get_section_contents (abfd, section, location, offset, count) -bfd *abfd; -sec_ptr section; -void *location; -file_ptr offset; -unsigned int count; +DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count), + bfd *abfd AND + sec_ptr section AND + void *location AND + file_ptr offset AND + unsigned int count) { oasys_per_section_type *p = section->used_by_bfd; oasys_slurp_section_data(abfd); @@ -618,100 +646,398 @@ unsigned int count; unsigned int -oasys_canonicalize_reloc (abfd, section, relptr, symbols) -bfd *abfd; -sec_ptr section; -arelent **relptr; -asymbol **symbols; +DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols), + bfd *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) { - if (src->relent.section == (asection *)NULL) { - src->relent.sym_ptr_ptr = symbols + src->symbol; - } + if (src->relent.section == (asection *)NULL) + { + src->relent.sym_ptr_ptr = symbols + src->symbol; + } *relptr ++ = &src->relent; src = src->next; + reloc_count++; } *relptr = (arelent *)NULL; - return section->reloc_count; + return section->reloc_count = reloc_count; } + boolean -oasys_set_arch_mach (abfd, arch, machine) -bfd *abfd; -enum bfd_architecture arch; -unsigned long machine; +DEFUN(oasys_set_arch_mach, (abfd, arch, machine), + bfd *abfd AND + enum bfd_architecture arch AND + unsigned long machine) { abfd->obj_arch = arch; abfd->obj_machine = machine; return true; } -boolean -oasys_mkobject(abfd) -bfd *abfd; + + +/* 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) { - oasys_data_type *oasys = - (oasys_data_type *) malloc(sizeof(oasys_data_type)); - oasys_data(abfd) = oasys; - if (oasys == (oasys_data_type *)NULL) { - bfd_error = no_memory; - return false; + int checksum; + size_t i; + uint8e_type *ptr; + record->header.length = size; + record->header.type = 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); +} - return true; + +/* 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->flags & BSF_FORT_COMM) { + symbol.relb = RELOCATION_TYPE_COM; + bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0])); + index++; + } + else if (g->flags & BSF_ABSOLUTE) { + symbol.relb = RELOCATION_TYPE_ABS; + bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0])); + + } + else if (g->flags & BSF_UNDEFINED) { + symbol.relb = RELOCATION_TYPE_UND ; + bfd_h_putshort(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 { + symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index; + bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0])); + } + while (src[l]) { + dst[l] = src[l]; + l++; + } + + bfd_h_putlong(abfd, g->value, 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 +DEFUN(oasys_write_sections, (abfd), + bfd *CONST abfd) +{ + asection *s; + static oasys_section_record_type out = {0}; + + for (s = abfd->sections; s != (asection *)NULL; s = s->next) { + if (!isdigit(s->name[0])) + { + bfd_error_vector.nonrepresentable_section(abfd, + s->name); + } + out.relb = RELOCATION_TYPE_REL | s->target_index; + bfd_h_putlong(abfd, s->size, out.value); + bfd_h_putlong(abfd, s->vma, out.vma); + + oasys_write_record(abfd, + oasys_record_is_section_enum, + (oasys_record_union_type *) &out, + sizeof(out)); + } } +static void +DEFUN(oasys_write_header, (abfd), + bfd *CONST abfd) +{ + /* Create and write the header */ + oasys_header_record_type r; + size_t length = strlen(abfd->filename); + if (length > sizeof(r.module_name)) { + length = sizeof(r.module_name); + } + (void)memcpy(r.module_name, + abfd->filename, + length); + (void)memset(r.module_name + length, + ' ', + sizeof(r.module_name) - length); + r.version_number = OASYS_VERSION_NUMBER; + r.rev_number = OASYS_REV_NUMBER; + oasys_write_record(abfd, + oasys_record_is_header_enum, + (oasys_record_union_type *)&r, + offsetof(oasys_header_record_type, description[0])); +} static void -init_for_output(abfd) -bfd *abfd; +DEFUN(oasys_write_end,(abfd), + bfd *CONST abfd) +{ + oasys_end_record_type end; + end.relb = RELOCATION_TYPE_ABS; + bfd_h_putlong(abfd, abfd->start_address, end.entry); + bfd_h_putshort(abfd, 0, end.fill); + end.zero =0; + oasys_write_record(abfd, + oasys_record_is_end_enum, + (oasys_record_union_type *)&end, + sizeof(end)); +} + +static int +DEFUN(comp,(ap, bp), + arelent **ap AND + arelent **bp) +{ + arelent *a = *ap; + arelent *b = *bp; + return a->address - b->address; +} + +/* + Writing data.. + +*/ +static void +DEFUN(oasys_write_data, (abfd), + bfd *CONST abfd) { - asection *s; + asection *s; for (s = abfd->sections; s != (asection *)NULL; s = s->next) { - if (s->size != 0) { - oasys_per_section(s)->data = (bfd_byte *)(malloc(s->size)); + uint8e_type *raw_data = oasys_per_section(s)->data; + oasys_data_record_type processed_data; + unsigned int current_byte_index = 0; + unsigned int relocs_to_go = s->reloc_count; + arelent **p = s->orelocation; + if (s->reloc_count != 0) { + /* Sort the reloc records so it's easy to insert the relocs into the + data */ + + qsort(s->orelocation, + s->reloc_count, + sizeof(arelent **), + comp); } + current_byte_index = 0; + processed_data.relb = s->target_index | RELOCATION_TYPE_REL; + + while (current_byte_index < s->size) + { + /* Scan forwards by eight bytes or however much is left and see if + there are any relocations going on */ + uint8e_type *mod = &processed_data.data[0]; + uint8e_type *dst = &processed_data.data[1]; + + unsigned int i; + unsigned int long_length = 128; + + + bfd_h_putlong(abfd, s->vma + current_byte_index, processed_data.addr); + if (long_length + current_byte_index > s->size) { + long_length = s->size - current_byte_index; + } + while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) { + + unsigned int length = long_length; + *mod =0; + if (length > 8) + length = 8; + + for (i = 0; i < length; i++) { + if (relocs_to_go != 0) { + arelent *r = *p; + reloc_howto_type *CONST how=r->howto; + /* There is a relocation, is it for this byte ? */ + if (r->address == current_byte_index) { + uint8e_type rel_byte; + p++; + relocs_to_go--; + + *mod |= (1<<i); + if(how->pc_relative) { + rel_byte = 0x80; + } + else { + rel_byte = 0; + } + if (how->size ==2) { + rel_byte |= 0x40; + } + + /* Is this a section relative relocation, or a symbol + relative relocation ? */ + if (r->section != (asection*)NULL) + { + /* The relent has a section attatched, so it must be section + relative */ + rel_byte |= RELOCATION_TYPE_REL; + rel_byte |= r->section->output_section->target_index; + *dst++ = rel_byte; + } + else + { + asymbol *p = *(r->sym_ptr_ptr); + + /* If this symbol has a section attatched, then it + has already been resolved. Change from a symbol + ref to a section ref */ + if(p->section != (asection *)NULL) { + rel_byte |= RELOCATION_TYPE_REL; + rel_byte |= + p->section->output_section->target_index; + *dst++ = rel_byte; + } + else { + rel_byte |= RELOCATION_TYPE_UND; + + + *dst++ = rel_byte; + /* Next two bytes are a symbol index - we can get + this from the symbol value which has been zapped + into the symbol index in the table when the + symbol table was written + */ + *dst++ = p->value >> 8; + *dst++ = p->value; + } + + } + } + } + /* If this is coming from an unloadable section then copy + zeros */ + if (raw_data == (uint8e_type *)NULL) { + *dst++ = 0; + } + else { + *dst++ = *raw_data++; + } + current_byte_index++; + } + mod = dst++; + long_length -= length; + } + + oasys_write_record(abfd, + oasys_record_is_data_enum, + (oasys_record_union_type *)&processed_data, + dst - (uint8e_type*)&processed_data); + + } } } +static boolean +DEFUN(oasys_write_object_contents, (abfd), + bfd * CONST abfd) +{ + oasys_write_header(abfd); + oasys_write_syms(abfd); + oasys_write_sections(abfd); + oasys_write_data(abfd); + oasys_write_end(abfd); + return true; +} + + + /** exec and core file sections */ /* set section contents is complicated with OASYS since the format is * not a byte image, but a record stream. */ -boolean -oasys_set_section_contents (abfd, section, location, offset, count) -bfd *abfd; -sec_ptr section; -unsigned char *location; -file_ptr offset; -int count; +static boolean +DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count), + bfd *abfd AND + sec_ptr section AND + unsigned char *location AND + file_ptr offset AND + int count) { - if (oasys_per_section(section)->data == (bfd_byte *)NULL) { - init_for_output(abfd); + if (count != 0) { + if (oasys_per_section(section)->data == (bfd_byte *)NULL ) + { + oasys_per_section(section)->data = + (bfd_byte *)(oasys_malloc(abfd,section->size)); + } + (void) memcpy(oasys_per_section(section)->data + offset, + location, + count); } - (void) memcpy(oasys_per_section(section)->data + offset, location, count); return true; } - /* Native-level interface to symbols. */ /* We read the symbols into a buffer, which is discarded when this function exits. We read the strings into a buffer large enough to hold them all plus all the cached symbol entries. */ -asymbol * -oasys_make_empty_symbol (abfd) -bfd *abfd; +static asymbol * +DEFUN(oasys_make_empty_symbol,(abfd), + bfd *abfd) { oasys_symbol_type *new = @@ -721,29 +1047,6 @@ bfd *abfd; } -void -oasys_reclaim_symbol_table (abfd) -bfd *abfd; -{ -#if 0 - asection *section; - - if (!bfd_get_symcount (abfd)) return; - - for (section = abfd->sections; section != NULL; section = section->next) - if (section->relocation) { - free ((void *)section->relocation); - section->relocation = NULL; - section->reloc_count = 0; - } - - bfd_get_symcount (abfd) = 0; - free ((void *)obj_aout_symbols (abfd)); - obj_aout_symbols (abfd) = (aout_symbol_type *)NULL; -#endif -} - - /* Obsbolete procedural interface; better to look at the cache directly */ @@ -751,109 +1054,7 @@ bfd *abfd; /* User should have checked the file flags; perhaps we should return BFD_NO_MORE_SYMBOLS if there are none? */ -int -oasys_get_symcount_upper_bound (abfd) -bfd *abfd; -{ -#if 0 - /* In case we're doing an output file or something...? */ - if (bfd_get_symcount (abfd)) return bfd_get_symcount (abfd); - - return (exec_hdr (abfd)->a_syms) / (sizeof (struct nlist)); -#endif -} - -symindex -oasys_get_first_symbol (ignore_abfd) -bfd * ignore_abfd; -{ - return 0; -} -symindex -oasys_get_next_symbol (abfd, oidx) -bfd *abfd; -symindex oidx; -{ -#if 0 - if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS; - return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS : - oidx; -#endif -} - -char * -oasys_symbol_name (abfd, idx) -bfd *abfd; -symindex idx; -{ -#if 0 - return (obj_aout_symbols (abfd) + idx)->symbol.name; -#endif -} - -long -oasys_symbol_value (abfd, idx) -bfd *abfd; -symindex idx; -{ -#if 0 - return (obj_aout_symbols (abfd) + idx)->symbol.value; -#endif -} - -symclass -oasys_classify_symbol (abfd, idx) -bfd *abfd; -symindex idx; -{ -#if 0 - aout_symbol_type *sym = obj_aout_symbols (abfd) + idx; - - if ((sym->symbol.flags & BSF_FORT_COMM) != 0) return bfd_symclass_fcommon; - if ((sym->symbol.flags & BSF_GLOBAL) != 0) return bfd_symclass_global; - if ((sym->symbol.flags & BSF_DEBUGGING) != 0) return bfd_symclass_debugger; - if ((sym->symbol.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined; -#endif - return bfd_symclass_unknown; -} - -boolean -oasys_symbol_hasclass (abfd, idx, class) -bfd *abfd; -symindex idx; -symclass class; -{ -#if 0 - aout_symbol_type *sym = obj_aout_symbols (abfd) + idx; - switch (class) { - case bfd_symclass_fcommon: - return (sym->symbol.flags & BSF_FORT_COMM) ? true :false; - case bfd_symclass_global: - return (sym->symbol.flags & BSF_GLOBAL) ? true:false; - case bfd_symclass_debugger: - return (sym->symbol.flags & BSF_DEBUGGING) ? true:false;; - case bfd_symclass_undefined: - return (sym->symbol.flags & BSF_UNDEFINED) ? true:false;; - default: return false; - } -#endif -} - - -void -oasys_reclaim_reloc (ignore_abfd, section) -bfd *ignore_abfd; -sec_ptr section; -{ -#if 0 - if (section->relocation) { - free (section->relocation); - section->relocation = NULL; - section->reloc_count = 0; - } -#endif -} boolean oasys_close_and_cleanup (abfd) @@ -867,7 +1068,7 @@ bfd *abfd; } break; case bfd_object: -/* if (!oasys_write_object_contents (abfd)) */{ + if (!oasys_write_object_contents (abfd)) { return false; } break; @@ -878,8 +1079,8 @@ bfd *abfd; if (oasys_data(abfd) != (oasys_data_type *)NULL) { - /* FIXME MORE LEAKS */ - + /* It's so easy to throw everything away */ +(void) obstack_finish(&(oasys_data(abfd)->oasys_obstack)); } return true; @@ -908,7 +1109,7 @@ bfd *prev; p->abfd->filename = p->name; /* Fixup a pointer to this element for the member */ - p->abfd->arelt_data = (void *)p; + p->abfd->arelt_data = (PTR)p; } return p->abfd; } |