/* Return a new BFD. All BFD's are allocated through this routine. */
bfd *
-_bfd_new_bfd ()
+_bfd_new_bfd (void)
{
bfd *nbfd;
- nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd));
+ nbfd = bfd_zmalloc (sizeof (bfd));
if (nbfd == NULL)
return NULL;
nbfd->id = _bfd_id_counter++;
- nbfd->memory = (PTR) objalloc_create ();
+ nbfd->memory = objalloc_create ();
if (nbfd->memory == NULL)
{
bfd_set_error (bfd_error_no_memory);
free (nbfd);
return NULL;
}
- nbfd->sections = (asection *) NULL;
+ nbfd->sections = NULL;
nbfd->section_tail = &nbfd->sections;
nbfd->format = bfd_unknown;
- nbfd->my_archive = (bfd *) NULL;
+ nbfd->my_archive = NULL;
nbfd->origin = 0;
nbfd->opened_once = FALSE;
nbfd->output_has_begun = FALSE;
nbfd->section_count = 0;
- nbfd->usrdata = (PTR) NULL;
+ nbfd->usrdata = NULL;
nbfd->cacheable = FALSE;
nbfd->flags = BFD_NO_FLAGS;
nbfd->mtime_set = FALSE;
/* Allocate a new BFD as a member of archive OBFD. */
bfd *
-_bfd_new_bfd_contained_in (obfd)
- bfd *obfd;
+_bfd_new_bfd_contained_in (bfd *obfd)
{
bfd *nbfd;
/* Delete a BFD. */
void
-_bfd_delete_bfd (abfd)
- bfd *abfd;
+_bfd_delete_bfd (bfd *abfd)
{
bfd_hash_table_free (&abfd->section_htab);
objalloc_free ((struct objalloc *) abfd->memory);
bfd_openr
SYNOPSIS
- bfd *bfd_openr(const char *filename, const char *target);
+ bfd *bfd_openr (const char *filename, const char *target);
DESCRIPTION
Open the file @var{filename} (using <<fopen>>) with the target
*/
bfd *
-bfd_openr (filename, target)
- const char *filename;
- const char *target;
+bfd_openr (const char *filename, const char *target)
{
bfd *nbfd;
const bfd_target *target_vec;
bfd_fdopenr
SYNOPSIS
- bfd *bfd_fdopenr(const char *filename, const char *target, int fd);
+ bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
DESCRIPTION
<<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
*/
bfd *
-bfd_fdopenr (filename, target, fd)
- const char *filename;
- const char *target;
- int fd;
+bfd_fdopenr (const char *filename, const char *target, int fd)
{
bfd *nbfd;
const bfd_target *target_vec;
}
#ifndef HAVE_FDOPEN
- nbfd->iostream = (PTR) fopen (filename, FOPEN_RB);
+ nbfd->iostream = fopen (filename, FOPEN_RB);
#else
/* (O_ACCMODE) parens are to avoid Ultrix header file bug. */
switch (fdflags & (O_ACCMODE))
{
- case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
- case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
- case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
+ case O_RDONLY: nbfd->iostream = fdopen (fd, FOPEN_RB); break;
+ case O_WRONLY: nbfd->iostream = fdopen (fd, FOPEN_RUB); break;
+ case O_RDWR: nbfd->iostream = fdopen (fd, FOPEN_RUB); break;
default: abort ();
}
#endif
bfd_openstreamr
SYNOPSIS
- bfd *bfd_openstreamr(const char *, const char *, PTR);
+ bfd *bfd_openstreamr (const char *, const char *, void *);
DESCRIPTION
*/
bfd *
-bfd_openstreamr (filename, target, streamarg)
- const char *filename;
- const char *target;
- PTR streamarg;
+bfd_openstreamr (const char *filename, const char *target, void *streamarg)
{
- FILE *stream = (FILE *) streamarg;
+ FILE *stream = streamarg;
bfd *nbfd;
const bfd_target *target_vec;
return NULL;
}
- nbfd->iostream = (PTR) stream;
+ nbfd->iostream = stream;
nbfd->filename = filename;
nbfd->direction = read_direction;
bfd_openw
SYNOPSIS
- bfd *bfd_openw(const char *filename, const char *target);
+ bfd *bfd_openw (const char *filename, const char *target);
DESCRIPTION
Create a BFD, associated with file @var{filename}, using the
*/
bfd *
-bfd_openw (filename, target)
- const char *filename;
- const char *target;
+bfd_openw (const char *filename, const char *target)
{
bfd *nbfd;
const bfd_target *target_vec;
bfd_boolean
-bfd_close (abfd)
- bfd *abfd;
+bfd_close (bfd *abfd)
{
bfd_boolean ret;
*/
bfd_boolean
-bfd_close_all_done (abfd)
- bfd *abfd;
+bfd_close_all_done (bfd *abfd)
{
bfd_boolean ret;
bfd_create
SYNOPSIS
- bfd *bfd_create(const char *filename, bfd *templ);
+ bfd *bfd_create (const char *filename, bfd *templ);
DESCRIPTION
Create a new BFD in the manner of <<bfd_openw>>, but without
*/
bfd *
-bfd_create (filename, templ)
- const char *filename;
- bfd *templ;
+bfd_create (const char *filename, bfd *templ)
{
bfd *nbfd;
*/
bfd_boolean
-bfd_make_writable(abfd)
- bfd *abfd;
+bfd_make_writable (bfd *abfd)
{
struct bfd_in_memory *bim;
return FALSE;
}
- bim = ((struct bfd_in_memory *)
- bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
- abfd->iostream = (PTR) bim;
+ bim = bfd_malloc (sizeof (struct bfd_in_memory));
+ abfd->iostream = bim;
/* bfd_bwrite will grow these as needed. */
bim->size = 0;
bim->buffer = 0;
<<TRUE>> is returned if all is ok, otherwise <<FALSE>>. */
bfd_boolean
-bfd_make_readable(abfd)
- bfd *abfd;
+bfd_make_readable (bfd *abfd)
{
if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
{
abfd->where = 0;
abfd->format = bfd_unknown;
- abfd->my_archive = (bfd *) NULL;
+ abfd->my_archive = NULL;
abfd->origin = 0;
abfd->opened_once = FALSE;
abfd->output_has_begun = FALSE;
abfd->section_count = 0;
- abfd->usrdata = (PTR) NULL;
+ abfd->usrdata = NULL;
abfd->cacheable = FALSE;
abfd->flags = BFD_IN_MEMORY;
abfd->mtime_set = FALSE;
bfd_alloc
SYNOPSIS
- PTR bfd_alloc (bfd *abfd, size_t wanted);
+ void *bfd_alloc (bfd *abfd, size_t wanted);
DESCRIPTION
Allocate a block of @var{wanted} bytes of memory attached to
*/
-PTR
-bfd_alloc (abfd, size)
- bfd *abfd;
- bfd_size_type size;
+void *
+bfd_alloc (bfd *abfd, bfd_size_type size)
{
- PTR ret;
+ void *ret;
if (size != (unsigned long) size)
{
return ret;
}
-PTR
-bfd_zalloc (abfd, size)
- bfd *abfd;
- bfd_size_type size;
+void *
+bfd_zalloc (bfd *abfd, bfd_size_type size)
{
- PTR res;
+ void *res;
res = bfd_alloc (abfd, size);
if (res)
Note: Also frees all more recently allocated blocks! */
void
-bfd_release (abfd, block)
- bfd *abfd;
- PTR block;
+bfd_release (bfd *abfd, void *block)
{
objalloc_free_block ((struct objalloc *) abfd->memory, block);
}
without debug symbols).
*/
-static unsigned long calc_crc32 PARAMS ((unsigned long, const unsigned char *, size_t));
-static char * get_debug_link_info PARAMS ((bfd *, unsigned long *));
-static bfd_boolean separate_debug_file_exists PARAMS ((const char *, const unsigned long));
-static char * find_separate_debug_file PARAMS ((bfd *, const char *));
-
+#define GNU_DEBUGLINK ".gnu_debuglink"
/*
-INTERNAL_FUNCTION
- calc_crc32
+FUNCTION
+ bfd_calc_gnu_debuglink_crc32
SYNOPSIS
- unsigned long calc_crc32 (unsigned long crc, const unsigned char *buf, size_t len);
+ unsigned long bfd_calc_gnu_debuglink_crc32
+ (unsigned long crc, const unsigned char *buf, bfd_size_type len);
DESCRIPTION
- Advance the CRC32 given by @var{crc} through @var{len}
- bytes of @var{buf}. Return the updated CRC32 value.
+ Computes a CRC value as used in the .gnu_debuglink section.
+ Advances the previously computed @var{crc} value by computing
+ and adding in the crc32 for @var{len} bytes of @var{buf}.
+
+RETURNS
+ Return the updated CRC32 value.
*/
-static unsigned long
-calc_crc32 (crc, buf, len)
- unsigned long crc;
- const unsigned char *buf;
- size_t len;
+unsigned long
+bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
+ const unsigned char *buf,
+ bfd_size_type len)
{
static const unsigned long crc32_table[256] =
{
get_debug_link_info
SYNOPSIS
- char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
+ char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
DESCRIPTION
fetch the filename and CRC32 value for any separate debuginfo
*/
static char *
-get_debug_link_info (abfd, crc32_out)
- bfd *abfd;
- unsigned long *crc32_out;
+get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
{
asection * sect;
bfd_size_type debuglink_size;
BFD_ASSERT (abfd);
BFD_ASSERT (crc32_out);
- sect = bfd_get_section_by_name (abfd, ".gnu_debuglink");
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
if (sect == NULL)
return NULL;
debuglink_size = bfd_section_size (abfd, sect);
- contents = xmalloc (debuglink_size);
- ret = bfd_get_section_contents (abfd, sect, contents,
- (file_ptr)0, debuglink_size);
+ contents = malloc (debuglink_size);
+ if (contents == NULL)
+ return NULL;
+
+ ret = bfd_get_section_contents (abfd, sect, contents, 0, debuglink_size);
if (! ret)
{
free (contents);
crc_offset = strlen (contents) + 1;
crc_offset = (crc_offset + 3) & ~3;
- crc32 = bfd_get_32 (abfd, (bfd_byte *) (contents + crc_offset));
+ crc32 = bfd_get_32 (abfd, contents + crc_offset);
*crc32_out = crc32;
return contents;
separate_debug_file_exists
SYNOPSIS
- bfd_boolean separate_debug_file_exists (char * name, unsigned long crc32)
+ bfd_boolean separate_debug_file_exists
+ (char *name, unsigned long crc32);
DESCRIPTION
Checks to see if @var{name} is a file and if its contents
*/
static bfd_boolean
-separate_debug_file_exists (name, crc)
- const char *name;
- const unsigned long crc;
+separate_debug_file_exists (const char *name, const unsigned long crc)
{
static char buffer [8 * 1024];
unsigned long file_crc = 0;
int fd;
- int count;
+ bfd_size_type count;
BFD_ASSERT (name);
return FALSE;
while ((count = read (fd, buffer, sizeof (buffer))) > 0)
- file_crc = calc_crc32 (file_crc, buffer, count);
+ file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
close (fd);
find_separate_debug_file
SYNOPSIS
- char * find_separate_debug_file (bfd *abfd)
+ char *find_separate_debug_file (bfd *abfd);
DESCRIPTION
Searches @var{abfd} for a reference to separate debugging
*/
static char *
-find_separate_debug_file (abfd, debug_file_directory)
- bfd *abfd;
- const char *debug_file_directory;
+find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
{
char *basename;
char *dir;
return NULL;
basename = get_debug_link_info (abfd, & crc32);
-
- if (basename == NULL || strlen (basename) < 1)
+ if (basename == NULL)
return NULL;
- dir = xstrdup (abfd->filename);
+ if (strlen (basename) < 1)
+ {
+ free (basename);
+ return NULL;
+ }
+
+ dir = strdup (abfd->filename);
+ if (dir == NULL)
+ {
+ free (basename);
+ return NULL;
+ }
BFD_ASSERT (strlen (dir) != 0);
/* Strip off filename part. */
dir[i + 1] = '\0';
BFD_ASSERT (dir[i] == '/' || dir[0] == '\0')
- debugfile = xmalloc (strlen (debug_file_directory) + 1
- + strlen (dir)
- + strlen (".debug/")
- + strlen (basename)
- + 1);
+ debugfile = malloc (strlen (debug_file_directory) + 1
+ + strlen (dir)
+ + strlen (".debug/")
+ + strlen (basename)
+ + 1);
+ if (debugfile == NULL)
+ {
+ free (basename);
+ free (dir);
+ return NULL;
+ }
/* First try in the same directory as the original file: */
strcpy (debugfile, dir);
bfd_follow_gnu_debuglink
SYNOPSIS
- char * bfd_follow_gnu_debuglink(bfd *abfd, const char *dir);
+ char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
DESCRIPTION
*/
char *
-bfd_follow_gnu_debuglink (abfd, dir)
- bfd *abfd;
- const char * dir;
+bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
{
#if 0 /* Disabled until DEBUGDIR can be defined by configure.in */
if (dir == NULL)
#endif
return find_separate_debug_file (abfd, dir);
}
+
+/*
+FUNCTION
+ bfd_create_gnu_debuglink_section
+
+SYNOPSIS
+ struct bfd_section *bfd_create_gnu_debuglink_section
+ (bfd *abfd, const char *filename);
+
+DESCRIPTION
+
+ Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized
+ to be big enough to contain a link to the specified @var{filename}.
+
+RETURNS
+ A pointer to the new section is returned if all is ok. Otherwise <<NULL>> is
+ returned and bfd_error is set.
+*/
+
+asection *
+bfd_create_gnu_debuglink_section (bfd *abfd, const char *filename)
+{
+ asection *sect;
+ bfd_size_type debuglink_size;
+
+ if (abfd == NULL || filename == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ /* Strip off any path components in filename. */
+ filename = lbasename (filename);
+
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
+ if (sect)
+ {
+ /* Section already exists. */
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ sect = bfd_make_section (abfd, GNU_DEBUGLINK);
+ if (sect == NULL)
+ return NULL;
+
+ if (! bfd_set_section_flags (abfd, sect,
+ SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING))
+ /* XXX Should we delete the section from the bfd ? */
+ return NULL;
+
+
+ debuglink_size = strlen (filename) + 1;
+ debuglink_size += 3;
+ debuglink_size &= ~3;
+ debuglink_size += 4;
+
+ if (! bfd_set_section_size (abfd, sect, debuglink_size))
+ /* XXX Should we delete the section from the bfd ? */
+ return NULL;
+
+ return sect;
+}
+
+
+/*
+FUNCTION
+ bfd_fill_in_gnu_debuglink_section
+
+SYNOPSIS
+ bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+
+DESCRIPTION
+
+ Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
+ and fills in the contents of the section to contain a link to the
+ specified @var{filename}. The filename should be relative to the
+ current directory.
+
+RETURNS
+ <<TRUE>> is returned if all is ok. Otherwise <<FALSE>> is returned
+ and bfd_error is set.
+*/
+
+bfd_boolean
+bfd_fill_in_gnu_debuglink_section (bfd *abfd,
+ struct bfd_section *sect,
+ const char *filename)
+{
+ bfd_size_type debuglink_size;
+ unsigned long crc32;
+ char * contents;
+ bfd_size_type crc_offset;
+ FILE * handle;
+ static char buffer[8 * 1024];
+ size_t count;
+
+ if (abfd == NULL || sect == NULL || filename == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* Make sure that we can read the file.
+ XXX - Should we attempt to locate the debug info file using the same
+ algorithm as gdb ? At the moment, since we are creating the
+ .gnu_debuglink section, we insist upon the user providing us with a
+ correct-for-section-creation-time path, but this need not conform to
+ the gdb location algorithm. */
+ handle = fopen (filename, FOPEN_RB);
+ if (handle == NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+ }
+
+ crc32 = 0;
+ while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0)
+ crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count);
+ fclose (handle);
+
+ /* Strip off any path components in filename,
+ now that we no longer need them. */
+ filename = lbasename (filename);
+
+ debuglink_size = strlen (filename) + 1;
+ debuglink_size += 3;
+ debuglink_size &= ~3;
+ debuglink_size += 4;
+
+ contents = malloc (debuglink_size);
+ if (contents == NULL)
+ {
+ /* XXX Should we delete the section from the bfd ? */
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+
+ strcpy (contents, filename);
+ crc_offset = debuglink_size - 4;
+
+ bfd_put_32 (abfd, crc32, contents + crc_offset);
+
+ if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
+ {
+ /* XXX Should we delete the section from the bfd ? */
+ free (contents);
+ return FALSE;
+ }
+
+ return TRUE;
+}