dwarf_getsrc_die.c revision 07d4f2fc1cb53f170a71bc13617bbdd9cb1c3c60
1/* Find line information for address. 2 Copyright (C) 2004, 2005 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper@redhat.com>, 2004. 4 5 This program is Open Source software; you can redistribute it and/or 6 modify it under the terms of the Open Software License version 1.0 as 7 published by the Open Source Initiative. 8 9 You should have received a copy of the Open Software License along 10 with this program; if not, you may obtain a copy of the Open Software 11 License version 1.0 from http://www.opensource.org/licenses/osl.php or 12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13 3001 King Ranch Road, Ukiah, CA 95482. */ 14 15#ifdef HAVE_CONFIG_H 16# include <config.h> 17#endif 18 19#include "libdwP.h" 20#include <assert.h> 21 22 23Dwarf_Line * 24dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr) 25{ 26 Dwarf_Lines *lines; 27 size_t nlines; 28 29 if (INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines) != 0) 30 return NULL; 31 32 /* The lines are sorted by address, so we can use binary search. */ 33 size_t l = 0, u = nlines; 34 while (l < u) 35 { 36 size_t idx = (l + u) / 2; 37 if (addr < lines->info[idx].addr) 38 u = idx; 39 else if (addr > lines->info[idx].addr || lines->info[idx].end_sequence) 40 l = idx + 1; 41 else 42 return &lines->info[idx]; 43 } 44 45 if (nlines > 0) 46 assert (lines->info[nlines - 1].end_sequence); 47 48 /* If none were equal, the closest one below is what we want. We 49 never want the last one, because it's the end-sequence marker 50 with an address at the high bound of the CU's code. If the debug 51 information is faulty and no end-sequence marker is present, we 52 still ignore it. */ 53 if (u > 0 && u < nlines && addr > lines->info[u - 1].addr) 54 { 55 while (lines->info[u - 1].end_sequence && u > 0) 56 --u; 57 if (u > 0) 58 return &lines->info[u - 1]; 59 } 60 61 __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE); 62 return NULL; 63} 64