+/*
+FUNCTION
+ bfd_get_size
+
+SYNOPSIS
+ long bfd_get_size(bfd *abfd);
+
+DESCRIPTION
+ Return the file size (as read from file system) for the file
+ associated with BFD @var{abfd}.
+
+ The initial motivation for, and use of, this routine is not
+ so we can get the exact size of the object the BFD applies to, since
+ that might not be generally possible (archive members for example).
+ It would be ideal if someone could eventually modify
+ it so that such results were guaranteed.
+
+ Instead, we want to ask questions like "is this NNN byte sized
+ object I'm about to try read from file offset YYY reasonable?"
+ As as example of where we might do this, some object formats
+ use string tables for which the first <<sizeof (long)>> bytes of the
+ table contain the size of the table itself, including the size bytes.
+ If an application tries to read what it thinks is one of these
+ string tables, without some way to validate the size, and for
+ some reason the size is wrong (byte swapping error, wrong location
+ for the string table, etc.), the only clue is likely to be a read
+ error when it tries to read the table, or a "virtual memory
+ exhausted" error when it tries to allocate 15 bazillon bytes
+ of space for the 15 bazillon byte table it is about to read.
+ This function at least allows us to answer the quesion, "is the
+ size reasonable?".
+*/
+
+long
+bfd_get_size (abfd)
+ bfd *abfd;
+{
+ FILE *fp;
+ struct stat buf;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ return ((struct bfd_in_memory *) abfd->iostream)->size;
+
+ fp = bfd_cache_lookup (abfd);
+ if (0 != fstat (fileno (fp), &buf))
+ return 0;
+
+ return buf.st_size;
+}
+
+/*
+FUNCTION
+ bfd_get_gp_size
+
+SYNOPSIS
+ int bfd_get_gp_size(bfd *abfd);
+
+DESCRIPTION
+ Return the maximum size of objects to be optimized using the GP
+ register under MIPS ECOFF. This is typically set by the <<-G>>
+ argument to the compiler, assembler or linker.
+*/
+
+int
+bfd_get_gp_size (abfd)
+ bfd *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;
+}
+
+/*
+FUNCTION
+ bfd_set_gp_size
+
+SYNOPSIS
+ void bfd_set_gp_size(bfd *abfd, int i);
+
+DESCRIPTION
+ Set the maximum size of objects to be optimized using the GP
+ register under ECOFF or MIPS ELF. This is typically set by
+ the <<-G>> argument to the compiler, assembler or linker.
+*/
+
+void
+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)
+ elf_gp_size (abfd) = i;
+}
+
+/* Get the GP value. This is an internal function used by some of the
+ relocation special_function routines on targets which support a GP
+ register. */
+
+bfd_vma
+_bfd_get_gp_value (abfd)
+ bfd *abfd;
+{
+ if (abfd->format == bfd_object)
+ {
+ if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+ return ecoff_data (abfd)->gp;
+ else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ return elf_gp (abfd);
+ }
+ return 0;
+}
+
+/* Set the GP value. */
+
+void
+_bfd_set_gp_value (abfd, v)
+ bfd *abfd;
+ bfd_vma v;
+{
+ if (abfd->format != bfd_object)
+ return;
+ if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+ ecoff_data (abfd)->gp = v;
+ else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ elf_gp (abfd) = v;
+}
+
+/*
+FUNCTION
+ bfd_scan_vma
+
+SYNOPSIS
+ bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
+
+DESCRIPTION
+ Convert, like <<strtoul>>, a numerical expression
+ @var{string} into a <<bfd_vma>> integer, and return that integer.
+ (Though without as many bells and whistles as <<strtoul>>.)
+ The expression is assumed to be unsigned (i.e., positive).
+ If given a @var{base}, it is used as the base for conversion.
+ A base of 0 causes the function to interpret the string
+ in hex if a leading "0x" or "0X" is found, otherwise
+ in octal if a leading zero is found, otherwise in decimal.
+
+ Overflow is not detected.
+*/
+
+bfd_vma
+bfd_scan_vma (string, end, base)
+ CONST char *string;
+ CONST char **end;
+ int base;
+{
+ bfd_vma value;
+ int digit;
+
+ /* Let the host do it if possible. */
+ if (sizeof (bfd_vma) <= sizeof (unsigned long))
+ return (bfd_vma) strtoul (string, (char **) end, base);
+
+ /* A negative base makes no sense, and we only need to go as high as hex. */
+ if ((base < 0) || (base > 16))
+ return (bfd_vma) 0;
+
+ if (base == 0)
+ {
+ if (string[0] == '0')
+ {
+ if ((string[1] == 'x') || (string[1] == 'X'))
+ base = 16;
+ /* XXX should we also allow "0b" or "0B" to set base to 2? */
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+ if ((base == 16) &&
+ (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
+ string += 2;
+ /* XXX should we also skip over "0b" or "0B" if base is 2? */
+
+/* Speed could be improved with a table like hex_value[] in gas. */
+#define HEX_VALUE(c) \
+ (isxdigit ((unsigned char) c) \
+ ? (isdigit ((unsigned char) c) \
+ ? (c - '0') \
+ : (10 + c - (islower ((unsigned char) c) ? 'a' : 'A'))) \
+ : 42)
+
+ for (value = 0; (digit = HEX_VALUE(*string)) < base; string++)
+ {
+ value = value * base + digit;
+ }
+
+ if (end)
+ *end = string;
+
+ return value;
+}
+
+/*
+FUNCTION
+ bfd_copy_private_bfd_data
+
+SYNOPSIS
+ boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd);
+
+DESCRIPTION
+ Copy private BFD information from the BFD @var{ibfd} to the
+ the BFD @var{obfd}. Return <<true>> on success, <<false>> on error.
+ Possible error returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}.
+
+.#define bfd_copy_private_bfd_data(ibfd, obfd) \
+. BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+. (ibfd, obfd))
+
+*/
+
+/*
+FUNCTION
+ bfd_merge_private_bfd_data
+
+SYNOPSIS
+ boolean bfd_merge_private_bfd_data(bfd *ibfd, bfd *obfd);
+
+DESCRIPTION
+ Merge private BFD information from the BFD @var{ibfd} to the
+ the output file BFD @var{obfd} when linking. Return <<true>>
+ on success, <<false>> on error. Possible error returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}.
+
+.#define bfd_merge_private_bfd_data(ibfd, obfd) \
+. BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+. (ibfd, obfd))
+
+*/
+
+/*
+FUNCTION
+ bfd_set_private_flags
+
+SYNOPSIS
+ boolean bfd_set_private_flags(bfd *abfd, flagword flags);
+
+DESCRIPTION
+ Set private BFD flag information in the BFD @var{abfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}.
+
+.#define bfd_set_private_flags(abfd, flags) \
+. BFD_SEND (abfd, _bfd_set_private_flags, \
+. (abfd, flags))
+
+*/
+