diff options
author | Ian Lance Taylor <ian@airs.com> | 1994-09-06 19:28:55 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1994-09-06 19:28:55 +0000 |
commit | 69645d10fb4647f6855c76ae54a1acf60f28fc94 (patch) | |
tree | 61e36c9f73fda03557d67fda9f185ea6a7828b5f /bfd/coffcode.h | |
parent | de733a0edf37f2e2f4a7733da66b55a07ef1f804 (diff) | |
download | gdb-69645d10fb4647f6855c76ae54a1acf60f28fc94.zip gdb-69645d10fb4647f6855c76ae54a1acf60f28fc94.tar.gz gdb-69645d10fb4647f6855c76ae54a1acf60f28fc94.tar.bz2 |
Add new style linker support to COFF backend. a29k only for now.
* cofflink.c: New file.
* libcoff-in.h: Include bfdlink.h.
(obj_coff_external_syms, obj_coff_strings): Define accessor macro.
(obj_coff_sym_hashes): Define accessor macro.
(struct coff_tdata): Add fields external_syms, strings, and
sym_hashes.
(struct coff_link_hash_entry): Define.
(struct coff_link_hash_table): Define.
(coff_link_hash_lookup, coff_link_hash_traverse): Define.
(coff_hash_table): Define.
(_bfd_coff_link_hash_table_create): Declare.
(_bfd_coff_link_add_symbols, _bfd_coff_final_link): Declare.
* coffcode.h (bfd_coff_backend_data): Add fields _bfd_relsz,
_bfd_coff_swap_reloc_in, _bfd_coff_sym_is_global,
_bfd_coff_compute_section_file_positions,
_bfd_coff_relocate_section.
(bfd_coff_relsz, bfd_coff_swap_reloc_in): Define.
(bfd_coff_sym_is_global): Define.
(bfd_coff_compute_section_file_positions): Define.
(bfd_coff_relocate_section): Define.
(coff_mkobject_hook): Initialize obj_raw_syment_count and
obj_conv_table_size.
(coff_compute_section_file_positions): Set target_index of all
sections. Set output_has_begun field.
(coff_write_object_contents): Don't set target_index; now done by
coff_compute_section_file_positions. Remove obsolete handling of
scn_base and data_base. Don't bother to check that target_index
is positive, since it always is. Remove use of pad, which is
always zero. Check obj_raw_syment_count, not bfd_get_symcount,
for the number of symbols, but only write them out if
bfd_get_symcount is non-zero.
(coff_slurp_symbol_table): Use obj_raw_syment_count, not
bfd_get_symcount for the number of symbols. Don't set
obj_conv_table_size.
(coff_sym_is_global): New static function or macro.
(coff_slurp_reloc_table): Call coff_swap_reloc_in, not
bfd_swap_reloc_in.
(coff_bfd_link_hash_table_create): If coff_relocate_section is
defined, define as _bfd_coff_link_hash_table_create.
(coff_bfd_link_add_symbols): Similar change.
(coff_bfd_final_link): Similar change.
(coff_relocate_section): Define as NULL if not defined.
(bfd_coff_std_swap_table): Initialize new fields.
* coffgen.c (coff_real_object_p): Don't set obj_raw_syment_count
and obj_conv_table_size here.
(coff_count_linenumbers): Reindent. If bfd_get_symcount is zero,
add up the line numbers from the sections.
(coff_write_symbols): Don't set bfd_get_symcount.
(coff_pointerize_aux): Don't pointerize a nonpositive x_endndx
field.
(coff_get_normalized_symtab): Use obj_raw_syment_count, not
bfd_get_symcount.
(coff_print_symbol): If auxp->fix_end, print x_endndx value.
* coffswap.h (coff_swap_reloc_in): Rename from bfd_swap_reloc_in.
Reindent. Change argument type to PTR.
* coff-a29k.c (coff_a29k_relocate_section): New static function.
(coff_relocate_section): Define.
* configure.in (a29kcoff_big_vec): Compile cofflink.o.
* coff-alpha.c (alpha_ecoff_backend_data): Initialize new fields.
* coff-mips.c (mips_ecoff_backend_data): Likewise.
* libcoff.h: Rebuilt.
* Makefile.in: Rebuilt dependencies.
(BFD32_BACKENDS): Add cofflink.o.
(CFILES): Add cofflink.c.
Diffstat (limited to 'bfd/coffcode.h')
-rw-r--r-- | bfd/coffcode.h | 351 |
1 files changed, 195 insertions, 156 deletions
diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 0eed749..f1729dd 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -608,6 +608,7 @@ dependent COFF routines: . unsigned int _bfd_scnhsz; . unsigned int _bfd_symesz; . unsigned int _bfd_auxesz; +. unsigned int _bfd_relsz; . unsigned int _bfd_linesz; . boolean _bfd_coff_long_filenames; . void (*_bfd_coff_swap_filehdr_in) PARAMS (( @@ -622,6 +623,10 @@ dependent COFF routines: . bfd *abfd, . PTR ext, . PTR in)); +. void (*_bfd_coff_swap_reloc_in) PARAMS (( +. bfd *abfd, +. PTR ext, +. PTR in)); . boolean (*_bfd_coff_bad_format_hook) PARAMS (( . bfd *abfd, . PTR internal_filehdr)); @@ -662,6 +667,20 @@ dependent COFF routines: . arelent *r, . unsigned int shrink, . struct bfd_link_info *link_info)); +. boolean (*_bfd_coff_sym_is_global) PARAMS (( +. bfd *abfd, +. struct internal_syment *)); +. void (*_bfd_coff_compute_section_file_positions) PARAMS (( +. bfd *abfd)); +. boolean (*_bfd_coff_relocate_section) PARAMS (( +. bfd *output_bfd, +. struct bfd_link_info *info, +. bfd *input_bfd, +. asection *input_section, +. bfd_byte *contents, +. struct internal_reloc *relocs, +. struct internal_syment *syms, +. asection **sections)); . .} bfd_coff_backend_data; . @@ -702,6 +721,7 @@ dependent COFF routines: .#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) .#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) .#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) +.#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) .#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) .#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) .#define bfd_coff_swap_filehdr_in(abfd, i,o) \ @@ -713,6 +733,9 @@ dependent COFF routines: .#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ . ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) . +.#define bfd_coff_swap_reloc_in(abfd, i, o) \ +. ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) +. .#define bfd_coff_bad_format_hook(abfd, filehdr) \ . ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) . @@ -744,6 +767,18 @@ dependent COFF routines: . ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ . (abfd, section, reloc, shrink, link_info)) . +.#define bfd_coff_sym_is_global(abfd, sym)\ +. ((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\ +. (abfd, sym)) +. +.#define bfd_coff_compute_section_file_positions(abfd)\ +. ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ +. (abfd)) +. +.#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ +. ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ +. (obfd, info, ibfd, o, con, rel, isyms, secs)) +. */ /* See whether the magic number matches. */ @@ -863,7 +898,6 @@ coff_mkobject (abfd) coff->symbols = (coff_symbol_type *) NULL; coff->conversion_table = (unsigned int *) NULL; coff->raw_syments = (struct coff_ptr_struct *) NULL; - coff->raw_linenos = (struct lineno *) NULL; coff->relocbase = 0; /* make_abs_section(abfd);*/ return true; @@ -886,7 +920,6 @@ coff_mkobject_hook (abfd, filehdr, aouthdr) coff = coff_data (abfd); coff->sym_filepos = internal_f->f_symptr; - coff->flags = internal_f->f_flags; /* These members communicate important constants about the symbol table to GDB's symbol-reading code. These `constants' @@ -899,6 +932,10 @@ coff_mkobject_hook (abfd, filehdr, aouthdr) coff->local_auxesz = AUXESZ; coff->local_linesz = LINESZ; + obj_raw_syment_count (abfd) = + obj_conv_table_size (abfd) = + internal_f->f_nsyms; + return (PTR) coff; } @@ -1386,6 +1423,8 @@ coff_compute_section_file_positions (abfd) #ifndef I960 file_ptr old_sofar; #endif + unsigned int count; + if (bfd_get_start_address (abfd)) { /* A start address may have been added to the original file. In this @@ -1397,10 +1436,11 @@ coff_compute_section_file_positions (abfd) sofar += AOUTSZ; sofar += abfd->section_count * SCNHSZ; - for (current = abfd->sections; + for (current = abfd->sections, count = 1; current != (asection *) NULL; - current = current->next) + current = current->next, ++count) { + current->target_index = count; /* Only deal with sections which have contents */ if (!(current->flags & SEC_HAS_CONTENTS)) @@ -1454,6 +1494,7 @@ coff_compute_section_file_positions (abfd) previous = current; } obj_relocbase (abfd) = sofar; + abfd->output_has_begun = true; } #ifndef RS6000COFF_C @@ -1538,15 +1579,11 @@ coff_write_object_contents (abfd) bfd * abfd; { asection *current; - unsigned int count; - boolean hasrelocs = false; boolean haslinno = false; file_ptr reloc_base; file_ptr lineno_base; file_ptr sym_base; - file_ptr scn_base; - file_ptr data_base; unsigned long reloc_size = 0; unsigned long lnno_size = 0; asection *text_sec = NULL; @@ -1558,55 +1595,22 @@ coff_write_object_contents (abfd) bfd_set_error (bfd_error_system_call); - /* Number the output sections, starting from one on the first section - with a name which doesn't start with a *. - @@ The code doesn't make this check. Is it supposed to be done, - or isn't it?? */ - count = 1; - for (current = abfd->sections; current != (asection *) NULL; - current = current->next) - { - current->target_index = count; - count++; - } if (abfd->output_has_begun == false) - { - coff_compute_section_file_positions (abfd); - } + coff_compute_section_file_positions (abfd); - if (abfd->sections != (asection *) NULL) - { - scn_base = abfd->sections->filepos; - } - else - { - scn_base = 0; - } - if (bfd_seek (abfd, scn_base, SEEK_SET) != 0) - return false; reloc_base = obj_relocbase (abfd); /* Make a pass through the symbol table to count line number entries and put them into the correct asections */ lnno_size = coff_count_linenumbers (abfd) * LINESZ; - data_base = scn_base; /* Work out the size of the reloc and linno areas */ for (current = abfd->sections; current != NULL; current = current->next) - { - /* We give section headers to +ve indexes */ - if (current->target_index > 0) - { - - reloc_size += current->reloc_count * RELSZ; - data_base += SCNHSZ; - } - - } + reloc_size += current->reloc_count * RELSZ; lineno_base = reloc_base + reloc_size; sym_base = lineno_base + lnno_size; @@ -1615,33 +1619,27 @@ coff_write_object_contents (abfd) for (current = abfd->sections; current != NULL; current = current->next) { - if (current->target_index > 0) + if (current->lineno_count) { - - if (current->lineno_count) - { - current->line_filepos = lineno_base; - current->moving_line_filepos = lineno_base; - lineno_base += current->lineno_count * LINESZ; - } - else - { - current->line_filepos = 0; - } - if (current->reloc_count) - { - current->rel_filepos = reloc_base; - reloc_base += current->reloc_count * RELSZ; - } - else - { - current->rel_filepos = 0; - } + current->line_filepos = lineno_base; + current->moving_line_filepos = lineno_base; + lineno_base += current->lineno_count * LINESZ; + } + else + { + current->line_filepos = 0; + } + if (current->reloc_count) + { + current->rel_filepos = reloc_base; + reloc_base += current->reloc_count * RELSZ; + } + else + { + current->rel_filepos = 0; } } - - /* Write section headers to the file. */ internal_f.f_nscns = 0; if (bfd_seek (abfd, @@ -1652,90 +1650,81 @@ coff_write_object_contents (abfd) return false; { -#if 0 - unsigned int pad = abfd->flags & D_PAGED ? data_base : 0; -#endif - unsigned int pad = 0; - for (current = abfd->sections; current != NULL; current = current->next) { struct internal_scnhdr section; - if (current->target_index > 0) - { - internal_f.f_nscns++; - strncpy (&(section.s_name[0]), current->name, 8); + + internal_f.f_nscns++; + strncpy (&(section.s_name[0]), current->name, 8); #ifdef _LIB - /* Always set s_vaddr of .lib to 0. This is right for SVR3.2 + /* Always set s_vaddr of .lib to 0. This is right for SVR3.2 Ian Taylor <ian@cygnus.com>. */ - if (strcmp (current->name, _LIB) == 0) - section.s_vaddr = 0; - else -#endif - section.s_vaddr = current->lma + pad; - section.s_paddr = current->lma + pad; - section.s_size = current->_raw_size - pad; - /* - If this section has no size or is unloadable then the scnptr - will be 0 too - */ - if (current->_raw_size - pad == 0 || - (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - { - section.s_scnptr = 0; - } - else - { - section.s_scnptr = current->filepos; - } - section.s_relptr = current->rel_filepos; - section.s_lnnoptr = current->line_filepos; - section.s_nreloc = current->reloc_count; - section.s_nlnno = current->lineno_count; - if (current->reloc_count != 0) - hasrelocs = true; - if (current->lineno_count != 0) - haslinno = true; - - section.s_flags = sec_to_styp_flags (current->name, current->flags); - - if (!strcmp (current->name, _TEXT)) - { - text_sec = current; - } - else if (!strcmp (current->name, _DATA)) - { - data_sec = current; + if (strcmp (current->name, _LIB) == 0) + section.s_vaddr = 0; + else +#endif + section.s_vaddr = current->lma; + section.s_paddr = current->lma; + section.s_size = current->_raw_size; + /* + If this section has no size or is unloadable then the scnptr + will be 0 too + */ + if (current->_raw_size == 0 || + (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) + { + section.s_scnptr = 0; + } + else + { + section.s_scnptr = current->filepos; + } + section.s_relptr = current->rel_filepos; + section.s_lnnoptr = current->line_filepos; + section.s_nreloc = current->reloc_count; + section.s_nlnno = current->lineno_count; + if (current->reloc_count != 0) + hasrelocs = true; + if (current->lineno_count != 0) + haslinno = true; + + section.s_flags = sec_to_styp_flags (current->name, current->flags); + + if (!strcmp (current->name, _TEXT)) + { + text_sec = current; + } + else if (!strcmp (current->name, _DATA)) + { + data_sec = current; #ifdef TWO_DATA_SECS - } - else if (!strcmp (current->name, ".data2")) - { - data_sec = current; + } + else if (!strcmp (current->name, ".data2")) + { + data_sec = current; #endif /* TWO_DATA_SECS */ - } - else if (!strcmp (current->name, _BSS)) - { - bss_sec = current; - } + } + else if (!strcmp (current->name, _BSS)) + { + bss_sec = current; + } #ifdef I960 - section.s_align = (current->alignment_power - ? 1 << current->alignment_power - : 0); + section.s_align = (current->alignment_power + ? 1 << current->alignment_power + : 0); #endif - { - SCNHDR buff; - - coff_swap_scnhdr_out (abfd, §ion, &buff); - if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ) - return false; + { + SCNHDR buff; - } + coff_swap_scnhdr_out (abfd, §ion, &buff); + if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ) + return false; - pad = 0; - } + } } } @@ -1752,7 +1741,7 @@ coff_write_object_contents (abfd) */ internal_f.f_timdat = 0; - if (bfd_get_symcount (abfd) != 0) + if (obj_raw_syment_count (abfd) != 0) internal_f.f_symptr = sym_base; else internal_f.f_symptr = 0; @@ -1768,7 +1757,7 @@ coff_write_object_contents (abfd) internal_f.f_flags |= F_RELFLG; if (!haslinno) internal_f.f_flags |= F_LNNO; - if (0 == bfd_get_symcount (abfd)) + if (obj_raw_syment_count (abfd) == 0) internal_f.f_flags |= F_LSYMS; if (abfd->flags & EXEC_P) internal_f.f_flags |= F_EXEC; @@ -1893,7 +1882,7 @@ coff_write_object_contents (abfd) } internal_a.entry = bfd_get_start_address (abfd); - internal_f.f_nsyms = bfd_get_symcount (abfd); + internal_f.f_nsyms = obj_raw_syment_count (abfd); /* now write them */ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) @@ -2097,18 +2086,20 @@ coff_slurp_symbol_table (abfd) } /* on error */ /* Allocate enough room for all the symbols in cached form */ - cached_area = - (coff_symbol_type *) - bfd_alloc (abfd, (size_t) (bfd_get_symcount (abfd) * sizeof (coff_symbol_type))); + cached_area = ((coff_symbol_type *) + bfd_alloc (abfd, + (obj_raw_syment_count (abfd) + * sizeof (coff_symbol_type)))); if (cached_area == NULL) { bfd_set_error (bfd_error_no_memory); return false; } /* on error */ - table_ptr = - (unsigned int *) - bfd_alloc (abfd, (size_t) (bfd_get_symcount (abfd) * sizeof (unsigned int))); + table_ptr = ((unsigned int *) + bfd_alloc (abfd, + (obj_raw_syment_count (abfd) + * sizeof (unsigned int)))); if (table_ptr == NULL) { @@ -2118,7 +2109,7 @@ coff_slurp_symbol_table (abfd) else { coff_symbol_type *dst = cached_area; - unsigned int last_native_index = bfd_get_symcount (abfd); + unsigned int last_native_index = obj_raw_syment_count (abfd); unsigned int this_index = 0; while (this_index < last_native_index) { @@ -2324,7 +2315,6 @@ coff_slurp_symbol_table (abfd) obj_symbols (abfd) = cached_area; obj_raw_syments (abfd) = native_symbols; - obj_conv_table_size (abfd) = bfd_get_symcount (abfd); bfd_get_symcount (abfd) = number_of_symbols; obj_convert (abfd) = table_ptr; /* Slurp the line tables for each section too */ @@ -2340,6 +2330,43 @@ coff_slurp_symbol_table (abfd) return true; } /* coff_slurp_symbol_table() */ +/* Check whether a symbol is globally visible. This is used by the + COFF backend linker code in cofflink.c, since a couple of targets + have globally visible symbols which are not class C_EXT. This + function need not handle the case of n_class == C_EXT. */ + +#undef OTHER_GLOBAL_CLASS + +#ifdef I960 +#define OTHER_GLOBAL_CLASS C_LEAFEXT +#endif + +#ifdef RS6000COFF_C +#define OTHER_GLOBAL_CLASS C_HIDEXT +#endif + +#ifdef OTHER_GLOBAL_CLASS + +static boolean +coff_sym_is_global (abfd, syment) + bfd *abfd; + struct internal_syment *syment; +{ + if (syment->n_sclass == OTHER_GLOBAL_CLASS) + return true; + return false; +} + +#undef OTHER_GLOBAL_CLASS + +#else /* ! defined (OTHER_GLOBAL_CLASS) */ + +/* sym_is_global should not be defined if it has nothing to do. */ + +#define coff_sym_is_global 0 + +#endif /* ! defined (OTHER_GLOBAL_CLASS) */ + /* SUBSUBSECTION Reading relocations @@ -2433,7 +2460,7 @@ coff_slurp_reloc_table (abfd, asect, symbols) cache_ptr = reloc_cache + idx; src = native_relocs + idx; - bfd_swap_reloc_in (abfd, src, &dst); + coff_swap_reloc_in (abfd, src, &dst); RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect); #else @@ -2444,7 +2471,7 @@ coff_slurp_reloc_table (abfd, asect, symbols) cache_ptr = reloc_cache + idx; src = native_relocs + idx; - bfd_swap_reloc_in (abfd, src, &dst); + coff_swap_reloc_in (abfd, src, &dst); cache_ptr->address = dst.r_vaddr; @@ -2572,6 +2599,19 @@ dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, } #endif +/* If coff_relocate_section is defined, we can use the optimized COFF + backend linker. Otherwise we must continue to use the old linker. */ +#ifdef coff_relocate_section +#define coff_bfd_link_hash_table_create _bfd_coff_link_hash_table_create +#define coff_bfd_link_add_symbols _bfd_coff_link_add_symbols +#define coff_bfd_final_link _bfd_coff_final_link +#else /* ! defined (coff_relocate_section) */ +#define coff_relocate_section NULL +#define coff_bfd_link_hash_table_create _bfd_generic_link_hash_table_create +#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols +#define coff_bfd_final_link _bfd_generic_final_link +#endif /* ! defined (coff_relocate_section) */ + static CONST bfd_coff_backend_data bfd_coff_std_swap_table = { coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, @@ -2579,17 +2619,19 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = coff_swap_lineno_out, coff_swap_reloc_out, coff_swap_filehdr_out, coff_swap_aouthdr_out, coff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, LINESZ, + FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, #ifdef COFF_LONG_FILENAMES true, #else false, #endif coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in, - coff_bad_format_hook, coff_set_arch_mach_hook, coff_mkobject_hook, - styp_to_sec_flags, coff_make_section_hook, coff_set_alignment_hook, - coff_slurp_symbol_table, symname_in_debug_hook, - coff_reloc16_extra_cases, coff_reloc16_estimate + coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, + coff_mkobject_hook, styp_to_sec_flags, coff_make_section_hook, + coff_set_alignment_hook, coff_slurp_symbol_table, symname_in_debug_hook, + coff_reloc16_extra_cases, coff_reloc16_estimate, + coff_sym_is_global, coff_compute_section_file_positions, + coff_relocate_section }; #define coff_close_and_cleanup _bfd_generic_close_and_cleanup @@ -2613,6 +2655,3 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = #define coff_bfd_get_relocated_section_contents \ bfd_generic_get_relocated_section_contents #define coff_bfd_relax_section bfd_generic_relax_section -#define coff_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define coff_bfd_final_link _bfd_generic_final_link |