X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoffcode.h;h=8576c0ad3e04c0a8901c869266561346c3a382ee;hb=6362a3f8757bfce133b724df2077573433823ad4;hp=19f4159ac3185a0410fce8633e65766161278f26;hpb=a50b1753d42fa4c760f96d72890684d3a3a221d0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 19f4159ac3..8576c0ad3e 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1,7 +1,5 @@ /* Support for the generic parts of most COFF variants, for BFD. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 1990-2015 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -119,11 +117,11 @@ SUBSUBSECTION The Microsoft PE variants of the Coff object file format add an extension to support the use of long section names. This - extension is defined in section 4 of the Microsoft PE/COFF + extension is defined in section 4 of the Microsoft PE/COFF specification (rev 8.1). If a section name is too long to fit into the section header's @code{s_name} field, it is instead placed into the string table, and the @code{s_name} field is - filled with a slash ("/") followed by the ASCII decimal + filled with a slash ("/") followed by the ASCII decimal representation of the offset of the full name relative to the string table base. @@ -140,11 +138,11 @@ SUBSUBSECTION expecting the MS standard format may become confused; @file{PEview} is one known example. - The functionality is supported in BFD by code implemented under + The functionality is supported in BFD by code implemented under the control of the macro @code{COFF_LONG_SECTION_NAMES}. If not defined, the format does not support long section names in any way. - If defined, it is used to initialise a flag, - @code{_bfd_coff_long_section_names}, and a hook function pointer, + If defined, it is used to initialise a flag, + @code{_bfd_coff_long_section_names}, and a hook function pointer, @code{_bfd_coff_set_long_section_names}, in the Coff backend data structure. The flag controls the generation of long section names in output BFDs at runtime; if it is false, as it will be by default @@ -153,7 +151,7 @@ SUBSUBSECTION points to a function that allows the value of the flag to be altered at runtime, on formats that support long section names at all; on other formats it points to a stub that returns an error indication. - + With input BFDs, the flag is set according to whether any long section names are detected while reading the section headers. For a completely new BFD, the flag is set to the default for the target format. This @@ -309,7 +307,7 @@ CODE_FRAGMENT .typedef struct coff_ptr_struct .{ . {* Remembers the offset from the first symbol in the file for -. this symbol. Generated by coff_renumber_symbols. *} +. this symbol. Generated by coff_renumber_symbols. *} . unsigned int offset; . . {* Should the value of this symbol be renumbered. Used for @@ -317,15 +315,15 @@ CODE_FRAGMENT . unsigned int fix_value : 1; . . {* Should the tag field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} +. Created by coff_pointerize_aux. *} . unsigned int fix_tag : 1; . . {* Should the endidx field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} +. Created by coff_pointerize_aux. *} . unsigned int fix_end : 1; . . {* Should the x_csect.x_scnlen field be renumbered. -. Created by coff_pointerize_aux. *} +. Created by coff_pointerize_aux. *} . unsigned int fix_scnlen : 1; . . {* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the @@ -333,12 +331,15 @@ CODE_FRAGMENT . unsigned int fix_line : 1; . . {* The container for the symbol structure as read and translated -. from the file. *} +. from the file. *} . union . { . union internal_auxent auxent; . struct internal_syment syment; . } u; +. +. {* Selector for the union above. *} +. bfd_boolean is_sym; .} combined_entry_type; . . @@ -372,7 +373,9 @@ CODE_FRAGMENT #define STRING_SIZE_SIZE 4 #define DOT_DEBUG ".debug" +#define DOT_ZDEBUG ".zdebug" #define GNU_LINKONCE_WI ".gnu.linkonce.wi." +#define GNU_LINKONCE_WT ".gnu.linkonce.wt." #define DOT_RELOC ".reloc" #if defined (COFF_LONG_SECTION_NAMES) @@ -544,7 +547,8 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags) styp_flags = STYP_LIT; #endif /* _LIT */ } - else if (CONST_STRNEQ (sec_name, DOT_DEBUG)) + else if (CONST_STRNEQ (sec_name, DOT_DEBUG) + || CONST_STRNEQ (sec_name, DOT_ZDEBUG)) { /* Handle the XCOFF debug section and DWARF2 debug sections. */ if (!sec_name[6]) @@ -557,7 +561,8 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags) styp_flags = STYP_DEBUG_INFO; } #ifdef COFF_LONG_SECTION_NAMES - else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)) + else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI) + || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT)) { styp_flags = STYP_DEBUG_INFO; } @@ -579,6 +584,17 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags) { styp_flags = STYP_TYPCHK; } + else if (sec_flags & SEC_DEBUGGING) + { + int i; + + for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++) + if (!strcmp (sec_name, xcoff_dwsect_names[i].name)) + { + styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag; + break; + } + } #endif /* Try and figure out what it should be */ else if (sec_flags & SEC_CODE) @@ -636,6 +652,16 @@ static long sec_to_styp_flags (const char *sec_name, flagword sec_flags) { long styp_flags = 0; + bfd_boolean is_dbg = FALSE; + + if (CONST_STRNEQ (sec_name, DOT_DEBUG) + || CONST_STRNEQ (sec_name, DOT_ZDEBUG) +#ifdef COFF_LONG_SECTION_NAMES + || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI) + || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT) +#endif + || CONST_STRNEQ (sec_name, ".stab")) + is_dbg = TRUE; /* caution: there are at least three groups of symbols that have very similar bits and meanings: IMAGE_SCN*, SEC_*, and STYP_*. @@ -646,16 +672,20 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags) but there are more IMAGE_SCN_* flags. */ /* FIXME: There is no gas syntax to specify the debug section flag. */ - if (CONST_STRNEQ (sec_name, DOT_DEBUG) - || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)) - sec_flags = SEC_DEBUGGING | SEC_READONLY; + if (is_dbg) + { + sec_flags &= (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD + | SEC_LINK_DUPLICATES_SAME_CONTENTS + | SEC_LINK_DUPLICATES_SAME_SIZE); + sec_flags |= SEC_DEBUGGING | SEC_READONLY; + } /* skip LOAD */ /* READONLY later */ /* skip RELOC */ if ((sec_flags & SEC_CODE) != 0) styp_flags |= IMAGE_SCN_CNT_CODE; - if ((sec_flags & SEC_DATA) != 0) + if ((sec_flags & (SEC_DATA | SEC_DEBUGGING)) != 0) styp_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA; if ((sec_flags & SEC_ALLOC) != 0 && (sec_flags & SEC_LOAD) == 0) styp_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; /* ==STYP_BSS */ @@ -666,15 +696,19 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags) styp_flags |= IMAGE_SCN_LNK_COMDAT; if ((sec_flags & SEC_DEBUGGING) != 0) styp_flags |= IMAGE_SCN_MEM_DISCARDABLE; - if ((sec_flags & SEC_EXCLUDE) != 0) + if ((sec_flags & SEC_EXCLUDE) != 0 && !is_dbg) styp_flags |= IMAGE_SCN_LNK_REMOVE; - if ((sec_flags & SEC_NEVER_LOAD) != 0) + if ((sec_flags & SEC_NEVER_LOAD) != 0 && !is_dbg) styp_flags |= IMAGE_SCN_LNK_REMOVE; /* skip IN_MEMORY */ /* skip SORT */ if (sec_flags & SEC_LINK_ONCE) styp_flags |= IMAGE_SCN_LNK_COMDAT; - /* skip LINK_DUPLICATES */ + if ((sec_flags + & (SEC_LINK_DUPLICATES_DISCARD | SEC_LINK_DUPLICATES_SAME_CONTENTS + | SEC_LINK_DUPLICATES_SAME_SIZE)) != 0) + styp_flags |= IMAGE_SCN_LNK_COMDAT; + /* skip LINKER_CREATED */ if ((sec_flags & SEC_COFF_NOREAD) == 0) @@ -763,6 +797,16 @@ styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED, } else if (styp_flags & STYP_PAD) sec_flags = 0; +#ifdef RS6000COFF_C + else if (styp_flags & STYP_EXCEPT) + sec_flags |= SEC_LOAD; + else if (styp_flags & STYP_LOADER) + sec_flags |= SEC_LOAD; + else if (styp_flags & STYP_TYPCHK) + sec_flags |= SEC_LOAD; + else if (styp_flags & STYP_DWARF) + sec_flags |= SEC_DEBUGGING; +#endif else if (strcmp (name, _TEXT) == 0) { if (sec_flags & SEC_NEVER_LOAD) @@ -787,11 +831,13 @@ styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED, sec_flags |= SEC_ALLOC; } else if (CONST_STRNEQ (name, DOT_DEBUG) + || CONST_STRNEQ (name, DOT_ZDEBUG) #ifdef _COMMENT || strcmp (name, _COMMENT) == 0 #endif #ifdef COFF_LONG_SECTION_NAMES || CONST_STRNEQ (name, GNU_LINKONCE_WI) + || CONST_STRNEQ (name, GNU_LINKONCE_WT) #endif || CONST_STRNEQ (name, ".stab")) { @@ -885,12 +931,7 @@ handle_COMDAT (bfd * abfd, bfd_coff_swap_sym_in (abfd, esym, & isym); - if (sizeof (internal_s->s_name) > SYMNMLEN) - { - /* This case implies that the matching - symbol name will be in the string table. */ - abort (); - } + BFD_ASSERT (sizeof (internal_s->s_name) <= SYMNMLEN); if (isym.n_scnum == section->target_index) { @@ -921,8 +962,12 @@ handle_COMDAT (bfd * abfd, /* All 3 branches use this. */ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf); + /* PR 17512 file: 078-11867-0.004 */ if (symname == NULL) - abort (); + { + _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd); + break; + } switch (seen_state) { @@ -949,7 +994,7 @@ handle_COMDAT (bfd * abfd, if (! ((isym.n_sclass == C_STAT || isym.n_sclass == C_EXT) - && isym.n_type == T_NULL + && BTYPE (isym.n_type) == T_NULL && isym.n_value == 0)) abort (); @@ -964,6 +1009,13 @@ handle_COMDAT (bfd * abfd, seen_state = 1; + /* PR 17512: file: e2cfe54f. */ + if (esym + bfd_coff_symesz (abfd) >= esymend) + { + _bfd_error_handler (_("%B: warning: No symbol for section '%s' found"), + abfd, symname); + break; + } /* This is the section symbol. */ bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)), isym.n_type, isym.n_sclass, @@ -1117,10 +1169,19 @@ styp_to_sec_flags (bfd *abfd, flagword *flags_ptr) { struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; - long styp_flags = internal_s->s_flags; + unsigned long styp_flags = internal_s->s_flags; flagword sec_flags; bfd_boolean result = TRUE; + bfd_boolean is_dbg = FALSE; + if (CONST_STRNEQ (name, DOT_DEBUG) + || CONST_STRNEQ (name, DOT_ZDEBUG) +#ifdef COFF_LONG_SECTION_NAMES + || CONST_STRNEQ (name, GNU_LINKONCE_WI) + || CONST_STRNEQ (name, GNU_LINKONCE_WT) +#endif + || CONST_STRNEQ (name, ".stab")) + is_dbg = TRUE; /* Assume read only unless IMAGE_SCN_MEM_WRITE is specified. */ sec_flags = SEC_READONLY; @@ -1131,7 +1192,7 @@ styp_to_sec_flags (bfd *abfd, /* Process each flag bit in styp_flags in turn. */ while (styp_flags) { - long flag = styp_flags & - styp_flags; + unsigned long flag = styp_flags & - styp_flags; char * unhandled = NULL; styp_flags &= ~ flag; @@ -1190,27 +1251,30 @@ styp_to_sec_flags (bfd *abfd, mean that a given section contains debug information. Thus we only set the SEC_DEBUGGING flag on sections that we recognise as containing debug information. */ - if (CONST_STRNEQ (name, DOT_DEBUG) + if (is_dbg #ifdef _COMMENT || strcmp (name, _COMMENT) == 0 #endif -#ifdef COFF_LONG_SECTION_NAMES - || CONST_STRNEQ (name, GNU_LINKONCE_WI) -#endif - || CONST_STRNEQ (name, ".stab")) - sec_flags |= SEC_DEBUGGING; + ) + { + sec_flags |= SEC_DEBUGGING | SEC_READONLY; + } break; case IMAGE_SCN_MEM_SHARED: sec_flags |= SEC_COFF_SHARED; break; case IMAGE_SCN_LNK_REMOVE: - sec_flags |= SEC_EXCLUDE; + if (!is_dbg) + sec_flags |= SEC_EXCLUDE; break; case IMAGE_SCN_CNT_CODE: sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD; break; case IMAGE_SCN_CNT_INITIALIZED_DATA: - sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD; + if (is_dbg) + sec_flags |= SEC_DEBUGGING; + else + sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD; break; case IMAGE_SCN_CNT_UNINITIALIZED_DATA: sec_flags |= SEC_ALLOC; @@ -1334,10 +1398,11 @@ Special entry points for gdb to swap in coff symbol table parts: . bfd_boolean _bfd_coff_long_section_names; . bfd_boolean (*_bfd_coff_set_long_section_names) . (bfd *, int); -. +. . unsigned int _bfd_coff_default_section_alignment_power; . bfd_boolean _bfd_coff_force_symnames_in_strings; . unsigned int _bfd_coff_debug_string_prefix_length; +. unsigned int _bfd_coff_max_nscns; . . void (*_bfd_coff_swap_filehdr_in) . (bfd *, void *, void *); @@ -1475,6 +1540,9 @@ Special entry points for gdb to swap in coff symbol table parts: . ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) .#define bfd_coff_default_section_alignment_power(abfd) \ . (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) +.#define bfd_coff_max_nscns(abfd) \ +. (coff_backend_info (abfd)->_bfd_coff_max_nscns) +. .#define bfd_coff_swap_filehdr_in(abfd, i,o) \ . ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) . @@ -1692,6 +1760,7 @@ coff_new_section_hook (bfd * abfd, asection * section) { combined_entry_type *native; bfd_size_type amt; + unsigned char sclass = C_STAT; section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER; @@ -1699,9 +1768,22 @@ coff_new_section_hook (bfd * abfd, asection * section) if (bfd_xcoff_text_align_power (abfd) != 0 && strcmp (bfd_get_section_name (abfd, section), ".text") == 0) section->alignment_power = bfd_xcoff_text_align_power (abfd); - if (bfd_xcoff_data_align_power (abfd) != 0 + else if (bfd_xcoff_data_align_power (abfd) != 0 && strcmp (bfd_get_section_name (abfd, section), ".data") == 0) section->alignment_power = bfd_xcoff_data_align_power (abfd); + else + { + int i; + + for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++) + if (strcmp (bfd_get_section_name (abfd, section), + xcoff_dwsect_names[i].name) == 0) + { + section->alignment_power = 0; + sclass = C_DWARF; + break; + } + } #endif /* Set up the section symbol. */ @@ -1724,8 +1806,9 @@ coff_new_section_hook (bfd * abfd, asection * section) in case this symbol winds up getting written out. The value 0 for n_numaux is already correct. */ + native->is_sym = TRUE; native->u.syment.n_type = T_NULL; - native->u.syment.n_sclass = C_STAT; + native->u.syment.n_sclass = sclass; coffsymbol (section->symbol)->native = native; @@ -1838,12 +1921,14 @@ coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED, file_ptr oldpos = bfd_tell (abfd); bfd_size_type relsz = bfd_coff_relsz (abfd); - bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0); + if (bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0) != 0) + return; if (bfd_bread (& dst, relsz, abfd) != relsz) return; coff_swap_reloc_in (abfd, &dst, &n); - bfd_seek (abfd, oldpos, 0); + if (bfd_seek (abfd, oldpos, 0) != 0) + return; section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1; section->rel_filepos += relsz; } @@ -1995,10 +2080,14 @@ coff_mkobject_hook (bfd * abfd, #endif if ((internal_f->f_flags & F_GO32STUB) != 0) - coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); + { + coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); + if (coff->go32stub == NULL) + return NULL; + } if (coff->go32stub != NULL) memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE); - + return coff; } #endif @@ -2021,12 +2110,6 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) machine = 0; switch (internal_f->f_magic) { -#ifdef OR32_MAGIC_BIG - case OR32_MAGIC_BIG: - case OR32_MAGIC_LITTLE: - arch = bfd_arch_or32; - break; -#endif #ifdef PPCMAGIC case PPCMAGIC: arch = bfd_arch_powerpc; @@ -2094,22 +2177,6 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) machine = bfd_mach_m68020; break; #endif -#ifdef MAXQ20MAGIC - case MAXQ20MAGIC: - arch = bfd_arch_maxq; - switch (internal_f->f_flags & F_MACHMASK) - { - case F_MAXQ10: - machine = bfd_mach_maxq10; - break; - case F_MAXQ20: - machine = bfd_mach_maxq20; - break; - default: - return FALSE; - } - break; -#endif #ifdef MC88MAGIC case MC88MAGIC: case MC88DMAGIC: @@ -2222,6 +2289,8 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) bfd_size_type amt = bfd_coff_symesz (abfd); buf = bfd_malloc (amt); + if (buf == NULL) + return FALSE; if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 || bfd_bread (buf, amt, abfd) != amt) { @@ -2445,11 +2514,13 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED, unsigned int indaux, combined_entry_type *aux) { + BFD_ASSERT (symbol->is_sym); int n_sclass = symbol->u.syment.n_sclass; if (CSECT_SYM_P (n_sclass) && indaux + 1 == symbol->u.syment.n_numaux) { + BFD_ASSERT (! aux->is_sym); if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD) { aux->u.auxent.x_csect.x_scnlen.p = @@ -2482,6 +2553,7 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED, /* Return TRUE if we don't want to pointerize this aux entry, which is the case for the lastfirst aux entry for a C_LEAFPROC symbol. */ return (indaux == 1 + && symbol->is_sym && (symbol->u.syment.n_sclass == C_LEAFPROC || symbol->u.syment.n_sclass == C_LEAFSTAT || symbol->u.syment.n_sclass == C_LEAFEXT)); @@ -2504,6 +2576,8 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED, combined_entry_type *aux ATTRIBUTE_UNUSED, unsigned int indaux ATTRIBUTE_UNUSED) { + BFD_ASSERT (symbol->is_sym); + BFD_ASSERT (! aux->is_sym); #ifdef RS6000COFF_C if (CSECT_SYM_P (symbol->u.syment.n_sclass) && indaux + 1 == symbol->u.syment.n_numaux) @@ -2605,10 +2679,16 @@ coff_write_relocs (bfd * abfd, int first_undef) amt = s->reloc_count; amt *= sizeof (arelent *); p = bfd_malloc (amt); - if (p == NULL && s->reloc_count > 0) - return FALSE; - memcpy (p, s->orelocation, (size_t) amt); - qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); + if (p == NULL) + { + if (s->reloc_count > 0) + return FALSE; + } + else + { + memcpy (p, s->orelocation, (size_t) amt); + qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); + } } #endif @@ -2648,7 +2728,7 @@ coff_write_relocs (bfd * abfd, int first_undef) entries know which symbol index they point to. So we have to look up the output symbol here. */ - if (q->sym_ptr_ptr[0]->the_bfd != abfd) + if (q->sym_ptr_ptr[0] != NULL && q->sym_ptr_ptr[0]->the_bfd != abfd) { int j; const char *sname = q->sym_ptr_ptr[0]->name; @@ -2677,7 +2757,7 @@ coff_write_relocs (bfd * abfd, int first_undef) n.r_symndx = q->addend; else #endif - if (q->sym_ptr_ptr) + if (q->sym_ptr_ptr && q->sym_ptr_ptr[0] != NULL) { #ifdef SECTION_RELATIVE_ABSOLUTE_SYMBOL_P if (SECTION_RELATIVE_ABSOLUTE_SYMBOL_P (q, s)) @@ -3009,26 +3089,6 @@ coff_set_flags (bfd * abfd, return TRUE; #endif -#ifdef OR32_MAGIC_BIG - case bfd_arch_or32: - if (bfd_big_endian (abfd)) - * magicp = OR32_MAGIC_BIG; - else - * magicp = OR32_MAGIC_LITTLE; - return TRUE; -#endif - -#ifdef MAXQ20MAGIC - case bfd_arch_maxq: - * magicp = MAXQ20MAGIC; - switch (bfd_get_mach (abfd)) - { - case bfd_mach_maxq10: * flagsp = F_MAXQ10; return TRUE; - case bfd_mach_maxq20: * flagsp = F_MAXQ20; return TRUE; - default: return FALSE; - } -#endif - default: /* Unknown architecture. */ /* Fall through to "return FALSE" below, to avoid "statement never reached" errors on the one below. */ @@ -3090,13 +3150,44 @@ static bfd_boolean coff_compute_section_file_positions (bfd * abfd) { asection *current; - asection *previous = NULL; file_ptr sofar = bfd_coff_filhsz (abfd); bfd_boolean align_adjust; + unsigned int target_index; #ifdef ALIGN_SECTIONS_IN_FILE + asection *previous = NULL; file_ptr old_sofar; #endif +#ifdef COFF_IMAGE_WITH_PE + int page_size; + + if (coff_data (abfd)->link_info + || (pe_data (abfd) && pe_data (abfd)->pe_opthdr.FileAlignment)) + { + page_size = pe_data (abfd)->pe_opthdr.FileAlignment; + + /* If no file alignment has been set, default to one. + This repairs 'ld -r' for arm-wince-pe target. */ + if (page_size == 0) + page_size = 1; + + /* PR 17512: file: 0ac816d3. */ + if (page_size < 0) + { + bfd_set_error (bfd_error_file_too_big); + (*_bfd_error_handler) + (_("%B: page size is too large (0x%x)"), abfd, page_size); + return FALSE; + } + } + else + page_size = PE_DEF_FILE_ALIGNMENT; +#else +#ifdef COFF_PAGE_SIZE + int page_size = COFF_PAGE_SIZE; +#endif +#endif + #ifdef RS6000COFF_C /* On XCOFF, if we have symbols, set up the .debug section. */ if (bfd_get_symcount (abfd) > 0) @@ -3111,9 +3202,10 @@ coff_compute_section_file_positions (bfd * abfd) { coff_symbol_type *cf; - cf = coff_symbol_from (abfd, *symp); + cf = coff_symbol_from (*symp); if (cf != NULL && cf->native != NULL + && cf->native->is_sym && SYMNAME_IN_DEBUG (&cf->native->u.syment)) { size_t len; @@ -3136,26 +3228,6 @@ coff_compute_section_file_positions (bfd * abfd) } #endif -#ifdef COFF_IMAGE_WITH_PE - int page_size; - - if (coff_data (abfd)->link_info) - { - page_size = pe_data (abfd)->pe_opthdr.FileAlignment; - - /* If no file alignment has been set, default to one. - This repairs 'ld -r' for arm-wince-pe target. */ - if (page_size == 0) - page_size = 1; - } - else - page_size = PE_DEF_FILE_ALIGNMENT; -#else -#ifdef COFF_PAGE_SIZE - int page_size = COFF_PAGE_SIZE; -#endif -#endif - if (bfd_get_start_address (abfd)) /* A start address may have been added to the original file. In this case it will need an optional header to record it. */ @@ -3191,7 +3263,6 @@ coff_compute_section_file_positions (bfd * abfd) unsigned int count; asection **section_list; unsigned int i; - int target_index; bfd_size_type amt; #ifdef COFF_PAGE_SIZE @@ -3254,14 +3325,20 @@ coff_compute_section_file_positions (bfd * abfd) #else /* ! COFF_IMAGE_WITH_PE */ { /* Set the target_index field. */ - int target_index; - target_index = 1; for (current = abfd->sections; current != NULL; current = current->next) current->target_index = target_index++; } #endif /* ! COFF_IMAGE_WITH_PE */ + if (target_index >= bfd_coff_max_nscns (abfd)) + { + bfd_set_error (bfd_error_file_too_big); + (*_bfd_error_handler) + (_("%B: too many sections (%d)"), abfd, target_index); + return FALSE; + } + align_adjust = FALSE; for (current = abfd->sections; current != NULL; @@ -3294,6 +3371,8 @@ coff_compute_section_file_positions (bfd * abfd) if (!(current->flags & SEC_HAS_CONTENTS)) continue; + current->rawsize = current->size; + #ifdef COFF_IMAGE_WITH_PE /* Make sure we skip empty sections in a PE image. */ if (current->size == 0) @@ -3311,36 +3390,38 @@ coff_compute_section_file_positions (bfd * abfd) padding the previous section up if necessary. */ old_sofar = sofar; + sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); + #ifdef RS6000COFF_C - /* AIX loader checks the text section alignment of (vma - filepos) - So even though the filepos may be aligned wrt the o_algntext, for - AIX executables, this check fails. This shows up when a native - AIX executable is stripped with gnu strip because the default vma - of native is 0x10000150 but default for gnu is 0x10000140. Gnu - stripped gnu excutable passes this check because the filepos is - 0x0140. This problem also show up with 64 bit shared objects. The - data section must also be aligned. */ + /* Make sure the file offset and the vma of .text/.data are at the + same page offset, so that the file can be mmap'ed without being + relocated. Failing that, AIX is able to load and execute the + program, but it will be silently relocated (possible as + executables are PIE). But the relocation is slightly costly and + complexify the use of addr2line or gdb. So better to avoid it, + like does the native linker. Usually gnu ld makes sure that + the vma of .text is the file offset so this issue shouldn't + appear unless you are stripping such an executable. + + AIX loader checks the text section alignment of (vma - filepos), + and the native linker doesn't try to align the text sections. + For example: + + 0 .text 000054cc 10000128 10000128 00000128 2**5 + CONTENTS, ALLOC, LOAD, CODE + */ + if (!strcmp (current->name, _TEXT) || !strcmp (current->name, _DATA)) { - bfd_vma pad; - bfd_vma align; - - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); - - align = 1 << current->alignment_power; - pad = abs (current->vma - sofar) % align; - - if (pad) - { - pad = align - pad; - sofar += pad; - } - } - else -#else - { - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); + bfd_vma align = 4096; + bfd_vma sofar_off = sofar % align; + bfd_vma vma_off = current->vma % align; + + if (vma_off > sofar_off) + sofar += vma_off - sofar_off; + else if (vma_off < sofar_off) + sofar += align + vma_off - sofar_off; } #endif if (previous != NULL) @@ -3360,7 +3441,7 @@ coff_compute_section_file_positions (bfd * abfd) #ifdef COFF_IMAGE_WITH_PE /* Set the padded size. */ - current->size = (current->size + page_size -1) & -page_size; + current->size = (current->size + page_size - 1) & -page_size; #endif sofar += current->size; @@ -3399,10 +3480,12 @@ coff_compute_section_file_positions (bfd * abfd) incremented in coff_set_section_contents. This is right for SVR3.2. */ if (strcmp (current->name, _LIB) == 0) - bfd_set_section_vma (abfd, current, 0); + (void) bfd_set_section_vma (abfd, current, 0); #endif +#ifdef ALIGN_SECTIONS_IN_FILE previous = current; +#endif } /* It is now safe to write to the output file. If we needed an @@ -3527,7 +3610,9 @@ coff_write_object_contents (bfd * abfd) asection *current; bfd_boolean hasrelocs = FALSE; bfd_boolean haslinno = FALSE; +#ifdef COFF_IMAGE_WITH_PE bfd_boolean hasdebug = FALSE; +#endif file_ptr scn_base; file_ptr reloc_base; file_ptr lineno_base; @@ -3630,9 +3715,9 @@ coff_write_object_contents (bfd * abfd) current = current->next) { struct internal_scnhdr section; +#ifdef COFF_IMAGE_WITH_PE bfd_boolean is_reloc_section = FALSE; -#ifdef COFF_IMAGE_WITH_PE if (strcmp (current->name, DOT_RELOC) == 0) { is_reloc_section = TRUE; @@ -3731,9 +3816,11 @@ coff_write_object_contents (bfd * abfd) #endif if (current->lineno_count != 0) haslinno = TRUE; +#ifdef COFF_IMAGE_WITH_PE if ((current->flags & SEC_DEBUGGING) != 0 && ! is_reloc_section) hasdebug = TRUE; +#endif #ifdef RS6000COFF_C #ifndef XCOFF64 @@ -3813,9 +3900,10 @@ coff_write_object_contents (bfd * abfd) /* See if this is the section symbol. */ if (strcmp ((*psym)->name, current->name) == 0) { - csym = coff_symbol_from (abfd, *psym); + csym = coff_symbol_from (*psym); if (csym == NULL || csym->native == NULL + || ! csym->native->is_sym || csym->native->u.syment.n_numaux < 1 || csym->native->u.syment.n_sclass != C_STAT || csym->native->u.syment.n_type != T_NULL) @@ -3838,6 +3926,7 @@ coff_write_object_contents (bfd * abfd) x_associated field is not currently supported. */ aux = csym->native + 1; + BFD_ASSERT (! aux->is_sym); switch (current->flags & SEC_LINK_DUPLICATES) { case SEC_LINK_DUPLICATES_DISCARD: @@ -3895,7 +3984,7 @@ coff_write_object_contents (bfd * abfd) bfd_size_type amt; internal_f.f_nscns++; - strncpy (&(scnhdr.s_name[0]), current->name, 8); + memcpy (scnhdr.s_name, ".ovrflo", 8); scnhdr.s_paddr = current->reloc_count; scnhdr.s_vaddr = current->lineno_count; scnhdr.s_size = 0; @@ -3983,8 +4072,6 @@ coff_write_object_contents (bfd * abfd) internal_f.f_flags |= F_DYNLOAD; #endif - memset (&internal_a, 0, sizeof internal_a); - /* Set up architecture-dependent stuff. */ { unsigned int magic = 0; @@ -4094,16 +4181,6 @@ coff_write_object_contents (bfd * abfd) internal_a.magic = MIPS_PE_MAGIC; #endif -#ifdef OR32 -#define __A_MAGIC_SET__ - internal_a.magic = NMAGIC; /* Assume separate i/d. */ -#endif - -#ifdef MAXQ20MAGIC -#define __A_MAGIC_SET__ - internal_a.magic = MAXQ20MAGIC; -#endif - #ifndef __A_MAGIC_SET__ #include "Your aouthdr magic number is not being set!" #else @@ -4270,7 +4347,18 @@ coff_write_object_contents (bfd * abfd) } #endif - /* Now write them. */ +#ifdef COFF_WITH_PE + { + /* After object contents are finalized so we can compute a reasonable hash, + but before header is written so we can update it to point to debug directory. */ + struct pe_tdata *pe = pe_data (abfd); + + if (pe->build_id.after_write_object_contents != NULL) + (*pe->build_id.after_write_object_contents) (abfd); + } +#endif + + /* Now write header. */ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return FALSE; @@ -4405,11 +4493,11 @@ buy_and_read (bfd *abfd, file_ptr where, bfd_size_type size) void * area = bfd_alloc (abfd, size); if (!area) - return (NULL); + return NULL; if (bfd_seek (abfd, where, SEEK_SET) != 0 || bfd_bread (area, size, abfd) != size) - return (NULL); - return (area); + return NULL; + return area; } /* @@ -4443,6 +4531,8 @@ coff_sort_func_alent (const void * arg1, const void * arg2) const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym); const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym); + if (s1 == NULL || s2 == NULL) + return 0; if (s1->symbol.value < s2->symbol.value) return -1; else if (s1->symbol.value > s2->symbol.value) @@ -4460,9 +4550,11 @@ coff_slurp_line_table (bfd *abfd, asection *asect) unsigned int counter; alent *cache_ptr; bfd_vma prev_offset = 0; - int ordered = 1; + bfd_boolean ordered = TRUE; unsigned int nbr_func; LINENO *src; + bfd_boolean have_func; + bfd_boolean ret = TRUE; BFD_ASSERT (asect->lineno == NULL); @@ -4485,57 +4577,88 @@ coff_slurp_line_table (bfd *abfd, asection *asect) asect->lineno = lineno_cache; src = native_lineno; nbr_func = 0; + have_func = FALSE; - for (counter = 0; counter < asect->lineno_count; counter++) + for (counter = 0; counter < asect->lineno_count; counter++, src++) { struct internal_lineno dst; bfd_coff_swap_lineno_in (abfd, src, &dst); cache_ptr->line_number = dst.l_lnno; + /* Appease memory checkers that get all excited about + uninitialised memory when copying alents if u.offset is + larger than u.sym. (64-bit BFD on 32-bit host.) */ + memset (&cache_ptr->u, 0, sizeof (cache_ptr->u)); if (cache_ptr->line_number == 0) { - bfd_boolean warned; - bfd_signed_vma symndx; + combined_entry_type * ent; + bfd_vma symndx; coff_symbol_type *sym; - nbr_func++; - warned = FALSE; + have_func = FALSE; symndx = dst.l_addr.l_symndx; - if (symndx < 0 - || (bfd_vma) symndx >= obj_raw_syment_count (abfd)) + if (symndx >= obj_raw_syment_count (abfd)) { (*_bfd_error_handler) - (_("%B: warning: illegal symbol index %ld in line numbers"), - abfd, dst.l_addr.l_symndx); - symndx = 0; - warned = TRUE; + (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), + abfd, (long) symndx, counter); + cache_ptr->line_number = -1; + ret = FALSE; + continue; } + ent = obj_raw_syments (abfd) + symndx; /* FIXME: We should not be casting between ints and pointers like this. */ - sym = ((coff_symbol_type *) - ((symndx + obj_raw_syments (abfd)) - ->u.syment._n._n_n._n_zeroes)); + if (! ent->is_sym) + { + (*_bfd_error_handler) + (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), + abfd, (long) symndx, counter); + cache_ptr->line_number = -1; + ret = FALSE; + continue; + } + sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes); + + /* PR 17512 file: 078-10659-0.004 */ + if (sym < obj_symbols (abfd) + || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd)) + { + (*_bfd_error_handler) + (_("%B: warning: illegal symbol in line number entry %d"), + abfd, counter); + cache_ptr->line_number = -1; + ret = FALSE; + continue; + } + + have_func = TRUE; + nbr_func++; cache_ptr->u.sym = (asymbol *) sym; - if (sym->lineno != NULL && ! warned) + if (sym->lineno != NULL) (*_bfd_error_handler) (_("%B: warning: duplicate line number information for `%s'"), abfd, bfd_asymbol_name (&sym->symbol)); sym->lineno = cache_ptr; if (sym->symbol.value < prev_offset) - ordered = 0; + ordered = FALSE; prev_offset = sym->symbol.value; } + else if (!have_func) + /* Drop line information that has no associated function. + PR 17521: file: 078-10659-0.004. */ + continue; else - cache_ptr->u.offset = dst.l_addr.l_paddr - - bfd_section_vma (abfd, asect); - + cache_ptr->u.offset = (dst.l_addr.l_paddr + - bfd_section_vma (abfd, asect)); cache_ptr++; - src++; } - cache_ptr->line_number = 0; + + asect->lineno_count = cache_ptr - lineno_cache; + memset (cache_ptr, 0, sizeof (*cache_ptr)); bfd_release (abfd, native_lineno); /* On some systems (eg AIX5.3) the lineno table may not be sorted. */ @@ -4552,15 +4675,17 @@ coff_slurp_line_table (bfd *abfd, asection *asect) alent **p = func_table; unsigned int i; - for (i = 0; i < counter; i++) + for (i = 0; i < asect->lineno_count; i++) if (lineno_cache[i].line_number == 0) *p++ = &lineno_cache[i]; + BFD_ASSERT ((unsigned int) (p - func_table) == nbr_func); + /* Sort by functions. */ qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent); /* Create the new sorted table. */ - amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent); + amt = (bfd_size_type) asect->lineno_count * sizeof (alent); n_lineno_cache = (alent *) bfd_alloc (abfd, amt); if (n_lineno_cache != NULL) { @@ -4571,25 +4696,29 @@ coff_slurp_line_table (bfd *abfd, asection *asect) coff_symbol_type *sym; alent *old_ptr = func_table[i]; - /* Copy the function entry and update it. */ - *n_cache_ptr = *old_ptr; - sym = (coff_symbol_type *)n_cache_ptr->u.sym; - sym->lineno = n_cache_ptr; - n_cache_ptr++; - old_ptr++; - - /* Copy the line number entries. */ - while (old_ptr->line_number != 0) + /* Update the function entry. */ + sym = (coff_symbol_type *) old_ptr->u.sym; + /* PR binutils/17512: Point the lineno to where + this entry will be after the memcpy below. */ + sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache); + /* Copy the function and line number entries. */ + do *n_cache_ptr++ = *old_ptr++; + while (old_ptr->line_number != 0); } - n_cache_ptr->line_number = 0; + BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent))); + memcpy (lineno_cache, n_lineno_cache, amt); } + else + ret = FALSE; bfd_release (abfd, func_table); } + else + ret = FALSE; } - return TRUE; + return ret; } /* Slurp in the symbol table, converting it to generic form. Note @@ -4604,6 +4733,7 @@ coff_slurp_symbol_table (bfd * abfd) unsigned int *table_ptr; bfd_size_type amt; unsigned int number_of_symbols = 0; + bfd_boolean ret = TRUE; if (obj_symbols (abfd)) return TRUE; @@ -4621,7 +4751,7 @@ coff_slurp_symbol_table (bfd * abfd) amt = obj_raw_syment_count (abfd); amt *= sizeof (unsigned int); - table_ptr = (unsigned int *) bfd_alloc (abfd, amt); + table_ptr = (unsigned int *) bfd_zalloc (abfd, amt); if (table_ptr == NULL) return FALSE; @@ -4635,14 +4765,17 @@ coff_slurp_symbol_table (bfd * abfd) { combined_entry_type *src = native_symbols + this_index; table_ptr[this_index] = number_of_symbols; - dst->symbol.the_bfd = abfd; + dst->symbol.the_bfd = abfd; + BFD_ASSERT (src->is_sym); dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset); /* We use the native name field to point to the cached field. */ src->u.syment._n._n_n._n_zeroes = (bfd_hostptr_t) dst; dst->symbol.section = coff_section_from_bfd_index (abfd, src->u.syment.n_scnum); dst->symbol.flags = 0; + /* PR 17512: file: 079-7098-0.001:0.1. */ + dst->symbol.value = 0; dst->done_lineno = FALSE; switch (src->u.syment.n_sclass) @@ -4745,6 +4878,10 @@ coff_slurp_symbol_table (bfd * abfd) case C_THUMBSTAT: /* Thumb static. */ case C_THUMBLABEL: /* Thumb label. */ case C_THUMBSTATFUNC:/* Thumb static function. */ +#endif +#ifdef RS6000COFF_C + case C_DWARF: /* A label in a dwarf section. */ + case C_INFO: /* A label in a comment section. */ #endif case C_LABEL: /* Label. */ if (src->u.syment.n_scnum == N_DEBUG) @@ -4850,7 +4987,7 @@ coff_slurp_symbol_table (bfd * abfd) to the symbol instead of the index. FIXME: This should use a union. */ src->u.syment.n_value = - (long) (native_symbols + src->u.syment.n_value); + (long) (intptr_t) (native_symbols + src->u.syment.n_value); dst->symbol.value = src->u.syment.n_value; src->fix_value = 1; break; @@ -4892,6 +5029,11 @@ coff_slurp_symbol_table (bfd * abfd) && src->u.syment.n_value == 0 && src->u.syment.n_scnum == 0) break; +#ifdef RS6000COFF_C + /* XCOFF specific: deleted entry. */ + if (src->u.syment.n_value == C_NULL_VALUE) + break; +#endif /* Fall through. */ case C_EXTDEF: /* External definition. */ case C_ULABEL: /* Undefined label. */ @@ -4907,22 +5049,23 @@ coff_slurp_symbol_table (bfd * abfd) #if defined(TIC80COFF) || defined(TICOFF) case C_UEXT: /* Tentative external definition. */ #endif - case C_EXTLAB: /* External load time label. */ - case C_HIDDEN: /* Ext symbol in dmert public lib. */ default: (*_bfd_error_handler) (_("%B: Unrecognized storage class %d for %s symbol `%s'"), abfd, src->u.syment.n_sclass, dst->symbol.section->name, dst->symbol.name); + ret = FALSE; + case C_EXTLAB: /* External load time label. */ + case C_HIDDEN: /* Ext symbol in dmert public lib. */ dst->symbol.flags = BSF_DEBUGGING; dst->symbol.value = (src->u.syment.n_value); break; } dst->native = src; - dst->symbol.udata.i = 0; dst->lineno = NULL; + this_index += (src->u.syment.n_numaux) + 1; dst++; number_of_symbols++; @@ -4941,12 +5084,13 @@ coff_slurp_symbol_table (bfd * abfd) p = abfd->sections; while (p) { - coff_slurp_line_table (abfd, p); + if (! coff_slurp_line_table (abfd, p)) + return FALSE; p = p->next; } } - return TRUE; + return ret; } /* Classify a COFF symbol. A couple of targets have globally visible @@ -5005,13 +5149,13 @@ coff_classify_symbol (bfd *abfd, if (syment->n_value == 0) { asection *sec; - char buf[SYMNMLEN + 1]; - - sec = coff_section_from_bfd_index (abfd, syment->n_scnum); - if (sec != NULL - && (strcmp (bfd_get_section_name (abfd, sec), - _bfd_coff_internal_syment_name (abfd, syment, buf)) - == 0)) + char * name; + char buf[SYMNMLEN + 1]; + + name = _bfd_coff_internal_syment_name (abfd, syment, buf) + sec = coff_section_from_bfd_index (abfd, syment->n_scnum); + if (sec != NULL && name != NULL + && (strcmp (bfd_get_section_name (abfd, sec), name) == 0)) return COFF_SYMBOL_PE_SECTION; } #endif @@ -5080,8 +5224,9 @@ SUBSUBSECTION coffsym = (obj_symbols (abfd) \ + (cache_ptr->sym_ptr_ptr - symbols)); \ else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ + coffsym = coff_symbol_from (ptr); \ if (coffsym != NULL \ + && coffsym->native->is_sym \ && coffsym->native->u.syment.n_scnum == 0) \ cache_ptr->addend = 0; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ @@ -5143,7 +5288,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols) { (*_bfd_error_handler) (_("%B: warning: illegal symbol index %ld in relocs"), - abfd, dst.r_symndx); + abfd, (long) dst.r_symndx); cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; ptr = NULL; } @@ -5169,6 +5314,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols) /* Calculate any reloc addend by looking at the symbol. */ CALC_ADDEND (abfd, ptr, dst, cache_ptr); + (void) ptr; cache_ptr->address -= asect->vma; /* !! cache_ptr->section = NULL;*/ @@ -5203,7 +5349,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols) static reloc_howto_type * coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, - struct internal_reloc *rel, + struct internal_reloc *rel ATTRIBUTE_UNUSED, struct coff_link_hash_entry *h ATTRIBUTE_UNUSED, struct internal_syment *sym ATTRIBUTE_UNUSED, bfd_vma *addendp ATTRIBUTE_UNUSED) @@ -5295,10 +5441,6 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED, } #endif -#ifndef coff_bfd_link_hash_table_free -#define coff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#endif - /* If coff_relocate_section is defined, we can use the optimized COFF backend linker. Otherwise we must continue to use the old linker. */ @@ -5328,6 +5470,8 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED, #endif /* ! defined (coff_relocate_section) */ #define coff_bfd_link_just_syms _bfd_generic_link_just_syms +#define coff_bfd_copy_link_hash_symbol_type \ + _bfd_generic_copy_link_hash_symbol_type #define coff_bfd_link_split_section _bfd_generic_link_split_section #ifndef coff_start_final_link @@ -5430,6 +5574,7 @@ static bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED = #else 2, #endif + 32768, 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, @@ -5470,6 +5615,7 @@ static bfd_coff_backend_data ticoff0_swap_table = #else 2, #endif + 32768, coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, coff_SWAP_reloc_in, ticoff0_bad_format_hook, coff_set_arch_mach_hook, coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, @@ -5511,6 +5657,7 @@ static bfd_coff_backend_data ticoff1_swap_table = #else 2, #endif + 32768, coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, coff_SWAP_reloc_in, ticoff1_bad_format_hook, coff_set_arch_mach_hook, coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, @@ -5524,6 +5671,253 @@ static bfd_coff_backend_data ticoff1_swap_table = }; #endif +#ifdef COFF_WITH_PE_BIGOBJ +/* The UID for bigobj files. */ + +static const char header_bigobj_classid[16] = +{ + 0xC7, 0xA1, 0xBA, 0xD1, + 0xEE, 0xBA, + 0xa9, 0x4b, + 0xAF, 0x20, + 0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8 +}; + +/* Swap routines. */ + +static void +coff_bigobj_swap_filehdr_in (bfd * abfd, void * src, void * dst) +{ + struct external_ANON_OBJECT_HEADER_BIGOBJ *filehdr_src = + (struct external_ANON_OBJECT_HEADER_BIGOBJ *) src; + struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; + + filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->Machine); + filehdr_dst->f_nscns = H_GET_32 (abfd, filehdr_src->NumberOfSections); + filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->TimeDateStamp); + filehdr_dst->f_symptr = + GET_FILEHDR_SYMPTR (abfd, filehdr_src->PointerToSymbolTable); + filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->NumberOfSymbols); + filehdr_dst->f_opthdr = 0; + filehdr_dst->f_flags = 0; + + /* Check other magic numbers. */ + if (H_GET_16 (abfd, filehdr_src->Sig1) != IMAGE_FILE_MACHINE_UNKNOWN + || H_GET_16 (abfd, filehdr_src->Sig2) != 0xffff + || H_GET_16 (abfd, filehdr_src->Version) != 2 + || memcmp (filehdr_src->ClassID, header_bigobj_classid, 16) != 0) + filehdr_dst->f_opthdr = 0xffff; + + /* Note that CLR metadata are ignored. */ +} + +static unsigned int +coff_bigobj_swap_filehdr_out (bfd *abfd, void * in, void * out) +{ + struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in; + struct external_ANON_OBJECT_HEADER_BIGOBJ *filehdr_out = + (struct external_ANON_OBJECT_HEADER_BIGOBJ *) out; + + memset (filehdr_out, 0, sizeof (*filehdr_out)); + + H_PUT_16 (abfd, IMAGE_FILE_MACHINE_UNKNOWN, filehdr_out->Sig1); + H_PUT_16 (abfd, 0xffff, filehdr_out->Sig2); + H_PUT_16 (abfd, 2, filehdr_out->Version); + memcpy (filehdr_out->ClassID, header_bigobj_classid, 16); + H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->Machine); + H_PUT_32 (abfd, filehdr_in->f_nscns, filehdr_out->NumberOfSections); + H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->TimeDateStamp); + PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, + filehdr_out->PointerToSymbolTable); + H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->NumberOfSymbols); + + return bfd_coff_filhsz (abfd); +} + +static void +coff_bigobj_swap_sym_in (bfd * abfd, void * ext1, void * in1) +{ + SYMENT_BIGOBJ *ext = (SYMENT_BIGOBJ *) ext1; + struct internal_syment *in = (struct internal_syment *) in1; + + if (ext->e.e_name[0] == 0) + { + in->_n._n_n._n_zeroes = 0; + in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset); + } + else + { +#if SYMNMLEN != E_SYMNMLEN +#error we need to cope with truncating or extending SYMNMLEN +#else + memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN); +#endif + } + + in->n_value = H_GET_32 (abfd, ext->e_value); + in->n_scnum = H_GET_32 (abfd, ext->e_scnum); + in->n_type = H_GET_16 (abfd, ext->e_type); + in->n_sclass = H_GET_8 (abfd, ext->e_sclass); + in->n_numaux = H_GET_8 (abfd, ext->e_numaux); +} + +static unsigned int +coff_bigobj_swap_sym_out (bfd * abfd, void * inp, void * extp) +{ + struct internal_syment *in = (struct internal_syment *) inp; + SYMENT_BIGOBJ *ext = (SYMENT_BIGOBJ *) extp; + + if (in->_n._n_name[0] == 0) + { + H_PUT_32 (abfd, 0, ext->e.e.e_zeroes); + H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset); + } + else + { +#if SYMNMLEN != E_SYMNMLEN +#error we need to cope with truncating or extending SYMNMLEN +#else + memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN); +#endif + } + + H_PUT_32 (abfd, in->n_value, ext->e_value); + H_PUT_32 (abfd, in->n_scnum, ext->e_scnum); + + H_PUT_16 (abfd, in->n_type, ext->e_type); + H_PUT_8 (abfd, in->n_sclass, ext->e_sclass); + H_PUT_8 (abfd, in->n_numaux, ext->e_numaux); + + return SYMESZ_BIGOBJ; +} + +static void +coff_bigobj_swap_aux_in (bfd *abfd, + void * ext1, + int type, + int in_class, + int indx, + int numaux, + void * in1) +{ + AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) ext1; + union internal_auxent *in = (union internal_auxent *) in1; + + switch (in_class) + { + case C_FILE: + if (numaux > 1) + { + if (indx == 0) + memcpy (in->x_file.x_fname, ext->File.Name, + numaux * sizeof (AUXENT_BIGOBJ)); + } + else + memcpy (in->x_file.x_fname, ext->File.Name, sizeof (ext->File.Name)); + break; + + case C_STAT: + case C_LEAFSTAT: + case C_HIDDEN: + if (type == T_NULL) + { + in->x_scn.x_scnlen = H_GET_32 (abfd, ext->Section.Length); + in->x_scn.x_nreloc = + H_GET_16 (abfd, ext->Section.NumberOfRelocations); + in->x_scn.x_nlinno = + H_GET_16 (abfd, ext->Section.NumberOfLinenumbers); + in->x_scn.x_checksum = H_GET_32 (abfd, ext->Section.Checksum); + in->x_scn.x_associated = H_GET_16 (abfd, ext->Section.Number) + | (H_GET_16 (abfd, ext->Section.HighNumber) << 16); + in->x_scn.x_comdat = H_GET_8 (abfd, ext->Section.Selection); + return; + } + break; + + default: + in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->Sym.WeakDefaultSymIndex); + /* Characteristics is ignored. */ + break; + } +} + +static unsigned int +coff_bigobj_swap_aux_out (bfd * abfd, + void * inp, + int type, + int in_class, + int indx ATTRIBUTE_UNUSED, + int numaux ATTRIBUTE_UNUSED, + void * extp) +{ + union internal_auxent * in = (union internal_auxent *) inp; + AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) extp; + + memset (ext, 0, AUXESZ); + + switch (in_class) + { + case C_FILE: + memcpy (ext->File.Name, in->x_file.x_fname, sizeof (ext->File.Name)); + + return AUXESZ; + + case C_STAT: + case C_LEAFSTAT: + case C_HIDDEN: + if (type == T_NULL) + { + H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->Section.Length); + H_PUT_16 (abfd, in->x_scn.x_nreloc, + ext->Section.NumberOfRelocations); + H_PUT_16 (abfd, in->x_scn.x_nlinno, + ext->Section.NumberOfLinenumbers); + H_PUT_32 (abfd, in->x_scn.x_checksum, ext->Section.Checksum); + H_PUT_16 (abfd, in->x_scn.x_associated & 0xffff, + ext->Section.Number); + H_PUT_16 (abfd, (in->x_scn.x_associated >> 16), + ext->Section.HighNumber); + H_PUT_8 (abfd, in->x_scn.x_comdat, ext->Section.Selection); + return AUXESZ; + } + break; + } + + H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->Sym.WeakDefaultSymIndex); + H_PUT_32 (abfd, 1, ext->Sym.WeakSearchType); + + return AUXESZ; +} + +static bfd_coff_backend_data bigobj_swap_table = +{ + coff_bigobj_swap_aux_in, coff_bigobj_swap_sym_in, coff_SWAP_lineno_in, + coff_bigobj_swap_aux_out, coff_bigobj_swap_sym_out, + coff_SWAP_lineno_out, coff_SWAP_reloc_out, + coff_bigobj_swap_filehdr_out, coff_SWAP_aouthdr_out, + coff_SWAP_scnhdr_out, + FILHSZ_BIGOBJ, AOUTSZ, SCNHSZ, SYMESZ_BIGOBJ, AUXESZ_BIGOBJ, + RELSZ, LINESZ, FILNMLEN_BIGOBJ, + TRUE, + COFF_DEFAULT_LONG_SECTION_NAMES, + COFF_DEFAULT_SECTION_ALIGNMENT_POWER, + FALSE, + 2, + 1U << 31, + coff_bigobj_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_classify_symbol, 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_link_output_has_begun, coff_final_link_postscript, + bfd_pe_print_pdata /* huh */ +}; + +#endif /* COFF_WITH_PE_BIGOBJ */ + #ifndef coff_close_and_cleanup #define coff_close_and_cleanup _bfd_generic_close_and_cleanup #endif @@ -5602,6 +5996,10 @@ static bfd_coff_backend_data ticoff1_swap_table = #define coff_bfd_gc_sections bfd_generic_gc_sections #endif +#ifndef coff_bfd_lookup_section_flags +#define coff_bfd_lookup_section_flags bfd_generic_lookup_section_flags +#endif + #ifndef coff_bfd_merge_sections #define coff_bfd_merge_sections bfd_generic_merge_sections #endif @@ -5616,7 +6014,7 @@ static bfd_coff_backend_data ticoff1_swap_table = #ifndef coff_section_already_linked #define coff_section_already_linked \ - _bfd_generic_section_already_linked + _bfd_coff_section_already_linked #endif #ifndef coff_bfd_define_common_symbol @@ -5638,6 +6036,7 @@ const bfd_target VAR = \ UNDER, /* Leading symbol underscore. */ \ '/', /* AR_pad_char. */ \ 15, /* AR_max_namelen. */ \ + 0, /* match priority. */ \ \ /* Data conversion functions. */ \ bfd_getb64, bfd_getb_signed_64, bfd_putb64, \ @@ -5688,6 +6087,7 @@ const bfd_target VAR = \ UNDER, /* Leading symbol underscore. */ \ '/', /* AR_pad_char. */ \ 15, /* AR_max_namelen. */ \ + 0, /* match priority. */ \ \ /* Data conversion functions. */ \ bfd_getb64, bfd_getb_signed_64, bfd_putb64, \ @@ -5738,6 +6138,7 @@ const bfd_target VAR = \ UNDER, /* Leading symbol underscore. */ \ '/', /* AR_pad_char. */ \ 15, /* AR_max_namelen. */ \ + 0, /* match priority. */ \ \ /* Data conversion functions. */ \ bfd_getl64, bfd_getl_signed_64, bfd_putl64, \