+RETURNS
+ <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
+*/
+
+bfd_boolean
+bfd_make_writable(abfd)
+ bfd *abfd;
+{
+ struct bfd_in_memory *bim;
+
+ if (abfd->direction != no_direction)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ bim = ((struct bfd_in_memory *)
+ bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
+ abfd->iostream = (PTR) bim;
+ /* bfd_bwrite will grow these as needed. */
+ bim->size = 0;
+ bim->buffer = 0;
+
+ abfd->flags |= BFD_IN_MEMORY;
+ abfd->direction = write_direction;
+ abfd->where = 0;
+
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_make_readable
+
+SYNOPSIS
+ bfd_boolean bfd_make_readable (bfd *abfd);
+
+DESCRIPTION
+ Takes a BFD as created by <<bfd_create>> and
+ <<bfd_make_writable>> and converts it into one like as
+ returned by <<bfd_openr>>. It does this by writing the
+ contents out to the memory buffer, then reversing the
+ direction.
+
+RETURNS
+ <<TRUE>> is returned if all is ok, otherwise <<FALSE>>. */
+
+bfd_boolean
+bfd_make_readable(abfd)
+ bfd *abfd;
+{
+ if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
+ return FALSE;
+
+ if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
+ return FALSE;
+
+
+ abfd->arch_info = &bfd_default_arch_struct;
+
+ abfd->where = 0;
+ abfd->format = bfd_unknown;
+ abfd->my_archive = (bfd *) NULL;
+ abfd->origin = 0;
+ abfd->opened_once = FALSE;
+ abfd->output_has_begun = FALSE;
+ abfd->section_count = 0;
+ abfd->usrdata = (PTR) NULL;
+ abfd->cacheable = FALSE;
+ abfd->flags = BFD_IN_MEMORY;
+ abfd->mtime_set = FALSE;
+
+ abfd->target_defaulted = TRUE;
+ abfd->direction = read_direction;
+ abfd->sections = 0;
+ abfd->symcount = 0;
+ abfd->outsymbols = 0;
+ abfd->tdata.any = 0;
+
+ bfd_section_list_clear (abfd);
+ bfd_check_format (abfd, bfd_object);
+
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_alloc
+
+SYNOPSIS
+ PTR bfd_alloc (bfd *abfd, size_t wanted);
+
+DESCRIPTION
+ Allocate a block of @var{wanted} bytes of memory attached to
+ <<abfd>> and return a pointer to it.
+*/
+
+
+PTR
+bfd_alloc (abfd, size)
+ bfd *abfd;
+ bfd_size_type size;
+{
+ PTR ret;
+
+ if (size != (unsigned long) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ ret = objalloc_alloc (abfd->memory, (unsigned long) size);
+ if (ret == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
+}
+
+PTR
+bfd_zalloc (abfd, size)
+ bfd *abfd;
+ bfd_size_type size;
+{
+ PTR res;
+
+ res = bfd_alloc (abfd, size);
+ if (res)
+ memset (res, 0, (size_t) size);
+ return res;
+}
+
+/* Free a block allocated for a BFD.
+ Note: Also frees all more recently allocated blocks! */
+
+void
+bfd_release (abfd, block)
+ bfd *abfd;
+ PTR block;
+{
+ objalloc_free_block ((struct objalloc *) abfd->memory, block);