1 2 /*--------------------------------------------------------------------*/ 3 /*--- Format-neutral storage of and querying of info acquired from ---*/ 4 /*--- ELF/XCOFF stabs/dwarf1/dwarf2/dwarf3 debug info. ---*/ 5 /*--- storage.c ---*/ 6 /*--------------------------------------------------------------------*/ 7 8 /* 9 This file is part of Valgrind, a dynamic binary instrumentation 10 framework. 11 12 Copyright (C) 2000-2012 Julian Seward 13 jseward (at) acm.org 14 15 This program is free software; you can redistribute it and/or 16 modify it under the terms of the GNU General Public License as 17 published by the Free Software Foundation; either version 2 of the 18 License, or (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, but 21 WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program; if not, write to the Free Software 27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28 02111-1307, USA. 29 30 The GNU General Public License is contained in the file COPYING. 31 */ 32 33 /* This file manages the data structures built by the debuginfo 34 system. These are: the top level SegInfo list. For each SegInfo, 35 there are tables for for address-to-symbol mappings, 36 address-to-src-file/line mappings, and address-to-CFI-info 37 mappings. 38 */ 39 40 #include "pub_core_basics.h" 41 #include "pub_core_options.h" /* VG_(clo_verbosity) */ 42 #include "pub_core_debuginfo.h" 43 #include "pub_core_libcassert.h" 44 #include "pub_core_libcbase.h" 45 #include "pub_core_libcprint.h" 46 #include "pub_core_xarray.h" 47 #include "pub_core_oset.h" 48 49 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */ 50 #include "priv_d3basics.h" /* ML_(pp_GX) */ 51 #include "priv_tytypes.h" 52 #include "priv_storage.h" /* self */ 53 54 55 /*------------------------------------------------------------*/ 56 /*--- Misc (printing, errors) ---*/ 57 /*------------------------------------------------------------*/ 58 59 /* Show a non-fatal debug info reading error. Use vg_panic if 60 terminal. 'serious' errors are shown regardless of the 61 verbosity setting. */ 62 void ML_(symerr) ( struct _DebugInfo* di, Bool serious, HChar* msg ) 63 { 64 /* XML mode hides everything :-( */ 65 if (VG_(clo_xml)) 66 return; 67 68 if (serious) { 69 70 VG_(message)(Vg_DebugMsg, "WARNING: Serious error when " 71 "reading debug info\n"); 72 if (True || VG_(clo_verbosity) < 2) { 73 /* Need to show what the file name is, at verbosity levels 2 74 or below, since that won't already have been shown */ 75 VG_(message)(Vg_DebugMsg, 76 "When reading debug info from %s:\n", 77 (di && di->fsm.filename) ? di->fsm.filename 78 : (UChar*)"???"); 79 } 80 VG_(message)(Vg_DebugMsg, "%s\n", msg); 81 82 } else { /* !serious */ 83 84 if (VG_(clo_verbosity) >= 2) 85 VG_(message)(Vg_DebugMsg, "%s\n", msg); 86 87 } 88 } 89 90 91 /* Print a symbol. */ 92 void ML_(ppSym) ( Int idx, DiSym* sym ) 93 { 94 UChar** sec_names = sym->sec_names; 95 vg_assert(sym->pri_name); 96 if (sec_names) 97 vg_assert(sec_names); 98 VG_(printf)( "%5d: %c%c %#8lx .. %#8lx (%d) %s%s", 99 idx, 100 sym->isText ? 'T' : '-', 101 sym->isIFunc ? 'I' : '-', 102 sym->addr, 103 sym->addr + sym->size - 1, sym->size, 104 sym->pri_name, sec_names ? " " : "" ); 105 if (sec_names) { 106 while (*sec_names) { 107 VG_(printf)("%s%s", *sec_names, *(sec_names+1) ? " " : ""); 108 sec_names++; 109 } 110 } 111 VG_(printf)("\n"); 112 } 113 114 /* Print a call-frame-info summary. */ 115 void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si ) 116 { 117 # define SHOW_HOW(_how, _off) \ 118 do { \ 119 if (_how == CFIR_UNKNOWN) { \ 120 VG_(printf)("Unknown"); \ 121 } else \ 122 if (_how == CFIR_SAME) { \ 123 VG_(printf)("Same"); \ 124 } else \ 125 if (_how == CFIR_CFAREL) { \ 126 VG_(printf)("cfa+%d", _off); \ 127 } else \ 128 if (_how == CFIR_MEMCFAREL) { \ 129 VG_(printf)("*(cfa+%d)", _off); \ 130 } else \ 131 if (_how == CFIR_EXPR) { \ 132 VG_(printf)("{"); \ 133 ML_(ppCfiExpr)(exprs, _off); \ 134 VG_(printf)("}"); \ 135 } else { \ 136 vg_assert(0+0); \ 137 } \ 138 } while (0) 139 140 VG_(printf)("[%#lx .. %#lx]: ", si->base, 141 si->base + (UWord)si->len - 1); 142 switch (si->cfa_how) { 143 case CFIC_IA_SPREL: 144 VG_(printf)("let cfa=oldSP+%d", si->cfa_off); 145 break; 146 case CFIC_IA_BPREL: 147 VG_(printf)("let cfa=oldBP+%d", si->cfa_off); 148 break; 149 case CFIC_ARM_R13REL: 150 VG_(printf)("let cfa=oldR13+%d", si->cfa_off); 151 break; 152 case CFIC_ARM_R12REL: 153 VG_(printf)("let cfa=oldR12+%d", si->cfa_off); 154 break; 155 case CFIC_ARM_R11REL: 156 VG_(printf)("let cfa=oldR11+%d", si->cfa_off); 157 break; 158 case CFIR_SAME: 159 VG_(printf)("let cfa=Same"); 160 break; 161 case CFIC_ARM_R7REL: 162 VG_(printf)("let cfa=oldR7+%d", si->cfa_off); 163 break; 164 case CFIC_EXPR: 165 VG_(printf)("let cfa={"); 166 ML_(ppCfiExpr)(exprs, si->cfa_off); 167 VG_(printf)("}"); 168 break; 169 default: 170 vg_assert(0); 171 } 172 173 VG_(printf)(" in RA="); 174 SHOW_HOW(si->ra_how, si->ra_off); 175 # if defined(VGA_x86) || defined(VGA_amd64) 176 VG_(printf)(" SP="); 177 SHOW_HOW(si->sp_how, si->sp_off); 178 VG_(printf)(" BP="); 179 SHOW_HOW(si->bp_how, si->bp_off); 180 # elif defined(VGA_arm) 181 VG_(printf)(" R14="); 182 SHOW_HOW(si->r14_how, si->r14_off); 183 VG_(printf)(" R13="); 184 SHOW_HOW(si->r13_how, si->r13_off); 185 VG_(printf)(" R12="); 186 SHOW_HOW(si->r12_how, si->r12_off); 187 VG_(printf)(" R11="); 188 SHOW_HOW(si->r11_how, si->r11_off); 189 VG_(printf)(" R7="); 190 SHOW_HOW(si->r7_how, si->r7_off); 191 # elif defined(VGA_ppc32) || defined(VGA_ppc64) 192 # elif defined(VGA_s390x) || defined(VGA_mips32) 193 VG_(printf)(" SP="); 194 SHOW_HOW(si->sp_how, si->sp_off); 195 VG_(printf)(" FP="); 196 SHOW_HOW(si->fp_how, si->fp_off); 197 # else 198 # error "Unknown arch" 199 # endif 200 VG_(printf)("\n"); 201 # undef SHOW_HOW 202 } 203 204 205 /*------------------------------------------------------------*/ 206 /*--- Adding stuff ---*/ 207 /*------------------------------------------------------------*/ 208 209 /* Add a str to the string table, including terminating zero, and 210 return pointer to the string in vg_strtab. Unless it's been seen 211 recently, in which case we find the old pointer and return that. 212 This avoids the most egregious duplications. 213 214 JSGF: changed from returning an index to a pointer, and changed to 215 a chunking memory allocator rather than reallocating, so the 216 pointers are stable. 217 */ 218 UChar* ML_(addStr) ( struct _DebugInfo* di, UChar* str, Int len ) 219 { 220 struct strchunk *chunk; 221 Int space_needed; 222 UChar* p; 223 224 if (len == -1) { 225 len = VG_(strlen)(str); 226 } else { 227 vg_assert(len >= 0); 228 } 229 230 space_needed = 1 + len; 231 232 // Allocate a new strtab chunk if necessary 233 if (di->strchunks == NULL || 234 (di->strchunks->strtab_used 235 + space_needed) > SEGINFO_STRCHUNKSIZE) { 236 chunk = ML_(dinfo_zalloc)("di.storage.addStr.1", sizeof(*chunk)); 237 chunk->strtab_used = 0; 238 chunk->next = di->strchunks; 239 di->strchunks = chunk; 240 } 241 chunk = di->strchunks; 242 243 p = &chunk->strtab[chunk->strtab_used]; 244 VG_(memcpy)(p, str, len); 245 chunk->strtab[chunk->strtab_used+len] = '\0'; 246 chunk->strtab_used += space_needed; 247 248 return p; 249 } 250 251 252 /* Add a symbol to the symbol table, by copying *sym. 'sym' may only 253 have one name, so there's no complexities to do with deep vs 254 shallow copying of the sec_name array. This is checked. 255 */ 256 void ML_(addSym) ( struct _DebugInfo* di, DiSym* sym ) 257 { 258 UInt new_sz, i; 259 DiSym* new_tab; 260 261 vg_assert(sym->pri_name != NULL); 262 vg_assert(sym->sec_names == NULL); 263 264 /* Ignore zero-sized syms. */ 265 if (sym->size == 0) return; 266 267 if (di->symtab_used == di->symtab_size) { 268 new_sz = 2 * di->symtab_size; 269 if (new_sz == 0) new_sz = 500; 270 new_tab = ML_(dinfo_zalloc)( "di.storage.addSym.1", 271 new_sz * sizeof(DiSym) ); 272 if (di->symtab != NULL) { 273 for (i = 0; i < di->symtab_used; i++) 274 new_tab[i] = di->symtab[i]; 275 ML_(dinfo_free)(di->symtab); 276 } 277 di->symtab = new_tab; 278 di->symtab_size = new_sz; 279 } 280 281 di->symtab[di->symtab_used++] = *sym; 282 vg_assert(di->symtab_used <= di->symtab_size); 283 } 284 285 286 /* Add a location to the location table. 287 */ 288 static void addLoc ( struct _DebugInfo* di, DiLoc* loc ) 289 { 290 UInt new_sz, i; 291 DiLoc* new_tab; 292 293 /* Zero-sized locs should have been ignored earlier */ 294 vg_assert(loc->size > 0); 295 296 if (di->loctab_used == di->loctab_size) { 297 new_sz = 2 * di->loctab_size; 298 if (new_sz == 0) new_sz = 500; 299 new_tab = ML_(dinfo_zalloc)( "di.storage.addLoc.1", 300 new_sz * sizeof(DiLoc) ); 301 if (di->loctab != NULL) { 302 for (i = 0; i < di->loctab_used; i++) 303 new_tab[i] = di->loctab[i]; 304 ML_(dinfo_free)(di->loctab); 305 } 306 di->loctab = new_tab; 307 di->loctab_size = new_sz; 308 } 309 310 di->loctab[di->loctab_used] = *loc; 311 di->loctab_used++; 312 vg_assert(di->loctab_used <= di->loctab_size); 313 } 314 315 316 /* Resize the LocTab (line number table) to save memory, by removing 317 (and, potentially, allowing m_mallocfree to unmap) any unused space 318 at the end of the table. 319 */ 320 static void shrinkLocTab ( struct _DebugInfo* di ) 321 { 322 DiLoc* new_tab; 323 UWord new_sz = di->loctab_used; 324 if (new_sz == di->loctab_size) return; 325 vg_assert(new_sz < di->loctab_size); 326 327 new_tab = ML_(dinfo_zalloc)( "di.storage.shrinkLocTab", 328 new_sz * sizeof(DiLoc) ); 329 VG_(memcpy)(new_tab, di->loctab, new_sz * sizeof(DiLoc)); 330 331 ML_(dinfo_free)(di->loctab); 332 di->loctab = new_tab; 333 di->loctab_size = new_sz; 334 } 335 336 337 /* Top-level place to call to add a source-location mapping entry. 338 */ 339 void ML_(addLineInfo) ( struct _DebugInfo* di, 340 UChar* filename, 341 UChar* dirname, /* NULL == directory is unknown */ 342 Addr this, 343 Addr next, 344 Int lineno, 345 Int entry /* only needed for debug printing */ 346 ) 347 { 348 static const Bool debug = False; 349 DiLoc loc; 350 UWord size = next - this; 351 352 /* Ignore zero-sized locs */ 353 if (this == next) return; 354 355 if (debug) 356 VG_(printf)( " src %s %s line %d %#lx-%#lx\n", 357 dirname ? dirname : (UChar*)"(unknown)", 358 filename, lineno, this, next ); 359 360 /* Maximum sanity checking. Some versions of GNU as do a shabby 361 * job with stabs entries; if anything looks suspicious, revert to 362 * a size of 1. This should catch the instruction of interest 363 * (since if using asm-level debug info, one instruction will 364 * correspond to one line, unlike with C-level debug info where 365 * multiple instructions can map to the one line), but avoid 366 * catching any other instructions bogusly. */ 367 if (this > next) { 368 if (VG_(clo_verbosity) > 2) { 369 VG_(message)(Vg_DebugMsg, 370 "warning: line info addresses out of order " 371 "at entry %d: 0x%lx 0x%lx\n", entry, this, next); 372 } 373 size = 1; 374 } 375 376 if (size > MAX_LOC_SIZE) { 377 if (0) 378 VG_(message)(Vg_DebugMsg, 379 "warning: line info address range too large " 380 "at entry %d: %lu\n", entry, size); 381 size = 1; 382 } 383 384 /* At this point, we know that the original value for |size|, viz 385 |next - this|, will only still be used in the case where 386 |this| <u |next|, so it can't have underflowed. Considering 387 that and the three checks that follow it, the following must 388 hold. */ 389 vg_assert(size >= 1); 390 vg_assert(size <= MAX_LOC_SIZE); 391 392 /* Rule out ones which are completely outside the r-x mapped area. 393 See "Comment_Regarding_Text_Range_Checks" elsewhere in this file 394 for background and rationale. */ 395 vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); 396 if (ML_(find_rx_mapping)(di, this, this + size - 1) == NULL) { 397 if (0) 398 VG_(message)(Vg_DebugMsg, 399 "warning: ignoring line info entry falling " 400 "outside current DebugInfo: %#lx %#lx %#lx %#lx\n", 401 di->text_avma, 402 di->text_avma + di->text_size, 403 this, this + size - 1); 404 return; 405 } 406 407 vg_assert(lineno >= 0); 408 if (lineno > MAX_LINENO) { 409 static Bool complained = False; 410 if (!complained) { 411 complained = True; 412 VG_(message)(Vg_UserMsg, 413 "warning: ignoring line info entry with " 414 "huge line number (%d)\n", lineno); 415 VG_(message)(Vg_UserMsg, 416 " Can't handle line numbers " 417 "greater than %d, sorry\n", MAX_LINENO); 418 VG_(message)(Vg_UserMsg, 419 "(Nb: this message is only shown once)\n"); 420 } 421 return; 422 } 423 424 loc.addr = this; 425 loc.size = (UShort)size; 426 loc.lineno = lineno; 427 loc.filename = filename; 428 loc.dirname = dirname; 429 430 if (0) VG_(message)(Vg_DebugMsg, 431 "addLoc: addr %#lx, size %lu, line %d, file %s\n", 432 this,size,lineno,filename); 433 434 addLoc ( di, &loc ); 435 } 436 437 438 /* Top-level place to call to add a CFI summary record. The supplied 439 DiCfSI is copied. */ 440 void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi_orig ) 441 { 442 static const Bool debug = False; 443 UInt new_sz, i; 444 DiCfSI* new_tab; 445 SSizeT delta; 446 struct _DebugInfoMapping* map; 447 struct _DebugInfoMapping* map2; 448 449 /* copy the original, so we can mess with it */ 450 DiCfSI cfsi = *cfsi_orig; 451 452 if (debug) { 453 VG_(printf)("adding DiCfSI: "); 454 ML_(ppDiCfSI)(di->cfsi_exprs, &cfsi); 455 } 456 457 /* sanity */ 458 vg_assert(cfsi.len > 0); 459 /* If this fails, the implication is you have a single procedure 460 with more than 5 million bytes of code. Which is pretty 461 unlikely. Either that, or the debuginfo reader is somehow 462 broken. 5 million is of course arbitrary; but it's big enough 463 to be bigger than the size of any plausible piece of code that 464 would fall within a single procedure. */ 465 vg_assert(cfsi.len < 5000000); 466 467 vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); 468 /* Find mapping where at least one end of the CFSI falls into. */ 469 map = ML_(find_rx_mapping)(di, cfsi.base, cfsi.base); 470 map2 = ML_(find_rx_mapping)(di, cfsi.base + cfsi.len - 1, 471 cfsi.base + cfsi.len - 1); 472 if (map == NULL) 473 map = map2; 474 else if (map2 == NULL) 475 map2 = map; 476 477 /* Rule out ones which are completely outside the r-x mapped area 478 (or which span across different areas). 479 See "Comment_Regarding_Text_Range_Checks" elsewhere in this file 480 for background and rationale. */ 481 if (map == NULL || map != map2) { 482 static Int complaints = 10; 483 if (VG_(clo_trace_cfi) || complaints > 0) { 484 complaints--; 485 if (VG_(clo_verbosity) > 1) { 486 VG_(message)( 487 Vg_DebugMsg, 488 "warning: DiCfSI %#lx .. %#lx outside mapped rw segments (%s)\n", 489 cfsi.base, 490 cfsi.base + cfsi.len - 1, 491 di->soname 492 ); 493 } 494 if (VG_(clo_trace_cfi)) 495 ML_(ppDiCfSI)(di->cfsi_exprs, &cfsi); 496 } 497 return; 498 } 499 500 /* Now we know the range is at least partially inside the r-x 501 mapped area. That implies that at least one of the ends of the 502 range falls inside the area. If necessary, clip it so it is 503 completely within the area. If we don't do this, 504 check_CFSI_related_invariants() in debuginfo.c (invariant #2) 505 will fail. See 506 "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 507 priv_storage.h for background. */ 508 if (cfsi.base < map->avma) { 509 /* Lower end is outside the mapped area. Hence upper end must 510 be inside it. */ 511 if (0) VG_(printf)("XXX truncate lower\n"); 512 vg_assert(cfsi.base + cfsi.len - 1 >= map->avma); 513 delta = (SSizeT)(map->avma - cfsi.base); 514 vg_assert(delta > 0); 515 vg_assert(delta < (SSizeT)cfsi.len); 516 cfsi.base += delta; 517 cfsi.len -= delta; 518 } 519 else 520 if (cfsi.base + cfsi.len - 1 > map->avma + map->size - 1) { 521 /* Upper end is outside the mapped area. Hence lower end must be 522 inside it. */ 523 if (0) VG_(printf)("XXX truncate upper\n"); 524 vg_assert(cfsi.base <= map->avma + map->size - 1); 525 delta = (SSizeT)( (cfsi.base + cfsi.len - 1) 526 - (map->avma + map->size - 1) ); 527 vg_assert(delta > 0); 528 vg_assert(delta < (SSizeT)cfsi.len); 529 cfsi.len -= delta; 530 } 531 532 /* Final checks */ 533 534 /* Because: either cfsi was entirely inside the range, in which 535 case we asserted that len > 0 at the start, OR it fell partially 536 inside the range, in which case we reduced it by some size 537 (delta) which is < its original size. */ 538 vg_assert(cfsi.len > 0); 539 540 /* Similar logic applies for the next two assertions. */ 541 vg_assert(cfsi.base >= map->avma); 542 vg_assert(cfsi.base + cfsi.len - 1 543 <= map->avma + map->size - 1); 544 545 if (di->cfsi_used == di->cfsi_size) { 546 new_sz = 2 * di->cfsi_size; 547 if (new_sz == 0) new_sz = 20; 548 new_tab = ML_(dinfo_zalloc)( "di.storage.addDiCfSI.1", 549 new_sz * sizeof(DiCfSI) ); 550 if (di->cfsi != NULL) { 551 for (i = 0; i < di->cfsi_used; i++) 552 new_tab[i] = di->cfsi[i]; 553 ML_(dinfo_free)(di->cfsi); 554 } 555 di->cfsi = new_tab; 556 di->cfsi_size = new_sz; 557 } 558 559 di->cfsi[di->cfsi_used] = cfsi; 560 di->cfsi_used++; 561 vg_assert(di->cfsi_used <= di->cfsi_size); 562 } 563 564 565 Int ML_(CfiExpr_Undef)( XArray* dst ) 566 { 567 CfiExpr e; 568 VG_(memset)( &e, 0, sizeof(e) ); 569 e.tag = Cex_Undef; 570 return (Int)VG_(addToXA)( dst, &e ); 571 } 572 Int ML_(CfiExpr_Deref)( XArray* dst, Int ixAddr ) 573 { 574 CfiExpr e; 575 VG_(memset)( &e, 0, sizeof(e) ); 576 e.tag = Cex_Deref; 577 e.Cex.Deref.ixAddr = ixAddr; 578 return (Int)VG_(addToXA)( dst, &e ); 579 } 580 Int ML_(CfiExpr_Const)( XArray* dst, UWord con ) 581 { 582 CfiExpr e; 583 VG_(memset)( &e, 0, sizeof(e) ); 584 e.tag = Cex_Const; 585 e.Cex.Const.con = con; 586 return (Int)VG_(addToXA)( dst, &e ); 587 } 588 Int ML_(CfiExpr_Binop)( XArray* dst, CfiOp op, Int ixL, Int ixR ) 589 { 590 CfiExpr e; 591 VG_(memset)( &e, 0, sizeof(e) ); 592 e.tag = Cex_Binop; 593 e.Cex.Binop.op = op; 594 e.Cex.Binop.ixL = ixL; 595 e.Cex.Binop.ixR = ixR; 596 return (Int)VG_(addToXA)( dst, &e ); 597 } 598 Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg ) 599 { 600 CfiExpr e; 601 VG_(memset)( &e, 0, sizeof(e) ); 602 e.tag = Cex_CfiReg; 603 e.Cex.CfiReg.reg = reg; 604 return (Int)VG_(addToXA)( dst, &e ); 605 } 606 Int ML_(CfiExpr_DwReg)( XArray* dst, Int reg ) 607 { 608 CfiExpr e; 609 VG_(memset)( &e, 0, sizeof(e) ); 610 e.tag = Cex_DwReg; 611 e.Cex.DwReg.reg = reg; 612 return (Int)VG_(addToXA)( dst, &e ); 613 } 614 615 static void ppCfiOp ( CfiOp op ) 616 { 617 switch (op) { 618 case Cop_Add: VG_(printf)("+"); break; 619 case Cop_Sub: VG_(printf)("-"); break; 620 case Cop_And: VG_(printf)("&"); break; 621 case Cop_Mul: VG_(printf)("*"); break; 622 case Cop_Shl: VG_(printf)("<<"); break; 623 case Cop_Shr: VG_(printf)(">>"); break; 624 case Cop_Eq: VG_(printf)("=="); break; 625 case Cop_Ge: VG_(printf)(">="); break; 626 case Cop_Gt: VG_(printf)(">"); break; 627 case Cop_Le: VG_(printf)("<="); break; 628 case Cop_Lt: VG_(printf)("<"); break; 629 case Cop_Ne: VG_(printf)("!="); break; 630 default: vg_assert(0); 631 } 632 } 633 634 static void ppCfiReg ( CfiReg reg ) 635 { 636 switch (reg) { 637 case Creg_IA_SP: VG_(printf)("xSP"); break; 638 case Creg_IA_BP: VG_(printf)("xBP"); break; 639 case Creg_IA_IP: VG_(printf)("xIP"); break; 640 case Creg_ARM_R13: VG_(printf)("R13"); break; 641 case Creg_ARM_R12: VG_(printf)("R12"); break; 642 case Creg_ARM_R15: VG_(printf)("R15"); break; 643 case Creg_ARM_R14: VG_(printf)("R14"); break; 644 case Creg_MIPS_RA: VG_(printf)("RA"); break; 645 case Creg_S390_R14: VG_(printf)("R14"); break; 646 default: vg_assert(0); 647 } 648 } 649 650 void ML_(ppCfiExpr)( XArray* src, Int ix ) 651 { 652 /* VG_(indexXA) checks for invalid src/ix values, so we can 653 use it indiscriminately. */ 654 CfiExpr* e = (CfiExpr*) VG_(indexXA)( src, ix ); 655 switch (e->tag) { 656 case Cex_Undef: 657 VG_(printf)("Undef"); 658 break; 659 case Cex_Deref: 660 VG_(printf)("*("); 661 ML_(ppCfiExpr)(src, e->Cex.Deref.ixAddr); 662 VG_(printf)(")"); 663 break; 664 case Cex_Const: 665 VG_(printf)("0x%lx", e->Cex.Const.con); 666 break; 667 case Cex_Binop: 668 VG_(printf)("("); 669 ML_(ppCfiExpr)(src, e->Cex.Binop.ixL); 670 VG_(printf)(")"); 671 ppCfiOp(e->Cex.Binop.op); 672 VG_(printf)("("); 673 ML_(ppCfiExpr)(src, e->Cex.Binop.ixR); 674 VG_(printf)(")"); 675 break; 676 case Cex_CfiReg: 677 ppCfiReg(e->Cex.CfiReg.reg); 678 break; 679 case Cex_DwReg: 680 VG_(printf)("dwr%d", e->Cex.DwReg.reg); 681 break; 682 default: 683 VG_(core_panic)("ML_(ppCfiExpr)"); 684 /*NOTREACHED*/ 685 break; 686 } 687 } 688 689 690 Word ML_(cmp_for_DiAddrRange_range) ( const void* keyV, 691 const void* elemV ) { 692 const Addr* key = (const Addr*)keyV; 693 const DiAddrRange* elem = (const DiAddrRange*)elemV; 694 if (0) 695 VG_(printf)("cmp_for_DiAddrRange_range: %#lx vs %#lx\n", 696 *key, elem->aMin); 697 if ((*key) < elem->aMin) return -1; 698 if ((*key) > elem->aMax) return 1; 699 return 0; 700 } 701 702 static 703 void show_scope ( OSet* /* of DiAddrRange */ scope, HChar* who ) 704 { 705 DiAddrRange* range; 706 VG_(printf)("Scope \"%s\" = {\n", who); 707 VG_(OSetGen_ResetIter)( scope ); 708 while (True) { 709 range = VG_(OSetGen_Next)( scope ); 710 if (!range) break; 711 VG_(printf)(" %#lx .. %#lx: %lu vars\n", range->aMin, range->aMax, 712 range->vars ? VG_(sizeXA)(range->vars) : 0); 713 } 714 VG_(printf)("}\n"); 715 } 716 717 /* Add the variable 'var' to 'scope' for the address range [aMin,aMax] 718 (inclusive of aMin and aMax). Split existing ranges as required if 719 aMin or aMax or both don't match existing range boundaries, and add 720 'var' to all required ranges. Take great care to preserve the 721 invariant that the ranges in 'scope' cover the entire address range 722 exactly once, with no overlaps and no holes. */ 723 static void add_var_to_arange ( 724 /*MOD*/OSet* /* of DiAddrRange */ scope, 725 Addr aMin, 726 Addr aMax, 727 DiVariable* var 728 ) 729 { 730 DiAddrRange *first, *last, *range; 731 /* These xx variables are for assertion checking only; they don't 732 contribute anything to the actual work of this function. */ 733 DiAddrRange *xxRangep, *xxFirst, *xxLast; 734 UWord xxIters; 735 736 vg_assert(aMin <= aMax); 737 738 if (0) VG_(printf)("add_var_to_arange: %#lx .. %#lx\n", aMin, aMax); 739 if (0) show_scope( scope, "add_var_to_arange(1)" ); 740 741 /* See if the lower end of the range (aMin) falls exactly on an 742 existing range boundary. If not, find the range it does fall 743 into, and split it (copying the variables in the process), so 744 that aMin does exactly fall on a range boundary. */ 745 first = VG_(OSetGen_Lookup)( scope, &aMin ); 746 /* It must be present, since the presented OSet must cover 747 the entire address range. */ 748 vg_assert(first); 749 vg_assert(first->aMin <= first->aMax); 750 vg_assert(first->aMin <= aMin && aMin <= first->aMax); 751 752 /* Fast track common case, which is that the range specified for 753 the variable exactly coincides with one already-existing 754 range. */ 755 if (first->aMin == aMin && first->aMax == aMax) { 756 vg_assert(first->vars); 757 VG_(addToXA)( first->vars, var ); 758 return; 759 } 760 761 /* We have to get into splitting ranges, which is complex 762 and slow. */ 763 if (first->aMin < aMin) { 764 DiAddrRange* nyu; 765 /* Ok. We'll have to split 'first'. */ 766 /* truncate the upper end of 'first' */ 767 Addr tmp = first->aMax; 768 first->aMax = aMin-1; 769 vg_assert(first->aMin <= first->aMax); 770 /* create a new range */ 771 nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) ); 772 vg_assert(nyu); 773 nyu->aMin = aMin; 774 nyu->aMax = tmp; 775 vg_assert(nyu->aMin <= nyu->aMax); 776 /* copy vars into it */ 777 vg_assert(first->vars); 778 nyu->vars = VG_(cloneXA)( "di.storage.avta.1", first->vars ); 779 vg_assert(nyu->vars); 780 VG_(OSetGen_Insert)( scope, nyu ); 781 first = nyu; 782 } 783 784 vg_assert(first->aMin == aMin); 785 786 /* Now do exactly the same for the upper end (aMax): if it doesn't 787 fall on a boundary, cause it to do so by splitting the range it 788 does currently fall into. */ 789 last = VG_(OSetGen_Lookup)( scope, &aMax ); 790 vg_assert(last->aMin <= last->aMax); 791 vg_assert(last->aMin <= aMax && aMax <= last->aMax); 792 793 if (aMax < last->aMax) { 794 DiAddrRange* nyu; 795 /* We have to split 'last'. */ 796 /* truncate the lower end of 'last' */ 797 Addr tmp = last->aMin; 798 last->aMin = aMax+1; 799 vg_assert(last->aMin <= last->aMax); 800 /* create a new range */ 801 nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) ); 802 vg_assert(nyu); 803 nyu->aMin = tmp; 804 nyu->aMax = aMax; 805 vg_assert(nyu->aMin <= nyu->aMax); 806 /* copy vars into it */ 807 vg_assert(last->vars); 808 nyu->vars = VG_(cloneXA)( "di.storage.avta.2", last->vars ); 809 vg_assert(nyu->vars); 810 VG_(OSetGen_Insert)( scope, nyu ); 811 last = nyu; 812 } 813 814 vg_assert(aMax == last->aMax); 815 816 xxFirst = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMin); 817 xxLast = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMax); 818 vg_assert(xxFirst); 819 vg_assert(xxLast); 820 vg_assert(xxFirst->aMin == aMin); 821 vg_assert(xxLast->aMax == aMax); 822 if (xxFirst != xxLast) 823 vg_assert(xxFirst->aMax < xxLast->aMin); 824 825 /* Great. Now we merely need to iterate over the segments from 826 'first' to 'last' inclusive, and add 'var' to the variable set 827 of each of them. */ 828 if (0) { 829 static UWord ctr = 0; 830 ctr++; 831 VG_(printf)("ctr = %lu\n", ctr); 832 if (ctr >= 33263) show_scope( scope, "add_var_to_arange(2)" ); 833 } 834 835 xxIters = 0; 836 range = xxRangep = NULL; 837 VG_(OSetGen_ResetIterAt)( scope, &aMin ); 838 while (True) { 839 xxRangep = range; 840 range = VG_(OSetGen_Next)( scope ); 841 if (!range) break; 842 if (range->aMin > aMax) break; 843 xxIters++; 844 if (0) VG_(printf)("have range %#lx %#lx\n", 845 range->aMin, range->aMax); 846 847 /* Sanity checks */ 848 if (!xxRangep) { 849 /* This is the first in the range */ 850 vg_assert(range->aMin == aMin); 851 } else { 852 vg_assert(xxRangep->aMax + 1 == range->aMin); 853 } 854 855 vg_assert(range->vars); 856 VG_(addToXA)( range->vars, var ); 857 } 858 /* Done. We should have seen at least one range. */ 859 vg_assert(xxIters >= 1); 860 if (xxIters == 1) vg_assert(xxFirst == xxLast); 861 if (xxFirst == xxLast) vg_assert(xxIters == 1); 862 vg_assert(xxRangep); 863 vg_assert(xxRangep->aMax == aMax); 864 vg_assert(xxRangep == xxLast); 865 } 866 867 868 /* Top-level place to call to add a variable description (as extracted 869 from a DWARF3 .debug_info section. */ 870 void ML_(addVar)( struct _DebugInfo* di, 871 Int level, 872 Addr aMin, 873 Addr aMax, 874 UChar* name, /* in di's .strchunks */ 875 UWord typeR, /* a cuOff */ 876 GExpr* gexpr, 877 GExpr* fbGX, 878 UChar* fileName, /* where decl'd - may be NULL. 879 in di's .strchunks */ 880 Int lineNo, /* where decl'd - may be zero */ 881 Bool show ) 882 { 883 OSet* /* of DiAddrRange */ scope; 884 DiVariable var; 885 Bool all; 886 TyEnt* ent; 887 MaybeULong mul; 888 HChar* badness; 889 890 tl_assert(di && di->admin_tyents); 891 892 if (0) { 893 VG_(printf)(" ML_(addVar): level %d %#lx-%#lx %s :: ", 894 level, aMin, aMax, name ); 895 ML_(pp_TyEnt_C_ishly)( di->admin_tyents, typeR ); 896 VG_(printf)("\n Var="); 897 ML_(pp_GX)(gexpr); 898 VG_(printf)("\n"); 899 if (fbGX) { 900 VG_(printf)(" FrB="); 901 ML_(pp_GX)( fbGX ); 902 VG_(printf)("\n"); 903 } else { 904 VG_(printf)(" FrB=none\n"); 905 } 906 VG_(printf)("\n"); 907 } 908 909 vg_assert(level >= 0); 910 vg_assert(aMin <= aMax); 911 vg_assert(name); 912 vg_assert(gexpr); 913 914 ent = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, typeR); 915 tl_assert(ent); 916 vg_assert(ML_(TyEnt__is_type)(ent)); 917 918 /* "Comment_Regarding_Text_Range_Checks" (is referred to elsewhere) 919 ---------------------------------------------------------------- 920 Ignore any variables whose aMin .. aMax (that is, range of text 921 addresses for which they actually exist) falls outside the text 922 segment. Is this indicative of a bug in the reader? Maybe. 923 (LATER): instead of restricting strictly to the .text segment, 924 be a bit more relaxed, and accept any variable whose text range 925 falls inside the r-x mapped area. This is useful because .text 926 is not always the only instruction-carrying segment: others are: 927 .init .plt __libc_freeres_fn and .fini. This implicitly assumes 928 that those extra sections have the same bias as .text, but that 929 seems a reasonable assumption to me. */ 930 /* This is assured us by top level steering logic in debuginfo.c, 931 and it is re-checked at the start of 932 ML_(read_elf_debug_info). */ 933 vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); 934 if (level > 0 && ML_(find_rx_mapping)(di, aMin, aMax) == NULL) { 935 if (VG_(clo_verbosity) >= 0) { 936 VG_(message)(Vg_DebugMsg, 937 "warning: addVar: in range %#lx .. %#lx outside " 938 "all rx mapped areas (%s)\n", 939 aMin, aMax, name 940 ); 941 } 942 return; 943 } 944 945 /* If the type's size is zero (which can mean unknown size), ignore 946 it. We will never be able to actually relate a data address to 947 a data object with zero size, so there's no point in storing 948 info on it. On 32-bit platforms, also reject types whose size 949 is 2^32 bytes or large. (It's amazing what junk shows up ..) */ 950 mul = ML_(sizeOfType)(di->admin_tyents, typeR); 951 952 badness = NULL; 953 if (mul.b != True) 954 badness = "unknown size"; 955 else if (mul.ul == 0) 956 badness = "zero size "; 957 else if (sizeof(void*) == 4 && mul.ul >= (1ULL<<32)) 958 badness = "implausibly large"; 959 960 if (badness) { 961 static Int complaints = 10; 962 if (VG_(clo_verbosity) >= 2 && complaints > 0) { 963 VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)\n", 964 badness, name ); 965 complaints--; 966 } 967 return; 968 } 969 970 if (!di->varinfo) { 971 di->varinfo = VG_(newXA)( ML_(dinfo_zalloc), 972 "di.storage.addVar.1", 973 ML_(dinfo_free), 974 sizeof(OSet*) ); 975 } 976 977 vg_assert(level < 256); /* arbitrary; stay sane */ 978 /* Expand the top level array enough to map this level */ 979 while ( VG_(sizeXA)(di->varinfo) <= level ) { 980 DiAddrRange* nyu; 981 scope = VG_(OSetGen_Create)( offsetof(DiAddrRange,aMin), 982 ML_(cmp_for_DiAddrRange_range), 983 ML_(dinfo_zalloc), "di.storage.addVar.2", 984 ML_(dinfo_free) ); 985 vg_assert(scope); 986 if (0) VG_(printf)("create: scope = %p, adding at %ld\n", 987 scope, VG_(sizeXA)(di->varinfo)); 988 VG_(addToXA)( di->varinfo, &scope ); 989 /* Add a single range covering the entire address space. At 990 level 0 we require this doesn't get split. At levels above 0 991 we require that any additions to it cause it to get split. 992 All of these invariants get checked both add_var_to_arange 993 and after reading is complete, in canonicaliseVarInfo. */ 994 nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) ); 995 vg_assert(nyu); 996 nyu->aMin = (Addr)0; 997 nyu->aMax = ~(Addr)0; 998 nyu->vars = VG_(newXA)( ML_(dinfo_zalloc), "di.storage.addVar.3", 999 ML_(dinfo_free), 1000 sizeof(DiVariable) ); 1001 vg_assert(nyu->vars); 1002 VG_(OSetGen_Insert)( scope, nyu ); 1003 } 1004 1005 vg_assert( VG_(sizeXA)(di->varinfo) > level ); 1006 scope = *(OSet**)VG_(indexXA)( di->varinfo, level ); 1007 vg_assert(scope); 1008 1009 var.name = name; 1010 var.typeR = typeR; 1011 var.gexpr = gexpr; 1012 var.fbGX = fbGX; 1013 var.fileName = fileName; 1014 var.lineNo = lineNo; 1015 1016 all = aMin == (Addr)0 && aMax == ~(Addr)0; 1017 vg_assert(level == 0 ? all : !all); 1018 1019 add_var_to_arange( /*MOD*/scope, aMin, aMax, &var ); 1020 } 1021 1022 1023 /* This really just checks the constructed data structure, as there is 1024 no canonicalisation to do. */ 1025 static void canonicaliseVarInfo ( struct _DebugInfo* di ) 1026 { 1027 Word i, nInThisScope; 1028 1029 if (!di->varinfo) 1030 return; 1031 1032 for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 1033 1034 DiAddrRange *range, *rangep; 1035 OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 1036 if (!scope) continue; 1037 1038 /* Deal with the global-scope case. */ 1039 if (i == 0) { 1040 Addr zero = 0; 1041 vg_assert(VG_(OSetGen_Size)( scope ) == 1); 1042 range = VG_(OSetGen_Lookup)( scope, &zero ); 1043 vg_assert(range); 1044 vg_assert(range->aMin == (Addr)0); 1045 vg_assert(range->aMax == ~(Addr)0); 1046 continue; 1047 } 1048 1049 /* All the rest of this is for the local-scope case. */ 1050 /* iterate over all entries in 'scope' */ 1051 nInThisScope = 0; 1052 rangep = NULL; 1053 VG_(OSetGen_ResetIter)(scope); 1054 while (True) { 1055 range = VG_(OSetGen_Next)(scope); 1056 if (!range) { 1057 /* We just saw the last one. There must have been at 1058 least one entry in the range. */ 1059 vg_assert(rangep); 1060 vg_assert(rangep->aMax == ~(Addr)0); 1061 break; 1062 } 1063 1064 vg_assert(range->aMin <= range->aMax); 1065 vg_assert(range->vars); 1066 1067 if (!rangep) { 1068 /* This is the first entry in the range. */ 1069 vg_assert(range->aMin == 0); 1070 } else { 1071 vg_assert(rangep->aMax + 1 == range->aMin); 1072 } 1073 1074 rangep = range; 1075 nInThisScope++; 1076 } /* iterating over ranges in a given scope */ 1077 1078 /* If there's only one entry in this (local) scope, it must 1079 cover the entire address space (obviously), but it must not 1080 contain any vars. */ 1081 1082 vg_assert(nInThisScope > 0); 1083 if (nInThisScope == 1) { 1084 Addr zero = 0; 1085 vg_assert(VG_(OSetGen_Size)( scope ) == 1); 1086 range = VG_(OSetGen_Lookup)( scope, &zero ); 1087 vg_assert(range); 1088 vg_assert(range->aMin == (Addr)0); 1089 vg_assert(range->aMax == ~(Addr)0); 1090 vg_assert(range->vars); 1091 vg_assert(VG_(sizeXA)(range->vars) == 0); 1092 } 1093 1094 } /* iterate over scopes */ 1095 } 1096 1097 1098 /*------------------------------------------------------------*/ 1099 /*--- Canonicalisers ---*/ 1100 /*------------------------------------------------------------*/ 1101 1102 /* Sort the symtab by starting address, and emit warnings if any 1103 symbols have overlapping address ranges. We use that old chestnut, 1104 shellsort. Mash the table around so as to establish the property 1105 that addresses are in order and the ranges to not overlap. This 1106 facilitates using binary search to map addresses to symbols when we 1107 come to query the table. 1108 */ 1109 static Int compare_DiSym ( void* va, void* vb ) 1110 { 1111 DiSym* a = (DiSym*)va; 1112 DiSym* b = (DiSym*)vb; 1113 if (a->addr < b->addr) return -1; 1114 if (a->addr > b->addr) return 1; 1115 return 0; 1116 } 1117 1118 1119 /* An address is associated with more than one name. Which do we 1120 prefer as the "display" name (that we show the user in stack 1121 traces)? In order: 1122 1123 - Prefer "PMPI_<foo>" over "MPI_<foo>". 1124 1125 - Else, prefer a non-empty name over an empty one. 1126 1127 - Else, prefer a non-whitespace name over an all-whitespace name. 1128 1129 - Else, prefer the shorter symbol name. If the symbol contains a 1130 version symbol ('@' on Linux, other platforms may differ), which means it 1131 is versioned, then the length up to the version symbol is used for length 1132 comparison purposes (so "foo (at) GLIBC_2.4.2" is considered shorter than 1133 "foobar"). 1134 1135 - Else, if two symbols have the same length, prefer a versioned symbol over 1136 a non-versioned symbol. 1137 1138 - Else, use alphabetical ordering. 1139 1140 - Otherwise, they must be the same; use the name with the lower address. 1141 1142 Very occasionally this goes wrong (eg. 'memcmp' and 'bcmp' are 1143 aliases in glibc, we choose the 'bcmp' symbol because it's shorter, 1144 so we can misdescribe memcmp() as bcmp()). This is hard to avoid. 1145 It's mentioned in the FAQ file. 1146 1147 Returned value is True if a_name is preferred, False if b_name is 1148 preferred. 1149 */ 1150 static 1151 Bool preferName ( struct _DebugInfo* di, 1152 UChar* a_name, UChar* b_name, 1153 Addr sym_avma/*exposition only*/ ) 1154 { 1155 Word cmp; 1156 Word vlena, vlenb; /* length without version */ 1157 const UChar *vpa, *vpb; 1158 1159 Bool preferA = False; 1160 Bool preferB = False; 1161 1162 vg_assert(a_name); 1163 vg_assert(b_name); 1164 vg_assert(a_name != b_name); 1165 1166 vlena = VG_(strlen)(a_name); 1167 vlenb = VG_(strlen)(b_name); 1168 1169 # if defined(VGO_linux) 1170 # define VERSION_CHAR '@' 1171 # elif defined(VGO_darwin) 1172 # define VERSION_CHAR '$' 1173 # else 1174 # error Unknown OS 1175 # endif 1176 1177 vpa = VG_(strchr)(a_name, VERSION_CHAR); 1178 vpb = VG_(strchr)(b_name, VERSION_CHAR); 1179 1180 # undef VERSION_CHAR 1181 1182 if (vpa) 1183 vlena = vpa - a_name; 1184 if (vpb) 1185 vlenb = vpb - b_name; 1186 1187 /* MPI hack: prefer PMPI_Foo over MPI_Foo */ 1188 if (0==VG_(strncmp)(a_name, "MPI_", 4) 1189 && 0==VG_(strncmp)(b_name, "PMPI_", 5) 1190 && 0==VG_(strcmp)(a_name, 1+b_name)) { 1191 preferB = True; goto out; 1192 } 1193 if (0==VG_(strncmp)(b_name, "MPI_", 4) 1194 && 0==VG_(strncmp)(a_name, "PMPI_", 5) 1195 && 0==VG_(strcmp)(b_name, 1+a_name)) { 1196 preferA = True; goto out; 1197 } 1198 1199 /* Prefer non-empty name. */ 1200 if (vlena && !vlenb) { 1201 preferA = True; goto out; 1202 } 1203 if (vlenb && !vlena) { 1204 preferB = True; goto out; 1205 } 1206 1207 /* Prefer non-whitespace name. */ 1208 { 1209 Bool blankA = True; 1210 Bool blankB = True; 1211 Char *s; 1212 s = a_name; 1213 while (*s) { 1214 if (!VG_(isspace)(*s++)) { 1215 blankA = False; 1216 break; 1217 } 1218 } 1219 s = b_name; 1220 while (*s) { 1221 if (!VG_(isspace)(*s++)) { 1222 blankB = False; 1223 break; 1224 } 1225 } 1226 1227 if (!blankA && blankB) { 1228 preferA = True; goto out; 1229 } 1230 if (!blankB && blankA) { 1231 preferB = True; goto out; 1232 } 1233 } 1234 1235 /* Select the shortest unversioned name */ 1236 if (vlena < vlenb) { 1237 preferA = True; goto out; 1238 } 1239 if (vlenb < vlena) { 1240 preferB = True; goto out; 1241 } 1242 1243 /* Equal lengths; select the versioned name */ 1244 if (vpa && !vpb) { 1245 preferA = True; goto out; 1246 } 1247 if (vpb && !vpa) { 1248 preferB = True; goto out; 1249 } 1250 1251 /* Either both versioned or neither is versioned; select them 1252 alphabetically */ 1253 cmp = VG_(strcmp)(a_name, b_name); 1254 if (cmp < 0) { 1255 preferA = True; goto out; 1256 } 1257 if (cmp > 0) { 1258 preferB = True; goto out; 1259 } 1260 1261 /* If we get here, they are the same name. */ 1262 1263 /* In this case we could choose either (arbitrarily), but might as 1264 well choose the one with the lowest DiSym* address, so as to try 1265 and make the comparison mechanism more stable (a la sorting 1266 parlance). Also, skip the diagnostic printing in this case. */ 1267 return a_name <= b_name ? True : False; 1268 1269 /*NOTREACHED*/ 1270 vg_assert(0); 1271 out: 1272 if (preferA && !preferB) { 1273 TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n", 1274 sym_avma, a_name, b_name ); 1275 return True; 1276 } 1277 if (preferB && !preferA) { 1278 TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n", 1279 sym_avma, b_name, a_name ); 1280 return False; 1281 } 1282 /*NOTREACHED*/ 1283 vg_assert(0); 1284 } 1285 1286 1287 /* Add the names in FROM to the names in TO. */ 1288 static 1289 void add_DiSym_names_to_from ( DebugInfo* di, DiSym* to, DiSym* from ) 1290 { 1291 vg_assert(to->pri_name); 1292 vg_assert(from->pri_name); 1293 /* Figure out how many names there will be in the new combined 1294 secondary vector. */ 1295 UChar** to_sec = to->sec_names; 1296 UChar** from_sec = from->sec_names; 1297 Word n_new_sec = 1; 1298 if (from_sec) { 1299 while (*from_sec) { 1300 n_new_sec++; 1301 from_sec++; 1302 } 1303 } 1304 if (to_sec) { 1305 while (*to_sec) { 1306 n_new_sec++; 1307 to_sec++; 1308 } 1309 } 1310 if (0) 1311 TRACE_SYMTAB("merge: -> %ld\n", n_new_sec); 1312 /* Create the new sec and copy stuff into it, putting the new 1313 entries at the end. */ 1314 UChar** new_sec = ML_(dinfo_zalloc)( "di.storage.aDntf.1", 1315 (n_new_sec+1) * sizeof(UChar*) ); 1316 from_sec = from->sec_names; 1317 to_sec = to->sec_names; 1318 Word i = 0; 1319 if (to_sec) { 1320 while (*to_sec) { 1321 new_sec[i++] = *to_sec; 1322 to_sec++; 1323 } 1324 } 1325 new_sec[i++] = from->pri_name; 1326 if (from_sec) { 1327 while (*from_sec) { 1328 new_sec[i++] = *from_sec; 1329 from_sec++; 1330 } 1331 } 1332 vg_assert(i == n_new_sec); 1333 vg_assert(new_sec[i] == NULL); 1334 /* If we're replacing an existing secondary vector, free it. */ 1335 if (to->sec_names) { 1336 ML_(dinfo_free)(to->sec_names); 1337 } 1338 to->sec_names = new_sec; 1339 } 1340 1341 1342 static void canonicaliseSymtab ( struct _DebugInfo* di ) 1343 { 1344 Word i, j, n_truncated; 1345 Addr sta1, sta2, end1, end2, toc1, toc2; 1346 UChar *pri1, *pri2, **sec1, **sec2; 1347 Bool ist1, ist2, isf1, isf2; 1348 1349 # define SWAP(ty,aa,bb) \ 1350 do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0) 1351 1352 if (di->symtab_used == 0) 1353 return; 1354 1355 /* Check initial invariants */ 1356 for (i = 0; i < di->symtab_used; i++) { 1357 DiSym* sym = &di->symtab[i]; 1358 vg_assert(sym->pri_name); 1359 vg_assert(!sym->sec_names); 1360 } 1361 1362 /* Sort by address. */ 1363 VG_(ssort)(di->symtab, di->symtab_used, 1364 sizeof(*di->symtab), compare_DiSym); 1365 1366 cleanup_more: 1367 1368 /* If two symbols have identical address ranges, and agree on 1369 .isText and .isIFunc, merge them into a single entry, but 1370 preserve both names, so we end up knowing all the names for that 1371 particular address range. */ 1372 while (1) { 1373 Word r, w, n_merged; 1374 n_merged = 0; 1375 w = 0; 1376 /* A pass merging entries together */ 1377 for (r = 1; r < di->symtab_used; r++) { 1378 vg_assert(w < r); 1379 if ( di->symtab[w].addr == di->symtab[r].addr 1380 && di->symtab[w].size == di->symtab[r].size 1381 && !!di->symtab[w].isText == !!di->symtab[r].isText) { 1382 /* merge the two into one */ 1383 n_merged++; 1384 /* Add r names to w if r has secondary names 1385 or r and w primary names differ. */ 1386 if (di->symtab[r].sec_names 1387 || (0 != VG_(strcmp)(di->symtab[r].pri_name, 1388 di->symtab[w].pri_name))) { 1389 add_DiSym_names_to_from(di, &di->symtab[w], &di->symtab[r]); 1390 } 1391 /* mark w as an IFunc if either w or r are */ 1392 di->symtab[w].isIFunc = di->symtab[w].isIFunc || di->symtab[r].isIFunc; 1393 /* and use ::pri_names to indicate this slot is no longer in use */ 1394 di->symtab[r].pri_name = NULL; 1395 if (di->symtab[r].sec_names) { 1396 ML_(dinfo_free)(di->symtab[r].sec_names); 1397 di->symtab[r].sec_names = NULL; 1398 } 1399 /* Completely zap the entry -- paranoia to make it more 1400 likely we'll notice if we inadvertantly use it 1401 again. */ 1402 VG_(memset)(&di->symtab[r], 0, sizeof(DiSym)); 1403 } else { 1404 w = r; 1405 } 1406 } 1407 TRACE_SYMTAB( "canonicaliseSymtab: %ld symbols merged\n", n_merged); 1408 if (n_merged == 0) 1409 break; 1410 /* Now a pass to squeeze out any unused ones */ 1411 w = 0; 1412 for (r = 0; r < di->symtab_used; r++) { 1413 vg_assert(w <= r); 1414 if (di->symtab[r].pri_name == NULL) 1415 continue; 1416 if (w < r) { 1417 di->symtab[w] = di->symtab[r]; 1418 } 1419 w++; 1420 } 1421 vg_assert(w + n_merged == di->symtab_used); 1422 di->symtab_used = w; 1423 } 1424 1425 /* Detect and "fix" overlapping address ranges. */ 1426 n_truncated = 0; 1427 1428 for (i = 0; i < ((Word)di->symtab_used) -1; i++) { 1429 1430 vg_assert(di->symtab[i].addr <= di->symtab[i+1].addr); 1431 1432 /* Check for common (no overlap) case. */ 1433 if (di->symtab[i].addr + di->symtab[i].size 1434 <= di->symtab[i+1].addr) 1435 continue; 1436 1437 /* There's an overlap. Truncate one or the other. */ 1438 if (di->trace_symtab) { 1439 VG_(printf)("overlapping address ranges in symbol table\n\t"); 1440 ML_(ppSym)( i, &di->symtab[i] ); 1441 VG_(printf)("\t"); 1442 ML_(ppSym)( i+1, &di->symtab[i+1] ); 1443 VG_(printf)("\n"); 1444 } 1445 1446 /* Truncate one or the other. */ 1447 sta1 = di->symtab[i].addr; 1448 end1 = sta1 + di->symtab[i].size - 1; 1449 toc1 = di->symtab[i].tocptr; 1450 pri1 = di->symtab[i].pri_name; 1451 sec1 = di->symtab[i].sec_names; 1452 ist1 = di->symtab[i].isText; 1453 isf1 = di->symtab[i].isIFunc; 1454 1455 sta2 = di->symtab[i+1].addr; 1456 end2 = sta2 + di->symtab[i+1].size - 1; 1457 toc2 = di->symtab[i+1].tocptr; 1458 pri2 = di->symtab[i+1].pri_name; 1459 sec2 = di->symtab[i+1].sec_names; 1460 ist2 = di->symtab[i+1].isText; 1461 isf2 = di->symtab[i+1].isIFunc; 1462 1463 if (sta1 < sta2) { 1464 end1 = sta2 - 1; 1465 } else { 1466 vg_assert(sta1 == sta2); 1467 if (end1 > end2) { 1468 sta1 = end2 + 1; 1469 SWAP(Addr,sta1,sta2); SWAP(Addr,end1,end2); SWAP(Addr,toc1,toc2); 1470 SWAP(UChar*,pri1,pri2); SWAP(UChar**,sec1,sec2); 1471 SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2); 1472 } else 1473 if (end1 < end2) { 1474 sta2 = end1 + 1; 1475 } else { 1476 /* end1 == end2. Identical addr ranges. We'll eventually wind 1477 up back at cleanup_more, which will take care of it. */ 1478 } 1479 } 1480 di->symtab[i].addr = sta1; 1481 di->symtab[i].size = end1 - sta1 + 1; 1482 di->symtab[i].tocptr = toc1; 1483 di->symtab[i].pri_name = pri1; 1484 di->symtab[i].sec_names = sec1; 1485 di->symtab[i].isText = ist1; 1486 di->symtab[i].isIFunc = isf1; 1487 1488 di->symtab[i+1].addr = sta2; 1489 di->symtab[i+1].size = end2 - sta2 + 1; 1490 di->symtab[i+1].tocptr = toc2; 1491 di->symtab[i+1].pri_name = pri2; 1492 di->symtab[i+1].sec_names = sec2; 1493 di->symtab[i+1].isText = ist2; 1494 di->symtab[i+1].isIFunc = isf2; 1495 1496 vg_assert(sta1 <= sta2); 1497 vg_assert(di->symtab[i].size > 0); 1498 vg_assert(di->symtab[i+1].size > 0); 1499 /* It may be that the i+1 entry now needs to be moved further 1500 along to maintain the address order requirement. */ 1501 j = i+1; 1502 while (j < ((Word)di->symtab_used)-1 1503 && di->symtab[j].addr > di->symtab[j+1].addr) { 1504 SWAP(DiSym,di->symtab[j],di->symtab[j+1]); 1505 j++; 1506 } 1507 n_truncated++; 1508 } 1509 1510 if (n_truncated > 0) goto cleanup_more; 1511 1512 /* Ensure relevant postconditions hold. */ 1513 for (i = 0; i < ((Word)di->symtab_used)-1; i++) { 1514 /* No zero-sized symbols. */ 1515 vg_assert(di->symtab[i].size > 0); 1516 /* In order. */ 1517 vg_assert(di->symtab[i].addr < di->symtab[i+1].addr); 1518 /* No overlaps. */ 1519 vg_assert(di->symtab[i].addr + di->symtab[i].size - 1 1520 < di->symtab[i+1].addr); 1521 /* Names are sane(ish) */ 1522 vg_assert(di->symtab[i].pri_name); 1523 if (di->symtab[i].sec_names) { 1524 vg_assert(di->symtab[i].sec_names[0]); 1525 } 1526 } 1527 1528 /* For each symbol that has more than one name, use preferName to 1529 select the primary name. This is a complete kludge in that 1530 doing it properly requires making a total ordering on the 1531 candidate names, whilst what we have to work with is an ad-hoc 1532 binary relation (preferName) that certainly doesn't have the 1533 relevant transitivity etc properties that are needed to induce a 1534 legitimate total order. Doesn't matter though if it doesn't 1535 always work right since this is only used to generate names to 1536 show the user. */ 1537 for (i = 0; i < ((Word)di->symtab_used)-1; i++) { 1538 DiSym* sym = &di->symtab[i]; 1539 UChar** sec = sym->sec_names; 1540 if (!sec) 1541 continue; 1542 /* Slow but simple. Copy all the cands into a temp array, 1543 choose the primary name, and copy them all back again. */ 1544 Word n_tmp = 1; 1545 while (*sec) { n_tmp++; sec++; } 1546 j = 0; 1547 UChar** tmp = ML_(dinfo_zalloc)( "di.storage.cS.1", 1548 (n_tmp+1) * sizeof(UChar*) ); 1549 tmp[j++] = sym->pri_name; 1550 sec = sym->sec_names; 1551 while (*sec) { tmp[j++] = *sec; sec++; } 1552 vg_assert(j == n_tmp); 1553 vg_assert(tmp[n_tmp] == NULL); /* because of zalloc */ 1554 /* Choose the most favoured. */ 1555 Word best = 0; 1556 for (j = 1; j < n_tmp; j++) { 1557 if (preferName(di, tmp[best], tmp[j], di->symtab[i].addr)) { 1558 /* best is unchanged */ 1559 } else { 1560 best = j; 1561 } 1562 } 1563 vg_assert(best >= 0 && best < n_tmp); 1564 /* Copy back */ 1565 sym->pri_name = tmp[best]; 1566 UChar** cursor = sym->sec_names; 1567 for (j = 0; j < n_tmp; j++) { 1568 if (j == best) 1569 continue; 1570 *cursor = tmp[j]; 1571 cursor++; 1572 } 1573 vg_assert(*cursor == NULL); 1574 ML_(dinfo_free)( tmp ); 1575 } 1576 1577 # undef SWAP 1578 } 1579 1580 1581 /* Sort the location table by starting address. Mash the table around 1582 so as to establish the property that addresses are in order and the 1583 ranges do not overlap. This facilitates using binary search to map 1584 addresses to locations when we come to query the table. 1585 */ 1586 static Int compare_DiLoc ( void* va, void* vb ) 1587 { 1588 DiLoc* a = (DiLoc*)va; 1589 DiLoc* b = (DiLoc*)vb; 1590 if (a->addr < b->addr) return -1; 1591 if (a->addr > b->addr) return 1; 1592 return 0; 1593 } 1594 1595 static void canonicaliseLoctab ( struct _DebugInfo* di ) 1596 { 1597 Word i, j; 1598 1599 # define SWAP(ty,aa,bb) \ 1600 do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0); 1601 1602 if (di->loctab_used == 0) 1603 return; 1604 1605 /* Sort by start address. */ 1606 VG_(ssort)(di->loctab, di->loctab_used, 1607 sizeof(*di->loctab), compare_DiLoc); 1608 1609 /* If two adjacent entries overlap, truncate the first. */ 1610 for (i = 0; i < ((Word)di->loctab_used)-1; i++) { 1611 vg_assert(di->loctab[i].size < 10000); 1612 if (di->loctab[i].addr + di->loctab[i].size > di->loctab[i+1].addr) { 1613 /* Do this in signed int32 because the actual .size fields 1614 are only 12 bits. */ 1615 Int new_size = di->loctab[i+1].addr - di->loctab[i].addr; 1616 if (new_size < 0) { 1617 di->loctab[i].size = 0; 1618 } else 1619 if (new_size > MAX_LOC_SIZE) { 1620 di->loctab[i].size = MAX_LOC_SIZE; 1621 } else { 1622 di->loctab[i].size = (UShort)new_size; 1623 } 1624 } 1625 } 1626 1627 /* Zap any zero-sized entries resulting from the truncation 1628 process. */ 1629 j = 0; 1630 for (i = 0; i < (Word)di->loctab_used; i++) { 1631 if (di->loctab[i].size > 0) { 1632 if (j != i) 1633 di->loctab[j] = di->loctab[i]; 1634 j++; 1635 } 1636 } 1637 di->loctab_used = j; 1638 1639 /* Ensure relevant postconditions hold. */ 1640 for (i = 0; i < ((Word)di->loctab_used)-1; i++) { 1641 /* 1642 VG_(printf)("%d (%d) %d 0x%x\n", 1643 i, di->loctab[i+1].confident, 1644 di->loctab[i+1].size, di->loctab[i+1].addr ); 1645 */ 1646 /* No zero-sized symbols. */ 1647 vg_assert(di->loctab[i].size > 0); 1648 /* In order. */ 1649 vg_assert(di->loctab[i].addr < di->loctab[i+1].addr); 1650 /* No overlaps. */ 1651 vg_assert(di->loctab[i].addr + di->loctab[i].size - 1 1652 < di->loctab[i+1].addr); 1653 } 1654 # undef SWAP 1655 1656 /* Free up unused space at the end of the table. */ 1657 shrinkLocTab(di); 1658 } 1659 1660 1661 /* Sort the call-frame-info table by starting address. Mash the table 1662 around so as to establish the property that addresses are in order 1663 and the ranges do not overlap. This facilitates using binary 1664 search to map addresses to locations when we come to query the 1665 table. 1666 1667 Also, set cfisi_minaddr and cfisi_maxaddr to be the min and max of 1668 any of the address ranges contained in cfisi[0 .. cfisi_used-1], so 1669 as to facilitate rapidly skipping this SegInfo when looking for an 1670 address which falls outside that range. 1671 */ 1672 static Int compare_DiCfSI ( void* va, void* vb ) 1673 { 1674 DiCfSI* a = (DiCfSI*)va; 1675 DiCfSI* b = (DiCfSI*)vb; 1676 if (a->base < b->base) return -1; 1677 if (a->base > b->base) return 1; 1678 return 0; 1679 } 1680 1681 void ML_(canonicaliseCFI) ( struct _DebugInfo* di ) 1682 { 1683 Word i, j; 1684 const Addr minAvma = 0; 1685 const Addr maxAvma = ~minAvma; 1686 1687 /* Note: take care in here. di->cfsi can be NULL, in which 1688 case _used and _size fields will be zero. */ 1689 if (di->cfsi == NULL) { 1690 vg_assert(di->cfsi_used == 0); 1691 vg_assert(di->cfsi_size == 0); 1692 } 1693 1694 /* Set cfsi_minavma and cfsi_maxavma to summarise the entire 1695 address range contained in cfsi[0 .. cfsi_used-1]. */ 1696 di->cfsi_minavma = maxAvma; 1697 di->cfsi_maxavma = minAvma; 1698 for (i = 0; i < (Word)di->cfsi_used; i++) { 1699 Addr here_min = di->cfsi[i].base; 1700 Addr here_max = di->cfsi[i].base + di->cfsi[i].len - 1; 1701 if (here_min < di->cfsi_minavma) 1702 di->cfsi_minavma = here_min; 1703 if (here_max > di->cfsi_maxavma) 1704 di->cfsi_maxavma = here_max; 1705 } 1706 1707 if (di->trace_cfi) 1708 VG_(printf)("canonicaliseCfiSI: %ld entries, %#lx .. %#lx\n", 1709 di->cfsi_used, 1710 di->cfsi_minavma, di->cfsi_maxavma); 1711 1712 /* Sort the cfsi array by base address. */ 1713 VG_(ssort)(di->cfsi, di->cfsi_used, sizeof(*di->cfsi), compare_DiCfSI); 1714 1715 /* If two adjacent entries overlap, truncate the first. */ 1716 for (i = 0; i < (Word)di->cfsi_used-1; i++) { 1717 if (di->cfsi[i].base + di->cfsi[i].len > di->cfsi[i+1].base) { 1718 Word new_len = di->cfsi[i+1].base - di->cfsi[i].base; 1719 /* how could it be otherwise? The entries are sorted by the 1720 .base field. */ 1721 vg_assert(new_len >= 0); 1722 vg_assert(new_len <= di->cfsi[i].len); 1723 di->cfsi[i].len = new_len; 1724 } 1725 } 1726 1727 /* Zap any zero-sized entries resulting from the truncation 1728 process. */ 1729 j = 0; 1730 for (i = 0; i < (Word)di->cfsi_used; i++) { 1731 if (di->cfsi[i].len > 0) { 1732 if (j != i) 1733 di->cfsi[j] = di->cfsi[i]; 1734 j++; 1735 } 1736 } 1737 /* VG_(printf)("XXXXXXXXXXXXX %d %d\n", di->cfsi_used, j); */ 1738 di->cfsi_used = j; 1739 1740 /* Ensure relevant postconditions hold. */ 1741 for (i = 0; i < (Word)di->cfsi_used; i++) { 1742 /* No zero-length ranges. */ 1743 vg_assert(di->cfsi[i].len > 0); 1744 /* Makes sense w.r.t. summary address range */ 1745 vg_assert(di->cfsi[i].base >= di->cfsi_minavma); 1746 vg_assert(di->cfsi[i].base + di->cfsi[i].len - 1 1747 <= di->cfsi_maxavma); 1748 1749 if (i < di->cfsi_used - 1) { 1750 /* 1751 if (!(di->cfsi[i].base < di->cfsi[i+1].base)) { 1752 VG_(printf)("\nOOO cfsis:\n"); 1753 ML_(ppCfiSI)(&di->cfsi[i]); 1754 ML_(ppCfiSI)(&di->cfsi[i+1]); 1755 } 1756 */ 1757 /* In order. */ 1758 vg_assert(di->cfsi[i].base < di->cfsi[i+1].base); 1759 /* No overlaps. */ 1760 vg_assert(di->cfsi[i].base + di->cfsi[i].len - 1 1761 < di->cfsi[i+1].base); 1762 } 1763 } 1764 1765 } 1766 1767 1768 /* Canonicalise the tables held by 'di', in preparation for use. Call 1769 this after finishing adding entries to these tables. */ 1770 void ML_(canonicaliseTables) ( struct _DebugInfo* di ) 1771 { 1772 canonicaliseSymtab ( di ); 1773 canonicaliseLoctab ( di ); 1774 ML_(canonicaliseCFI) ( di ); 1775 canonicaliseVarInfo ( di ); 1776 } 1777 1778 1779 /*------------------------------------------------------------*/ 1780 /*--- Searching the tables ---*/ 1781 /*------------------------------------------------------------*/ 1782 1783 /* Find a symbol-table index containing the specified pointer, or -1 1784 if not found. Binary search. */ 1785 1786 Word ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr, 1787 Bool match_anywhere_in_sym, 1788 Bool findText ) 1789 { 1790 Addr a_mid_lo, a_mid_hi; 1791 Word mid, size, 1792 lo = 0, 1793 hi = di->symtab_used-1; 1794 while (True) { 1795 /* current unsearched space is from lo to hi, inclusive. */ 1796 if (lo > hi) return -1; /* not found */ 1797 mid = (lo + hi) / 2; 1798 a_mid_lo = di->symtab[mid].addr; 1799 size = ( match_anywhere_in_sym 1800 ? di->symtab[mid].size 1801 : 1); 1802 a_mid_hi = ((Addr)di->symtab[mid].addr) + size - 1; 1803 1804 if (ptr < a_mid_lo) { hi = mid-1; continue; } 1805 if (ptr > a_mid_hi) { lo = mid+1; continue; } 1806 vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi); 1807 /* Found a symbol with the correct address range. But is it 1808 of the right kind (text vs data) ? */ 1809 if ( findText && di->symtab[mid].isText ) return mid; 1810 if ( (!findText) && (!di->symtab[mid].isText) ) return mid; 1811 return -1; 1812 } 1813 } 1814 1815 1816 /* Find a location-table index containing the specified pointer, or -1 1817 if not found. Binary search. */ 1818 1819 Word ML_(search_one_loctab) ( struct _DebugInfo* di, Addr ptr ) 1820 { 1821 Addr a_mid_lo, a_mid_hi; 1822 Word mid, 1823 lo = 0, 1824 hi = di->loctab_used-1; 1825 while (True) { 1826 /* current unsearched space is from lo to hi, inclusive. */ 1827 if (lo > hi) return -1; /* not found */ 1828 mid = (lo + hi) / 2; 1829 a_mid_lo = di->loctab[mid].addr; 1830 a_mid_hi = ((Addr)di->loctab[mid].addr) + di->loctab[mid].size - 1; 1831 1832 if (ptr < a_mid_lo) { hi = mid-1; continue; } 1833 if (ptr > a_mid_hi) { lo = mid+1; continue; } 1834 vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi); 1835 return mid; 1836 } 1837 } 1838 1839 1840 /* Find a CFI-table index containing the specified pointer, or -1 1841 if not found. Binary search. */ 1842 1843 Word ML_(search_one_cfitab) ( struct _DebugInfo* di, Addr ptr ) 1844 { 1845 Addr a_mid_lo, a_mid_hi; 1846 Word mid, size, 1847 lo = 0, 1848 hi = di->cfsi_used-1; 1849 while (True) { 1850 /* current unsearched space is from lo to hi, inclusive. */ 1851 if (lo > hi) return -1; /* not found */ 1852 mid = (lo + hi) / 2; 1853 a_mid_lo = di->cfsi[mid].base; 1854 size = di->cfsi[mid].len; 1855 a_mid_hi = a_mid_lo + size - 1; 1856 vg_assert(a_mid_hi >= a_mid_lo); 1857 if (ptr < a_mid_lo) { hi = mid-1; continue; } 1858 if (ptr > a_mid_hi) { lo = mid+1; continue; } 1859 vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi); 1860 return mid; 1861 } 1862 } 1863 1864 1865 /* Find a FPO-table index containing the specified pointer, or -1 1866 if not found. Binary search. */ 1867 1868 Word ML_(search_one_fpotab) ( struct _DebugInfo* di, Addr ptr ) 1869 { 1870 Addr const addr = ptr - di->fpo_base_avma; 1871 Addr a_mid_lo, a_mid_hi; 1872 Word mid, size, 1873 lo = 0, 1874 hi = di->fpo_size-1; 1875 while (True) { 1876 /* current unsearched space is from lo to hi, inclusive. */ 1877 if (lo > hi) return -1; /* not found */ 1878 mid = (lo + hi) / 2; 1879 a_mid_lo = di->fpo[mid].ulOffStart; 1880 size = di->fpo[mid].cbProcSize; 1881 a_mid_hi = a_mid_lo + size - 1; 1882 vg_assert(a_mid_hi >= a_mid_lo); 1883 if (addr < a_mid_lo) { hi = mid-1; continue; } 1884 if (addr > a_mid_hi) { lo = mid+1; continue; } 1885 vg_assert(addr >= a_mid_lo && addr <= a_mid_hi); 1886 return mid; 1887 } 1888 } 1889 1890 /*--------------------------------------------------------------------*/ 1891 /*--- end ---*/ 1892 /*--------------------------------------------------------------------*/ 1893