X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bfd%2Fbfd.c;h=2d9397b5b2981b683956eefe3cb59940776fdf79;hb=1903aa3536a887f693088b0404a8dd2214dfb6fc;hp=1ffd7d05b1d54c69c47dc444f87bfaa8e63bcf4b;hpb=5c1d2f5f4c7747c36eae8be3abd4ef4e9669690c;p=platform%2Fupstream%2Fbinutils.git diff --git a/bfd/bfd.c b/bfd/bfd.c index 1ffd7d05..2d9397b 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1,7 +1,5 @@ /* Generic BFD library interface and support routines. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1990-2014 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -22,6 +20,9 @@ MA 02110-1301, USA. */ /* +INODE +typedef bfd, Error reporting, BFD front end, BFD front end + SECTION <> @@ -35,11 +36,16 @@ SECTION CODE_FRAGMENT . +.enum bfd_direction +. { +. no_direction = 0, +. read_direction = 1, +. write_direction = 2, +. both_direction = 3 +. }; +. .struct bfd .{ -. {* A unique identifier of the BFD *} -. unsigned int id; -. . {* The filename the application opened the BFD with. *} . const char *filename; . @@ -62,24 +68,17 @@ CODE_FRAGMENT . {* File modified time, if mtime_set is TRUE. *} . long mtime; . -. {* Reserved for an unimplemented file locking extension. *} -. int ifd; +. {* A unique identifier of the BFD *} +. unsigned int id; . . {* The format which belongs to the BFD. (object, core, etc.) *} -. bfd_format format; +. ENUM_BITFIELD (bfd_format) format : 3; . . {* The direction with which the BFD was opened. *} -. enum bfd_direction -. { -. no_direction = 0, -. read_direction = 1, -. write_direction = 2, -. both_direction = 3 -. } -. direction; +. ENUM_BITFIELD (bfd_direction) direction : 2; . . {* Format_specific flags. *} -. flagword flags; +. flagword flags : 17; . . {* Values that may appear in the flags field of a BFD. These also . appear in the object_flags field of the bfd_target structure, where @@ -138,12 +137,68 @@ CODE_FRAGMENT . struct. *} .#define BFD_IN_MEMORY 0x800 . -. {* The sections in this BFD specify a memory page. *} -.#define HAS_LOAD_PAGE 0x1000 -. . {* This BFD has been created by the linker and doesn't correspond . to any input file. *} -.#define BFD_LINKER_CREATED 0x2000 +.#define BFD_LINKER_CREATED 0x1000 +. +. {* This may be set before writing out a BFD to request that it +. be written using values for UIDs, GIDs, timestamps, etc. that +. will be consistent from run to run. *} +.#define BFD_DETERMINISTIC_OUTPUT 0x2000 +. +. {* Compress sections in this BFD. *} +.#define BFD_COMPRESS 0x4000 +. +. {* Decompress sections in this BFD. *} +.#define BFD_DECOMPRESS 0x8000 +. +. {* BFD is a dummy, for plugins. *} +.#define BFD_PLUGIN 0x10000 +. +. {* Flags bits to be saved in bfd_preserve_save. *} +.#define BFD_FLAGS_SAVED \ +. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN) +. +. {* Flags bits which are for BFD use only. *} +.#define BFD_FLAGS_FOR_BFD_USE_MASK \ +. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ +. | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT) +. +. {* Is the file descriptor being cached? That is, can it be closed as +. needed, and re-opened when accessed later? *} +. unsigned int cacheable : 1; +. +. {* Marks whether there was a default target specified when the +. BFD was opened. This is used to select which matching algorithm +. to use to choose the back end. *} +. unsigned int target_defaulted : 1; +. +. {* ... and here: (``once'' means at least once). *} +. unsigned int opened_once : 1; +. +. {* Set if we have a locally maintained mtime value, rather than +. getting it from the file each time. *} +. unsigned int mtime_set : 1; +. +. {* Flag set if symbols from this BFD should not be exported. *} +. unsigned int no_export : 1; +. +. {* Remember when output has begun, to stop strange things +. from happening. *} +. unsigned int output_has_begun : 1; +. +. {* Have archive map. *} +. unsigned int has_armap : 1; +. +. {* Set if this is a thin archive. *} +. unsigned int is_thin_archive : 1; +. +. {* Set if only required symbols should be added in the link hash table for +. this object. Used by VMS linkers. *} +. unsigned int selective_search : 1; +. +. {* Set if this is the linker output BFD. *} +. unsigned int is_linker_output : 1; . . {* Currently my_archive is tested before adding origin to . anything. I believe that this can become always an add of @@ -169,17 +224,21 @@ CODE_FRAGMENT . {* The number of sections. *} . unsigned int section_count; . +. {* A field used by _bfd_generic_link_add_archive_symbols. This will +. be used only for archive elements. *} +. int archive_pass; +. . {* Stuff only useful for object files: . The start address. *} . bfd_vma start_address; . -. {* Used for input and output. *} -. unsigned int symcount; -. . {* Symbol table for output BFD (with symcount entries). . Also used by the linker to cache input BFD symbols. *} . struct bfd_symbol **outsymbols; . +. {* Used for input and output. *} +. unsigned int symcount; +. . {* Used for slurped dynamic symbol tables. *} . unsigned int dynsymcount; . @@ -194,12 +253,12 @@ CODE_FRAGMENT . struct bfd *nested_archives; {* List of nested archive in a flattened . thin archive. *} . -. {* A chain of BFD structures involved in a link. *} -. struct bfd *link_next; -. -. {* A field used by _bfd_generic_link_add_archive_symbols. This will -. be used only for archive elements. *} -. int archive_pass; +. union { +. {* For input BFDs, a chain of BFDs involved in a link. *} +. struct bfd *next; +. {* For output BFD, the linker hash table. *} +. struct bfd_link_hash_table *hash; +. } link; . . {* Used by the back end to hold private data. *} . union @@ -215,6 +274,7 @@ CODE_FRAGMENT . struct ieee_data_struct *ieee_data; . struct ieee_ar_data_struct *ieee_ar_data; . struct srec_data_struct *srec_data; +. struct verilog_data_struct *verilog_data; . struct ihex_data_struct *ihex_data; . struct tekhex_data_struct *tekhex_data; . struct elf_obj_tdata *elf_obj_data; @@ -235,6 +295,7 @@ CODE_FRAGMENT . struct netbsd_core_struct *netbsd_core_data; . struct mach_o_data_struct *mach_o_data; . struct mach_o_fat_data_struct *mach_o_fat_data; +. struct plugin_data_struct *plugin_data; . struct bfd_pef_data_struct *pef_data; . struct bfd_pef_xlib_data_struct *pef_xlib_data; . struct bfd_sym_data_struct *sym_data; @@ -249,37 +310,16 @@ CODE_FRAGMENT . struct objalloc *, but we use void * to avoid requiring the inclusion . of objalloc.h. *} . void *memory; -. -. {* Is the file descriptor being cached? That is, can it be closed as -. needed, and re-opened when accessed later? *} -. unsigned int cacheable : 1; -. -. {* Marks whether there was a default target specified when the -. BFD was opened. This is used to select which matching algorithm -. to use to choose the back end. *} -. unsigned int target_defaulted : 1; -. -. {* ... and here: (``once'' means at least once). *} -. unsigned int opened_once : 1; -. -. {* Set if we have a locally maintained mtime value, rather than -. getting it from the file each time. *} -. unsigned int mtime_set : 1; -. -. {* Flag set if symbols from this BFD should not be exported. *} -. unsigned int no_export : 1; -. -. {* Remember when output has begun, to stop strange things -. from happening. *} -. unsigned int output_has_begun : 1; -. -. {* Have archive map. *} -. unsigned int has_armap : 1; -. -. {* Set if this is a thin archive. *} -. unsigned int is_thin_archive : 1; .}; . +.{* See note beside bfd_set_section_userdata. *} +.static inline bfd_boolean +.bfd_set_cacheable (bfd * abfd, bfd_boolean val) +.{ +. abfd->cacheable = val; +. return TRUE; +.} +. */ #include "sysdep.h" @@ -310,6 +350,9 @@ CODE_FRAGMENT where it is needed. The typedef's used are defined in bfd.h */ /* +INODE +Error reporting, Miscellaneous, typedef bfd, BFD front end + SECTION Error reporting @@ -344,6 +387,7 @@ CODE_FRAGMENT . bfd_error_no_armap, . bfd_error_no_more_archived_files, . bfd_error_malformed_archive, +. bfd_error_missing_dso, . bfd_error_file_not_recognized, . bfd_error_file_ambiguously_recognized, . bfd_error_no_contents, @@ -376,6 +420,7 @@ const char *const bfd_errmsgs[] = N_("Archive has no index; run ranlib to add one"), N_("No more archived files"), N_("Malformed archive"), + N_("DSO missing from command line"), N_("File format not recognized"), N_("File format is ambiguous"), N_("Section has no contents"), @@ -431,7 +476,7 @@ bfd_set_error (bfd_error_type error_tag, ...) va_start (ap, error_tag); input_bfd = va_arg (ap, bfd *); - input_error = va_arg (ap, int); + input_error = (bfd_error_type) va_arg (ap, int); if (input_error >= bfd_error_on_input) abort (); va_end (ap); @@ -496,10 +541,12 @@ DESCRIPTION void bfd_perror (const char *message) { + fflush (stdout); if (message == NULL || *message == '\0') fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ())); else fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ())); + fflush (stderr); } /* @@ -695,7 +742,10 @@ _bfd_default_error_handler (const char *fmt, ...) vfprintf (stderr, new_fmt, ap); va_end (ap); - putc ('\n', stderr); + /* On AIX, putc is implemented as a macro that triggers a -Wunused-value + warning, so use the fputc function to avoid it. */ + fputc ('\n', stderr); + fflush (stderr); } /* This is a function pointer to the routine which should handle BFD @@ -764,8 +814,93 @@ bfd_get_error_handler (void) { return _bfd_error_handler; } + +/* +SUBSECTION + BFD assert handler + + If BFD finds an internal inconsistency, the bfd assert + handler is called with information on the BFD version, BFD + source file and line. If this happens, most programs linked + against BFD are expected to want to exit with an error, or mark + the current BFD operation as failed, so it is recommended to + override the default handler, which just calls + _bfd_error_handler and continues. + +CODE_FRAGMENT +. +.typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg, +. const char *bfd_version, +. const char *bfd_file, +. int bfd_line); +. +*/ + +/* Note the use of bfd_ prefix on the parameter names above: we want to + show which one is the message and which is the version by naming the + parameters, but avoid polluting the program-using-bfd namespace as + the typedef is visible in the exported headers that the program + includes. Below, it's just for consistency. */ + +static void +_bfd_default_assert_handler (const char *bfd_formatmsg, + const char *bfd_version, + const char *bfd_file, + int bfd_line) + +{ + (*_bfd_error_handler) (bfd_formatmsg, bfd_version, bfd_file, bfd_line); +} + +/* Similar to _bfd_error_handler, a program can decide to exit on an + internal BFD error. We use a non-variadic type to simplify passing + on parameters to other functions, e.g. _bfd_error_handler. */ + +bfd_assert_handler_type _bfd_assert_handler = _bfd_default_assert_handler; + +/* +FUNCTION + bfd_set_assert_handler + +SYNOPSIS + bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type); + +DESCRIPTION + Set the BFD assert handler function. Returns the previous + function. +*/ + +bfd_assert_handler_type +bfd_set_assert_handler (bfd_assert_handler_type pnew) +{ + bfd_assert_handler_type pold; + + pold = _bfd_assert_handler; + _bfd_assert_handler = pnew; + return pold; +} + +/* +FUNCTION + bfd_get_assert_handler + +SYNOPSIS + bfd_assert_handler_type bfd_get_assert_handler (void); + +DESCRIPTION + Return the BFD assert handler function. +*/ + +bfd_assert_handler_type +bfd_get_assert_handler (void) +{ + return _bfd_assert_handler; +} /* +INODE +Miscellaneous, Memory Usage, Error reporting, BFD front end + SECTION Miscellaneous @@ -909,8 +1044,8 @@ bfd_set_file_flags (bfd *abfd, flagword flags) void bfd_assert (const char *file, int line) { - (*_bfd_error_handler) (_("BFD %s assertion fail %s:%d"), - BFD_VERSION_STRING, file, line); + (*_bfd_assert_handler) (_("BFD %s assertion fail %s:%d"), + BFD_VERSION_STRING, file, line); } /* A more or less friendly abort message. In libbfd.h abort is @@ -939,9 +1074,11 @@ SYNOPSIS int bfd_get_arch_size (bfd *abfd); DESCRIPTION - Returns the architecture address size, in bits, as determined - by the object file's format. For ELF, this information is - included in the header. + Returns the normalized architecture address size, in bits, as + determined by the object file's format. By normalized, we mean + either 32 or 64. For ELF, this information is included in the + header. Use bfd_arch_bits_per_address for number of bits in + the architecture address. RETURNS Returns the arch size in bits if known, <<-1>> otherwise. @@ -953,7 +1090,7 @@ bfd_get_arch_size (bfd *abfd) if (abfd->xvec->flavour == bfd_target_elf_flavour) return get_elf_backend_data (abfd)->s->arch_size; - return -1; + return bfd_arch_bits_per_address (abfd) > 32 ? 64 : 32; } /* @@ -998,9 +1135,13 @@ bfd_get_sign_extend_vma (bfd *abfd) || strcmp (name, "pe-x86-64") == 0 || strcmp (name, "pei-x86-64") == 0 || strcmp (name, "pe-arm-wince-little") == 0 - || strcmp (name, "pei-arm-wince-little") == 0) + || strcmp (name, "pei-arm-wince-little") == 0 + || strcmp (name, "aixcoff-rs6000") == 0) return 1; + if (CONST_STRNEQ (name, "mach-o")) + return 0; + bfd_set_error (bfd_error_wrong_format); return -1; } @@ -1303,7 +1444,12 @@ DESCRIPTION . .#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ . BFD_SEND (abfd, _bfd_find_nearest_line, \ -. (abfd, sec, syms, off, file, func, line)) +. (abfd, syms, sec, off, file, func, line, NULL)) +. +.#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ +. line, disc) \ +. BFD_SEND (abfd, _bfd_find_nearest_line, \ +. (abfd, syms, sec, off, file, func, line, disc)) . .#define bfd_find_line(abfd, syms, sym, file, line) \ . BFD_SEND (abfd, _bfd_find_line, \ @@ -1337,6 +1483,9 @@ DESCRIPTION .#define bfd_gc_sections(abfd, link_info) \ . BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) . +.#define bfd_lookup_section_flags(link_info, flag_info, section) \ +. BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section)) +. .#define bfd_merge_sections(abfd, link_info) \ . BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) . @@ -1349,9 +1498,6 @@ DESCRIPTION .#define bfd_link_hash_table_create(abfd) \ . BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) . -.#define bfd_link_hash_table_free(abfd, hash) \ -. BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) -. .#define bfd_link_add_symbols(abfd, info) \ . BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) . @@ -1438,7 +1584,7 @@ bfd_record_phdr (bfd *abfd, amt = sizeof (struct elf_segment_map); amt += ((bfd_size_type) count - 1) * sizeof (asection *); - m = bfd_zalloc (abfd, amt); + m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); if (m == NULL) return FALSE; @@ -1453,7 +1599,7 @@ bfd_record_phdr (bfd *abfd, if (count > 0) memcpy (m->sections, secs, count * sizeof (asection *)); - for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next) + for (pm = &elf_seg_map (abfd); *pm != NULL; pm = &(*pm)->next) ; *pm = m; @@ -1472,9 +1618,8 @@ is32bit (bfd *abfd) return bed->s->elfclass == ELFCLASS32; } - /* For non-ELF, make a guess based on the target name. */ - return (strstr (bfd_get_target (abfd), "64") == NULL - && strcmp (bfd_get_target (abfd), "mmo") != 0); + /* For non-ELF targets, use architecture information. */ + return bfd_arch_bits_per_address (abfd) <= 32; } #endif @@ -1561,128 +1706,6 @@ bfd_alt_mach_code (bfd *abfd, int alternative) } /* -CODE_FRAGMENT - -.struct bfd_preserve -.{ -. void *marker; -. void *tdata; -. flagword flags; -. const struct bfd_arch_info *arch_info; -. struct bfd_section *sections; -. struct bfd_section *section_last; -. unsigned int section_count; -. struct bfd_hash_table section_htab; -.}; -. -*/ - -/* -FUNCTION - bfd_preserve_save - -SYNOPSIS - bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); - -DESCRIPTION - When testing an object for compatibility with a particular - target back-end, the back-end object_p function needs to set - up certain fields in the bfd on successfully recognizing the - object. This typically happens in a piecemeal fashion, with - failures possible at many points. On failure, the bfd is - supposed to be restored to its initial state, which is - virtually impossible. However, restoring a subset of the bfd - state works in practice. This function stores the subset and - reinitializes the bfd. - -*/ - -bfd_boolean -bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve) -{ - preserve->tdata = abfd->tdata.any; - preserve->arch_info = abfd->arch_info; - preserve->flags = abfd->flags; - preserve->sections = abfd->sections; - preserve->section_last = abfd->section_last; - preserve->section_count = abfd->section_count; - preserve->section_htab = abfd->section_htab; - - if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc, - sizeof (struct section_hash_entry))) - return FALSE; - - abfd->tdata.any = NULL; - abfd->arch_info = &bfd_default_arch_struct; - abfd->flags &= BFD_IN_MEMORY; - abfd->sections = NULL; - abfd->section_last = NULL; - abfd->section_count = 0; - - return TRUE; -} - -/* -FUNCTION - bfd_preserve_restore - -SYNOPSIS - void bfd_preserve_restore (bfd *, struct bfd_preserve *); - -DESCRIPTION - This function restores bfd state saved by bfd_preserve_save. - If MARKER is non-NULL in struct bfd_preserve then that block - and all subsequently bfd_alloc'd memory is freed. - -*/ - -void -bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve) -{ - bfd_hash_table_free (&abfd->section_htab); - - abfd->tdata.any = preserve->tdata; - abfd->arch_info = preserve->arch_info; - abfd->flags = preserve->flags; - abfd->section_htab = preserve->section_htab; - abfd->sections = preserve->sections; - abfd->section_last = preserve->section_last; - abfd->section_count = preserve->section_count; - - /* bfd_release frees all memory more recently bfd_alloc'd than - its arg, as well as its arg. */ - if (preserve->marker != NULL) - { - bfd_release (abfd, preserve->marker); - preserve->marker = NULL; - } -} - -/* -FUNCTION - bfd_preserve_finish - -SYNOPSIS - void bfd_preserve_finish (bfd *, struct bfd_preserve *); - -DESCRIPTION - This function should be called when the bfd state saved by - bfd_preserve_save is no longer needed. ie. when the back-end - object_p function returns with success. - -*/ - -void -bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve) -{ - /* It would be nice to be able to free more memory here, eg. old - tdata, but that's not possible since these blocks are sitting - inside bfd_alloc'd memory. The section hash is on a separate - objalloc. */ - bfd_hash_table_free (&preserve->section_htab); -} - -/* FUNCTION bfd_emul_get_maxpagesize @@ -1694,8 +1717,7 @@ DESCRIPTION emulation. RETURNS - Returns the maximum page size in bytes for ELF, abort - otherwise. + Returns the maximum page size in bytes for ELF, 0 otherwise. */ bfd_vma @@ -1708,7 +1730,6 @@ bfd_emul_get_maxpagesize (const char *emul) && target->flavour == bfd_target_elf_flavour) return xvec_get_elf_backend_data (target)->maxpagesize; - abort (); return 0; } @@ -1767,7 +1788,7 @@ DESCRIPTION emulation. RETURNS - Returns the common page size in bytes for ELF, abort otherwise. + Returns the common page size in bytes for ELF, 0 otherwise. */ bfd_vma @@ -1780,7 +1801,6 @@ bfd_emul_get_commonpagesize (const char *emul) && target->flavour == bfd_target_elf_flavour) return xvec_get_elf_backend_data (target)->commonpagesize; - abort (); return 0; } @@ -1852,7 +1872,7 @@ bfd_demangle (bfd *abfd, const char *name, int options) suf = strchr (name, '@'); if (suf != NULL) { - alloc = bfd_malloc (suf - name + 1); + alloc = (char *) bfd_malloc (suf - name + 1); if (alloc == NULL) return NULL; memcpy (alloc, name, suf - name); @@ -1870,7 +1890,7 @@ bfd_demangle (bfd *abfd, const char *name, int options) if (skip_lead) { size_t len = strlen (pre) + 1; - alloc = bfd_malloc (len); + alloc = (char *) bfd_malloc (len); if (alloc == NULL) return NULL; memcpy (alloc, pre, len); @@ -1890,7 +1910,7 @@ bfd_demangle (bfd *abfd, const char *name, int options) if (suf == NULL) suf = res + len; suf_len = strlen (suf) + 1; - final = bfd_malloc (pre_len + len + suf_len); + final = (char *) bfd_malloc (pre_len + len + suf_len); if (final != NULL) { memcpy (final, pre, pre_len);