This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

problems using BFD to reproduce objdump functionality (--stabs)


Hello everyone,

could you please advice me in my attempt to reproduce 'objdump --stabs xyz' functionality.

I like to extract the same information objdump delivers from executables, but don't want to parse objdump's output, so I like to use the BFD lib, but my programm's output looks different and omits the most important part (the string information / last column of 'objdump --stabs' output) and I have almost no idea why.

I am compiling on a suse linux 8.1 system with
linux kernel 2.4.19,
a Pentium 4 processor and
I do link libbfd and libiberty to my program and of course I include bfd.h.

I don't use any special compile options and gcc seems to be satisfied.

This is what the output should look like (objdump's output from a simple testfile):
.
.
318 LSYM 0 0 00000000 12677 my_date:T(0,20)=s12Tag:(0,1),0,32;Monat:(0,1),32,32;Jahr:(0,1),64,32;;
319 LSYM 0 0 00000000 12748 my_date:t(0,21)=(0,20)
320 LSYM 0 0 00000000 12771 my_time:T(0,22)=s8Minute:(0,1),0,32;Stunde:(0,1),32,32;;
321 LSYM 0 0 00000000 12828 my_time:t(0,23)=(0,22)
322 LSYM 0 0 00000000 12851 my_date_time:T(0,24)=s20Datum:(0,21),0,96;Zeit:(0,23),96,64;;
323 LSYM 0 0 00000000 12913 my_date_time:t(0,25)=(0,24)
324 FUN 0 0 08048460 12941 main:F(0,1)
.
.


This is my program's output (from the same testfile):

.
.
318    107    95     14964  2c392874 1668246638 *
319    LCSYM  48     12588  74700029 1026110002 *
320    SO     95     24930  65697272 1634038376 *
321    116    40     11321  3d293332 980705138 *
322    NOMAP  41     29501  5f5f3032 841759016 *
323    111    99     14955  312c3928 1818190178 *
324    54     52     24379  5f61625f 741354537 *
.
.

A colleague of mine thinks certain defines are maybe missing or there are more header to be include than only bfd.h.

Could you please help me with this question what is missing or point me to someone or other mailing list who can?

Thankyou very much!!
I have attached my program and beneath is my makefile.

Thanks
Roul Oldenburger


------------------ OBJS = $(patsubst %.c, %.o, $(wildcard *.c)) CFLAGS = -g -gstabs -Wall

bfd_test : $(OBJS)
        $(CC) $(CFLAGS) -o $@ $^ -lbfd -liberty

clean :
        rm *~ $(OBJS) bfd_test
#include <stdio.h>
#include <bfd.h>


#define N_UNDF  0       /* Undefined symbol */


#define STRDXOFF (0)
#define TYPEOFF (4)
#define OTHEROFF (5)
#define DESCOFF (6)
#define VALOFF (8)
#define STABSIZE (12)

static bfd_size_type sec_size;
static bfd_size_type stabstr_size;
static bfd_byte *stabs;
static char *strtab;


void print_section_stabs (bfd *abfd, char *sec_name)
{
  int i;
  unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
  bfd_byte *stabp, *stabs_end;

  stabp = stabs;
  stabs_end = stabp + sec_size;

  printf ("Contents of %s section:\n\n", sec_name);
  printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");

  /* Loop through all symbols and print them.

     We start the index at -1 because there is a dummy symbol on
     the front of stabs-in-{coff,elf} sections that supplies sizes.  */

  for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
    {
      const char *name;
      unsigned long strx;
      unsigned char type, other;
      unsigned short desc;
      bfd_vma value;

      strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
      type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
      other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
      desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
      value = bfd_h_get_32 (abfd, stabp + VALOFF);

      printf ("\n%-6d ", i);
      /* Either print the stab name, or, if unnamed, print its number
	 again (makes consistent formatting for tools like awk).  */
      name = bfd_get_stab_name (type);
      if (name != NULL)
	printf ("%-6s", name);
      else if (type == N_UNDF)
	printf ("HdrSym");
      else
	printf ("%-6d", type);
      printf (" %-6d %-6d ", other, desc);
      bfd_printf_vma (abfd, value);
      printf (" %-6lu", strx);

      /* Symbols with type == 0 (N_UNDF) specify the length of the
	 string table associated with this file.  We use that info
	 to know how to relocate the *next* file's string table indices.  */

      if (type == N_UNDF)
	{
	  file_string_table_offset = next_file_string_table_offset;
	  next_file_string_table_offset += value;
	}
      else
	{
	  /* Using the (possibly updated) string table offset, print the
	     string (if any) associated with this symbol.  */

	  if ((strx + file_string_table_offset) < stabstr_size)
	    printf (" %s", &strtab[strx + file_string_table_offset]);
	  else
	    printf (" *");
	}
    }
  printf ("\n\n");
}

void retrieve_stab(bfd *abfd, asection *section, char *sec_name)
{
  printf("Der Sektionsname ist: %s\n", sec_name);
  sec_size = bfd_section_size (abfd, section); 
  stabs  = (bfd_byte *) xmalloc (sec_size);
  printf("sec_size ist jetzt %d\n", (int) sec_size);
  if (! bfd_get_section_contents (abfd, section, (PTR) stabs, 0, sec_size))
  {
    if (sec_name == ".stab")
      free (stabs);
    bfd_errmsg( bfd_get_error() );
    return;
  }
}

void retrieve_stabstr(bfd *abfd, asection *section, char *sec_name)
{
  printf("Der Sektionsname ist: %s\n", sec_name);
  stabstr_size = bfd_section_size (abfd, section); 
  strtab = (char *) xmalloc (stabstr_size);
  printf("stabstr_size ist %d\n", (int) stabstr_size);
  if (! bfd_get_section_contents (abfd, section, (PTR) stabs, 0, sec_size))
  {
    if (sec_name == ".stabstr")
      free (strtab);
    bfd_errmsg( bfd_get_error() );
    return;
  }
}

void retrieve_section_stab(bfd *abfd, asection *section, PTR jnk)
{
  char * sec_name;
  sec_name = bfd_get_section_name (abfd, section);
  printf("sec_name vor if : %s!!\n", sec_name);
  printf("Compare zu .stab %d\n", strncmp(sec_name, ".stab", 4));
  printf("Compare zu .stabstr %d\n", strncmp(sec_name, ".stabstr", 7));
  if ( strncmp(sec_name, ".stabstr", 7)==0 )
  {
    retrieve_stabstr(abfd, section, sec_name);
  }
  else if ( strncmp(sec_name, ".stab", 4)==0 )
  {
    retrieve_stab(abfd, section, sec_name);
  }
  
  if ( (sec_size != 0) && (stabstr_size != 0) )
  {
    print_section_stabs(abfd, sec_name);
    free (stabs);
    free (strtab);
    sec_size = 0;
    stabstr_size = 0;
    return;
  }
  printf("Sektionsname: %s\n", sec_name);
  return;
}
// comment from objdump.c
/* Stabs entries use a 12 byte format:
     4 byte string table index
     1 byte stab type
     1 byte stab other field
     2 byte stab desc field
     4 byte stab value
   FIXME: This will have to change for a 64 bit object format.  */


void close_it(bfd *abfd)
{
  if (!bfd_close(abfd))
  {
    bfd_perror("Fehler beim Schliessen mit bfd_close");
    exit(1);
  }
}

boolean check_format(bfd *abfd)
{
  int x;
  char **matching;
  extern bfd_target *bfd_target_vector[];
  if (! bfd_check_format_matches(abfd, bfd_object, &matching))
  {
    printf("Unrecognized File!\n Supported targets: ");
    bfd_errmsg( bfd_get_error() );
    for ( x = 0; bfd_target_vector[x]; x++) 
    {
      bfd_target *p = bfd_target_vector[x];
      printf("%s ", p->name);
    } 
    return false;
  }
  return true;
}


int main( int argc, char* argv[])
{
  bfd *abfd;
  char *target = NULL;
  // asection *p;

  bfd_init();  // necesary to use BFD at all
  if (argc < 2)
  {
    printf("Missing argument: No input file selected!\n");
    return 1;
  }
  else
  {
    abfd = bfd_openr(argv[1], target);
    if ( abfd == NULL) 
    { 
      printf("Unable to open %s\n", argv[1]); 
      bfd_errmsg( bfd_get_error() );
      return 1;
    }

  }
  if (!check_format(abfd))
    return 1;

  // use of this bfd_ function is necessary to get hold of the actual
  // sections, it runs through them calls retrieve_section_stab for each one
  bfd_map_over_sections(abfd, retrieve_section_stab, (PTR) NULL);

  //some info from the bfd structure
  printf("File in abfd : %s\n", abfd->filename);
  if (abfd->target_defaulted) 
    printf("A default target was set!!\n");
  if (abfd->format==bfd_object)
    printf("The format is bfd_object.\n");
  if (abfd->direction == read_direction)
    printf("%s was opened for reading...\n",abfd->filename);

  close_it(abfd);  
  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]