X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=bfd%2Fcoffgen.c;fp=bfd%2Fcoffgen.c;h=5f6921d9d91d151f1256b56fdf4a67a31cf1e9b7;hp=0e8b7eda5c4263e8b82f95c95a93b8c2c0ac75dd;hb=88750007d7869f178f0ba528f41efd3b74c424cf;hpb=6df9443a374e2b81278c61b8afc0a1eef7db280b diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 0e8b7ed..5f6921d 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1,6 +1,6 @@ /* Support for the generic parts of COFF, for BFD. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2007 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Cygnus Support. @@ -59,8 +59,13 @@ make_a_section_from_file (bfd *abfd, name = NULL; - /* Handle long section names as in PE. */ - if (bfd_coff_long_section_names (abfd) + /* Handle long section names as in PE. On reading, we want to + accept long names if the format permits them at all, regardless + of the current state of the flag that dictates if we would generate + them in outputs; this construct checks if that is the case by + attempting to set the flag, without changing its state; the call + will fail for formats that do not support long names at all. */ + if (bfd_coff_set_long_section_names (abfd, bfd_coff_long_section_names (abfd)) && hdr->s_name[0] == '/') { char buf[SCNNMLEN]; @@ -68,6 +73,11 @@ make_a_section_from_file (bfd *abfd, char *p; const char *strings; + /* Flag that this BFD uses long names, even though the format might + expect them to be off by default. This won't directly affect the + format of any output BFD created from this one, but the information + can be used to decide what to do. */ + bfd_coff_set_long_section_names (abfd, TRUE); memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1); buf[SCNNMLEN - 1] = '\0'; strindex = strtol (buf, &p, 10); @@ -80,7 +90,8 @@ make_a_section_from_file (bfd *abfd, strindex does not run us past the end, but right now we don't know the length of the string table. */ strings += strindex; - name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1); + name = (char *) bfd_alloc (abfd, + (bfd_size_type) strlen (strings) + 1); if (name == NULL) return FALSE; strcpy (name, strings); @@ -90,7 +101,8 @@ make_a_section_from_file (bfd *abfd, if (name == NULL) { /* Assorted wastage to null-terminate the name, thanks AT&T! */ - name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1); + name = (char *) bfd_alloc (abfd, + (bfd_size_type) sizeof (hdr->s_name) + 1); if (name == NULL) return FALSE; strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); @@ -185,7 +197,7 @@ coff_real_object_p (bfd *abfd, scnhsz = bfd_coff_scnhsz (abfd); readsize = (bfd_size_type) nscns * scnhsz; - external_sections = bfd_alloc (abfd, readsize); + external_sections = (char *) bfd_alloc (abfd, readsize); if (!external_sections) goto fail; @@ -427,7 +439,7 @@ _bfd_coff_read_internal_relocs (bfd *abfd, amt = sec->reloc_count * relsz; if (external_relocs == NULL) { - free_external = bfd_malloc (amt); + free_external = (bfd_byte *) bfd_malloc (amt); if (free_external == NULL) goto error_return; external_relocs = free_external; @@ -441,7 +453,7 @@ _bfd_coff_read_internal_relocs (bfd *abfd, { amt = sec->reloc_count; amt *= sizeof (struct internal_reloc); - free_internal = bfd_malloc (amt); + free_internal = (struct internal_reloc *) bfd_malloc (amt); if (free_internal == NULL) goto error_return; internal_relocs = free_internal; @@ -641,7 +653,7 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) bfd_size_type amt; amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); - newsyms = bfd_alloc (bfd_ptr, amt); + newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt); if (!newsyms) return FALSE; bfd_ptr->outsymbols = newsyms; @@ -902,7 +914,7 @@ coff_write_symbol (bfd *abfd, { unsigned int numaux = native->u.syment.n_numaux; int type = native->u.syment.n_type; - int class = native->u.syment.n_sclass; + int n_sclass = (int) native->u.syment.n_sclass; void * buf; bfd_size_type symesz; @@ -948,7 +960,7 @@ coff_write_symbol (bfd *abfd, { bfd_coff_swap_aux_out (abfd, &((native + j + 1)->u.auxent), - type, class, (int) j, + type, n_sclass, (int) j, native->u.syment.n_numaux, buf); if (bfd_bwrite (buf, auxesz, abfd) != auxesz) @@ -1082,6 +1094,11 @@ coff_write_native_symbol (bfd *abfd, debug_string_size_p); } +static void +null_error_handler (const char * fmt ATTRIBUTE_UNUSED, ...) +{ +} + /* Write out the COFF symbols. */ bfd_boolean @@ -1138,6 +1155,43 @@ coff_write_symbols (bfd *abfd) } else { + if (coff_backend_info (abfd)->_bfd_coff_classify_symbol != NULL) + { + bfd_error_handler_type current_error_handler; + enum coff_symbol_classification sym_class; + unsigned char *n_sclass; + + /* Suppress error reporting by bfd_coff_classify_symbol. + Error messages can be generated when we are processing a local + symbol which has no associated section and we do not have to + worry about this, all we need to know is that it is local. */ + current_error_handler = bfd_set_error_handler (null_error_handler); + sym_class = bfd_coff_classify_symbol (abfd, + &c_symbol->native->u.syment); + (void) bfd_set_error_handler (current_error_handler); + + n_sclass = &c_symbol->native->u.syment.n_sclass; + + /* If the symbol class has been changed (eg objcopy/ld script/etc) + we cannot retain the existing sclass from the original symbol. + Weak symbols only have one valid sclass, so just set it always. + If it is not local class and should be, set it C_STAT. + If it is global and not classified as global, or if it is + weak (which is also classified as global), set it C_EXT. */ + + if (symbol->flags & BSF_WEAK) + *n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; + else if (symbol->flags & BSF_LOCAL && sym_class != COFF_SYMBOL_LOCAL) + *n_sclass = C_STAT; + else if (symbol->flags & BSF_GLOBAL + && (sym_class != COFF_SYMBOL_GLOBAL +#ifdef COFF_WITH_PE + || *n_sclass == C_NT_WEAK +#endif + || *n_sclass == C_WEAKEXT)) + c_symbol->native->u.syment.n_sclass = C_EXT; + } + if (!coff_write_native_symbol (abfd, c_symbol, &written, &string_size, &debug_string_section, &debug_string_size)) @@ -1339,7 +1393,7 @@ coff_pointerize_aux (bfd *abfd, combined_entry_type *auxent) { unsigned int type = symbol->u.syment.n_type; - unsigned int class = symbol->u.syment.n_sclass; + unsigned int n_sclass = symbol->u.syment.n_sclass; if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) { @@ -1349,16 +1403,17 @@ coff_pointerize_aux (bfd *abfd, } /* Don't bother if this is a file or a section. */ - if (class == C_STAT && type == T_NULL) + if (n_sclass == C_STAT && type == T_NULL) return; - if (class == C_FILE) + if (n_sclass == C_FILE) return; /* Otherwise patch up. */ #define N_TMASK coff_data (abfd)->local_n_tmask #define N_BTSHFT coff_data (abfd)->local_n_btshft - if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN) + if ((ISFCN (type) || ISTAG (n_sclass) || n_sclass == C_BLOCK + || n_sclass == C_FCN) && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) { auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = @@ -1395,7 +1450,7 @@ build_debug_section (bfd *abfd) } sec_size = sect->size; - debug_section = bfd_alloc (abfd, sec_size); + debug_section = (char *) bfd_alloc (abfd, sec_size); if (debug_section == NULL) return NULL; @@ -1425,7 +1480,7 @@ copy_name (bfd *abfd, char *name, size_t maxlen) if (name[len] == '\0') break; - if ((newname = bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL) + if ((newname = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL) return NULL; strncpy (newname, name, len); @@ -1520,7 +1575,7 @@ _bfd_coff_read_string_table (bfd *abfd) return NULL; } - strings = bfd_malloc (strsize); + strings = (char *) bfd_malloc (strsize); if (strings == NULL) return NULL; @@ -1579,7 +1634,7 @@ coff_get_normalized_symtab (bfd *abfd) return obj_raw_syments (abfd); size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type); - internal = bfd_zalloc (abfd, size); + internal = (combined_entry_type *) bfd_zalloc (abfd, size); if (internal == NULL && size != 0) return NULL; internal_end = internal + obj_raw_syment_count (abfd); @@ -1685,7 +1740,7 @@ coff_get_normalized_symtab (bfd *abfd) if (internal_ptr->u.syment._n._n_name[i] == '\0') break; - newstring = bfd_zalloc (abfd, (bfd_size_type) (i + 1)); + newstring = (char *) bfd_zalloc (abfd, (bfd_size_type) (i + 1)); if (newstring == NULL) return NULL; strncpy (newstring, internal_ptr->u.syment._n._n_name, i); @@ -1743,17 +1798,17 @@ asymbol * coff_make_empty_symbol (bfd *abfd) { bfd_size_type amt = sizeof (coff_symbol_type); - coff_symbol_type *new = bfd_zalloc (abfd, amt); + coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_zalloc (abfd, amt); - if (new == NULL) + if (new_symbol == NULL) return NULL; - new->symbol.section = 0; - new->native = 0; - new->lineno = NULL; - new->done_lineno = FALSE; - new->symbol.the_bfd = abfd; + new_symbol->symbol.section = 0; + new_symbol->native = 0; + new_symbol->lineno = NULL; + new_symbol->done_lineno = FALSE; + new_symbol->symbol.the_bfd = abfd; - return & new->symbol; + return & new_symbol->symbol; } /* Make a debugging symbol. */ @@ -1764,23 +1819,23 @@ coff_bfd_make_debug_symbol (bfd *abfd, unsigned long sz ATTRIBUTE_UNUSED) { bfd_size_type amt = sizeof (coff_symbol_type); - coff_symbol_type *new = bfd_alloc (abfd, amt); + coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_alloc (abfd, amt); - if (new == NULL) + if (new_symbol == NULL) return NULL; /* @@ The 10 is a guess at a plausible maximum number of aux entries (but shouldn't be a constant). */ amt = sizeof (combined_entry_type) * 10; - new->native = bfd_zalloc (abfd, amt); - if (!new->native) + new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt); + if (!new_symbol->native) return NULL; - new->symbol.section = bfd_abs_section_ptr; - new->symbol.flags = BSF_DEBUGGING; - new->lineno = NULL; - new->done_lineno = FALSE; - new->symbol.the_bfd = abfd; + new_symbol->symbol.section = bfd_abs_section_ptr; + new_symbol->symbol.flags = BSF_DEBUGGING; + new_symbol->lineno = NULL; + new_symbol->done_lineno = FALSE; + new_symbol->symbol.the_bfd = abfd; - return & new->symbol; + return & new_symbol->symbol; } void @@ -1908,16 +1963,7 @@ coff_print_symbol (bfd *abfd, combined->u.syment.n_type, combined->u.syment.n_sclass, combined->u.syment.n_numaux); -#ifdef BFD64 - /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit - value, but really we want to display the address in the target's - address size. Since we do not have a field in the bfd structure - to tell us this, we take a guess, based on the target's name. */ - if (strstr (bfd_get_target (abfd), "64") == NULL) - fprintf (file, "%08lx", (unsigned long) (val & 0xffffffff)); - else -#endif - fprintf_vma (file, val); + bfd_fprintf_vma (abfd, file, val); fprintf (file, " %s", symbol->name); for (aux = 0; aux < combined->u.syment.n_numaux; aux++) @@ -1946,7 +1992,7 @@ coff_print_symbol (bfd *abfd, /* Probably a section symbol ? */ { fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d", - (long) auxp->u.auxent.x_scn.x_scnlen, + (unsigned long) auxp->u.auxent.x_scn.x_scnlen, auxp->u.auxent.x_scn.x_nreloc, auxp->u.auxent.x_scn.x_nlinno); if (auxp->u.auxent.x_scn.x_checksum != 0 @@ -1960,6 +2006,7 @@ coff_print_symbol (bfd *abfd, } /* Otherwise fall through. */ case C_EXT: + case C_AIX_WEAKEXT: if (ISFCN (combined->u.syment.n_type)) { long next, llnos; @@ -1972,7 +2019,8 @@ coff_print_symbol (bfd *abfd, llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr; fprintf (file, "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld", - tagndx, auxp->u.auxent.x_sym.x_misc.x_fsize, + tagndx, + (unsigned long) auxp->u.auxent.x_sym.x_misc.x_fsize, llnos, next); break; } @@ -1998,7 +2046,7 @@ coff_print_symbol (bfd *abfd, while (l->line_number) { fprintf (file, "\n%4d : ", l->line_number); - fprintf_vma (file, l->u.offset + symbol->section->vma); + bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma); l++; } } @@ -2144,7 +2192,7 @@ coff_find_nearest_line (bfd *abfd, } /* Now wander though the raw linenumbers of the section. */ - /* If we have been called on this section before, and th. e offset we + /* If we have been called on this section before, and the offset we want is further down then we can prime the lookup loop. */ sec_data = coff_section_data (abfd, section); if (sec_data != NULL @@ -2231,7 +2279,7 @@ coff_find_nearest_line (bfd *abfd, if (sec_data != NULL) { sec_data->offset = offset; - sec_data->i = i; + sec_data->i = i - 1; sec_data->function = *functionname_ptr; sec_data->line_base = line_base; } @@ -2272,7 +2320,7 @@ coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info) bfd_boolean bfd_coff_set_symbol_class (bfd * abfd, asymbol * symbol, - unsigned int class) + unsigned int symbol_class) { coff_symbol_type * csym; @@ -2292,12 +2340,12 @@ bfd_coff_set_symbol_class (bfd * abfd, combined_entry_type * native; bfd_size_type amt = sizeof (* native); - native = bfd_zalloc (abfd, amt); + native = (combined_entry_type *) bfd_zalloc (abfd, amt); if (native == NULL) return FALSE; native->u.syment.n_type = T_NULL; - native->u.syment.n_sclass = class; + native->u.syment.n_sclass = symbol_class; if (bfd_is_und_section (symbol->section)) { @@ -2326,7 +2374,7 @@ bfd_coff_set_symbol_class (bfd * abfd, csym->native = native; } else - csym->native->u.syment.n_sclass = class; + csym->native->u.syment.n_sclass = symbol_class; return TRUE; }