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