binutils-gdb/binutils/rddbg.c
Ian Lance Taylor e1c145993e Implement generic debugging support. Implement a stabs reader and
a generic printer.
	* budbg.h, debug.c, debug.h, prdbg.c, rddbg.c, stabs.c: New files.
	* objdump.c: Include "debug.h" and "budbg.h".
	(dump_debugging): New global variable.
	(usage): Mention --debugging.
	(long_options): Add "debugging".
	(display_bfd): Handle --debugging.
	* Makefile.in (OBJDUMP_OBJS): New variable.
	($(OBJDUMP_PROG)): Use $(OBJDUMP_OBJS).
	* binutils.texi, objdump.1: Document --debugging.
1996-01-02 22:48:58 +00:00

196 lines
4.9 KiB
C

/* rddbg.c -- Read debugging information into a generic form.
Copyright (C) 1995 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>.
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This file reads debugging information into a generic form. This
file knows how to dig the debugging information out of an object
file. */
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "debug.h"
#include "budbg.h"
static boolean read_section_stabs_debugging_info
PARAMS ((bfd *, PTR, boolean *));
/* Read debugging information from a BFD. Returns a generic debugging
pointer. */
PTR
read_debugging_info (abfd)
bfd *abfd;
{
PTR dhandle;
boolean found;
dhandle = debug_init ();
if (dhandle == NULL)
return NULL;
/* All we know about right now is stabs in sections. */
if (! read_section_stabs_debugging_info (abfd, dhandle, &found))
return NULL;
if (! found)
{
fprintf (stderr, "%s: no recognized debugging information\n",
bfd_get_filename (abfd));
return NULL;
}
return dhandle;
}
/* Read stabs in sections debugging information from a BFD. */
static boolean
read_section_stabs_debugging_info (abfd, dhandle, pfound)
bfd *abfd;
PTR dhandle;
boolean *pfound;
{
static struct
{
const char *secname;
const char *strsecname;
} names[] = { { ".stab", ".stabstr" } };
unsigned int i;
PTR shandle;
*pfound = false;
shandle = NULL;
for (i = 0; i < sizeof names / sizeof names[0]; i++)
{
asection *sec, *strsec;
sec = bfd_get_section_by_name (abfd, names[i].secname);
strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
if (sec != NULL && strsec != NULL)
{
bfd_size_type stabsize, strsize;
bfd_byte *stabs, *strings;
bfd_byte *stab;
bfd_size_type stroff, next_stroff;
stabsize = bfd_section_size (abfd, sec);
stabs = (bfd_byte *) xmalloc (stabsize);
if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
{
fprintf (stderr, "%s: %s: %s\n",
bfd_get_filename (abfd), names[i].secname,
bfd_errmsg (bfd_get_error ()));
return false;
}
strsize = bfd_section_size (abfd, strsec);
strings = (bfd_byte *) xmalloc (strsize);
if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
{
fprintf (stderr, "%s: %s: %s\n",
bfd_get_filename (abfd), names[i].strsecname,
bfd_errmsg (bfd_get_error ()));
return false;
}
if (shandle == NULL)
{
shandle = start_stab (dhandle);
if (shandle == NULL)
return false;
}
*pfound = true;
stroff = 0;
next_stroff = 0;
for (stab = stabs; stab < stabs + stabsize; stab += 12)
{
bfd_size_type strx;
int type;
int other;
int desc;
bfd_vma value;
/* This code presumes 32 bit values. */
strx = bfd_get_32 (abfd, stab);
type = bfd_get_8 (abfd, stab + 4);
other = bfd_get_8 (abfd, stab + 5);
desc = bfd_get_16 (abfd, stab + 6);
value = bfd_get_32 (abfd, stab + 8);
if (type == 0)
{
/* Special type 0 stabs indicate the offset to the
next string table. */
stroff = next_stroff;
next_stroff += value;
}
else
{
char *f, *s;
f = NULL;
s = (char *) strings + stroff + strx;
while (s[strlen (s) - 1] == '\\'
&& stab + 12 < stabs + stabsize)
{
stab += 12;
s[strlen (s) - 1] = '\0';
s = concat (s,
((char *) strings
+ stroff
+ bfd_get_32 (abfd, stab)),
(const char *) NULL);
if (f != NULL)
free (f);
f = s;
}
if (! parse_stab (dhandle, shandle, type, desc, value, s))
return false;
/* Don't free f, since I think the stabs code
expects strings to hang around. This should be
straightened out. FIXME. */
}
}
free (stabs);
/* Don't free strings, since I think the stabs code expects
the strings to hang around. This should be straightened
out. FIXME. */
}
}
if (shandle != NULL)
{
if (! finish_stab (dhandle, shandle))
return false;
}
return true;
}