1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Find matching source locations in a module. 2b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Copyright (C) 2005 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 7b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libdwflP.h" 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "../libdw/libdwP.h" 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 333148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsiehstatic inline const char * 343148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsiehdwfl_dwarf_line_file (const Dwarf_Line *line) 353148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh{ 363148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh return line->files->info[line->file].name; 373148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh} 383148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh 393148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsiehstatic inline Dwarf_Line * 403148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsiehdwfl_line (const Dwfl_Line *line) 413148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh{ 423148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh return &dwfl_linecu (line)->die.cu->lines->info[line->idx]; 433148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh} 443148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh 453148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsiehstatic inline const char * 463148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsiehdwfl_line_file (const Dwfl_Line *line) 473148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh{ 483148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh return dwfl_dwarf_line_file (dwfl_line (line)); 493148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh} 503148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdwfl_module_getsrc_file (Dwfl_Module *mod, 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, int lineno, int column, 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwfl_Line ***srcsp, size_t *nsrcs) 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (mod == NULL) 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 59d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod->dw == NULL) 60d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 61d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Dwarf_Addr bias; 62d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL) 63d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath return -1; 64d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 65d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool is_basename = strchr (fname, '/') == NULL; 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t max_match = *nsrcs ?: ~0u; 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t act_match = *nsrcs; 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cur_match = 0; 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwfl_Line **match = *nsrcs == 0 ? NULL : *srcsp; 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct dwfl_cu *cu = NULL; 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwfl_Error error; 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((error = __libdwfl_nextcu (mod, cu, &cu)) == DWFL_E_NOERROR 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && cu != NULL 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (error = __libdwfl_cu_getsrclines (cu)) == DWFL_E_NOERROR) 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Search through all the line number records for a matching 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper file and line/column number. If any of the numbers is zero, 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper no match is performed. */ 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *lastfile = NULL; 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool lastmatch = false; 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < cu->die.cu->lines->nlines; ++cnt) 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Line *line = &cu->die.cu->lines->info[cnt]; 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (line->file >= line->files->nfiles)) 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF)); 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 953148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh const char *file = dwfl_dwarf_line_file (line); 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (file != lastfile) 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Match the name with the name the user provided. */ 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper lastfile = file; 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper lastmatch = !strcmp (is_basename ? basename (file) : file, 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname); 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!lastmatch) 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* See whether line and possibly column match. */ 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (lineno != 0 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (lineno > line->line 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (column != 0 && column > line->column))) 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot match. */ 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Determine whether this is the best match so far. */ 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t inner; 116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (inner = 0; inner < cur_match; ++inner) 1174959bf89d92b59ba72bea5786d7b3f9b5564f750Roland McGrath if (dwfl_line_file (match[inner]) 1183148f5cd3dafdce78a30b609901fc9b27cceb983Chih-Hung Hsieh == dwfl_dwarf_line_file (line)) 119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (inner < cur_match 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (dwfl_line (match[inner])->line != line->line 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || dwfl_line (match[inner])->line != lineno 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (column != 0 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (dwfl_line (match[inner])->column != line->column 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || dwfl_line (match[inner])->column != column)))) 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We know about this file already. If this is a better 128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper match for the line number, use it. */ 129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwfl_line (match[inner])->line >= line->line 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (dwfl_line (match[inner])->line != line->line 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || dwfl_line (match[inner])->column >= line->column)) 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Use the new line. Otherwise the old one. */ 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper match[inner] = &cu->lines->idx[cnt]; 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cur_match < max_match) 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cur_match == act_match) 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Enlarge the array for the results. */ 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper act_match += 10; 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwfl_Line **newp = realloc (match, 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper act_match 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * sizeof (Dwfl_Line *)); 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (newp == NULL) 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (match); 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdwfl_seterrno (DWFL_E_NOMEM); 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper match = newp; 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper match[cur_match++] = &cu->lines->idx[cnt]; 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cur_match > 0) 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (*nsrcs == 0 || *srcsp == match); 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *nsrcs = cur_match; 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *srcsp = match; 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdwfl_seterrno (DWFL_E_NO_MATCH); 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 173