This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: List of source files
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Wed, 05 Jun 2013 11:22:22 +0200
- Subject: Re: List of source files
On Tue, 2013-06-04 at 21:47 +0000, Bruce Dawson wrote:
> I want to get a list of all of the source files and header files used
> to create a particular shared object. I can do this with "objdump
> -Wl" [...]
As Roland pointed out elfutils currently doesn't provide an [eu-]objdump
that support -Wl, but you can get the same information using eu-readelf
--debug-dump=line (and in current git with --debug-dump=decodedline).
If you really just want the source files and don't need to parse the
whole DIE tree or line number information you can easily write something
that does just that using libdw. Attached is an old hack that I did some
time ago just for that.
Cheers,
Mark
// dwarfsrcfiles.c - Get source files associated with the dwarf in a elf file.
// gcc -Wall -g -O2 -lelf -ldw -o dwarfsrcfiles dwarfsrcfiles.c
//
// Copyright (C) 2011, Mark Wielaard <mjw@redhat.com>
//
// This file is free software. You can redistribute it and/or modify
// it under the terms of the GNU General Public License (GPL); either
// version 2, or (at your option) any later version.
#include <argp.h>
#include <error.h>
#include <stdio.h>
#include <dwarf.h>
#include <elfutils/libdw.h>
#include <elfutils/libdwfl.h>
static int
process_cu (Dwarf_Die *cu_die)
{
Dwarf_Attribute attr;
const char *name;
const char *dir = NULL;
Dwarf_Files *files;
size_t n;
int i;
if (dwarf_tag (cu_die) != DW_TAG_compile_unit)
{
error (0, 0, "DIE isn't a compile unit");
return -1;
}
if (dwarf_attr (cu_die, DW_AT_name, &attr) == NULL)
{
error (0, 0, "CU doesn't have a DW_AT_name");
return -1;
}
name = dwarf_formstring (&attr);
if (name == NULL)
{
error (0, 0, "Couldn't get DW_AT_name as string, %s",
dwarf_errmsg (-1));
return -1;
}
if (dwarf_attr (cu_die, DW_AT_comp_dir, &attr) != NULL)
{
dir = dwarf_formstring (&attr);
if (dir == NULL)
{
error (0, 0, "Couldn't get DW_AT_comp_die as string, %s",
dwarf_errmsg (-1));
return -1;
}
}
if (dir == NULL)
printf ("%s\n", name);
else
printf ("%s/%s\n", dir, name);
if (dwarf_getsrcfiles (cu_die, &files, &n) != 0)
{
error (0, 0, "Couldn't get CU file table, %s",
dwarf_errmsg (-1));
return -1;
}
for (i = 1; i < n; i++)
{
const char *file = dwarf_filesrc (files, i, NULL, NULL);
if (dir != NULL && file[0] != '/')
printf ("\t%s/%s\n", dir, file);
else
printf ("\t%s\n", file);
}
return 0;
}
int
main (int argc, char **argv)
{
char* args[3];
int res = 0;
Dwfl *dwfl;
Dwarf_Addr bias;
if (argc != 2)
error (-1, 0, "Usage %s <file>", argv[0]);
// Pretend "dwarfsrcfiles -e <file>" was given, so we can use standard
// dwfl argp parser to open the file for us and get our Dwfl. Useful
// in case argument is an ET_REL file (like kernel modules). libdwfl
// will fix up relocations for us.
args[0] = argv[0];
args[1] = "-e";
args[2] = argv[1];
argp_parse (dwfl_standard_argp (), 3, args, 0, NULL, &dwfl);
Dwarf_Die *cu = NULL;
while ((cu = dwfl_nextcu (dwfl, cu, &bias)) != NULL)
res |= process_cu (cu);
dwfl_end (dwfl);
return res;
}