1da0c48c4Sopenharmony_ci/* Return source file information of CU. 2da0c48c4Sopenharmony_ci Copyright (C) 2004, 2005, 2013, 2015, 2018 Red Hat, Inc. 3da0c48c4Sopenharmony_ci This file is part of elfutils. 4da0c48c4Sopenharmony_ci 5da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 6da0c48c4Sopenharmony_ci it under the terms of either 7da0c48c4Sopenharmony_ci 8da0c48c4Sopenharmony_ci * the GNU Lesser General Public License as published by the Free 9da0c48c4Sopenharmony_ci Software Foundation; either version 3 of the License, or (at 10da0c48c4Sopenharmony_ci your option) any later version 11da0c48c4Sopenharmony_ci 12da0c48c4Sopenharmony_ci or 13da0c48c4Sopenharmony_ci 14da0c48c4Sopenharmony_ci * the GNU General Public License as published by the Free 15da0c48c4Sopenharmony_ci Software Foundation; either version 2 of the License, or (at 16da0c48c4Sopenharmony_ci your option) any later version 17da0c48c4Sopenharmony_ci 18da0c48c4Sopenharmony_ci or both in parallel, as here. 19da0c48c4Sopenharmony_ci 20da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 21da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 22da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23da0c48c4Sopenharmony_ci General Public License for more details. 24da0c48c4Sopenharmony_ci 25da0c48c4Sopenharmony_ci You should have received copies of the GNU General Public License and 26da0c48c4Sopenharmony_ci the GNU Lesser General Public License along with this program. If 27da0c48c4Sopenharmony_ci not, see <http://www.gnu.org/licenses/>. */ 28da0c48c4Sopenharmony_ci 29da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 30da0c48c4Sopenharmony_ci# include <config.h> 31da0c48c4Sopenharmony_ci#endif 32da0c48c4Sopenharmony_ci 33da0c48c4Sopenharmony_ci#include <assert.h> 34da0c48c4Sopenharmony_ci#include <dwarf.h> 35da0c48c4Sopenharmony_ci#include "libdwP.h" 36da0c48c4Sopenharmony_ci 37da0c48c4Sopenharmony_ci 38da0c48c4Sopenharmony_ciint 39da0c48c4Sopenharmony_cidwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles) 40da0c48c4Sopenharmony_ci{ 41da0c48c4Sopenharmony_ci if (cudie == NULL) 42da0c48c4Sopenharmony_ci return -1; 43da0c48c4Sopenharmony_ci if (! is_cudie (cudie)) 44da0c48c4Sopenharmony_ci { 45da0c48c4Sopenharmony_ci __libdw_seterrno (DWARF_E_NOT_CUDIE); 46da0c48c4Sopenharmony_ci return -1; 47da0c48c4Sopenharmony_ci } 48da0c48c4Sopenharmony_ci 49da0c48c4Sopenharmony_ci int res = -1; 50da0c48c4Sopenharmony_ci 51da0c48c4Sopenharmony_ci /* Get the information if it is not already known. */ 52da0c48c4Sopenharmony_ci struct Dwarf_CU *const cu = cudie->cu; 53da0c48c4Sopenharmony_ci if (cu->files == NULL) 54da0c48c4Sopenharmony_ci { 55da0c48c4Sopenharmony_ci /* For split units there might be a simple file table (without lines). 56da0c48c4Sopenharmony_ci If not, use the one from the skeleton. */ 57da0c48c4Sopenharmony_ci if (cu->unit_type == DW_UT_split_compile 58da0c48c4Sopenharmony_ci || cu->unit_type == DW_UT_split_type) 59da0c48c4Sopenharmony_ci { 60da0c48c4Sopenharmony_ci /* We tried, assume we fail... */ 61da0c48c4Sopenharmony_ci cu->files = (void *) -1; 62da0c48c4Sopenharmony_ci 63da0c48c4Sopenharmony_ci /* See if there is a .debug_line section, for split CUs 64da0c48c4Sopenharmony_ci the table is at offset zero. */ 65da0c48c4Sopenharmony_ci if (cu->dbg->sectiondata[IDX_debug_line] != NULL) 66da0c48c4Sopenharmony_ci { 67da0c48c4Sopenharmony_ci /* We are only interested in the files, the lines will 68da0c48c4Sopenharmony_ci always come from the skeleton. */ 69da0c48c4Sopenharmony_ci res = __libdw_getsrclines (cu->dbg, 0, 70da0c48c4Sopenharmony_ci __libdw_getcompdir (cudie), 71da0c48c4Sopenharmony_ci cu->address_size, NULL, 72da0c48c4Sopenharmony_ci &cu->files); 73da0c48c4Sopenharmony_ci } 74da0c48c4Sopenharmony_ci else 75da0c48c4Sopenharmony_ci { 76da0c48c4Sopenharmony_ci Dwarf_CU *skel = __libdw_find_split_unit (cu); 77da0c48c4Sopenharmony_ci if (skel != NULL) 78da0c48c4Sopenharmony_ci { 79da0c48c4Sopenharmony_ci Dwarf_Die skeldie = CUDIE (skel); 80da0c48c4Sopenharmony_ci res = INTUSE(dwarf_getsrcfiles) (&skeldie, files, nfiles); 81da0c48c4Sopenharmony_ci cu->files = skel->files; 82da0c48c4Sopenharmony_ci } 83da0c48c4Sopenharmony_ci } 84da0c48c4Sopenharmony_ci } 85da0c48c4Sopenharmony_ci else 86da0c48c4Sopenharmony_ci { 87da0c48c4Sopenharmony_ci Dwarf_Lines *lines; 88da0c48c4Sopenharmony_ci size_t nlines; 89da0c48c4Sopenharmony_ci 90da0c48c4Sopenharmony_ci /* Let the more generic function do the work. It'll create more 91da0c48c4Sopenharmony_ci data but that will be needed in an real program anyway. */ 92da0c48c4Sopenharmony_ci res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines); 93da0c48c4Sopenharmony_ci } 94da0c48c4Sopenharmony_ci } 95da0c48c4Sopenharmony_ci else if (cu->files != (void *) -1l) 96da0c48c4Sopenharmony_ci /* We already have the information. */ 97da0c48c4Sopenharmony_ci res = 0; 98da0c48c4Sopenharmony_ci 99da0c48c4Sopenharmony_ci if (likely (res == 0)) 100da0c48c4Sopenharmony_ci { 101da0c48c4Sopenharmony_ci assert (cu->files != NULL && cu->files != (void *) -1l); 102da0c48c4Sopenharmony_ci *files = cu->files; 103da0c48c4Sopenharmony_ci if (nfiles != NULL) 104da0c48c4Sopenharmony_ci *nfiles = cu->files->nfiles; 105da0c48c4Sopenharmony_ci } 106da0c48c4Sopenharmony_ci 107da0c48c4Sopenharmony_ci // XXX Eventually: unlocking here. 108da0c48c4Sopenharmony_ci 109da0c48c4Sopenharmony_ci return res; 110da0c48c4Sopenharmony_ci} 111da0c48c4Sopenharmony_ciINTDEF (dwarf_getsrcfiles) 112