X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoffcode.h;h=bdd9769d5bb112c601daa84b89c9ad211c911deb;hb=948221a8bd69c734e599d0cd9f0d7227b6bfdc02;hp=ae07e91d9c0a5d22ede8f6abc86c5a4752840904;hpb=28eb95aa337f72b4a87cdd2a2d6aff9cc0984a4b;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffcode.h b/bfd/coffcode.h index ae07e91d9c..bdd9769d5b 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1,5 +1,6 @@ /* Support for the generic parts of most COFF variants, for BFD. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998 + Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -310,6 +311,30 @@ CODE_FRAGMENT #endif #define STRING_SIZE_SIZE (4) + +static long sec_to_styp_flags PARAMS ((const char *, flagword)); +static flagword styp_to_sec_flags PARAMS ((bfd *, PTR, const char *)); +static boolean coff_bad_format_hook PARAMS ((bfd *, PTR)); +static boolean coff_new_section_hook PARAMS ((bfd *, asection *)); +static boolean coff_set_arch_mach_hook PARAMS ((bfd *, PTR)); +static boolean coff_write_relocs PARAMS ((bfd *, int)); +static boolean coff_set_flags + PARAMS ((bfd *, unsigned int *, unsigned short *)); +static boolean coff_set_arch_mach + PARAMS ((bfd *, enum bfd_architecture, unsigned long)); +static boolean coff_compute_section_file_positions PARAMS ((bfd *)); +static boolean coff_write_object_contents PARAMS ((bfd *)); +static boolean coff_set_section_contents + PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); +static PTR buy_and_read PARAMS ((bfd *, file_ptr, int, size_t)); +static boolean coff_slurp_line_table PARAMS ((bfd *, asection *)); +static boolean coff_slurp_symbol_table PARAMS ((bfd *)); +static boolean coff_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **)); +static long coff_canonicalize_reloc + PARAMS ((bfd *, asection *, arelent **, asymbol **)); +#ifndef coff_mkobject_hook +static PTR coff_mkobject_hook PARAMS ((bfd *, PTR, PTR)); +#endif /* void warning(); */ @@ -479,7 +504,7 @@ styp_to_sec_flags (abfd, hdr, name) section VMA and the file offset match. If we don't know COFF_PAGE_SIZE, we can't ensure the correct correspondence, and demand page loading of the file will fail. */ -#ifdef COFF_PAGE_SIZE +#if defined (COFF_PAGE_SIZE) && !defined (COFF_ALIGN_IN_S_FLAGS) sec_flags |= SEC_DEBUGGING; #endif } @@ -563,6 +588,12 @@ styp_to_sec_flags (abfd, hdr, name) can't call slurp_symtab, because the linker doesn't want the swapped symbols. */ + /* COMDAT sections are special. The first symbol is the section + symbol, which tells what kind of COMDAT section it is. The + *second* symbol is the "comdat symbol" - the one with the + unique name. GNU uses the section symbol for the unique + name; MS uses ".text" for every comdat section. Sigh. - DJ */ + if (_bfd_coff_get_external_symbols (abfd)) { bfd_byte *esym, *esymend; @@ -604,10 +635,23 @@ styp_to_sec_flags (abfd, hdr, name) isym.n_type, isym.n_sclass, 0, isym.n_numaux, (PTR) &aux); + /* FIXME: Microsoft uses NODUPLICATES and + ASSOCIATIVE, but gnu uses ANY and SAME_SIZE. + Unfortunately, gnu doesn't do the comdat + symbols right. So, until we can fix it to do + the right thing, we are temporarily disabling + comdats for the MS types (they're used in + DLLs and C++, but we don't support *their* + C++ libraries anyway - DJ */ + switch (aux.x_scn.x_comdat) { case IMAGE_COMDAT_SELECT_NODUPLICATES: +#if 0 sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY; +#else + sec_flags &= ~SEC_LINK_ONCE; +#endif break; default: @@ -624,8 +668,12 @@ styp_to_sec_flags (abfd, hdr, name) break; case IMAGE_COMDAT_SELECT_ASSOCIATIVE: +#if 0 /* FIXME: This is not currently implemented. */ sec_flags |= SEC_LINK_DUPLICATES_DISCARD; +#else + sec_flags &= ~SEC_LINK_ONCE; +#endif break; } @@ -727,6 +775,7 @@ dependent COFF routines: . unsigned int _bfd_linesz; . boolean _bfd_coff_long_filenames; . boolean _bfd_coff_long_section_names; +. unsigned int _bfd_coff_default_section_alignment_power; . void (*_bfd_coff_swap_filehdr_in) PARAMS (( . bfd *abfd, . PTR ext, @@ -796,7 +845,7 @@ dependent COFF routines: . boolean (*_bfd_coff_sym_is_global) PARAMS (( . bfd *abfd, . struct internal_syment *)); -. void (*_bfd_coff_compute_section_file_positions) PARAMS (( +. boolean (*_bfd_coff_compute_section_file_positions) PARAMS (( . bfd *abfd)); . boolean (*_bfd_coff_start_final_link) PARAMS (( . bfd *output_bfd, @@ -836,6 +885,13 @@ dependent COFF routines: . boolean collect, . struct bfd_link_hash_entry **hashp)); . +. boolean (*_bfd_coff_link_output_has_begun) PARAMS (( +. bfd * abfd, +. struct coff_final_link_info * pfinfo)); +. boolean (*_bfd_coff_final_link_postscript) PARAMS (( +. bfd * abfd, +. struct coff_final_link_info * pfinfo)); +. .} bfd_coff_backend_data; . .#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) @@ -880,6 +936,8 @@ dependent COFF routines: .#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) .#define bfd_coff_long_section_names(abfd) \ . (coff_backend_info (abfd)->_bfd_coff_long_section_names) +.#define bfd_coff_default_section_alignment_power(abfd) \ +. (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) .#define bfd_coff_swap_filehdr_in(abfd, i,o) \ . ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) . @@ -948,6 +1006,11 @@ dependent COFF routines: . ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ . (info, abfd, name, flags, section, value, string, cp, coll, hashp)) . +.#define bfd_coff_link_output_has_begun(a,p) \ +. ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a,p)) +.#define bfd_coff_final_link_postscript(a,p) \ +. ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a,p)) +. */ /* See whether the magic number matches. */ @@ -989,6 +1052,8 @@ coff_new_section_hook (abfd, section) bfd * abfd; asection * section; { + combined_entry_type *native; + section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER; #ifdef RS6000COFF_C @@ -1005,9 +1070,21 @@ coff_new_section_hook (abfd, section) @@ The 10 is a guess at a plausible maximum number of aux entries (but shouldn't be a constant). */ - coffsymbol (section->symbol)->native = - (combined_entry_type *) bfd_zalloc (abfd, - sizeof (combined_entry_type) * 10); + native = ((combined_entry_type *) + bfd_zalloc (abfd, sizeof (combined_entry_type) * 10)); + if (native == NULL) + return false; + + /* We don't need to set up n_name, n_value, or n_scnum in the native + symbol information, since they'll be overriden by the BFD symbol + anyhow. However, we do need to set the type and storage class, + in case this symbol winds up getting written out. The value 0 + for n_numaux is already correct. */ + + native->u.syment.n_type = T_NULL; + native->u.syment.n_sclass = C_STAT; + + coffsymbol (section->symbol)->native = native; /* The .stab section must be aligned to 2**2 at most, because otherwise there may be gaps in the section which gdb will not @@ -1029,10 +1106,12 @@ coff_new_section_hook (abfd, section) return true; } -#ifdef I960 +#ifdef COFF_ALIGN_IN_SECTION_HEADER /* Set the alignment of a BFD section. */ +static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR)); + static void coff_set_alignment_hook (abfd, section, scnhdr) bfd * abfd; @@ -1042,13 +1121,20 @@ coff_set_alignment_hook (abfd, section, scnhdr) struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr; unsigned int i; +#ifdef I960 + /* Extract ALIGN from 2**ALIGN stored in section header */ for (i = 0; i < 32; i++) if ((1 << i) >= hdr->s_align) break; +#endif +#ifdef TIC80COFF + /* TI tools hijack bits 8-11 for the alignment */ + i = (hdr->s_flags >> 8) & 0xF ; +#endif section->alignment_power = i; } -#else /* ! I960 */ +#else /* ! COFF_ALIGN_IN_SECTION_HEADER */ #ifdef COFF_WITH_PE /* a couple of macros to help setting the alignment power field */ @@ -1064,6 +1150,8 @@ coff_set_alignment_hook (abfd, section, scnhdr) section->alignment_power = y;\ } +static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR)); + static void coff_set_alignment_hook (abfd, section, scnhdr) bfd * abfd; @@ -1151,6 +1239,8 @@ coff_set_alignment_hook (abfd, section, scnhdr) When we see one, we correct the reloc and line number counts in the real header, and remove the section we just created. */ +static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR)); + static void coff_set_alignment_hook (abfd, section, scnhdr) bfd *abfd; @@ -1189,9 +1279,12 @@ coff_set_alignment_hook (abfd, section, scnhdr) #endif /* ! RS6000COFF_C */ #endif /* ! COFF_WITH_PE */ -#endif /* ! I960 */ +#endif /* ! COFF_ALIGN_IN_SECTION_HEADER */ #ifndef coff_mkobject + +static boolean coff_mkobject PARAMS ((bfd *)); + static boolean coff_mkobject (abfd) bfd * abfd; @@ -1270,6 +1363,12 @@ coff_mkobject_hook (abfd, filehdr, aouthdr) } #endif +#ifdef ARM + /* Set the flags field from the COFF header read in */ + if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags)) + coff->flags = 0; +#endif + return (PTR) coff; } #endif @@ -1318,7 +1417,16 @@ coff_set_arch_mach_hook (abfd, filehdr) #ifdef ARMMAGIC case ARMMAGIC: arch = bfd_arch_arm; - machine =0; + switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK) + { + case F_ARM_2: machine = bfd_mach_arm_2; break; + case F_ARM_2a: machine = bfd_mach_arm_2a; break; + case F_ARM_3: machine = bfd_mach_arm_3; break; + default: + case F_ARM_3M: machine = bfd_mach_arm_3M; break; + case F_ARM_4: machine = bfd_mach_arm_4; break; + case F_ARM_4T: machine = bfd_mach_arm_4T; break; + } break; #endif #ifdef MC68MAGIC @@ -1334,7 +1442,7 @@ coff_set_arch_mach_hook (abfd, filehdr) case LYNXCOFFMAGIC: #endif arch = bfd_arch_m68k; - machine = 68020; + machine = bfd_mach_m68020; break; #endif #ifdef MC88MAGIC @@ -1533,12 +1641,23 @@ coff_set_arch_mach_hook (abfd, filehdr) break; #endif +#ifdef TIC30MAGIC + case TIC30MAGIC: + arch = bfd_arch_tic30; + break; +#endif + #ifdef TIC80_ARCH_MAGIC case TIC80_ARCH_MAGIC: arch = bfd_arch_tic80; break; #endif +#ifdef MCOREMAGIC + case MCOREMAGIC: + arch = bfd_arch_mcore; + break; +#endif default: /* Unreadable input file type */ arch = bfd_arch_obscure; break; @@ -1550,6 +1669,9 @@ coff_set_arch_mach_hook (abfd, filehdr) #ifdef SYMNAME_IN_DEBUG +static boolean symname_in_debug_hook + PARAMS ((bfd *, struct internal_syment *)); + static boolean symname_in_debug_hook (abfd, sym) bfd * abfd; @@ -1840,7 +1962,7 @@ coff_write_relocs (abfd, first_undef) static boolean coff_set_flags (abfd, magicp, flagsp) bfd * abfd; - unsigned *magicp; + unsigned int *magicp; unsigned short *flagsp; { switch (bfd_get_arch (abfd)) @@ -1906,9 +2028,43 @@ coff_set_flags (abfd, magicp, flagsp) } break; #endif + +#ifdef TIC30MAGIC + case bfd_arch_tic30: + *magicp = TIC30MAGIC; + return true; +#endif +#ifdef TIC80_ARCH_MAGIC + case bfd_arch_tic80: + *magicp = TIC80_ARCH_MAGIC; + return true; +#endif #ifdef ARMMAGIC case bfd_arch_arm: - *magicp = ARMMAGIC; + * magicp = ARMMAGIC; + * flagsp = 0; + if (APCS_SET (abfd)) + { + if (APCS_26_FLAG (abfd)) + * flagsp |= F_APCS26; + + if (APCS_FLOAT_FLAG (abfd)) + * flagsp |= F_APCS_FLOAT; + + if (PIC_FLAG (abfd)) + * flagsp |= F_PIC; + } + if (INTERWORK_SET (abfd) && INTERWORK_FLAG (abfd)) + * flagsp |= F_INTERWORK; + switch (bfd_get_mach (abfd)) + { + case bfd_mach_arm_2: * flagsp |= F_ARM_2; break; + case bfd_mach_arm_2a: * flagsp |= F_ARM_2a; break; + case bfd_mach_arm_3: * flagsp |= F_ARM_3; break; + case bfd_mach_arm_3M: * flagsp |= F_ARM_3M; break; + case bfd_mach_arm_4: * flagsp |= F_ARM_4; break; + case bfd_mach_arm_4T: * flagsp |= F_ARM_4T; break; + } return true; #endif #ifdef PPCMAGIC @@ -2030,6 +2186,12 @@ coff_set_flags (abfd, magicp, flagsp) break; #endif +#ifdef MCOREMAGIC + case bfd_arch_mcore: + * magicp = MCOREMAGIC; + return true; +#endif + default: /* Unknown architecture */ /* return false; -- fall through to "return false" below, to avoid "statement never reached" errors on the one below. */ @@ -2062,18 +2224,25 @@ coff_set_arch_mach (abfd, arch, machine) /* Calculate the file position for each section. */ -static void +#ifndef I960 +#define ALIGN_SECTIONS_IN_FILE +#endif +#ifdef TIC80COFF +#undef ALIGN_SECTIONS_IN_FILE +#endif + +static boolean coff_compute_section_file_positions (abfd) bfd * abfd; { asection *current; asection *previous = (asection *) NULL; file_ptr sofar = FILHSZ; - -#ifndef I960 + boolean align_adjust; + unsigned int count; +#ifdef ALIGN_SECTIONS_IN_FILE file_ptr old_sofar; #endif - unsigned int count; #ifdef RS6000COFF_C /* On XCOFF, if we have symbols, set up the .debug section. */ @@ -2154,10 +2323,24 @@ coff_compute_section_file_positions (abfd) sofar += SCNHSZ; #endif + align_adjust = false; for (current = abfd->sections, count = 1; current != (asection *) NULL; current = current->next, ++count) { +#ifdef COFF_IMAGE_WITH_PE + /* The NT loader does not want empty section headers, so we omit + them. We don't actually remove the section from the BFD, + although we probably should. This matches code in + coff_write_object_contents. */ + if (current->_raw_size == 0) + { + current->target_index = -1; + --count; + continue; + } +#endif + current->target_index = count; /* Only deal with sections which have contents */ @@ -2168,7 +2351,7 @@ coff_compute_section_file_positions (abfd) which they are aligned in virtual memory. I960 doesn't do this (FIXME) so we can stay in sync with Intel. 960 doesn't yet page from files... */ -#ifndef I960 +#ifdef ALIGN_SECTIONS_IN_FILE if ((abfd->flags & EXEC_P) != 0) { /* make sure this section is aligned on the right boundary - by @@ -2202,20 +2385,14 @@ coff_compute_section_file_positions (abfd) current->used_by_bfd = (PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata)); if (current->used_by_bfd == NULL) - { - /* FIXME: Return error. */ - abort (); - } + return false; } if (pei_section_data (abfd, current) == NULL) { coff_section_data (abfd, current)->tdata = (PTR) bfd_zalloc (abfd, sizeof (struct pei_section_tdata)); if (coff_section_data (abfd, current)->tdata == NULL) - { - /* FIXME: Return error. */ - abort (); - } + return false; } if (pei_section_data (abfd, current)->virt_size == 0) pei_section_data (abfd, current)->virt_size = current->_raw_size; @@ -2225,7 +2402,7 @@ coff_compute_section_file_positions (abfd) sofar += current->_raw_size; -#ifndef I960 +#ifdef ALIGN_SECTIONS_IN_FILE /* make sure that this section is of the right size too */ if ((abfd->flags & EXEC_P) == 0) { @@ -2234,16 +2411,26 @@ coff_compute_section_file_positions (abfd) old_size = current->_raw_size; current->_raw_size = BFD_ALIGN (current->_raw_size, 1 << current->alignment_power); + align_adjust = current->_raw_size != old_size; sofar += current->_raw_size - old_size; } else { old_sofar = sofar; sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); + align_adjust = sofar != old_sofar; current->_raw_size += sofar - old_sofar; } #endif +#ifdef COFF_IMAGE_WITH_PE + /* For PE we need to make sure we pad out to the aligned + _raw_size, in case the caller only writes out data to the + unaligned _raw_size. */ + if (pei_section_data (abfd, current)->virt_size < current->_raw_size) + align_adjust = true; +#endif + #ifdef _LIB /* Force .lib sections to start at zero. The vma is then incremented in coff_set_section_contents. This is right for @@ -2255,9 +2442,30 @@ coff_compute_section_file_positions (abfd) previous = current; } + /* It is now safe to write to the output file. If we needed an + alignment adjustment for the last section, then make sure that + there is a byte at offset sofar. If there are no symbols and no + relocs, then nothing follows the last section. If we don't force + the last byte out, then the file may appear to be truncated. */ + if (align_adjust) + { + bfd_byte b; + + b = 0; + if (bfd_seek (abfd, sofar - 1, SEEK_SET) != 0 + || bfd_write (&b, 1, 1, abfd) != 1) + return false; + } + + /* Make sure the relocations are aligned. We don't need to make + sure that this byte exists, because it will only matter if there + really are relocs. */ + sofar = BFD_ALIGN (sofar, 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER); + obj_relocbase (abfd) = sofar; abfd->output_has_begun = true; + return true; } #if 0 @@ -2314,7 +2522,7 @@ coff_add_missing_symbols (abfd) if (!need_text && !need_data && !need_bss && !need_file) return true; nsyms += need_text + need_data + need_bss + need_file; - sympp2 = (asymbol **) bfd_alloc_by_size_t (abfd, nsyms * sizeof (asymbol *)); + sympp2 = (asymbol **) bfd_alloc (abfd, nsyms * sizeof (asymbol *)); if (!sympp2) return false; memcpy (sympp2, sympp, i * sizeof (asymbol *)); @@ -2369,7 +2577,10 @@ coff_write_object_contents (abfd) lnno_size = coff_count_linenumbers (abfd) * LINESZ; if (abfd->output_has_begun == false) - coff_compute_section_file_positions (abfd); + { + if (! coff_compute_section_file_positions (abfd)) + return false; + } reloc_base = obj_relocbase (abfd); @@ -2538,7 +2749,10 @@ coff_write_object_contents (abfd) section.s_align = (current->alignment_power ? 1 << current->alignment_power : 0); - +#else +#ifdef TIC80COFF + section.s_flags |= (current->alignment_power & 0xF) << 8; +#endif #endif #ifdef COFF_IMAGE_WITH_PE @@ -2565,13 +2779,22 @@ coff_write_object_contents (abfd) { unsigned int i, count; asymbol **psym; - coff_symbol_type *csym; + coff_symbol_type *csym = NULL; + asymbol **psymsec; + psymsec = NULL; count = bfd_get_symcount (abfd); for (i = 0, psym = abfd->outsymbols; i < count; i++, psym++) { - /* Here *PSYM is the section symbol for CURRENT. */ + if ((*psym)->section != current) + continue; + + /* Remember the location of the first symbol in this + section. */ + if (psymsec == NULL) + psymsec = psym; + /* See if this is the section symbol. */ if (strcmp ((*psym)->name, current->name) == 0) { csym = coff_symbol_from (abfd, *psym); @@ -2581,6 +2804,9 @@ coff_write_object_contents (abfd) || csym->native->u.syment.n_sclass != C_STAT || csym->native->u.syment.n_type != T_NULL) continue; + + /* Here *PSYM is the section symbol for CURRENT. */ + break; } } @@ -2617,6 +2843,24 @@ coff_write_object_contents (abfd) IMAGE_COMDAT_SELECT_EXACT_MATCH; break; } + + /* The COMDAT symbol must be the first symbol from this + section in the symbol table. In order to make this + work, we move the COMDAT symbol before the first + symbol we found in the search above. It's OK to + rearrange the symbol table at this point, because + coff_renumber_symbols is going to rearrange it + further and fix up all the aux entries. */ + if (psym != psymsec) + { + asymbol *hold; + asymbol **pcopy; + + hold = *psym; + for (pcopy = psym; pcopy > psymsec; pcopy--) + pcopy[0] = pcopy[-1]; + *psymsec = hold; + } } } #endif /* COFF_WITH_PE */ @@ -2690,6 +2934,10 @@ coff_write_object_contents (abfd) else internal_f.f_flags |= F_AR32W; +#ifdef TIC80_TARGET_ID + internal_f.f_target_id = TIC80_TARGET_ID; +#endif + /* FIXME, should do something about the other byte orders and architectures. @@ -2727,8 +2975,8 @@ coff_write_object_contents (abfd) internal_a.magic = NMAGIC; /* Assume separate i/d */ #define __A_MAGIC_SET__ #endif /* A29K */ -#ifdef TIC80 - internal_a.magic = TIC80MAGIC; +#ifdef TIC80COFF + internal_a.magic = TIC80_ARCH_MAGIC; #define __A_MAGIC_SET__ #endif /* TIC80 */ #ifdef I860 @@ -2771,10 +3019,17 @@ coff_write_object_contents (abfd) #define __A_MAGIC_SET__ internal_a.magic = ZMAGIC; #endif + #if defined(PPC_PE) #define __A_MAGIC_SET__ internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; #endif + +#if defined MCORE_PE +#define __A_MAGIC_SET__ + internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; +#endif + #if defined(I386) #define __A_MAGIC_SET__ #if defined(LYNXOS) @@ -2791,7 +3046,7 @@ coff_write_object_contents (abfd) #endif /* LYNXOS */ #endif /* SPARC */ -#if RS6000COFF_C +#ifdef RS6000COFF_C #define __A_MAGIC_SET__ internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC : (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC : @@ -2828,6 +3083,15 @@ coff_write_object_contents (abfd) if (! coff_write_relocs (abfd, firstundef)) return false; } +#ifdef COFF_LONG_SECTION_NAMES + else if (long_section_names) + { + /* If we have long section names we have to write out the string + table even if there are no symbols. */ + if (! coff_write_symbols (abfd)) + return false; + } +#endif #ifdef COFF_IMAGE_WITH_PE #ifdef PPC_PE else if ((abfd->flags & EXEC_P) != 0) @@ -3005,7 +3269,10 @@ coff_set_section_contents (abfd, section, location, offset, count) bfd_size_type count; { if (abfd->output_has_begun == false) /* set by bfd.c handler */ - coff_compute_section_file_positions (abfd); + { + if (! coff_compute_section_file_positions (abfd)) + return false; + } #if defined(_LIB) && !defined(TARG_AUX) @@ -3082,8 +3349,7 @@ coff_close_and_cleanup (abfd) return false; } - /* We depend on bfd_close to free all the memory on the obstack. */ - /* FIXME if bfd_release is not using obstacks! */ + /* We depend on bfd_close to free all the memory on the objalloc. */ return true; } @@ -3165,10 +3431,11 @@ coff_slurp_line_table (abfd, asect) warned = false; symndx = dst.l_addr.l_symndx; - if (symndx < 0 || symndx >= obj_raw_syment_count (abfd)) + if (symndx < 0 + || (unsigned long) symndx >= obj_raw_syment_count (abfd)) { (*_bfd_error_handler) - ("%s: warning: illegal symbol index %ld in line numbers", + (_("%s: warning: illegal symbol index %ld in line numbers"), bfd_get_filename (abfd), dst.l_addr.l_symndx); symndx = 0; warned = true; @@ -3182,7 +3449,7 @@ coff_slurp_line_table (abfd, asect) if (sym->lineno != NULL && ! warned) { (*_bfd_error_handler) - ("%s: warning: duplicate line number information for `%s'", + (_("%s: warning: duplicate line number information for `%s'"), bfd_get_filename (abfd), bfd_asymbol_name (&sym->symbol)); } @@ -3273,13 +3540,21 @@ coff_slurp_symbol_table (abfd) #endif case C_EXT: + case C_WEAKEXT: +#if defined ARM + case C_THUMBEXT: + case C_THUMBEXTFUNC: +#endif #ifdef RS6000COFF_C case C_HIDEXT: #endif +#ifdef C_SYSTEM + case C_SYSTEM: /* System Wide variable */ +#endif #ifdef COFF_WITH_PE /* PE uses storage class 0x68 to denote a section symbol */ case C_SECTION: - /* PE uses storage class 0x67 for a weak external symbol. */ + /* PE uses storage class 0x69 for a weak external symbol. */ case C_NT_WEAK: #endif if ((src->u.syment.n_scnum) == 0) @@ -3301,8 +3576,15 @@ coff_slurp_symbol_table (abfd) section */ dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; + +#if defined COFF_WITH_PE + /* PE sets the symbol to a value relative to the + start of the section. */ + dst->symbol.value = src->u.syment.n_value; +#else dst->symbol.value = (src->u.syment.n_value - dst->symbol.section->vma); +#endif if (ISFCN ((src->u.syment.n_type))) { @@ -3324,13 +3606,26 @@ coff_slurp_symbol_table (abfd) #ifdef COFF_WITH_PE if (src->u.syment.n_sclass == C_NT_WEAK) dst->symbol.flags = BSF_WEAK; + if (src->u.syment.n_sclass == C_SECTION + && src->u.syment.n_scnum > 0) + { + dst->symbol.flags = BSF_LOCAL; + } #endif + if (src->u.syment.n_sclass == C_WEAKEXT) + dst->symbol.flags = BSF_WEAK; + break; case C_STAT: /* static */ #ifdef I960 case C_LEAFSTAT: /* static leaf procedure */ +#endif +#if defined ARM + case C_THUMBSTAT: /* Thumb static */ + case C_THUMBLABEL: /* Thumb label */ + case C_THUMBSTATFUNC:/* Thumb static function */ #endif case C_LABEL: /* label */ if (src->u.syment.n_scnum == -2) @@ -3341,8 +3636,16 @@ coff_slurp_symbol_table (abfd) /* Base the value as an index from the base of the section, if there is one. */ if (dst->symbol.section) - dst->symbol.value = (src->u.syment.n_value - - dst->symbol.section->vma); + { +#if defined COFF_WITH_PE + /* PE sets the symbol to a value relative to the + start of the section. */ + dst->symbol.value = src->u.syment.n_value; +#else + dst->symbol.value = (src->u.syment.n_value + - dst->symbol.section->vma); +#endif + } else dst->symbol.value = src->u.syment.n_value; break; @@ -3356,8 +3659,10 @@ coff_slurp_symbol_table (abfd) #endif case C_REGPARM: /* register parameter */ case C_REG: /* register variable */ +#ifndef TIC80COFF #ifdef C_AUTOARG case C_AUTOARG: /* 960-specific storage class */ +#endif #endif case C_TPDEF: /* type definition */ case C_ARG: @@ -3438,10 +3743,16 @@ coff_slurp_symbol_table (abfd) case C_FCN: /* ".bf" or ".ef" */ case C_EFCN: /* physical end of function */ dst->symbol.flags = BSF_LOCAL; +#if defined COFF_WITH_PE + /* PE sets the symbol to a value relative to the start + of the section. */ + dst->symbol.value = src->u.syment.n_value; +#else /* Base the value as an index from the base of the section. */ dst->symbol.value = (src->u.syment.n_value - dst->symbol.section->vma); +#endif break; case C_NULL: @@ -3455,10 +3766,16 @@ coff_slurp_symbol_table (abfd) /* NT uses 0x67 for a weak symbol, not C_ALIAS. */ case C_ALIAS: /* duplicate tag */ #endif + /* New storage classes for TIc80 */ +#ifdef TIC80COFF + case C_UEXT: /* Tentative external definition */ +#endif + case C_STATLAB: /* Static load time label */ + case C_EXTLAB: /* External load time label */ case C_HIDDEN: /* ext symbol in dmert public lib */ default: (*_bfd_error_handler) - ("%s: Unrecognized storage class %d for %s symbol `%s'", + (_("%s: Unrecognized storage class %d for %s symbol `%s'"), bfd_get_filename (abfd), src->u.syment.n_sclass, dst->symbol.section->name, dst->symbol.name); dst->symbol.flags = BSF_DEBUGGING; @@ -3507,20 +3824,24 @@ coff_slurp_symbol_table (abfd) #define OTHER_GLOBAL_CLASS C_LEAFEXT #endif +#ifdef COFFARM +#define OTHER_GLOBAL_CLASS C_THUMBEXT || syment->n_sclass == C_THUMBEXTFUNC +#else #ifdef COFF_WITH_PE #define OTHER_GLOBAL_CLASS C_SECTION #endif +#endif #ifdef OTHER_GLOBAL_CLASS +static boolean coff_sym_is_global PARAMS ((bfd *, struct internal_syment *)); + static boolean coff_sym_is_global (abfd, syment) - bfd *abfd; - struct internal_syment *syment; + bfd * abfd; + struct internal_syment * syment; { - if (syment->n_sclass == OTHER_GLOBAL_CLASS) - return true; - return false; + return (syment->n_sclass == OTHER_GLOBAL_CLASS); } #undef OTHER_GLOBAL_CLASS @@ -3617,26 +3938,20 @@ coff_slurp_reloc_table (abfd, asect, symbols) for (idx = 0; idx < asect->reloc_count; idx++) { -#ifdef RELOC_PROCESSING struct internal_reloc dst; struct external_reloc *src; - - cache_ptr = reloc_cache + idx; - src = native_relocs + idx; - coff_swap_reloc_in (abfd, src, &dst); - - RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect); -#else - struct internal_reloc dst; +#ifndef RELOC_PROCESSING asymbol *ptr; - struct external_reloc *src; +#endif cache_ptr = reloc_cache + idx; src = native_relocs + idx; coff_swap_reloc_in (abfd, src, &dst); - +#ifdef RELOC_PROCESSING + RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect); +#else cache_ptr->address = dst.r_vaddr; if (dst.r_symndx != -1) @@ -3644,10 +3959,10 @@ coff_slurp_reloc_table (abfd, asect, symbols) if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd)) { (*_bfd_error_handler) - ("%s: warning: illegal symbol index %ld in relocs", + (_("%s: warning: illegal symbol index %ld in relocs"), bfd_get_filename (abfd), dst.r_symndx); cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - ptr = 0; + ptr = NULL; } else { @@ -3659,7 +3974,7 @@ coff_slurp_reloc_table (abfd, asect, symbols) else { cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - ptr = 0; + ptr = NULL; } /* The symbols definitions that we have read in have been @@ -3677,12 +3992,12 @@ coff_slurp_reloc_table (abfd, asect, symbols) /* Fill in the cache_ptr->howto field from dst.r_type */ RTYPE2HOWTO (cache_ptr, &dst); -#endif +#endif /* RELOC_PROCESSING */ if (cache_ptr->howto == NULL) { (*_bfd_error_handler) - ("%s: illegal relocation type %d at address 0x%lx", + (_("%s: illegal relocation type %d at address 0x%lx"), bfd_get_filename (abfd), dst.r_type, (long) dst.r_vaddr); bfd_set_error (bfd_error_bad_value); return false; @@ -3783,6 +4098,10 @@ coff_sym_filepos (abfd) #ifndef coff_reloc16_estimate #define coff_reloc16_estimate dummy_reloc16_estimate +static int dummy_reloc16_estimate + PARAMS ((bfd *, asection *, arelent *, unsigned int, + struct bfd_link_info *)); + static int dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) bfd *abfd; @@ -3797,8 +4116,15 @@ dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) #endif #ifndef coff_reloc16_extra_cases + #define coff_reloc16_extra_cases dummy_reloc16_extra_cases + /* This works even if abort is not declared in any header file. */ + +static void dummy_reloc16_extra_cases + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, + bfd_byte *, unsigned int *, unsigned int *)); + static void dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr) @@ -3836,6 +4162,7 @@ dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, #endif #define coff_bfd_final_link _bfd_generic_final_link #endif /* ! defined (coff_relocate_section) */ + #define coff_bfd_link_split_section _bfd_generic_link_split_section #ifndef coff_start_final_link @@ -3850,13 +4177,86 @@ dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, #define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol #endif +#ifndef coff_link_output_has_begun + +static boolean coff_link_output_has_begun + PARAMS ((bfd *, struct coff_final_link_info *)); + +static boolean +coff_link_output_has_begun (abfd, info) + bfd * abfd; + struct coff_final_link_info * info; +{ + return abfd->output_has_begun; +} +#endif + +#ifndef coff_final_link_postscript + +static boolean coff_final_link_postscript + PARAMS ((bfd *, struct coff_final_link_info *)); + +static boolean +coff_final_link_postscript (abfd, pfinfo) + bfd * abfd; + struct coff_final_link_info * pfinfo; +{ + return true; +} +#endif + +#ifndef coff_SWAP_aux_in +#define coff_SWAP_aux_in coff_swap_aux_in +#endif +#ifndef coff_SWAP_sym_in +#define coff_SWAP_sym_in coff_swap_sym_in +#endif +#ifndef coff_SWAP_lineno_in +#define coff_SWAP_lineno_in coff_swap_lineno_in +#endif +#ifndef coff_SWAP_aux_out +#define coff_SWAP_aux_out coff_swap_aux_out +#endif +#ifndef coff_SWAP_sym_out +#define coff_SWAP_sym_out coff_swap_sym_out +#endif +#ifndef coff_SWAP_lineno_out +#define coff_SWAP_lineno_out coff_swap_lineno_out +#endif +#ifndef coff_SWAP_reloc_out +#define coff_SWAP_reloc_out coff_swap_reloc_out +#endif +#ifndef coff_SWAP_filehdr_out +#define coff_SWAP_filehdr_out coff_swap_filehdr_out +#endif +#ifndef coff_SWAP_aouthdr_out +#define coff_SWAP_aouthdr_out coff_swap_aouthdr_out +#endif +#ifndef coff_SWAP_scnhdr_out +#define coff_SWAP_scnhdr_out coff_swap_scnhdr_out +#endif +#ifndef coff_SWAP_reloc_in +#define coff_SWAP_reloc_in coff_swap_reloc_in +#endif +#ifndef coff_SWAP_filehdr_in +#define coff_SWAP_filehdr_in coff_swap_filehdr_in +#endif +#ifndef coff_SWAP_aouthdr_in +#define coff_SWAP_aouthdr_in coff_swap_aouthdr_in +#endif +#ifndef coff_SWAP_scnhdr_in +#define coff_SWAP_scnhdr_in coff_swap_scnhdr_in +#endif + + + static CONST bfd_coff_backend_data bfd_coff_std_swap_table = { - coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, - coff_swap_aux_out, coff_swap_sym_out, - coff_swap_lineno_out, coff_swap_reloc_out, - coff_swap_filehdr_out, coff_swap_aouthdr_out, - coff_swap_scnhdr_out, + coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in, + coff_SWAP_aux_out, coff_SWAP_sym_out, + 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, RELSZ, LINESZ, #ifdef COFF_LONG_FILENAMES true, @@ -3868,22 +4268,32 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = #else false, #endif - coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in, - coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, + COFF_DEFAULT_SECTION_ALIGNMENT_POWER, + coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, + coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook, coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, coff_sym_is_global, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol + coff_adjust_symndx, coff_link_add_one_symbol, + coff_link_output_has_begun, coff_final_link_postscript }; -#define coff_close_and_cleanup _bfd_generic_close_and_cleanup -#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define coff_get_section_contents _bfd_generic_get_section_contents +#ifndef coff_close_and_cleanup +#define coff_close_and_cleanup _bfd_generic_close_and_cleanup +#endif + +#ifndef coff_bfd_free_cached_info +#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#endif + +#ifndef coff_get_section_contents +#define coff_get_section_contents _bfd_generic_get_section_contents +#endif #ifndef coff_bfd_copy_private_symbol_data -#define coff_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data +#define coff_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data #endif #ifndef coff_bfd_copy_private_section_data @@ -3891,36 +4301,48 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = #endif #ifndef coff_bfd_copy_private_bfd_data -#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data +#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data #endif -#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data -#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags +#ifndef coff_bfd_merge_private_bfd_data +#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data +#endif + +#ifndef coff_bfd_set_private_flags +#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags +#endif #ifndef coff_bfd_print_private_bfd_data -#define coff_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data +#define coff_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data #endif -#ifndef coff_bfd_is_local_label -#define coff_bfd_is_local_label bfd_generic_is_local_label +#ifndef coff_bfd_is_local_label_name +#define coff_bfd_is_local_label_name _bfd_coff_is_local_label_name #endif + #ifndef coff_read_minisymbols -#define coff_read_minisymbols _bfd_generic_read_minisymbols +#define coff_read_minisymbols _bfd_generic_read_minisymbols #endif + #ifndef coff_minisymbol_to_symbol -#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol +#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #endif /* The reloc lookup routine must be supplied by each individual COFF backend. */ #ifndef coff_bfd_reloc_type_lookup -#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup +#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup #endif #ifndef coff_bfd_get_relocated_section_contents #define coff_bfd_get_relocated_section_contents \ bfd_generic_get_relocated_section_contents #endif + #ifndef coff_bfd_relax_section -#define coff_bfd_relax_section bfd_generic_relax_section +#define coff_bfd_relax_section bfd_generic_relax_section +#endif + +#ifndef coff_bfd_gc_sections +#define coff_bfd_gc_sections bfd_generic_gc_sections #endif