Home | History | Annotate | Download | only in tests
      1 /* Copyright (C) 2005 Red Hat, Inc.
      2    This file is part of Red Hat elfutils.
      3 
      4    Red Hat elfutils is free software; you can redistribute it and/or modify
      5    it under the terms of the GNU General Public License as published by the
      6    Free Software Foundation; version 2 of the License.
      7 
      8    Red Hat elfutils is distributed in the hope that it will be useful, but
      9    WITHOUT ANY WARRANTY; without even the implied warranty of
     10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11    General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License along
     14    with Red Hat elfutils; if not, write to the Free Software Foundation,
     15    Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
     16 
     17    Red Hat elfutils is an included package of the Open Invention Network.
     18    An included package of the Open Invention Network is a package for which
     19    Open Invention Network licensees cross-license their patents.  No patent
     20    license is granted, either expressly or impliedly, by designation as an
     21    included package.  Should you wish to participate in the Open Invention
     22    Network licensing program, please visit www.openinventionnetwork.com
     23    <http://www.openinventionnetwork.com>.  */
     24 
     25 #ifdef HAVE_CONFIG_H
     26 # include <config.h>
     27 #endif
     28 
     29 #include <inttypes.h>
     30 #include <assert.h>
     31 #include ELFUTILS_HEADER(dwfl)
     32 #include <argp.h>
     33 #include <stdio.h>
     34 #include <locale.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <error.h>
     38 
     39 
     40 static void
     41 print_address (Dwfl_Module *mod, Dwarf_Addr address)
     42 {
     43   int n = dwfl_module_relocations (mod);
     44   if (n < 0)
     45     error (0, 0, "dwfl_module_relocations: %s", dwfl_errmsg (-1));
     46   else if (n > 0)
     47     {
     48       int i = dwfl_module_relocate_address (mod, &address);
     49       if (i < 0)
     50 	error (0, 0, "dwfl_module_relocate_address: %s", dwfl_errmsg (-1));
     51       else
     52 	{
     53 	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
     54 						  NULL, NULL, NULL, NULL);
     55 	  const char *secname = dwfl_module_relocation_info (mod, i, NULL);
     56 	  if (n > 1 || secname[0] != '\0')
     57 	    printf ("%s(%s)+%#" PRIx64, modname, secname, address);
     58 	  else
     59 	    printf ("%s+%#" PRIx64, modname, address);
     60 	  return;
     61 	}
     62     }
     63 
     64   printf ("%#" PRIx64, address);
     65 }
     66 
     67 
     68 struct args
     69 {
     70   const char *arg;
     71   char *file;
     72   int line;
     73 };
     74 
     75 static int
     76 handle_module (Dwfl_Module *mod __attribute__ ((unused)),
     77 	       void **udata __attribute__ ((unused)),
     78 	       const char *modname, Dwarf_Addr base __attribute__ ((unused)),
     79 	       Dwarf *dbg __attribute__ ((unused)),
     80 	       Dwarf_Addr bias __attribute__ ((unused)), void *arg)
     81 {
     82   const struct args *const a = arg;
     83 
     84   Dwfl_Line **lines = NULL;
     85   size_t nlines = 0;
     86 
     87   if (dwfl_module_getsrc_file (mod, a->file, a->line, 0, &lines, &nlines) == 0)
     88     {
     89       for (size_t inner = 0; inner < nlines; ++inner)
     90 	{
     91 	  Dwarf_Addr addr;
     92 	  int line = a->line, col = 0;
     93 	  const char *file = dwfl_lineinfo (lines[inner], &addr, &line, &col,
     94 					    NULL, NULL);
     95 	  if (file != NULL)
     96 	    {
     97 	      printf ("%s -> ", a->arg);
     98 	      print_address (mod, addr);
     99 	      if (modname[0] != '\0')
    100 		printf (" (%s:", modname);
    101 	      if (strcmp (file, a->file) || line != a->line || col != 0)
    102 		printf (" %s%s:%d", modname[0] != '\0' ? "" : "(",
    103 			file, line);
    104 	      if (col != 0)
    105 		printf (":%d", col);
    106 	      if (modname[0] != '\0'
    107 		  || strcmp (file, a->file) || line != a->line || col != 0)
    108 		puts (")");
    109 	      else
    110 		puts ("");
    111 	    }
    112 	}
    113       free (lines);
    114     }
    115 
    116   return DWARF_CB_OK;
    117 }
    118 
    119 int
    120 main (int argc, char *argv[])
    121 {
    122   int cnt;
    123 
    124   /* Set locale.  */
    125   (void) setlocale (LC_ALL, "");
    126 
    127   Dwfl *dwfl = NULL;
    128   (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl);
    129   assert (dwfl != NULL);
    130 
    131   for (; cnt < argc; ++cnt)
    132     {
    133       struct args a = { .arg = argv[cnt] };
    134 
    135       switch (sscanf (a.arg, "%m[^:]:%d", &a.file, &a.line))
    136 	{
    137 	default:
    138 	case 0:
    139 	  printf ("ignored %s\n", argv[cnt]);
    140 	  continue;
    141 	case 1:
    142 	  a.line = 0;
    143 	  break;
    144 	case 2:
    145 	  break;
    146 	}
    147 
    148       (void) dwfl_getdwarf (dwfl, &handle_module, &a, 0);
    149 
    150       free (a.file);
    151     }
    152 
    153   dwfl_end (dwfl);
    154 
    155   return 0;
    156 }
    157