diff options
Diffstat (limited to 'bfd/bfd.c')
-rw-r--r-- | bfd/bfd.c | 202 |
1 files changed, 155 insertions, 47 deletions
@@ -1,5 +1,5 @@ /* Generic BFD library interface and support routines. - Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -191,18 +191,56 @@ CODE_FRAGMENT #undef obj_symbols #include "libelf.h" -#undef strerror -extern char *strerror(); + +/* +SECTION + Error reporting + + Most BFD functions return nonzero on success (check their + individual documentation for precise semantics). On an error, + they call <<bfd_set_error>> to set an error condition that callers + can check by calling <<bfd_get_error>>. + If that returns <<bfd_error_system_call>>, then check + <<errno>>. -/** Error handling - o - Most functions return nonzero on success (check doc for - precise semantics); 0 or NULL on error. - o - Internal errors are documented by the value of bfd_error. - If that is system_call_error then check errno. - o - The easiest way to report this to the user is to use bfd_perror. + The easiest way to report a BFD error to the user is to + use <<bfd_perror>>. + +SUBSECTION + Type <<bfd_error_type>> + + The values returned by <<bfd_get_error>> are defined by the + enumerated type <<bfd_error_type>>. + +CODE_FRAGMENT +. +.typedef enum bfd_error +.{ +. bfd_error_no_error = 0, +. bfd_error_system_call, +. bfd_error_invalid_target, +. bfd_error_wrong_format, +. bfd_error_invalid_operation, +. bfd_error_no_memory, +. bfd_error_no_symbols, +. bfd_error_no_more_archived_files, +. bfd_error_malformed_archive, +. bfd_error_file_not_recognized, +. bfd_error_file_ambiguously_recognized, +. bfd_error_no_contents, +. bfd_error_nonrepresentable_section, +. bfd_error_no_debug_section, +. bfd_error_bad_value, +. bfd_error_file_truncated, +. bfd_error_invalid_error_code +.} bfd_error_type; +. */ -bfd_ec bfd_error = no_error; +#undef strerror +extern char *strerror(); + +static bfd_error_type bfd_error = bfd_error_no_error; CONST char *CONST bfd_errmsgs[] = { "No error", @@ -224,40 +262,104 @@ CONST char *CONST bfd_errmsgs[] = { "#<Invalid error code>" }; +/* +FUNCTION + bfd_get_error + +SYNOPSIS + bfd_error_type bfd_get_error (void); + +DESCRIPTION + Return the current BFD error condition. +*/ + +bfd_error_type +bfd_get_error () +{ + return bfd_error; +} + +/* +FUNCTION + bfd_set_error + +SYNOPSIS + void bfd_set_error (bfd_error_type error_tag); + +DESCRIPTION + Set the BFD error condition to be @var{error_tag}. +*/ + +void +bfd_set_error (error_tag) + bfd_error_type error_tag; +{ + bfd_error = error_tag; +} + +/* +FUNCTION + bfd_errmsg + +SYNOPSIS + CONST char *bfd_errmsg (bfd_error_type error_tag); + +DESCRIPTION + Return a string describing the error @var{error_tag}, or + the system error if @var{error_tag} is <<bfd_error_system_call>>. +*/ + CONST char * bfd_errmsg (error_tag) - bfd_ec error_tag; + bfd_error_type error_tag; { #ifndef errno extern int errno; #endif - if (error_tag == system_call_error) + if (error_tag == bfd_error_system_call) return strerror (errno); - if ((((int)error_tag <(int) no_error) || - ((int)error_tag > (int)invalid_error_code))) - error_tag = invalid_error_code;/* sanity check */ + if ((((int)error_tag <(int) bfd_error_no_error) || + ((int)error_tag > (int)bfd_error_invalid_error_code))) + error_tag = bfd_error_invalid_error_code;/* sanity check */ return bfd_errmsgs [(int)error_tag]; } +/* +FUNCTION + bfd_perror + +SYNOPSIS + void bfd_perror (CONST char *message); + +DESCRIPTION + Print to the standard error stream a string describing the + last BFD error that occurred, or the last system error if + the last BFD error was a system call failure. If @var{message} + is non-NULL and non-empty, the error string printed is preceded + by @var{message}, a colon, and a space. It is followed by a newline. +*/ + void -DEFUN(bfd_perror,(message), - CONST char *message) +bfd_perror (message) + CONST char *message; { - if (bfd_error == system_call_error) + if (bfd_get_error () == bfd_error_system_call) perror((char *)message); /* must be system error then... */ else { if (message == NULL || *message == '\0') - fprintf (stderr, "%s\n", bfd_errmsg (bfd_error)); + fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ())); else - fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_error)); + fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ())); } } - -/** Symbols */ - + +/* +SECTION + Symbols +*/ /* FUNCTION @@ -275,12 +377,12 @@ DESCRIPTION unsigned int -DEFUN(bfd_get_reloc_upper_bound,(abfd, asect), - bfd *abfd AND - sec_ptr asect) +bfd_get_reloc_upper_bound (abfd, asect) + bfd *abfd; + sec_ptr asect; { if (abfd->format != bfd_object) { - bfd_error = invalid_operation; + bfd_set_error (bfd_error_invalid_operation); return 0; } @@ -312,14 +414,14 @@ DESCRIPTION */ unsigned int -DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols), - bfd *abfd AND - sec_ptr asect AND - arelent **location AND - asymbol **symbols) +bfd_canonicalize_reloc (abfd, asect, location, symbols) + bfd *abfd; + sec_ptr asect; + arelent **location; + asymbol **symbols; { if (abfd->format != bfd_object) { - bfd_error = invalid_operation; + bfd_set_error (bfd_error_invalid_operation); return 0; } return BFD_SEND (abfd, _bfd_canonicalize_reloc, @@ -363,9 +465,9 @@ DESCRIPTION Set the flag word in the BFD @var{abfd} to the value @var{flags}. Possible errors are: - o <<wrong_format>> - The target bfd was not of object format. - o <<invalid_operation>> - The target bfd was open for reading. - o <<invalid_operation>> - + o <<bfd_error_wrong_format>> - The target bfd was not of object format. + o <<bfd_error_invalid_operation>> - The target bfd was open for reading. + o <<bfd_error_invalid_operation>> - The flag word contained a bit which was not applicable to the type of file. E.g., an attempt was made to set the <<D_PAGED>> bit on a BFD format which does not support demand paging. @@ -378,18 +480,18 @@ bfd_set_file_flags (abfd, flags) flagword flags; { if (abfd->format != bfd_object) { - bfd_error = wrong_format; + bfd_set_error (bfd_error_wrong_format); return false; } if (bfd_read_p (abfd)) { - bfd_error = invalid_operation; + bfd_set_error (bfd_error_invalid_operation); return false; } bfd_get_file_flags (abfd) = flags; if ((flags & bfd_applicable_file_flags (abfd)) != flags) { - bfd_error = invalid_operation; + bfd_set_error (bfd_error_invalid_operation); return false; } @@ -524,10 +626,13 @@ int bfd_get_gp_size (abfd) bfd *abfd; { - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - return ecoff_data (abfd)->gp_size; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - return elf_gp_size (abfd); + if (abfd->format == bfd_object) + { + if (abfd->xvec->flavour == bfd_target_ecoff_flavour) + return ecoff_data (abfd)->gp_size; + else if (abfd->xvec->flavour == bfd_target_elf_flavour) + return elf_gp_size (abfd); + } return 0; } @@ -549,6 +654,9 @@ bfd_set_gp_size (abfd, i) bfd *abfd; int i; { + /* Don't try to set GP size on an archive or core file! */ + if (abfd->format != bfd_object) + return; if (abfd->xvec->flavour == bfd_target_ecoff_flavour) ecoff_data (abfd)->gp_size = i; else if (abfd->xvec->flavour == bfd_target_elf_flavour) @@ -576,10 +684,10 @@ DESCRIPTION */ bfd_vma -DEFUN(bfd_scan_vma,(string, end, base), - CONST char *string AND - CONST char **end AND - int base) +bfd_scan_vma (string, end, base) + CONST char *string; + CONST char **end; + int base; { bfd_vma value; int digit; |