readelf.c revision 7b94a0dca726691868a1a8c3c1ae47f77871d9e0
1 2/*--------------------------------------------------------------------*/ 3/*--- Reading of syms & debug info from ELF .so/executable files. ---*/ 4/*--- readelf.c ---*/ 5/*--------------------------------------------------------------------*/ 6 7/* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2012 Julian Seward 12 jseward@acm.org 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30*/ 31 32#if defined(VGO_linux) 33 34#include "pub_core_basics.h" 35#include "pub_core_vki.h" 36#include "pub_core_debuginfo.h" 37#include "pub_core_libcbase.h" 38#include "pub_core_libcprint.h" 39#include "pub_core_libcassert.h" 40#include "pub_core_machine.h" /* VG_ELF_CLASS */ 41#include "pub_core_options.h" 42#include "pub_core_oset.h" 43#include "pub_core_tooliface.h" /* VG_(needs) */ 44#include "pub_core_xarray.h" 45#include "priv_misc.h" /* dinfo_zalloc/free/strdup */ 46#include "priv_image.h" 47#include "priv_d3basics.h" 48#include "priv_tytypes.h" 49#include "priv_storage.h" 50#include "priv_readelf.h" /* self */ 51#include "priv_readdwarf.h" /* 'cos ELF contains DWARF */ 52#include "priv_readdwarf3.h" 53#include "priv_readstabs.h" /* and stabs, if we're unlucky */ 54 55/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ 56#include <elf.h> 57/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ 58 59/*------------------------------------------------------------*/ 60/*--- 32/64-bit parameterisation ---*/ 61/*------------------------------------------------------------*/ 62 63/* For all the ELF macros and types which specify '32' or '64', 64 select the correct variant for this platform and give it 65 an 'XX' name. Then use the 'XX' variant consistently in 66 the rest of this file. 67*/ 68#if VG_WORDSIZE == 4 69# define ElfXX_Ehdr Elf32_Ehdr 70# define ElfXX_Shdr Elf32_Shdr 71# define ElfXX_Phdr Elf32_Phdr 72# define ElfXX_Nhdr Elf32_Nhdr 73# define ElfXX_Sym Elf32_Sym 74# define ElfXX_Off Elf32_Off 75# define ElfXX_Word Elf32_Word 76# define ElfXX_Addr Elf32_Addr 77# define ElfXX_Dyn Elf32_Dyn 78# define ELFXX_ST_BIND ELF32_ST_BIND 79# define ELFXX_ST_TYPE ELF32_ST_TYPE 80 81#elif VG_WORDSIZE == 8 82# define ElfXX_Ehdr Elf64_Ehdr 83# define ElfXX_Shdr Elf64_Shdr 84# define ElfXX_Phdr Elf64_Phdr 85# define ElfXX_Nhdr Elf64_Nhdr 86# define ElfXX_Sym Elf64_Sym 87# define ElfXX_Off Elf64_Off 88# define ElfXX_Word Elf64_Word 89# define ElfXX_Addr Elf64_Addr 90# define ElfXX_Dyn Elf64_Dyn 91# define ELFXX_ST_BIND ELF64_ST_BIND 92# define ELFXX_ST_TYPE ELF64_ST_TYPE 93 94#else 95# error "VG_WORDSIZE should be 4 or 8" 96#endif 97 98 99/*------------------------------------------------------------*/ 100/*--- ---*/ 101/*--- Read symbol table and line info from ELF files. ---*/ 102/*--- ---*/ 103/*------------------------------------------------------------*/ 104 105/* readelf.c parses ELF files and acquires symbol table info from 106 them. It calls onwards to readdwarf.c to read DWARF2/3 line number 107 and call frame info found. */ 108 109/* Identify an ELF object file by peering at the first few bytes of 110 it. */ 111 112Bool ML_(is_elf_object_file)( void* image, SizeT n_image, Bool rel_ok ) 113{ 114 ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image; 115 Int ok = 1; 116 117 if (n_image < sizeof(ElfXX_Ehdr)) 118 return False; 119 120 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F 121 && ehdr->e_ident[EI_MAG1] == 'E' 122 && ehdr->e_ident[EI_MAG2] == 'L' 123 && ehdr->e_ident[EI_MAG3] == 'F'); 124 ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS 125 && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX 126 && ehdr->e_ident[EI_VERSION] == EV_CURRENT); 127 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN 128 || (rel_ok && ehdr->e_type == ET_REL)); 129 ok &= (ehdr->e_machine == VG_ELF_MACHINE); 130 ok &= (ehdr->e_version == EV_CURRENT); 131 ok &= (ehdr->e_shstrndx != SHN_UNDEF); 132 ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0); 133 ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0) 134 || ehdr->e_type == ET_REL); 135 136 return ok ? True : False; 137} 138 139 140/* The same thing, but operating on a DiImage instead. */ 141 142static Bool is_elf_object_file_by_DiImage( DiImage* img, Bool rel_ok ) 143{ 144 /* Be sure this doesn't make the frame too big. */ 145 vg_assert(sizeof(ElfXX_Ehdr) <= 512); 146 147 ElfXX_Ehdr ehdr; 148 if (!ML_(img_valid)(img, 0, sizeof(ehdr))) 149 return False; 150 151 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr)); 152 return ML_(is_elf_object_file)( &ehdr, sizeof(ehdr), rel_ok ); 153} 154 155 156/* Show a raw ELF symbol, given its in-image address and name. */ 157 158static 159void show_raw_elf_symbol ( DiImage* strtab_img, 160 Int i, 161 ElfXX_Sym* sym, 162 DiOffT sym_name_ioff, Addr sym_svma, 163 Bool ppc64_linux_format ) 164{ 165 const HChar* space = ppc64_linux_format ? " " : ""; 166 VG_(printf)("raw symbol [%4d]: ", i); 167 switch (ELFXX_ST_BIND(sym->st_info)) { 168 case STB_LOCAL: VG_(printf)("LOC "); break; 169 case STB_GLOBAL: VG_(printf)("GLO "); break; 170 case STB_WEAK: VG_(printf)("WEA "); break; 171 case STB_LOPROC: VG_(printf)("lop "); break; 172 case STB_HIPROC: VG_(printf)("hip "); break; 173 default: VG_(printf)("??? "); break; 174 } 175 switch (ELFXX_ST_TYPE(sym->st_info)) { 176 case STT_NOTYPE: VG_(printf)("NOT "); break; 177 case STT_OBJECT: VG_(printf)("OBJ "); break; 178 case STT_FUNC: VG_(printf)("FUN "); break; 179 case STT_SECTION: VG_(printf)("SEC "); break; 180 case STT_FILE: VG_(printf)("FIL "); break; 181 case STT_LOPROC: VG_(printf)("lop "); break; 182 case STT_HIPROC: VG_(printf)("hip "); break; 183 default: VG_(printf)("??? "); break; 184 } 185 HChar* sym_name = NULL; 186 if (sym->st_name) 187 sym_name = ML_(img_strdup)(strtab_img, "di.sres.1", sym_name_ioff); 188 VG_(printf)(": svma %#010lx, %ssz %4ld %s\n", 189 sym_svma, space, sym->st_size + 0UL, 190 (sym_name ? sym_name : "NONAME") ); 191 if (sym_name) 192 ML_(dinfo_free)(sym_name); 193} 194 195 196/* Decide whether SYM is something we should collect, and if so, copy 197 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux 198 this is straightforward - the name, address, size are copied out 199 unchanged. 200 201 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK 202 below): we assume that the .bss is mapped immediately after .data, 203 and so accept any data symbol which exists in the range [start of 204 .data, size of .data + size of .bss). I don't know if this is 205 really correct/justifiable, or not. 206 207 For ppc64-linux it's more complex. If the symbol is seen to be in 208 the .opd section, it is taken to be a function descriptor, and so 209 a dereference is attempted, in order to get hold of the real entry 210 point address. Also as part of the dereference, there is an attempt 211 to calculate the TOC pointer (R2 value) associated with the symbol. 212 213 To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0), 214 if the symbol is seen to be outside the .opd section and its name 215 starts with a dot, an .opd deference is not attempted, and no TOC 216 pointer is calculated, but the the leading dot is removed from the 217 name. 218 219 As a result, on ppc64-linux, the caller of this function may have 220 to piece together the real size, address, name of the symbol from 221 multiple calls to this function. Ugly and confusing. 222*/ 223static 224Bool get_elf_symbol_info ( 225 /* INPUTS */ 226 struct _DebugInfo* di, /* containing DebugInfo */ 227 ElfXX_Sym* sym, /* ELF symbol */ 228 DiOffT sym_name_ioff, /* name, may be absent (DiOffT_INVALID) */ 229 DiSlice* escn_strtab, /* holds the name */ 230 Addr sym_svma, /* address as stated in the object file */ 231 Bool symtab_in_debug, /* symbol table is in the debug file */ 232 DiSlice* escn_opd, /* the .opd (ppc64-linux only) */ 233 PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */ 234 /* OUTPUTS */ 235 DiOffT* sym_name_out_ioff, /* name (in strtab) we should record */ 236 Addr* sym_avma_out, /* addr we should record */ 237 Int* sym_size_out, /* symbol size */ 238 Addr* sym_tocptr_out, /* ppc64-linux only: R2 value to be 239 used on entry */ 240 Bool* from_opd_out, /* ppc64-linux only: did we deref an 241 .opd entry? */ 242 Bool* is_text_out, /* is this a text symbol? */ 243 Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/ 244 ) 245{ 246 Bool plausible; 247# if defined(VGP_ppc64_linux) 248 Bool is_in_opd; 249# endif 250 Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss; 251 Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma; 252 PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias; 253 254 /* Set defaults */ 255 *sym_name_out_ioff = sym_name_ioff; 256 *sym_avma_out = sym_svma; /* we will bias this shortly */ 257 *is_text_out = True; 258 *sym_tocptr_out = 0; /* unknown/inapplicable */ 259 *from_opd_out = False; 260 *is_ifunc = False; 261 /* Get the symbol size, but restrict it to fit in a signed 32 bit 262 int. Also, deal with the stupid case of negative size by making 263 the size be 1. Note that sym->st_size has type UWord, 264 effectively. */ 265 { Word size_tmp = (Word)sym->st_size; 266 Word max_Int = (1LL << 31) - 1; 267 if (size_tmp < 0) size_tmp = 1; 268 if (size_tmp > max_Int) size_tmp = max_Int; 269 *sym_size_out = (Int)size_tmp; 270 } 271 /* After this point refer only to *sym_size_out and not to 272 sym->st_size. */ 273 274 /* Figure out if we're interested in the symbol. Firstly, is it of 275 the right flavour? */ 276 plausible 277 = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL 278 || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL 279 || ELFXX_ST_BIND(sym->st_info) == STB_WEAK 280 ) 281 && 282 (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC 283 || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT 284# ifdef STT_GNU_IFUNC 285 || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC 286# endif 287 ); 288 289 /* Work out the svma and bias for each section as it will appear in 290 addresses in the symbol table. */ 291 if (symtab_in_debug) { 292 text_svma = di->text_debug_svma; 293 text_bias = di->text_debug_bias; 294 data_svma = di->data_debug_svma; 295 data_bias = di->data_debug_bias; 296 sdata_svma = di->sdata_debug_svma; 297 sdata_bias = di->sdata_debug_bias; 298 rodata_svma = di->rodata_debug_svma; 299 rodata_bias = di->rodata_debug_bias; 300 bss_svma = di->bss_debug_svma; 301 bss_bias = di->bss_debug_bias; 302 sbss_svma = di->sbss_debug_svma; 303 sbss_bias = di->sbss_debug_bias; 304 } else { 305 text_svma = di->text_svma; 306 text_bias = di->text_bias; 307 data_svma = di->data_svma; 308 data_bias = di->data_bias; 309 sdata_svma = di->sdata_svma; 310 sdata_bias = di->sdata_bias; 311 rodata_svma = di->rodata_svma; 312 rodata_bias = di->rodata_bias; 313 bss_svma = di->bss_svma; 314 bss_bias = di->bss_bias; 315 sbss_svma = di->sbss_svma; 316 sbss_bias = di->sbss_bias; 317 } 318 319 /* Now bias sym_avma_out accordingly by figuring out exactly which 320 section the symbol is from and bias accordingly. Screws up if 321 the previously deduced section svma address ranges are wrong. */ 322 if (di->text_present 323 && di->text_size > 0 324 && sym_svma >= text_svma 325 && sym_svma < text_svma + di->text_size) { 326 *is_text_out = True; 327 *sym_avma_out += text_bias; 328 } else 329 if (di->data_present 330 && di->data_size > 0 331 && sym_svma >= data_svma 332 && sym_svma < data_svma + di->data_size) { 333 *is_text_out = False; 334 *sym_avma_out += data_bias; 335 } else 336 if (di->sdata_present 337 && di->sdata_size > 0 338 && sym_svma >= sdata_svma 339 && sym_svma < sdata_svma + di->sdata_size) { 340 *is_text_out = False; 341 *sym_avma_out += sdata_bias; 342 } else 343 if (di->rodata_present 344 && di->rodata_size > 0 345 && sym_svma >= rodata_svma 346 && sym_svma < rodata_svma + di->rodata_size) { 347 *is_text_out = False; 348 *sym_avma_out += rodata_bias; 349 } else 350 if (di->bss_present 351 && di->bss_size > 0 352 && sym_svma >= bss_svma 353 && sym_svma < bss_svma + di->bss_size) { 354 *is_text_out = False; 355 *sym_avma_out += bss_bias; 356 } else 357 if (di->sbss_present 358 && di->sbss_size > 0 359 && sym_svma >= sbss_svma 360 && sym_svma < sbss_svma + di->sbss_size) { 361 *is_text_out = False; 362 *sym_avma_out += sbss_bias; 363 } else { 364 /* Assume it's in .text. Is this a good idea? */ 365 *is_text_out = True; 366 *sym_avma_out += text_bias; 367 } 368 369# ifdef STT_GNU_IFUNC 370 /* Check for indirect functions. */ 371 if (*is_text_out 372 && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) { 373 *is_ifunc = True; 374 } 375# endif 376 377# if defined(VGP_ppc64_linux) 378 /* Allow STT_NOTYPE in the very special case where we're running on 379 ppc64-linux and the symbol is one which the .opd-chasing hack 380 below will chase. */ 381 if (!plausible 382 && *is_text_out 383 && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE 384 && *sym_size_out > 0 385 && di->opd_present 386 && di->opd_size > 0 387 && *sym_avma_out >= di->opd_avma 388 && *sym_avma_out < di->opd_avma + di->opd_size) 389 plausible = True; 390# endif 391 392 if (!plausible) 393 return False; 394 395 /* Ignore if nameless. */ 396 if (sym_name_ioff == DiOffT_INVALID 397 || /* VG_(strlen)(sym_name) == 0 */ 398 /* equivalent but cheaper ... */ 399 ML_(img_get_UChar)(escn_strtab->img, sym_name_ioff) == '\0') { 400 if (TRACE_SYMTAB_ENABLED) { 401 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 402 "di.gesi.1", sym_name_ioff); 403 TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name); 404 if (sym_name) ML_(dinfo_free)(sym_name); 405 } 406 return False; 407 } 408 409 /* Ignore if zero-sized. Except on Android: 410 411 On Android 2.3.5, some of the symbols that Memcheck needs to 412 intercept (for noise reduction purposes) have zero size, due to 413 lack of .size directives in handwritten assembly sources. So we 414 can't reject them out of hand -- instead give them a bogusly 415 large size and let canonicaliseSymtab trim them so they don't 416 overlap any following symbols. At least the following symbols 417 are known to be affected: 418 419 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy 420 in /system/bin/linker: __dl_strcmp __dl_strlen 421 */ 422 if (*sym_size_out == 0) { 423# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) 424 *sym_size_out = 2048; 425# else 426 if (TRACE_SYMTAB_ENABLED) { 427 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 428 "di.gesi.2", sym_name_ioff); 429 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name); 430 if (sym_name) ML_(dinfo_free)(sym_name); 431 } 432 return False; 433# endif 434 } 435 436 /* This seems to significantly reduce the number of junk 437 symbols, and particularly reduces the number of 438 overlapping address ranges. Don't ask me why ... */ 439 if ((Int)sym->st_value == 0) { 440 if (TRACE_SYMTAB_ENABLED) { 441 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 442 "di.gesi.3", sym_name_ioff); 443 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name); 444 if (sym_name) ML_(dinfo_free)(sym_name); 445 } 446 return False; 447 } 448 449 /* If it's apparently in a GOT or PLT, it's really a reference to a 450 symbol defined elsewhere, so ignore it. */ 451 if (di->got_present 452 && di->got_size > 0 453 && *sym_avma_out >= di->got_avma 454 && *sym_avma_out < di->got_avma + di->got_size) { 455 if (TRACE_SYMTAB_ENABLED) { 456 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 457 "di.gesi.4", sym_name_ioff); 458 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name); 459 if (sym_name) ML_(dinfo_free)(sym_name); 460 } 461 return False; 462 } 463 if (di->plt_present 464 && di->plt_size > 0 465 && *sym_avma_out >= di->plt_avma 466 && *sym_avma_out < di->plt_avma + di->plt_size) { 467 if (TRACE_SYMTAB_ENABLED) { 468 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 469 "di.gesi.5", sym_name_ioff); 470 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name); 471 if (sym_name) ML_(dinfo_free)(sym_name); 472 } 473 return False; 474 } 475 476 /* ppc64-linux nasty hack: if the symbol is in an .opd section, 477 then really what we have is the address of a function 478 descriptor. So use the first word of that as the function's 479 text. 480 481 See thread starting at 482 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html 483 */ 484# if defined(VGP_ppc64_linux) 485 is_in_opd = False; 486# endif 487 488 if (di->opd_present 489 && di->opd_size > 0 490 && *sym_avma_out >= di->opd_avma 491 && *sym_avma_out < di->opd_avma + di->opd_size) { 492# if !defined(VGP_ppc64_linux) 493 if (TRACE_SYMTAB_ENABLED) { 494 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 495 "di.gesi.6", sym_name_ioff); 496 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name); 497 if (sym_name) ML_(dinfo_free)(sym_name); 498 } 499 return False; 500# else 501 Int offset_in_opd; 502 Bool details = 1||False; 503 504 if (details) 505 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n", 506 (void*)(opd_bias), (void*)*sym_avma_out); 507 508 if (!VG_IS_8_ALIGNED(*sym_avma_out)) { 509 if (TRACE_SYMTAB_ENABLED) { 510 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 511 "di.gesi.6a", sym_name_ioff); 512 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name); 513 if (sym_name) ML_(dinfo_free)(sym_name); 514 } 515 return False; 516 } 517 518 /* *sym_avma_out is a vma pointing into the .opd section. We 519 know the vma of the opd section start, so we can figure out 520 how far into the opd section this is. */ 521 522 offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma); 523 if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) { 524 if (TRACE_SYMTAB_ENABLED) { 525 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 526 "di.gesi.6a", sym_name_ioff); 527 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name); 528 if (sym_name) ML_(dinfo_free)(sym_name); 529 } 530 return False; 531 } 532 533 /* Now we want to know what's at that offset in the .opd 534 section. We can't look in the running image since it won't 535 necessarily have been mapped. But we can consult the oimage. 536 opd_img is the start address of the .opd in the oimage. 537 Hence: */ 538 539 ULong fn_descr[2]; /* is actually 3 words, but we need only 2 */ 540 if (!ML_(img_valid)(escn_opd->img, escn_opd->ioff + offset_in_opd, 541 sizeof(fn_descr))) { 542 if (TRACE_SYMTAB_ENABLED) { 543 HChar* sym_name = ML_(img_strdup)(escn_strtab->img, 544 "di.gesi.6b", sym_name_ioff); 545 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n", 546 sym_name); 547 if (sym_name) ML_(dinfo_free)(sym_name); 548 549 } 550 return False; 551 } 552 553 /* This can't fail now, because we just checked the offset 554 above. */ 555 ML_(img_get)(&fn_descr[0], escn_opd->img, 556 escn_opd->ioff + offset_in_opd, sizeof(fn_descr)); 557 558 if (details) 559 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n", 560 offset_in_opd, fn_descr); 561 if (details) 562 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0])); 563 564 /* opd_bias is the what we have to add to SVMAs found in .opd to 565 get plausible .text AVMAs for the entry point, and .data 566 AVMAs (presumably) for the TOC locations. We use the caller 567 supplied value (which is di->text_bias) for both of these. 568 Not sure why that is correct - it seems to work, and sounds 569 OK for fn_descr[0], but surely we need to use the data bias 570 and not the text bias for fn_descr[1] ? Oh Well. 571 */ 572 *sym_avma_out = fn_descr[0] + opd_bias; 573 *sym_tocptr_out = fn_descr[1] + opd_bias; 574 *from_opd_out = True; 575 is_in_opd = True; 576 577 /* Do a final sanity check: if the symbol falls outside the 578 DebugInfo's mapped range, ignore it. Since *sym_avma_out has 579 been updated, that can be achieved simply by falling through 580 to the test below. */ 581 582# endif /* ppc64-linux nasty hack */ 583 } 584 585 /* Here's yet another ppc64-linux hack. Get rid of leading dot if 586 the symbol is outside .opd. */ 587# if defined(VGP_ppc64_linux) 588 if (di->opd_size > 0 589 && !is_in_opd 590 && *sym_name_out_ioff != DiOffT_INVALID 591 && ML_(img_get_UChar)(escn_strtab->img, *sym_name_out_ioff) == '.') { 592 vg_assert(!(*from_opd_out)); 593 (*sym_name_out_ioff)++; 594 } 595# endif 596 597 /* If no part of the symbol falls within the mapped range, 598 ignore it. */ 599 600 in_text 601 = di->text_present 602 && di->text_size > 0 603 && !(*sym_avma_out + *sym_size_out <= di->text_avma 604 || *sym_avma_out >= di->text_avma + di->text_size); 605 606 in_data 607 = di->data_present 608 && di->data_size > 0 609 && !(*sym_avma_out + *sym_size_out <= di->data_avma 610 || *sym_avma_out >= di->data_avma + di->data_size); 611 612 in_sdata 613 = di->sdata_present 614 && di->sdata_size > 0 615 && !(*sym_avma_out + *sym_size_out <= di->sdata_avma 616 || *sym_avma_out >= di->sdata_avma + di->sdata_size); 617 618 in_rodata 619 = di->rodata_present 620 && di->rodata_size > 0 621 && !(*sym_avma_out + *sym_size_out <= di->rodata_avma 622 || *sym_avma_out >= di->rodata_avma + di->rodata_size); 623 624 in_bss 625 = di->bss_present 626 && di->bss_size > 0 627 && !(*sym_avma_out + *sym_size_out <= di->bss_avma 628 || *sym_avma_out >= di->bss_avma + di->bss_size); 629 630 in_sbss 631 = di->sbss_present 632 && di->sbss_size > 0 633 && !(*sym_avma_out + *sym_size_out <= di->sbss_avma 634 || *sym_avma_out >= di->sbss_avma + di->sbss_size); 635 636 637 if (*is_text_out) { 638 /* This used to reject any symbol falling outside the text 639 segment ("if (!in_text) ..."). Now it is relaxed slightly, 640 to reject only symbols which fall outside the area mapped 641 r-x. This is in accordance with r7427. See 642 "Comment_Regarding_Text_Range_Checks" in storage.c for 643 background. */ 644 Bool in_rx; 645 vg_assert(di->fsm.have_rx_map); 646 /* This could actually wrap around and cause 647 ML_(find_rx_mapping) to assert. But that seems so unlikely, 648 let's wait for it to happen before fixing it. */ 649 in_rx = (ML_(find_rx_mapping)(di, *sym_avma_out, 650 *sym_avma_out + *sym_size_out) != NULL); 651 if (in_text) 652 vg_assert(in_rx); 653 if (!in_rx) { 654 TRACE_SYMTAB( 655 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n", 656 *sym_avma_out, *sym_avma_out + *sym_size_out, 657 di->text_avma, 658 di->text_avma + di->text_size); 659 return False; 660 } 661 } else { 662 if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) { 663 TRACE_SYMTAB( 664 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata " 665 "/ .bss / .sbss svma ranges\n", 666 *sym_avma_out, *sym_avma_out + *sym_size_out); 667 return False; 668 } 669 } 670 671# if defined(VGP_ppc64_linux) 672 /* It's crucial that we never add symbol addresses in the .opd 673 section. This would completely mess up function redirection and 674 intercepting. This assert ensures that any symbols that make it 675 into the symbol table on ppc64-linux don't point into .opd. */ 676 if (di->opd_present && di->opd_size > 0) { 677 vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma 678 || *sym_avma_out >= di->opd_avma + di->opd_size); 679 } 680# endif 681 682 /* Acquire! */ 683 return True; 684} 685 686 687/* Read an ELF symbol table (normal or dynamic). This one is for the 688 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64}-linux). */ 689static 690__attribute__((unused)) /* not referred to on all targets */ 691void read_elf_symtab__normal( 692 struct _DebugInfo* di, const HChar* tab_name, 693 DiSlice* escn_symtab, 694 DiSlice* escn_strtab, 695 DiSlice* escn_opd, /* ppc64-linux only */ 696 Bool symtab_in_debug 697 ) 698{ 699 if (escn_strtab->img == NULL || escn_symtab->img == NULL) { 700 HChar buf[80]; 701 vg_assert(VG_(strlen)(tab_name) < 40); 702 VG_(sprintf)(buf, " object doesn't have a %s", tab_name); 703 ML_(symerr)(di, False, buf); 704 return; 705 } 706 707 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%lld entries) ---\n", 708 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) ); 709 710 /* Perhaps should start at i = 1; ELF docs suggest that entry 711 0 always denotes 'unknown symbol'. */ 712 Word i; 713 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) { 714 ElfXX_Sym sym; 715 ML_(img_get)(&sym, escn_symtab->img, 716 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym)); 717 DiOffT sym_name = escn_strtab->ioff + sym.st_name; 718 Addr sym_svma = sym.st_value; 719 720 if (di->trace_symtab) 721 show_raw_elf_symbol(escn_strtab->img, i, 722 &sym, sym_name, sym_svma, False); 723 724 Addr sym_avma_really = 0; 725 Int sym_size = 0; 726 Addr sym_tocptr = 0; 727 Bool from_opd = False, is_text = False, is_ifunc = False; 728 DiOffT sym_name_really = DiOffT_INVALID; 729 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab, 730 sym_svma, symtab_in_debug, 731 escn_opd, di->text_bias, 732 &sym_name_really, 733 &sym_avma_really, 734 &sym_size, 735 &sym_tocptr, 736 &from_opd, &is_text, &is_ifunc)) { 737 738 DiSym disym; 739 VG_(memset)(&disym, 0, sizeof(disym)); 740 HChar* cstr = ML_(img_strdup)(escn_strtab->img, 741 "di.res__n.1", sym_name_really); 742 disym.addr = sym_avma_really; 743 disym.tocptr = sym_tocptr; 744 disym.pri_name = ML_(addStr) ( di, cstr, -1 ); 745 disym.sec_names = NULL; 746 disym.size = sym_size; 747 disym.isText = is_text; 748 disym.isIFunc = is_ifunc; 749 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; } 750 vg_assert(disym.pri_name); 751 vg_assert(disym.tocptr == 0); /* has no role except on ppc64-linux */ 752 ML_(addSym) ( di, &disym ); 753 754 if (TRACE_SYMTAB_ENABLED) { 755 TRACE_SYMTAB(" rec(%c) [%4ld]: " 756 " val %#010lx, sz %4d %s\n", 757 is_text ? 't' : 'd', 758 i, 759 disym.addr, 760 (Int)disym.size, 761 (HChar*)disym.pri_name 762 ); 763 } 764 765 } 766 } 767} 768 769 770/* Read an ELF symbol table (normal or dynamic). This one is for 771 ppc64-linux, which requires special treatment. */ 772 773typedef 774 struct { 775 Addr addr; 776 DiOffT name; 777 /* We have to store also the DiImage* so as to give context for 778 |name|. This is not part of the key (in terms of lookup) but 779 there's no easy other way to do this. Ugly. */ 780 DiImage* img; 781 } 782 TempSymKey; 783 784typedef 785 struct { 786 TempSymKey key; 787 Addr tocptr; 788 Int size; 789 Bool from_opd; 790 Bool is_text; 791 Bool is_ifunc; 792 } 793 TempSym; 794 795static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) 796{ 797 /* Stay sane ... */ 798 vg_assert(key1->img == elem2->key.img); 799 vg_assert(key1->img != NULL); 800 if (key1->addr < elem2->key.addr) return -1; 801 if (key1->addr > elem2->key.addr) return 1; 802 vg_assert(key1->name != DiOffT_INVALID); 803 vg_assert(elem2->key.name != DiOffT_INVALID); 804 return (Word)ML_(img_strcmp)(key1->img, key1->name, elem2->key.name); 805} 806 807static 808__attribute__((unused)) /* not referred to on all targets */ 809void read_elf_symtab__ppc64_linux( 810 struct _DebugInfo* di, const HChar* tab_name, 811 DiSlice* escn_symtab, 812 DiSlice* escn_strtab, 813 DiSlice* escn_opd, /* ppc64-linux only */ 814 Bool symtab_in_debug 815 ) 816{ 817 Word i; 818 Int old_size; 819 Bool modify_size, modify_tocptr; 820 OSet *oset; 821 TempSymKey key; 822 TempSym *elem; 823 TempSym *prev; 824 825 if (escn_strtab->img == NULL || escn_symtab->img == NULL) { 826 HChar buf[80]; 827 vg_assert(VG_(strlen)(tab_name) < 40); 828 VG_(sprintf)(buf, " object doesn't have a %s", tab_name); 829 ML_(symerr)(di, False, buf); 830 return; 831 } 832 833 TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%lld entries) ---\n", 834 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) ); 835 836 oset = VG_(OSetGen_Create)( offsetof(TempSym,key), 837 (OSetCmp_t)cmp_TempSymKey, 838 ML_(dinfo_zalloc), "di.respl.1", 839 ML_(dinfo_free) ); 840 vg_assert(oset); 841 842 /* Perhaps should start at i = 1; ELF docs suggest that entry 843 0 always denotes 'unknown symbol'. */ 844 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) { 845 ElfXX_Sym sym; 846 ML_(img_get)(&sym, escn_symtab->img, 847 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym)); 848 DiOffT sym_name = escn_strtab->ioff + sym.st_name; 849 Addr sym_svma = sym.st_value; 850 851 if (di->trace_symtab) 852 show_raw_elf_symbol(escn_strtab->img, i, 853 &sym, sym_name, sym_svma, True); 854 855 Addr sym_avma_really = 0; 856 Int sym_size = 0; 857 Addr sym_tocptr = 0; 858 Bool from_opd = False, is_text = False, is_ifunc = False; 859 DiOffT sym_name_really = DiOffT_INVALID; 860 DiSym disym; 861 VG_(memset)(&disym, 0, sizeof(disym)); 862 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab, 863 sym_svma, symtab_in_debug, 864 escn_opd, di->text_bias, 865 &sym_name_really, 866 &sym_avma_really, 867 &sym_size, 868 &sym_tocptr, 869 &from_opd, &is_text, &is_ifunc)) { 870 871 /* Check if we've seen this (name,addr) key before. */ 872 key.addr = sym_avma_really; 873 key.name = sym_name_really; 874 key.img = escn_strtab->img; 875 prev = VG_(OSetGen_Lookup)( oset, &key ); 876 877 if (prev) { 878 879 /* Seen it before. Fold in whatever new info we can. */ 880 modify_size = False; 881 modify_tocptr = False; 882 old_size = 0; 883 884 if (prev->from_opd && !from_opd 885 && (prev->size == 24 || prev->size == 16) 886 && sym_size != prev->size) { 887 /* Existing one is an opd-redirect, with a bogus size, 888 so the only useful new fact we have is the real size 889 of the symbol. */ 890 modify_size = True; 891 old_size = prev->size; 892 prev->size = sym_size; 893 } 894 else 895 if (!prev->from_opd && from_opd 896 && (sym_size == 24 || sym_size == 16)) { 897 /* Existing one is non-opd, new one is opd. What we 898 can acquire from the new one is the TOC ptr to be 899 used. Since the existing sym is non-toc, it 900 shouldn't currently have an known TOC ptr. */ 901 vg_assert(prev->tocptr == 0); 902 modify_tocptr = True; 903 prev->tocptr = sym_tocptr; 904 } 905 else { 906 /* ignore. can we do better here? */ 907 } 908 909 /* Only one or the other is possible (I think) */ 910 vg_assert(!(modify_size && modify_tocptr)); 911 912 if (modify_size && di->trace_symtab) { 913 VG_(printf)(" modify (old sz %4d) " 914 " val %#010lx, toc %#010lx, sz %4d %lld\n", 915 old_size, 916 prev->key.addr, 917 prev->tocptr, 918 (Int) prev->size, 919 (ULong)prev->key.name 920 ); 921 } 922 if (modify_tocptr && di->trace_symtab) { 923 VG_(printf)(" modify (upd tocptr) " 924 " val %#010lx, toc %#010lx, sz %4d %lld\n", 925 prev->key.addr, 926 prev->tocptr, 927 (Int) prev->size, 928 (ULong)prev->key.name 929 ); 930 } 931 932 } else { 933 934 /* A new (name,addr) key. Add and continue. */ 935 elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym)); 936 vg_assert(elem); 937 elem->key = key; 938 elem->tocptr = sym_tocptr; 939 elem->size = sym_size; 940 elem->from_opd = from_opd; 941 elem->is_text = is_text; 942 elem->is_ifunc = is_ifunc; 943 VG_(OSetGen_Insert)(oset, elem); 944 if (di->trace_symtab) { 945 HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2", 946 elem->key.name); 947 VG_(printf)(" to-oset [%4ld]: " 948 " val %#010lx, toc %#010lx, sz %4d %s\n", 949 i, 950 elem->key.addr, 951 elem->tocptr, 952 (Int) elem->size, 953 str 954 ); 955 if (str) ML_(dinfo_free)(str); 956 } 957 958 } 959 } 960 } 961 962 /* All the syms that matter are in the oset. Now pull them out, 963 build a "standard" symbol table, and nuke the oset. */ 964 965 i = 0; 966 VG_(OSetGen_ResetIter)( oset ); 967 968 while ( (elem = VG_(OSetGen_Next)(oset)) ) { 969 DiSym disym; 970 VG_(memset)(&disym, 0, sizeof(disym)); 971 HChar* cstr = ML_(img_strdup)(escn_strtab->img, 972 "di.res__ppc64.1", elem->key.name); 973 disym.addr = elem->key.addr; 974 disym.tocptr = elem->tocptr; 975 disym.pri_name = ML_(addStr) ( di, cstr, -1 ); 976 disym.sec_names = NULL; 977 disym.size = elem->size; 978 disym.isText = elem->is_text; 979 disym.isIFunc = elem->is_ifunc; 980 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; } 981 vg_assert(disym.pri_name != NULL); 982 983 ML_(addSym) ( di, &disym ); 984 if (di->trace_symtab) { 985 VG_(printf)(" rec(%c) [%4ld]: " 986 " val %#010lx, toc %#010lx, sz %4d %s\n", 987 disym.isText ? 't' : 'd', 988 i, 989 disym.addr, 990 disym.tocptr, 991 (Int) disym.size, 992 (HChar*)disym.pri_name 993 ); 994 } 995 i++; 996 } 997 998 VG_(OSetGen_Destroy)( oset ); 999} 1000 1001 1002/* 1003 * Look for a build-id in an ELF image. The build-id specification 1004 * can be found here: 1005 * 1006 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID 1007 * 1008 * Returned string must be freed by the caller. 1009 */ 1010static 1011HChar* find_buildid(DiImage* img, Bool rel_ok, Bool search_shdrs) 1012{ 1013 HChar* buildid = NULL; 1014 1015# ifdef NT_GNU_BUILD_ID 1016 if (is_elf_object_file_by_DiImage(img, rel_ok)) { 1017 Word i; 1018 1019 ElfXX_Ehdr ehdr; 1020 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr)); 1021 for (i = 0; i < ehdr.e_phnum; i++) { 1022 ElfXX_Phdr phdr; 1023 ML_(img_get)(&phdr, img, 1024 ehdr.e_phoff + i * ehdr.e_phentsize, sizeof(phdr)); 1025 1026 if (phdr.p_type == PT_NOTE) { 1027 ElfXX_Off note_ioff = phdr.p_offset; 1028 1029 while (note_ioff < phdr.p_offset + phdr.p_filesz) { 1030 ElfXX_Nhdr note; 1031 ML_(img_get)(¬e, img, (DiOffT)note_ioff, sizeof(note)); 1032 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr); 1033 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3); 1034 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0 1035 && note.n_type == NT_GNU_BUILD_ID) { 1036 buildid = ML_(dinfo_zalloc)("di.fbi.1", 1037 note.n_descsz * 2 + 1); 1038 Word j; 1039 for (j = 0; j < note.n_descsz; j++) { 1040 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j); 1041 VG_(sprintf)(buildid + VG_(strlen)(buildid), 1042 "%02x", (UInt)desc_j); 1043 } 1044 } 1045 1046 note_ioff = note_ioff + sizeof(ElfXX_Nhdr) 1047 + ((note.n_namesz + 3) & ~3) 1048 + ((note.n_descsz + 3) & ~3); 1049 } 1050 } 1051 } 1052 1053 /* Normally we would only search shdrs for ET_REL files, but when 1054 we search for a separate .debug file phdrs might not be there 1055 (they are never loaded) or have been corrupted, so try again 1056 against shdrs. */ 1057 if (buildid || (!rel_ok && !search_shdrs)) 1058 return buildid; 1059 1060 for (i = 0; i < ehdr.e_shnum; i++) { 1061 ElfXX_Shdr shdr; 1062 ML_(img_get)(&shdr, img, 1063 ehdr.e_shoff + i * ehdr.e_shentsize, sizeof(shdr)); 1064 1065 if (shdr.sh_type == SHT_NOTE) { 1066 ElfXX_Off note_ioff = shdr.sh_offset; 1067 1068 while (note_ioff < shdr.sh_offset + shdr.sh_size) { 1069 ElfXX_Nhdr note; 1070 ML_(img_get)(¬e, img, (DiOffT)note_ioff, sizeof(note)); 1071 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr); 1072 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3); 1073 1074 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0 1075 && note.n_type == NT_GNU_BUILD_ID) { 1076 buildid = ML_(dinfo_zalloc)("di.fbi.2", 1077 note.n_descsz * 2 + 1); 1078 Word j; 1079 for (j = 0; j < note.n_descsz; j++) { 1080 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j); 1081 VG_(sprintf)(buildid + VG_(strlen)(buildid), 1082 "%02x", (UInt)desc_j); 1083 } 1084 } 1085 1086 note_ioff = note_ioff + sizeof(ElfXX_Nhdr) 1087 + ((note.n_namesz + 3) & ~3) 1088 + ((note.n_descsz + 3) & ~3); 1089 } 1090 } 1091 } 1092 } 1093# endif /* def NT_GNU_BUILD_ID */ 1094 1095 return buildid; 1096} 1097 1098 1099/* Try and open a separate debug file, ignoring any where the CRC does 1100 not match the value from the main object file. Returned DiImage 1101 must be discarded by the caller. 1102 1103 If |serverAddr| is NULL, |name| is expected to be a fully qualified 1104 (absolute) path to the file in the local filesystem. If 1105 |serverAddr| is non-NULL, it is expected to be an IPv4 and port 1106 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected 1107 to be a plain filename (no path components at all). 1108 */ 1109static 1110DiImage* open_debug_file( const HChar* name, const HChar* buildid, UInt crc, 1111 Bool rel_ok, const HChar* serverAddr ) 1112{ 1113 DiImage* dimg 1114 = serverAddr ? ML_(img_from_di_server)(name, serverAddr) 1115 : ML_(img_from_local_file)(name); 1116 if (dimg == NULL) 1117 return NULL; 1118 1119 if (VG_(clo_verbosity) > 1) { 1120 if (serverAddr) 1121 VG_(message)(Vg_DebugMsg, " Considering %s on server %s ..\n", 1122 name, serverAddr); 1123 else 1124 VG_(message)(Vg_DebugMsg, " Considering %s ..\n", name); 1125 } 1126 1127 if (buildid) { 1128 HChar* debug_buildid = find_buildid(dimg, rel_ok, True); 1129 if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) { 1130 ML_(img_done)(dimg); 1131 if (VG_(clo_verbosity) > 1) 1132 VG_(message)(Vg_DebugMsg, 1133 " .. build-id mismatch (found %s wanted %s)\n", 1134 debug_buildid, buildid); 1135 ML_(dinfo_free)(debug_buildid); 1136 return NULL; 1137 } 1138 ML_(dinfo_free)(debug_buildid); 1139 if (VG_(clo_verbosity) > 1) 1140 VG_(message)(Vg_DebugMsg, " .. build-id is valid\n"); 1141 } else { 1142 UInt calccrc = ML_(img_calc_gnu_debuglink_crc32)(dimg); 1143 if (calccrc != crc) { 1144 ML_(img_done)(dimg); 1145 if (VG_(clo_verbosity) > 1) 1146 VG_(message)(Vg_DebugMsg, 1147 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc); 1148 return NULL; 1149 } 1150 1151 if (VG_(clo_verbosity) > 1) 1152 VG_(message)(Vg_DebugMsg, " .. CRC is valid\n"); 1153 } 1154 1155 return dimg; 1156} 1157 1158 1159/* Try to find a separate debug file for a given object file. If 1160 found, return its DiImage, which should be freed by the caller. If 1161 |buildid| is non-NULL, then a debug object matching it is 1162 acceptable. If |buildid| is NULL or doesn't specify a findable 1163 debug object, then we look in various places to find a file with 1164 the specified CRC. And if that doesn't work out then we give 1165 up. */ 1166static 1167DiImage* find_debug_file( struct _DebugInfo* di, 1168 const HChar* objpath, const HChar* buildid, 1169 const HChar* debugname, UInt crc, Bool rel_ok ) 1170{ 1171 const HChar* extrapath = VG_(clo_extra_debuginfo_path); 1172 const HChar* serverpath = VG_(clo_debuginfo_server); 1173 1174 DiImage* dimg = NULL; /* the img that we found */ 1175 HChar* debugpath = NULL; /* where we found it */ 1176 1177 if (buildid != NULL) { 1178 debugpath = ML_(dinfo_zalloc)("di.fdf.1", 1179 VG_(strlen)(buildid) + 33); 1180 1181 VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug", 1182 buildid[0], buildid[1], buildid + 2); 1183 1184 dimg = open_debug_file(debugpath, buildid, 0, rel_ok, NULL); 1185 if (!dimg) { 1186 ML_(dinfo_free)(debugpath); 1187 debugpath = NULL; 1188 } 1189 } 1190 1191 if (dimg == NULL && debugname != NULL && !rel_ok) { 1192 HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath); 1193 HChar *objdirptr; 1194 1195 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL) 1196 *objdirptr = '\0'; 1197 1198 debugpath = ML_(dinfo_zalloc)( 1199 "di.fdf.3", 1200 VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64 1201 + (extrapath ? VG_(strlen)(extrapath) : 0) 1202 + (serverpath ? VG_(strlen)(serverpath) : 0)); 1203 1204 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname); 1205 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL); 1206 if (dimg != NULL) goto dimg_ok; 1207 1208 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname); 1209 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL); 1210 if (dimg != NULL) goto dimg_ok; 1211 1212 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname); 1213 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL); 1214 if (dimg != NULL) goto dimg_ok; 1215 1216 if (extrapath) { 1217 VG_(sprintf)(debugpath, "%s%s/%s", extrapath, 1218 objdir, debugname); 1219 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL); 1220 if (dimg != NULL) goto dimg_ok; 1221 } 1222 1223 if (serverpath) { 1224 /* When looking on the debuginfo server, always just pass the 1225 basename. */ 1226 const HChar* basename = debugname; 1227 if (VG_(strstr)(basename, "/") != NULL) { 1228 basename = VG_(strrchr)(basename, '/') + 1; 1229 } 1230 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath); 1231 dimg = open_debug_file(basename, NULL, crc, rel_ok, serverpath); 1232 if (dimg) goto dimg_ok; 1233 } 1234 1235 dimg_ok: 1236 1237 ML_(dinfo_free)(objdir); 1238 } 1239 1240 if (dimg != NULL) { 1241 vg_assert(debugpath); 1242 TRACE_SYMTAB("\n"); 1243 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath); 1244 } 1245 1246 if (debugpath) 1247 ML_(dinfo_free)(debugpath); 1248 1249 return dimg; 1250} 1251 1252 1253/* Try to find a separate debug file for a given object file, in a 1254 hacky and dangerous way: check only the --extra-debuginfo-path and 1255 the --debuginfo-server. And don't do a consistency check. */ 1256static 1257DiImage* find_debug_file_ad_hoc( struct _DebugInfo* di, 1258 const HChar* objpath ) 1259{ 1260 const HChar* extrapath = VG_(clo_extra_debuginfo_path); 1261 const HChar* serverpath = VG_(clo_debuginfo_server); 1262 1263 DiImage* dimg = NULL; /* the img that we found */ 1264 HChar* debugpath = NULL; /* where we found it */ 1265 1266 HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath); 1267 HChar *objdirptr; 1268 1269 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL) 1270 *objdirptr = '\0'; 1271 1272 debugpath = ML_(dinfo_zalloc)( 1273 "di.fdfah.3", 1274 VG_(strlen)(objdir) + 64 1275 + (extrapath ? VG_(strlen)(extrapath) : 0) 1276 + (serverpath ? VG_(strlen)(serverpath) : 0)); 1277 1278 if (extrapath) { 1279 VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath); 1280 dimg = ML_(img_from_local_file)(debugpath); 1281 if (dimg != NULL) { 1282 if (VG_(clo_verbosity) > 1) { 1283 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n", 1284 debugpath); 1285 } 1286 goto dimg_ok; 1287 } 1288 } 1289 if (serverpath) { 1290 /* When looking on the debuginfo server, always just pass the 1291 basename. */ 1292 const HChar* basename = objpath; 1293 if (VG_(strstr)(basename, "/") != NULL) { 1294 basename = VG_(strrchr)(basename, '/') + 1; 1295 } 1296 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath); 1297 dimg = ML_(img_from_di_server)(basename, serverpath); 1298 if (dimg != NULL) { 1299 if (VG_(clo_verbosity) > 1) { 1300 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n", 1301 debugpath); 1302 } 1303 goto dimg_ok; 1304 } 1305 } 1306 1307 dimg_ok: 1308 1309 ML_(dinfo_free)(objdir); 1310 1311 if (dimg != NULL) { 1312 vg_assert(debugpath); 1313 TRACE_SYMTAB("\n"); 1314 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath); 1315 } 1316 1317 if (debugpath) 1318 ML_(dinfo_free)(debugpath); 1319 1320 return dimg; 1321} 1322 1323 1324static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) { 1325 // This is a bit stupid. Really, idx and scale ought to be 1326 // 64-bit quantities, always. 1327 return base + (DiOffT)idx * (DiOffT)scale; 1328} 1329 1330 1331/* Find the file offset corresponding to SVMA by using the program 1332 headers. This is taken from binutils-2.17/binutils/readelf.c 1333 offset_from_vma(). */ 1334static 1335Word file_offset_from_svma ( /*OUT*/Bool* ok, 1336 Addr svma, 1337 DiImage* img, 1338 DiOffT phdr_ioff, 1339 Word phdr_nent, 1340 Word phdr_ent_szB ) 1341{ 1342 Word i; 1343 for (i = 0; i < phdr_nent; i++) { 1344 ElfXX_Phdr seg; 1345 ML_(img_get)(&seg, img, 1346 INDEX_BIS(phdr_ioff, i, phdr_ent_szB), sizeof(seg)); 1347 if (seg.p_type != PT_LOAD) 1348 continue; 1349 if (svma >= (seg.p_vaddr & -seg.p_align) 1350 && svma + 1 <= seg.p_vaddr + seg.p_filesz) { 1351 *ok = True; 1352 return svma - seg.p_vaddr + seg.p_offset; 1353 } 1354 } 1355 *ok = False; 1356 return 0; 1357} 1358 1359 1360/* The central function for reading ELF debug info. For the 1361 object/exe specified by the DebugInfo, find ELF sections, then read 1362 the symbols, line number info, file name info, CFA (stack-unwind 1363 info) and anything else we want, into the tables within the 1364 supplied DebugInfo. 1365*/ 1366 1367Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) 1368{ 1369 /* This function is long and complex. That, and the presence of 1370 nested scopes, means it's not always easy to see which parts are 1371 in loops/conditionals and which aren't. To make it easier to 1372 follow, points executed exactly once -- that is, those which are 1373 the top level of the function -- are marked TOPLEVEL. 1374 */ 1375 /* Consistent terminology for local variable names, without which 1376 it's almost unfollowably complex: 1377 1378 In which file? 1379 in the main ELF file *_m* 1380 in the debuginfo file *_d* 1381 in the alt debuginfo file *_a* 1382 1383 What kind of thing? 1384 _{m,d,a}img a DiImage* 1385 _{m,d,a}ioff an offset in the image (DiOffT) 1386 _{m,d,a}nent "number of entries" 1387 _{m,d,a}ent_szB "size in bytes of an entry" 1388 ehdr_{m,d,a} ELF header 1389 phdr Program header 1390 shdr Section header 1391 a_X a temporary X 1392 _escn an DiSlice (elf section info) variable 1393 szB size in bytes 1394 */ 1395 1396 1397 /* TOPLEVEL */ 1398 Bool res, ok; 1399 Word i, j; 1400 Bool dynbss_present = False; 1401 Bool sdynbss_present = False; 1402 1403 /* Image for the main ELF file we're working with. */ 1404 DiImage* mimg = NULL; 1405 1406 /* Ditto for any ELF debuginfo file that we might happen to load. */ 1407 DiImage* dimg = NULL; 1408 1409 /* Ditto for alternate ELF debuginfo file that we might happen to load. */ 1410 DiImage* aimg = NULL; 1411 1412 /* ELF header offset for the main file. Should be zero since the 1413 ELF header is at start of file. */ 1414 DiOffT ehdr_mioff = 0; 1415 1416 /* Program header table image addr, # entries, entry size */ 1417 DiOffT phdr_mioff = 0; 1418 UWord phdr_mnent = 0; 1419 UWord phdr_ment_szB = 0; 1420 1421 /* Section header image addr, # entries, entry size. Also the 1422 associated string table. */ 1423 DiOffT shdr_mioff = 0; 1424 UWord shdr_mnent = 0; 1425 UWord shdr_ment_szB = 0; 1426 DiOffT shdr_strtab_mioff = 0; 1427 1428 /* SVMAs covered by rx and rw segments and corresponding biases. 1429 Normally each object would provide just one rx and one rw area, 1430 but various ELF mangling tools create objects with multiple 1431 such entries, hence the generality. */ 1432 typedef 1433 struct { 1434 Addr svma_base; 1435 Addr svma_limit; 1436 PtrdiffT bias; 1437 Bool exec; 1438 } 1439 RangeAndBias; 1440 1441 XArray* /* of RangeAndBias */ svma_ranges = NULL; 1442 1443 vg_assert(di); 1444 vg_assert(di->fsm.have_rx_map == True); 1445 vg_assert(di->fsm.have_rw_map == True); 1446 vg_assert(di->have_dinfo == False); 1447 vg_assert(di->fsm.filename); 1448 vg_assert(!di->symtab); 1449 vg_assert(!di->loctab); 1450 vg_assert(!di->cfsi); 1451 vg_assert(!di->cfsi_exprs); 1452 vg_assert(!di->strchunks); 1453 vg_assert(!di->soname); 1454 1455 { 1456 Bool has_nonempty_rx = False; 1457 Bool has_nonempty_rw = False; 1458 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1459 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 1460 if (!map->rx && !map->rw) 1461 continue; 1462 if (map->rx && map->size > 0) 1463 has_nonempty_rx = True; 1464 if (map->rw && map->size > 0) 1465 has_nonempty_rw = True; 1466 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr 1467 managed to do a mapping where the start isn't page aligned. 1468 Which sounds pretty bogus to me. */ 1469 vg_assert(VG_IS_PAGE_ALIGNED(map->avma)); 1470 } 1471 vg_assert(has_nonempty_rx); 1472 vg_assert(has_nonempty_rw); 1473 } 1474 1475 /* ---------------------------------------------------------- 1476 At this point, there is very little information in the 1477 DebugInfo. We only know that something that looks like an ELF 1478 file has been mapped rx-ishly and rw-ishly as recorded in the 1479 di->fsm.maps array items. First we examine the file's ELF 1480 Program Header, and, by comparing that against the di->fsm.maps 1481 info, try to figure out the AVMAs for the sections we care 1482 about, that should have been mapped: text, data, sdata, bss, 1483 got, plt, and toc. 1484 ---------------------------------------------------------- */ 1485 1486 res = False; 1487 1488 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)) 1489 VG_(message)(Vg_DebugMsg, "Reading syms from %s\n", 1490 di->fsm.filename ); 1491 1492 /* Connect to the primary object image, so that we can read symbols 1493 and line number info out of it. It will be disconnected 1494 immediately thereafter; it is only connected transiently. */ 1495 mimg = ML_(img_from_local_file)(di->fsm.filename); 1496 if (mimg == NULL) { 1497 VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n", 1498 di->fsm.filename ); 1499 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" ); 1500 return False; 1501 } 1502 1503 /* Ok, the object image is available. Now verify that it is a 1504 valid ELF .so or executable image. */ 1505 ok = is_elf_object_file_by_DiImage(mimg, False); 1506 if (!ok) { 1507 ML_(symerr)(di, True, "Invalid ELF Header"); 1508 goto out; 1509 } 1510 1511 /* Find where the program and section header tables are, and give 1512 up if either is missing or outside the image (bogus). */ 1513 ElfXX_Ehdr ehdr_m; 1514 vg_assert(ehdr_mioff == 0); // ensured by its initialisation 1515 ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m)); 1516 vg_assert(ok); // ML_(is_elf_object_file) should ensure this 1517 ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m)); 1518 1519 phdr_mioff = ehdr_mioff + ehdr_m.e_phoff; 1520 phdr_mnent = ehdr_m.e_phnum; 1521 phdr_ment_szB = ehdr_m.e_phentsize; 1522 1523 shdr_mioff = ehdr_mioff + ehdr_m.e_shoff; 1524 shdr_mnent = ehdr_m.e_shnum; 1525 shdr_ment_szB = ehdr_m.e_shentsize; 1526 1527 TRACE_SYMTAB("------ Basic facts about the object ------\n"); 1528 TRACE_SYMTAB("object: n_oimage %llu\n", 1529 (ULong)ML_(img_size)(mimg)); 1530 TRACE_SYMTAB("phdr: ioff %llu nent %ld ent_szB %ld\n", 1531 phdr_mioff, phdr_mnent, phdr_ment_szB); 1532 TRACE_SYMTAB("shdr: ioff %llu nent %ld ent_szB %ld\n", 1533 shdr_mioff, shdr_mnent, shdr_ment_szB); 1534 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1535 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 1536 if (map->rx) 1537 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lu\n", 1538 map->avma, map->size, map->foff); 1539 } 1540 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1541 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 1542 if (map->rw) 1543 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lu\n", 1544 map->avma, map->size, map->foff); 1545 } 1546 1547 if (phdr_mnent == 0 1548 || !ML_(img_valid)(mimg, phdr_mioff, phdr_mnent * phdr_ment_szB)) { 1549 ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table"); 1550 goto out; 1551 } 1552 1553 if (shdr_mnent == 0 1554 || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) { 1555 ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table"); 1556 goto out; 1557 } 1558 1559 /* Also find the section header's string table, and validate. */ 1560 /* checked previously by is_elf_object_file: */ 1561 vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF); 1562 1563 // shdr_mioff is the offset of the section header table 1564 // and we need the ehdr_m.e_shstrndx'th entry 1565 { ElfXX_Shdr a_shdr; 1566 ML_(img_get)(&a_shdr, mimg, 1567 INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB), 1568 sizeof(a_shdr)); 1569 shdr_strtab_mioff 1570 = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset; 1571 1572 if (!ML_(img_valid)(mimg, shdr_strtab_mioff, 1573 1/*bogus, but we don't know the real size*/ )) { 1574 ML_(symerr)(di, True, "Invalid ELF Section Header String Table"); 1575 goto out; 1576 } 1577 } 1578 1579 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff); 1580 1581 svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1", 1582 ML_(dinfo_free), sizeof(RangeAndBias)); 1583 1584 /* TOPLEVEL */ 1585 /* Look through the program header table, and: 1586 - copy information from suitable PT_LOAD entries into svma_ranges 1587 - find (or fake up) the .soname for this object. 1588 */ 1589 TRACE_SYMTAB("\n"); 1590 TRACE_SYMTAB("------ Examining the program headers ------\n"); 1591 vg_assert(di->soname == NULL); 1592 { 1593 /* TOPLEVEL */ 1594 ElfXX_Addr prev_svma = 0; 1595 1596 for (i = 0; i < phdr_mnent; i++) { 1597 ElfXX_Phdr a_phdr; 1598 ML_(img_get)(&a_phdr, mimg, 1599 INDEX_BIS(phdr_mioff, i, phdr_ment_szB), 1600 sizeof(a_phdr)); 1601 1602 /* Make sure the PT_LOADable entries are in order and 1603 non-overlapping. This in turn means the address ranges 1604 slurped into svma_ranges are in order and 1605 non-overlapping. */ 1606 1607 if (a_phdr.p_type == PT_LOAD) { 1608 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n", 1609 i, (UWord)a_phdr.p_vaddr, (UWord)prev_svma); 1610 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu," 1611 " perms %c%c%c\n", 1612 i, (UWord)a_phdr.p_offset, (UWord)a_phdr.p_filesz, 1613 a_phdr.p_flags & PF_R ? 'r' : '-', 1614 a_phdr.p_flags & PF_W ? 'w' : '-', 1615 a_phdr.p_flags & PF_X ? 'x' : '-'); 1616 if (a_phdr.p_vaddr < prev_svma) { 1617 ML_(symerr)(di, True, 1618 "ELF Program Headers are not in ascending order"); 1619 goto out; 1620 } 1621 prev_svma = a_phdr.p_vaddr; 1622 if (a_phdr.p_memsz > 0) { 1623 Bool loaded = False; 1624 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) { 1625 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j); 1626 if ( (map->rx || map->rw) 1627 && a_phdr.p_offset >= map->foff 1628 && a_phdr.p_offset < map->foff + map->size 1629 && a_phdr.p_offset + a_phdr.p_filesz 1630 <= map->foff + map->size) { 1631 RangeAndBias item; 1632 item.svma_base = a_phdr.p_vaddr; 1633 item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz; 1634 item.bias = map->avma - map->foff 1635 + a_phdr.p_offset - a_phdr.p_vaddr; 1636 if (map->rw 1637 && (a_phdr.p_flags & (PF_R | PF_W)) 1638 == (PF_R | PF_W)) { 1639 item.exec = False; 1640 VG_(addToXA)(svma_ranges, &item); 1641 TRACE_SYMTAB("PT_LOAD[%ld]: acquired as rw\n", i); 1642 loaded = True; 1643 } 1644 if (map->rx 1645 && (a_phdr.p_flags & (PF_R | PF_X)) 1646 == (PF_R | PF_X)) { 1647 item.exec = True; 1648 VG_(addToXA)(svma_ranges, &item); 1649 TRACE_SYMTAB("PT_LOAD[%ld]: acquired as rx\n", i); 1650 loaded = True; 1651 } 1652 } 1653 } 1654 if (!loaded) { 1655 ML_(symerr)(di, False, 1656 "ELF section outside all mapped regions"); 1657 /* This problem might be solved by further memory mappings. 1658 Avoid the vg_assert(!di->soname) at the beginning of this 1659 function if DYNAMIC section has been already processed. */ 1660 if (di->soname) { 1661 ML_(dinfo_free)(di->soname); 1662 di->soname = NULL; 1663 } 1664 goto out; 1665 } 1666 } 1667 } 1668 1669 /* Try to get the soname. If there isn't one, use "NONE". 1670 The seginfo needs to have some kind of soname in order to 1671 facilitate writing redirect functions, since all redirect 1672 specifications require a soname (pattern). */ 1673 if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) { 1674 Word stroff = -1; 1675 DiOffT strtab_mioff = DiOffT_INVALID; 1676 for (j = 0; True/*exit check is in the loop*/; j++) { 1677 ElfXX_Dyn t_dyn_m; /* dyn_img[j] */ 1678 ML_(img_get)(&t_dyn_m, mimg, 1679 INDEX_BIS(ehdr_mioff + a_phdr.p_offset, 1680 j, sizeof(ElfXX_Dyn)), 1681 sizeof(t_dyn_m)); 1682 if (t_dyn_m.d_tag == DT_NULL) 1683 break; 1684 1685 switch (t_dyn_m.d_tag) { 1686 case DT_SONAME: { 1687 stroff = t_dyn_m.d_un.d_val; 1688 break; 1689 } 1690 case DT_STRTAB: { 1691 Bool ok2 = False; 1692 Word offset = file_offset_from_svma( 1693 &ok2, t_dyn_m.d_un.d_ptr, mimg, 1694 phdr_mioff, phdr_mnent, phdr_ment_szB 1695 ); 1696 if (ok2 && strtab_mioff == DiOffT_INVALID) { 1697 // Check for obviously bogus offsets. 1698 if (!ML_(img_valid)(mimg, offset, 1)) { 1699 ML_(symerr)(di, True, "Invalid DT_STRTAB offset"); 1700 goto out; 1701 } 1702 strtab_mioff = ehdr_mioff + offset; 1703 vg_assert(ehdr_mioff == 0); // should always be 1704 } 1705 break; 1706 } 1707 default: 1708 break; 1709 } 1710 } 1711 if (stroff != -1 && strtab_mioff != DiOffT_INVALID) { 1712 di->soname = ML_(img_strdup)(mimg, "di.redi.1", 1713 strtab_mioff + stroff); 1714 TRACE_SYMTAB("Found soname = %s\n", di->soname); 1715 } 1716 } 1717 } /* for (i = 0; i < phdr_Mnent; i++) ... */ 1718 /* TOPLEVEL */ 1719 1720 } /* examine the program headers (local scope) */ 1721 1722 /* TOPLEVEL */ 1723 1724 /* If, after looking at all the program headers, we still didn't 1725 find a soname, add a fake one. */ 1726 if (di->soname == NULL) { 1727 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n"); 1728 di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE"); 1729 } 1730 1731 vg_assert(VG_(sizeXA)(svma_ranges) != 0); 1732 1733 /* Now read the section table. */ 1734 TRACE_SYMTAB("\n"); 1735 TRACE_SYMTAB("------ Examining the section headers ------\n"); 1736 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1737 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 1738 if (map->rx) 1739 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n", 1740 map->avma, map->foff, map->foff + map->size - 1 ); 1741 } 1742 TRACE_SYMTAB("rx: contains these svma regions:\n"); 1743 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) { 1744 RangeAndBias* reg = VG_(indexXA)(svma_ranges, i); 1745 if (reg->exec) 1746 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n", 1747 reg->svma_base, reg->svma_limit - 1, reg->bias ); 1748 } 1749 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1750 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 1751 if (map->rw) 1752 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n", 1753 map->avma, map->foff, map->foff + map->size - 1 ); 1754 } 1755 TRACE_SYMTAB("rw: contains these svma regions:\n"); 1756 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) { 1757 RangeAndBias* reg = VG_(indexXA)(svma_ranges, i); 1758 if (!reg->exec) 1759 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n", 1760 reg->svma_base, reg->svma_limit - 1, reg->bias ); 1761 } 1762 1763 /* TOPLEVEL */ 1764 /* Iterate over section headers */ 1765 for (i = 0; i < shdr_mnent; i++) { 1766 ElfXX_Shdr a_shdr; 1767 ML_(img_get)(&a_shdr, mimg, 1768 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr)); 1769 DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name; 1770 HChar* name = ML_(img_strdup)(mimg, "di.redi_name.1", name_mioff); 1771 Addr svma = a_shdr.sh_addr; 1772 OffT foff = a_shdr.sh_offset; 1773 UWord size = a_shdr.sh_size; /* Do not change this to be signed. */ 1774 UInt alyn = a_shdr.sh_addralign; 1775 Bool bits = !(a_shdr.sh_type == SHT_NOBITS); 1776 /* Look through our collection of info obtained from the PT_LOAD 1777 headers, and make 'inrx' and 'inrw' point to the first entry 1778 in each that intersects 'avma'. If in each case none is found, 1779 leave the relevant pointer at NULL. */ 1780 RangeAndBias* inrx = NULL; 1781 RangeAndBias* inrw = NULL; 1782 for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) { 1783 RangeAndBias* rng = VG_(indexXA)(svma_ranges, j); 1784 if (svma >= rng->svma_base && svma < rng->svma_limit) { 1785 if (!inrx && rng->exec) { 1786 inrx = rng; 1787 } else if (!inrw && !rng->exec) { 1788 inrw = rng; 1789 } 1790 if (inrx && inrw) 1791 break; 1792 } 1793 } 1794 1795 TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld " 1796 " svma %p name \"%s\"\n", 1797 i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn, 1798 foff, foff+size-1, (void*)svma, name); 1799 1800 /* Check for sane-sized segments. SHT_NOBITS sections have zero 1801 size in the file. */ 1802 if ((foff >= ML_(img_size)(mimg)) 1803 || (foff + (bits ? size : 0) > ML_(img_size)(mimg))) { 1804 ML_(symerr)(di, True, "ELF Section extends beyond image end"); 1805 goto out; 1806 } 1807 1808 /* Check for a sane alignment value. */ 1809 if (alyn > 0 && -1 == VG_(log2)(alyn)) { 1810 ML_(symerr)(di, True, "ELF Section contains invalid " 1811 ".sh_addralign value"); 1812 goto out; 1813 } 1814 1815 /* Ignore zero sized sections. */ 1816 if (size == 0) { 1817 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name); 1818 ML_(dinfo_free)(name); 1819 continue; 1820 } 1821 1822# define BAD(_secname) \ 1823 do { ML_(symerr)(di, True, \ 1824 "Can't make sense of " _secname \ 1825 " section mapping"); \ 1826 /* make sure we don't assert if we find */ \ 1827 /* ourselves back in this routine later, */ \ 1828 /* with the same di */ \ 1829 di->soname = NULL; \ 1830 goto out; \ 1831 } while (0) 1832 1833 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd 1834 and .eh_frame */ 1835 1836 /* Accept .text where mapped as rx (code), even if zero-sized */ 1837 if (0 == VG_(strcmp)(name, ".text")) { 1838 if (inrx && !di->text_present) { 1839 di->text_present = True; 1840 di->text_svma = svma; 1841 di->text_avma = svma + inrx->bias; 1842 di->text_size = size; 1843 di->text_bias = inrx->bias; 1844 di->text_debug_svma = svma; 1845 di->text_debug_bias = inrx->bias; 1846 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n", 1847 di->text_svma, 1848 di->text_svma + di->text_size - 1); 1849 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n", 1850 di->text_avma, 1851 di->text_avma + di->text_size - 1); 1852 TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias); 1853 } else { 1854 BAD(".text"); 1855 } 1856 } 1857 1858 /* Accept .data where mapped as rw (data), even if zero-sized */ 1859 if (0 == VG_(strcmp)(name, ".data")) { 1860 if (inrw && !di->data_present) { 1861 di->data_present = True; 1862 di->data_svma = svma; 1863 di->data_avma = svma + inrw->bias; 1864 di->data_size = size; 1865 di->data_bias = inrw->bias; 1866 di->data_debug_svma = svma; 1867 di->data_debug_bias = inrw->bias; 1868 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n", 1869 di->data_svma, 1870 di->data_svma + di->data_size - 1); 1871 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n", 1872 di->data_avma, 1873 di->data_avma + di->data_size - 1); 1874 TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias); 1875 } else { 1876 BAD(".data"); 1877 } 1878 } 1879 1880 /* Accept .sdata where mapped as rw (data) */ 1881 if (0 == VG_(strcmp)(name, ".sdata")) { 1882 if (inrw && !di->sdata_present) { 1883 di->sdata_present = True; 1884 di->sdata_svma = svma; 1885 di->sdata_avma = svma + inrw->bias; 1886 di->sdata_size = size; 1887 di->sdata_bias = inrw->bias; 1888 di->sdata_debug_svma = svma; 1889 di->sdata_debug_bias = inrw->bias; 1890 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n", 1891 di->sdata_svma, 1892 di->sdata_svma + di->sdata_size - 1); 1893 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n", 1894 di->sdata_avma, 1895 di->sdata_avma + di->sdata_size - 1); 1896 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias); 1897 } else { 1898 BAD(".sdata"); 1899 } 1900 } 1901 1902 /* Accept .rodata where mapped as rx (data), even if zero-sized */ 1903 if (0 == VG_(strcmp)(name, ".rodata")) { 1904 if (inrx && !di->rodata_present) { 1905 di->rodata_present = True; 1906 di->rodata_svma = svma; 1907 di->rodata_avma = svma + inrx->bias; 1908 di->rodata_size = size; 1909 di->rodata_bias = inrx->bias; 1910 di->rodata_debug_svma = svma; 1911 di->rodata_debug_bias = inrx->bias; 1912 /* NB was 'inrw' prior to r11794 */ 1913 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n", 1914 di->rodata_svma, 1915 di->rodata_svma + di->rodata_size - 1); 1916 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n", 1917 di->rodata_avma, 1918 di->rodata_avma + di->rodata_size - 1); 1919 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias); 1920 } else { 1921 BAD(".rodata"); 1922 } 1923 } 1924 1925 if (0 == VG_(strcmp)(name, ".dynbss")) { 1926 if (inrw && !di->bss_present) { 1927 dynbss_present = True; 1928 di->bss_present = True; 1929 di->bss_svma = svma; 1930 di->bss_avma = svma + inrw->bias; 1931 di->bss_size = size; 1932 di->bss_bias = inrw->bias; 1933 di->bss_debug_svma = svma; 1934 di->bss_debug_bias = inrw->bias; 1935 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n", 1936 di->bss_svma, 1937 di->bss_svma + di->bss_size - 1); 1938 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n", 1939 di->bss_avma, 1940 di->bss_avma + di->bss_size - 1); 1941 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias); 1942 } 1943 } 1944 1945 /* Accept .bss where mapped as rw (data), even if zero-sized */ 1946 if (0 == VG_(strcmp)(name, ".bss")) { 1947 if (inrw && dynbss_present) { 1948 vg_assert(di->bss_present); 1949 dynbss_present = False; 1950 vg_assert(di->bss_svma + di->bss_size == svma); 1951 di->bss_size += size; 1952 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n", 1953 svma, svma + size - 1); 1954 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n", 1955 svma + inrw->bias, svma + inrw->bias + size - 1); 1956 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias); 1957 } else 1958 1959 if (inrw && !di->bss_present) { 1960 di->bss_present = True; 1961 di->bss_svma = svma; 1962 di->bss_avma = svma + inrw->bias; 1963 di->bss_size = size; 1964 di->bss_bias = inrw->bias; 1965 di->bss_debug_svma = svma; 1966 di->bss_debug_bias = inrw->bias; 1967 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n", 1968 di->bss_svma, 1969 di->bss_svma + di->bss_size - 1); 1970 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n", 1971 di->bss_avma, 1972 di->bss_avma + di->bss_size - 1); 1973 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias); 1974 } else 1975 1976 /* Now one from the wtf?! department ... */ 1977 if (inrx && (!inrw) && !di->bss_present) { 1978 /* File contains a .bss, but it got mapped as rx only. 1979 This is very strange. For now, just pretend we didn't 1980 see it :-) */ 1981 di->bss_present = False; 1982 di->bss_svma = 0; 1983 di->bss_avma = 0; 1984 di->bss_size = 0; 1985 di->bss_bias = 0; 1986 di->bss_debug_svma = 0; 1987 di->bss_debug_bias = 0; 1988 if (!VG_(clo_xml)) { 1989 VG_(message)(Vg_UserMsg, 1990 "Warning: the following file's .bss is " 1991 "mapped r-x only - ignoring .bss syms\n"); 1992 VG_(message)(Vg_UserMsg, " %s\n", di->fsm.filename 1993 ? di->fsm.filename 1994 : "(null?!)" ); 1995 } 1996 } else 1997 1998 if ((!inrw) && (!inrx) && !di->bss_present) { 1999 /* File contains a .bss, but it didn't get mapped. Ignore. */ 2000 di->bss_present = False; 2001 di->bss_svma = 0; 2002 di->bss_avma = 0; 2003 di->bss_size = 0; 2004 di->bss_bias = 0; 2005 } else { 2006 BAD(".bss"); 2007 } 2008 } 2009 2010 if (0 == VG_(strcmp)(name, ".sdynbss")) { 2011 if (inrw && !di->sbss_present) { 2012 sdynbss_present = True; 2013 di->sbss_present = True; 2014 di->sbss_svma = svma; 2015 di->sbss_avma = svma + inrw->bias; 2016 di->sbss_size = size; 2017 di->sbss_bias = inrw->bias; 2018 di->sbss_debug_svma = svma; 2019 di->sbss_debug_bias = inrw->bias; 2020 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n", 2021 di->sbss_svma, 2022 di->sbss_svma + di->sbss_size - 1); 2023 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n", 2024 di->sbss_avma, 2025 di->sbss_avma + di->sbss_size - 1); 2026 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias); 2027 } 2028 } 2029 2030 /* Accept .sbss where mapped as rw (data) */ 2031 if (0 == VG_(strcmp)(name, ".sbss")) { 2032 if (inrw && sdynbss_present) { 2033 vg_assert(di->sbss_present); 2034 sdynbss_present = False; 2035 vg_assert(di->sbss_svma + di->sbss_size == svma); 2036 di->sbss_size += size; 2037 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n", 2038 svma, svma + size - 1); 2039 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n", 2040 svma + inrw->bias, svma + inrw->bias + size - 1); 2041 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias); 2042 } else 2043 2044 if (inrw && !di->sbss_present) { 2045 di->sbss_present = True; 2046 di->sbss_svma = svma; 2047 di->sbss_avma = svma + inrw->bias; 2048 di->sbss_size = size; 2049 di->sbss_bias = inrw->bias; 2050 di->sbss_debug_svma = svma; 2051 di->sbss_debug_bias = inrw->bias; 2052 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n", 2053 di->sbss_svma, 2054 di->sbss_svma + di->sbss_size - 1); 2055 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n", 2056 di->sbss_avma, 2057 di->sbss_avma + di->sbss_size - 1); 2058 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias); 2059 } else { 2060 BAD(".sbss"); 2061 } 2062 } 2063 2064 /* Accept .got where mapped as rw (data) */ 2065 if (0 == VG_(strcmp)(name, ".got")) { 2066 if (inrw && !di->got_present) { 2067 di->got_present = True; 2068 di->got_avma = svma + inrw->bias; 2069 di->got_size = size; 2070 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma); 2071 } else { 2072 BAD(".got"); 2073 } 2074 } 2075 2076 /* Accept .got.plt where mapped as rw (data) */ 2077 if (0 == VG_(strcmp)(name, ".got.plt")) { 2078 if (inrw && !di->gotplt_present) { 2079 di->gotplt_present = True; 2080 di->gotplt_avma = svma + inrw->bias; 2081 di->gotplt_size = size; 2082 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma); 2083 } else if (size != 0) { 2084 BAD(".got.plt"); 2085 } 2086 } 2087 2088 /* PLT is different on different platforms, it seems. */ 2089# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \ 2090 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \ 2091 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) 2092 /* Accept .plt where mapped as rx (code) */ 2093 if (0 == VG_(strcmp)(name, ".plt")) { 2094 if (inrx && !di->plt_present) { 2095 di->plt_present = True; 2096 di->plt_avma = svma + inrx->bias; 2097 di->plt_size = size; 2098 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); 2099 } else { 2100 BAD(".plt"); 2101 } 2102 } 2103# elif defined(VGP_ppc32_linux) 2104 /* Accept .plt where mapped as rw (data) */ 2105 if (0 == VG_(strcmp)(name, ".plt")) { 2106 if (inrw && !di->plt_present) { 2107 di->plt_present = True; 2108 di->plt_avma = svma + inrw->bias; 2109 di->plt_size = size; 2110 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); 2111 } else { 2112 BAD(".plt"); 2113 } 2114 } 2115# elif defined(VGP_ppc64_linux) 2116 /* Accept .plt where mapped as rw (data), or unmapped */ 2117 if (0 == VG_(strcmp)(name, ".plt")) { 2118 if (inrw && !di->plt_present) { 2119 di->plt_present = True; 2120 di->plt_avma = svma + inrw->bias; 2121 di->plt_size = size; 2122 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); 2123 } else 2124 if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) { 2125 /* File contains a .plt, but it didn't get mapped. 2126 Presumably it is not required on this platform. At 2127 least don't reject the situation as invalid. */ 2128 di->plt_present = True; 2129 di->plt_avma = 0; 2130 di->plt_size = 0; 2131 } else { 2132 BAD(".plt"); 2133 } 2134 } 2135# else 2136# error "Unsupported platform" 2137# endif 2138 2139 /* Accept .opd where mapped as rw (data) */ 2140 if (0 == VG_(strcmp)(name, ".opd")) { 2141 if (inrw && !di->opd_present) { 2142 di->opd_present = True; 2143 di->opd_avma = svma + inrw->bias; 2144 di->opd_size = size; 2145 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma); 2146 } else { 2147 BAD(".opd"); 2148 } 2149 } 2150 2151 /* Accept .eh_frame where mapped as rx (code). This seems to be 2152 the common case. However, if that doesn't pan out, try for 2153 rw (data) instead. We can handle up to N_EHFRAME_SECTS per 2154 ELF object. */ 2155 if (0 == VG_(strcmp)(name, ".eh_frame")) { 2156 if (inrx && di->n_ehframe < N_EHFRAME_SECTS) { 2157 di->ehframe_avma[di->n_ehframe] = svma + inrx->bias; 2158 di->ehframe_size[di->n_ehframe] = size; 2159 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", 2160 di->ehframe_avma[di->n_ehframe]); 2161 di->n_ehframe++; 2162 } else 2163 if (inrw && di->n_ehframe < N_EHFRAME_SECTS) { 2164 di->ehframe_avma[di->n_ehframe] = svma + inrw->bias; 2165 di->ehframe_size[di->n_ehframe] = size; 2166 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", 2167 di->ehframe_avma[di->n_ehframe]); 2168 di->n_ehframe++; 2169 } else { 2170 BAD(".eh_frame"); 2171 } 2172 } 2173 2174 ML_(dinfo_free)(name); 2175 2176# undef BAD 2177 2178 } /* iterate over the section headers */ 2179 2180 /* TOPLEVEL */ 2181 if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n", 2182 di->text_avma, di->text_size, di->text_bias); 2183 2184 if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir)) 2185 VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx\n", 2186 di->text_avma - di->text_bias, 2187 di->text_avma ); 2188 2189 TRACE_SYMTAB("\n"); 2190 TRACE_SYMTAB("------ Finding image addresses " 2191 "for debug-info sections ------\n"); 2192 2193 /* TOPLEVEL */ 2194 /* Find interesting sections, read the symbol table(s), read any 2195 debug information. Each section is located either in the main, 2196 debug or alt-debug files, but only in one. For each section, 2197 |section_escn| records which of |mimg|, |dimg| or |aimg| we 2198 found it in, along with the section's image offset and its size. 2199 The triples (section_img, section_ioff, section_szB) are 2200 consistent, in that they are always either (NULL, 2201 DiOffT_INVALID, 0), or refer to the same image, and are all 2202 assigned together. */ 2203 { 2204 /* TOPLEVEL */ 2205 DiSlice strtab_escn = DiSlice_INVALID; // .strtab 2206 DiSlice symtab_escn = DiSlice_INVALID; // .symtab 2207 DiSlice dynstr_escn = DiSlice_INVALID; // .dynstr 2208 DiSlice dynsym_escn = DiSlice_INVALID; // .dynsym 2209 DiSlice debuglink_escn = DiSlice_INVALID; // .gnu_debuglink 2210 DiSlice debugaltlink_escn = DiSlice_INVALID; // .gnu_debugaltlink 2211 DiSlice stab_escn = DiSlice_INVALID; // .stab (stabs) 2212 DiSlice stabstr_escn = DiSlice_INVALID; // .stabstr (stabs) 2213 DiSlice debug_line_escn = DiSlice_INVALID; // .debug_line (dwarf2) 2214 DiSlice debug_info_escn = DiSlice_INVALID; // .debug_info (dwarf2) 2215 DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4) 2216 DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2) 2217 DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2) 2218 DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2) 2219 DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2) 2220 DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2) 2221 DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt) 2222 DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info (alt) 2223 DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt) 2224 DiSlice debug_str_alt_escn = DiSlice_INVALID; // .debug_str (alt) 2225 DiSlice dwarf1d_escn = DiSlice_INVALID; // .debug (dwarf1) 2226 DiSlice dwarf1l_escn = DiSlice_INVALID; // .line (dwarf1) 2227 DiSlice opd_escn = DiSlice_INVALID; // .opd (dwarf2, 2228 // ppc64-linux) 2229 DiSlice ehframe_escn[N_EHFRAME_SECTS]; // .eh_frame (dwarf2) 2230 2231 for (i = 0; i < N_EHFRAME_SECTS; i++) 2232 ehframe_escn[i] = DiSlice_INVALID; 2233 2234 /* Find all interesting sections */ 2235 2236 UInt ehframe_mix = 0; 2237 2238 /* What FIND does: it finds the section called _SEC_NAME. The 2239 size of it is assigned to _SEC_SIZE. The address of the 2240 section in the transiently loaded oimage is assigned to 2241 _SEC_IMG. If the section is found, _POST_FX is executed 2242 after _SEC_NAME and _SEC_SIZE have been assigned to. 2243 2244 Even for sections which are marked loadable, the client's 2245 ld.so may not have loaded them yet, so there is no guarantee 2246 that we can safely prod around in any such area). Because 2247 the entire object file is transiently mapped aboard for 2248 inspection, it's always safe to inspect that area. */ 2249 2250 /* TOPLEVEL */ 2251 /* Iterate over section headers (again) */ 2252 for (i = 0; i < ehdr_m.e_shnum; i++) { 2253 2254# define FINDX(_sec_name, _sec_escn, _post_fx) \ 2255 do { \ 2256 ElfXX_Shdr a_shdr; \ 2257 ML_(img_get)(&a_shdr, mimg, \ 2258 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \ 2259 sizeof(a_shdr)); \ 2260 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \ 2261 + a_shdr.sh_name, _sec_name)) { \ 2262 Bool nobits; \ 2263 _sec_escn.img = mimg; \ 2264 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \ 2265 _sec_escn.szB = a_shdr.sh_size; \ 2266 nobits = a_shdr.sh_type == SHT_NOBITS; \ 2267 vg_assert(_sec_escn.img != NULL); \ 2268 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \ 2269 TRACE_SYMTAB( "%18s: ioff %llu .. %llu\n", \ 2270 _sec_name, (ULong)_sec_escn.ioff, \ 2271 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \ 2272 /* SHT_NOBITS sections have zero size in the file. */ \ 2273 if ( a_shdr.sh_offset \ 2274 + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(mimg) ) { \ 2275 ML_(symerr)(di, True, \ 2276 " section beyond image end?!"); \ 2277 goto out; \ 2278 } \ 2279 _post_fx; \ 2280 } \ 2281 } while (0); 2282 2283 /* Version with no post-effects */ 2284# define FIND(_sec_name, _sec_escn) \ 2285 FINDX(_sec_name, _sec_escn, /**/) 2286 2287 /* NAME ElfSec */ 2288 FIND(".dynsym", dynsym_escn) 2289 FIND(".dynstr", dynstr_escn) 2290 FIND(".symtab", symtab_escn) 2291 FIND(".strtab", strtab_escn) 2292 2293 FIND(".gnu_debuglink", debuglink_escn) 2294 FIND(".gnu_debugaltlink", debugaltlink_escn) 2295 2296 FIND(".stab", stab_escn) 2297 FIND(".stabstr", stabstr_escn) 2298 2299 FIND(".debug_line", debug_line_escn) 2300 FIND(".debug_info", debug_info_escn) 2301 FIND(".debug_types", debug_types_escn) 2302 FIND(".debug_abbrev", debug_abbv_escn) 2303 FIND(".debug_str", debug_str_escn) 2304 FIND(".debug_ranges", debug_ranges_escn) 2305 FIND(".debug_loc", debug_loc_escn) 2306 FIND(".debug_frame", debug_frame_escn) 2307 2308 FIND(".debug", dwarf1d_escn) 2309 FIND(".line", dwarf1l_escn) 2310 2311 FIND(".opd", opd_escn) 2312 2313 FINDX(".eh_frame", ehframe_escn[ehframe_mix], 2314 do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS); 2315 } while (0) 2316 ) 2317 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame 2318 multi-instance kludgery, how are we assured that the order 2319 in which we fill in ehframe_escn[] is consistent with the 2320 order in which we previously filled in di->ehframe_avma[] 2321 and di->ehframe_size[] ? By the fact that in both cases, 2322 these arrays were filled in by iterating over the section 2323 headers top-to-bottom. So both loops (this one and the 2324 previous one) encounter the .eh_frame entries in the same 2325 order and so fill in these arrays in a consistent order. 2326 */ 2327 2328# undef FINDX 2329# undef FIND 2330 } /* Iterate over section headers (again) */ 2331 2332 /* TOPLEVEL */ 2333 /* Now, see if we can find a debuginfo object, and if so connect 2334 |dimg| to it. */ 2335 vg_assert(dimg == NULL && aimg == NULL); 2336 2337 /* Look for a build-id */ 2338 HChar* buildid = find_buildid(mimg, False, False); 2339 2340 /* Look for a debug image that matches either the build-id or 2341 the debuglink-CRC32 in the main image. If the main image 2342 doesn't contain either of those then this won't even bother 2343 to try looking. This looks in all known places, including 2344 the --extra-debuginfo-path if specified and on the 2345 --debuginfo-server if specified. */ 2346 if (buildid != NULL || debuglink_escn.img != NULL) { 2347 /* Do have a debuglink section? */ 2348 if (debuglink_escn.img != NULL) { 2349 UInt crc_offset 2350 = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img, 2351 debuglink_escn.ioff)+1, 4); 2352 vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB); 2353 2354 /* Extract the CRC from the debuglink section */ 2355 UInt crc = ML_(img_get_UInt)(debuglink_escn.img, 2356 debuglink_escn.ioff + crc_offset); 2357 2358 /* See if we can find a matching debug file */ 2359 HChar* debuglink_str_m 2360 = ML_(img_strdup)(debuglink_escn.img, 2361 "di.redi_dlk.1", debuglink_escn.ioff); 2362 dimg = find_debug_file( di, di->fsm.filename, buildid, 2363 debuglink_str_m, crc, False ); 2364 if (debuglink_str_m) 2365 ML_(dinfo_free)(debuglink_str_m); 2366 } else { 2367 /* See if we can find a matching debug file */ 2368 dimg = find_debug_file( di, di->fsm.filename, buildid, 2369 NULL, 0, False ); 2370 } 2371 } 2372 2373 if (buildid) { 2374 ML_(dinfo_free)(buildid); 2375 buildid = NULL; /* paranoia */ 2376 } 2377 2378 /* As a last-ditch measure, try looking for in the 2379 --extra-debuginfo-path and/or on the --debuginfo-server, but 2380 only in the case where --allow-mismatched-debuginfo=yes. 2381 This is dangerous in that (1) it gives no assurance that the 2382 debuginfo object matches the main one, and hence (2) we will 2383 very likely get an assertion in the code below, if indeed 2384 there is a mismatch. Hence it is disabled by default 2385 (--allow-mismatched-debuginfo=no). Nevertheless it's 2386 sometimes a useful way of getting out of a tight spot. 2387 2388 Note that we're ignoring the name in the .gnu_debuglink 2389 section here, and just looking for a file of the same name 2390 either the extra-path or on the server. */ 2391 if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) { 2392 dimg = find_debug_file_ad_hoc( di, di->fsm.filename ); 2393 } 2394 2395 /* TOPLEVEL */ 2396 /* If we were successful in finding a debug image, pull various 2397 SVMA/bias/size and image addresses out of it. */ 2398 if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) { 2399 2400 /* Pull out and validate program header and section header info */ 2401 DiOffT ehdr_dioff = 0; 2402 ElfXX_Ehdr ehdr_dimg; 2403 ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg)); 2404 2405 DiOffT phdr_dioff = ehdr_dimg.e_phoff; 2406 UWord phdr_dnent = ehdr_dimg.e_phnum; 2407 UWord phdr_dent_szB = ehdr_dimg.e_phentsize; 2408 2409 DiOffT shdr_dioff = ehdr_dimg.e_shoff; 2410 UWord shdr_dnent = ehdr_dimg.e_shnum; 2411 UWord shdr_dent_szB = ehdr_dimg.e_shentsize; 2412 2413 DiOffT shdr_strtab_dioff = DiOffT_INVALID; 2414 2415 /* SVMAs covered by rx and rw segments and corresponding bias. */ 2416 Addr rx_dsvma_limit = 0; 2417 PtrdiffT rx_dbias = 0; 2418 Addr rw_dsvma_limit = 0; 2419 PtrdiffT rw_dbias = 0; 2420 2421 Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1; 2422 2423 if (phdr_dnent == 0 2424 || !ML_(img_valid)(dimg, phdr_dioff, 2425 phdr_dnent * phdr_dent_szB)) { 2426 ML_(symerr)(di, True, 2427 "Missing or invalid ELF Program Header Table" 2428 " (debuginfo file)"); 2429 goto out; 2430 } 2431 2432 if (shdr_dnent == 0 2433 || !ML_(img_valid)(dimg, shdr_dioff, 2434 shdr_dnent * shdr_dent_szB)) { 2435 ML_(symerr)(di, True, 2436 "Missing or invalid ELF Section Header Table" 2437 " (debuginfo file)"); 2438 goto out; 2439 } 2440 2441 /* Also find the section header's string table, and validate. */ 2442 /* checked previously by is_elf_object_file: */ 2443 vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF); 2444 2445 // shdr_dioff is the offset of the section header table 2446 // and we need the ehdr_dimg.e_shstrndx'th entry 2447 { ElfXX_Shdr a_shdr; 2448 ML_(img_get)(&a_shdr, dimg, 2449 INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx, 2450 shdr_dent_szB), 2451 sizeof(a_shdr)); 2452 shdr_strtab_dioff = a_shdr.sh_offset; 2453 if (!ML_(img_valid)(dimg, shdr_strtab_dioff, 2454 1/*bogus, but we don't know the real size*/)) { 2455 ML_(symerr)(di, True, 2456 "Invalid ELF Section Header String Table" 2457 " (debuginfo file)"); 2458 goto out; 2459 } 2460 } 2461 2462 for (i = 0; i < ehdr_dimg.e_phnum; i++) { 2463 ElfXX_Phdr a_phdr; 2464 ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff, 2465 i, phdr_dent_szB), 2466 sizeof(a_phdr)); 2467 if (a_phdr.p_type == PT_LOAD) { 2468 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) { 2469 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j); 2470 if ( a_phdr.p_offset >= map->foff 2471 && a_phdr.p_offset < map->foff + map->size 2472 && a_phdr.p_offset + a_phdr.p_filesz 2473 < map->foff + map->size) { 2474 if (map->rx && rx_dsvma_limit == 0) { 2475 rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz; 2476 rx_dbias = map->avma - map->foff + a_phdr.p_offset 2477 - a_phdr.p_vaddr; 2478 } 2479 if (map->rw && rw_dsvma_limit == 0) { 2480 rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz; 2481 rw_dbias = map->avma - map->foff + a_phdr.p_offset 2482 - a_phdr.p_vaddr; 2483 } 2484 break; 2485 } 2486 } 2487 } 2488 } 2489 2490 need_symtab = (symtab_escn.img == NULL); 2491 need_stabs = (stab_escn.img == NULL); 2492 need_dwarf2 = (debug_info_escn.img == NULL); 2493 need_dwarf1 = (dwarf1d_escn.img == NULL); 2494 2495 /* Find all interesting sections in the debug image */ 2496 for (i = 0; i < ehdr_dimg.e_shnum; i++) { 2497 2498 /* Find debug svma and bias information for sections 2499 we found in the main file. */ 2500 2501# define FIND(_sec, _seg) \ 2502 do { \ 2503 ElfXX_Shdr a_shdr; \ 2504 ML_(img_get)(&a_shdr, dimg, \ 2505 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \ 2506 sizeof(a_shdr)); \ 2507 if (di->_sec##_present \ 2508 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \ 2509 + a_shdr.sh_name, "." #_sec)) { \ 2510 vg_assert(di->_sec##_size == a_shdr.sh_size); \ 2511 /* JRS 2013-Jun-01: the following assert doesn't contain */ \ 2512 /* any ==s, which seems to me to be suspicious. */ \ 2513 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \ 2514 /* Assume we have a correct value for the main */ \ 2515 /* object's bias. Use that to derive the debuginfo */ \ 2516 /* object's bias, by adding the difference in SVMAs */ \ 2517 /* for the corresponding sections in the two files. */ \ 2518 /* That should take care of all prelinking effects. */ \ 2519 di->_sec##_debug_svma = a_shdr.sh_addr; \ 2520 di->_sec##_debug_bias \ 2521 = di->_sec##_bias + \ 2522 di->_sec##_svma - di->_sec##_debug_svma; \ 2523 TRACE_SYMTAB("acquiring ." #_sec \ 2524 " debug svma = %#lx .. %#lx\n", \ 2525 di->_sec##_debug_svma, \ 2526 di->_sec##_debug_svma + di->_sec##_size - 1); \ 2527 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \ 2528 di->_sec##_debug_bias); \ 2529 } \ 2530 } while (0); 2531 2532 /* SECTION SEGMENT */ 2533 FIND(text, rx) 2534 FIND(data, rw) 2535 FIND(sdata, rw) 2536 FIND(rodata, rw) 2537 FIND(bss, rw) 2538 FIND(sbss, rw) 2539 2540# undef FIND 2541 2542 /* Same deal as previous FIND, except only do it for those 2543 sections which we didn't find in the main file. */ 2544 2545# define FIND(_condition, _sec_name, _sec_escn) \ 2546 do { \ 2547 ElfXX_Shdr a_shdr; \ 2548 ML_(img_get)(&a_shdr, dimg, \ 2549 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \ 2550 sizeof(a_shdr)); \ 2551 if (_condition \ 2552 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \ 2553 + a_shdr.sh_name, _sec_name)) { \ 2554 Bool nobits; \ 2555 if (_sec_escn.img != NULL) { \ 2556 ML_(symerr)(di, True, \ 2557 " debuginfo section duplicates a" \ 2558 " section in the main ELF file"); \ 2559 goto out; \ 2560 } \ 2561 _sec_escn.img = dimg; \ 2562 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \ 2563 _sec_escn.szB = a_shdr.sh_size; \ 2564 nobits = a_shdr.sh_type == SHT_NOBITS; \ 2565 vg_assert(_sec_escn.img != NULL); \ 2566 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \ 2567 TRACE_SYMTAB( "%18s: dioff %llu .. %llu\n", \ 2568 _sec_name, \ 2569 (ULong)_sec_escn.ioff, \ 2570 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \ 2571 /* SHT_NOBITS sections have zero size in the file. */ \ 2572 if (a_shdr.sh_offset \ 2573 + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(dimg)) { \ 2574 ML_(symerr)(di, True, \ 2575 " section beyond image end?!"); \ 2576 goto out; \ 2577 } \ 2578 } \ 2579 } while (0); 2580 2581 /* NEEDED? NAME ElfSec */ 2582 FIND(need_symtab, ".symtab", symtab_escn) 2583 FIND(need_symtab, ".strtab", strtab_escn) 2584 FIND(need_stabs, ".stab", stab_escn) 2585 FIND(need_stabs, ".stabstr", stabstr_escn) 2586 FIND(need_dwarf2, ".debug_line", debug_line_escn) 2587 FIND(need_dwarf2, ".debug_info", debug_info_escn) 2588 FIND(need_dwarf2, ".debug_types", debug_types_escn) 2589 2590 FIND(need_dwarf2, ".debug_abbrev", debug_abbv_escn) 2591 FIND(need_dwarf2, ".debug_str", debug_str_escn) 2592 FIND(need_dwarf2, ".debug_ranges", debug_ranges_escn) 2593 2594 FIND(need_dwarf2, ".debug_loc", debug_loc_escn) 2595 FIND(need_dwarf2, ".debug_frame", debug_frame_escn) 2596 2597 FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn) 2598 2599 FIND(need_dwarf1, ".debug", dwarf1d_escn) 2600 FIND(need_dwarf1, ".line", dwarf1l_escn) 2601 2602# undef FIND 2603 } /* Find all interesting sections */ 2604 } /* do we have a debug image? */ 2605 2606 /* TOPLEVEL */ 2607 /* Look for alternate debug image, and if found, connect |aimg| 2608 to it. */ 2609 vg_assert(aimg == NULL); 2610 2611 if (debugaltlink_escn.img != NULL) { 2612 UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img, 0)+1; 2613 2614 vg_assert(buildid_offset < debugaltlink_escn.szB); 2615 2616 HChar *altbuildid 2617 = ML_(dinfo_zalloc)("di.fbi.4", 2618 (debugaltlink_escn.szB - buildid_offset) 2619 * 2 + 1); 2620 2621 for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++) 2622 VG_(sprintf)( 2623 altbuildid + 2 * j, "%02x", 2624 (UInt)ML_(img_get_UChar)(debugaltlink_escn.img, 2625 debugaltlink_escn.ioff 2626 + buildid_offset + j)); 2627 2628 /* See if we can find a matching debug file */ 2629 aimg = find_debug_file( di, di->fsm.filename, altbuildid, 2630 NULL, 0, True ); 2631 2632 ML_(dinfo_free)(altbuildid); 2633 } 2634 2635 /* TOPLEVEL */ 2636 /* If we were successful in finding alternate debug image, pull various 2637 size and image addresses out of it. */ 2638 if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) { 2639 2640 /* Pull out and validate program header and section header info */ 2641 DiOffT ehdr_aioff = 0; 2642 ElfXX_Ehdr ehdr_aimg; 2643 ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg)); 2644 2645 DiOffT shdr_aioff = ehdr_aimg.e_shoff; 2646 UWord shdr_anent = ehdr_aimg.e_shnum; 2647 UWord shdr_aent_szB = ehdr_aimg.e_shentsize; 2648 2649 DiOffT shdr_strtab_aioff = DiOffT_INVALID; 2650 2651 if (shdr_anent == 0 2652 || !ML_(img_valid)(aimg, shdr_aioff, 2653 shdr_anent * shdr_aent_szB)) { 2654 ML_(symerr)(di, True, 2655 "Missing or invalid ELF Section Header Table" 2656 " (alternate debuginfo file)"); 2657 goto out; 2658 } 2659 2660 /* Also find the section header's string table, and validate. */ 2661 /* checked previously by is_elf_object_file: */ 2662 vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF); 2663 2664 // shdr_aioff is the offset of the section header table 2665 // and we need the ehdr_aimg.e_shstrndx'th entry 2666 { ElfXX_Shdr a_shdr; 2667 ML_(img_get)(&a_shdr, aimg, 2668 INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx, 2669 shdr_aent_szB), 2670 sizeof(a_shdr)); 2671 shdr_strtab_aioff = a_shdr.sh_offset; 2672 if (!ML_(img_valid)(aimg, shdr_strtab_aioff, 2673 1/*bogus, but we don't know the real size*/)) { 2674 ML_(symerr)(di, True, 2675 "Invalid ELF Section Header String Table" 2676 " (alternate debuginfo file)"); 2677 goto out; 2678 } 2679 } 2680 2681 /* Find all interesting sections */ 2682 for (i = 0; i < ehdr_aimg.e_shnum; i++) { 2683 2684# define FIND(_sec_name, _sec_escn) \ 2685 do { \ 2686 ElfXX_Shdr a_shdr; \ 2687 ML_(img_get)(&a_shdr, aimg, \ 2688 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \ 2689 sizeof(a_shdr)); \ 2690 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \ 2691 + a_shdr.sh_name, _sec_name)) { \ 2692 if (_sec_escn.img != NULL) { \ 2693 ML_(symerr)(di, True, \ 2694 " alternate debuginfo section duplicates a" \ 2695 " section in the main ELF file"); \ 2696 goto out; \ 2697 } \ 2698 _sec_escn.img = aimg; \ 2699 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \ 2700 _sec_escn.szB = a_shdr.sh_size; \ 2701 vg_assert(_sec_escn.img != NULL); \ 2702 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \ 2703 TRACE_SYMTAB( "%18s: aioff %llu .. %llu\n", \ 2704 _sec_name, \ 2705 (ULong)_sec_escn.ioff, \ 2706 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \ 2707 } \ 2708 } while (0); 2709 2710 /* NAME ElfSec */ 2711 FIND(".debug_line", debug_line_alt_escn) 2712 FIND(".debug_info", debug_info_alt_escn) 2713 FIND(".debug_abbrev", debug_abbv_alt_escn) 2714 FIND(".debug_str", debug_str_alt_escn) 2715 2716# undef FIND 2717 } /* Find all interesting sections */ 2718 } /* do we have a debug image? */ 2719 2720 2721 /* TOPLEVEL */ 2722 /* Check some sizes */ 2723 vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0); 2724 vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0); 2725 2726 /* Read symbols */ 2727 { 2728 void (*read_elf_symtab)(struct _DebugInfo*, const HChar*, 2729 DiSlice*, DiSlice*, DiSlice*, Bool); 2730 Bool symtab_in_debug; 2731# if defined(VGP_ppc64_linux) 2732 read_elf_symtab = read_elf_symtab__ppc64_linux; 2733# else 2734 read_elf_symtab = read_elf_symtab__normal; 2735# endif 2736 symtab_in_debug = symtab_escn.img == dimg; 2737 read_elf_symtab(di, "symbol table", 2738 &symtab_escn, &strtab_escn, &opd_escn, 2739 symtab_in_debug); 2740 read_elf_symtab(di, "dynamic symbol table", 2741 &dynsym_escn, &dynstr_escn, &opd_escn, 2742 False); 2743 } /* Read symbols */ 2744 2745 /* TOPLEVEL */ 2746 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do 2747 the .eh_frame section(s) first. */ 2748 vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS); 2749 for (i = 0; i < di->n_ehframe; i++) { 2750 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why 2751 this next assertion should hold. */ 2752 vg_assert(ML_(sli_is_valid)(ehframe_escn[i])); 2753 vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]); 2754 ML_(read_callframe_info_dwarf3)( di, 2755 ehframe_escn[i], 2756 di->ehframe_avma[i], 2757 True/*is_ehframe*/ ); 2758 } 2759 if (ML_(sli_is_valid)(debug_frame_escn)) { 2760 ML_(read_callframe_info_dwarf3)( di, 2761 debug_frame_escn, 2762 0/*assume zero avma*/, 2763 False/*!is_ehframe*/ ); 2764 } 2765 2766 /* Read the stabs and/or dwarf2 debug information, if any. It 2767 appears reading stabs stuff on amd64-linux doesn't work, so 2768 we ignore it. On s390x stabs also doesnt work and we always 2769 have the dwarf info in the eh_frame. We also segfault on 2770 ppc64-linux when reading stabs, so skip that. ppc32-linux 2771 seems OK though. Also skip on Android. */ 2772# if !defined(VGP_amd64_linux) \ 2773 && !defined(VGP_s390x_linux) \ 2774 && !defined(VGP_ppc64_linux) \ 2775 && !defined(VGPV_arm_linux_android) \ 2776 && !defined(VGPV_x86_linux_android) \ 2777 && !defined(VGP_mips64_linux) 2778#if 0 2779 if (stab_img && stabstr_img) { 2780 ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz, 2781 stabstr_img, stabstr_sz ); 2782 } 2783#endif 2784# endif 2785 /* jrs 2006-01-01: icc-8.1 has been observed to generate 2786 binaries without debug_str sections. Don't preclude 2787 debuginfo reading for that reason, but, in 2788 read_unitinfo_dwarf2, do check that debugstr is non-NULL 2789 before using it. */ 2790 if (ML_(sli_is_valid)(debug_info_escn) 2791 && ML_(sli_is_valid)(debug_abbv_escn) 2792 && ML_(sli_is_valid)(debug_line_escn)) { 2793 /* The old reader: line numbers and unwind info only */ 2794 ML_(read_debuginfo_dwarf3) ( di, 2795 debug_info_escn, 2796 debug_types_escn, 2797 debug_abbv_escn, 2798 debug_line_escn, 2799 debug_str_escn, 2800 debug_str_alt_escn ); 2801 /* The new reader: read the DIEs in .debug_info to acquire 2802 information on variable types and locations. But only if 2803 the tool asks for it, or the user requests it on the 2804 command line. */ 2805 if (VG_(needs).var_info /* the tool requires it */ 2806 || VG_(clo_read_var_info) /* the user asked for it */) { 2807 ML_(new_dwarf3_reader)( 2808 di, debug_info_escn, debug_types_escn, 2809 debug_abbv_escn, debug_line_escn, 2810 debug_str_escn, debug_ranges_escn, 2811 debug_loc_escn, debug_info_alt_escn, 2812 debug_abbv_alt_escn, debug_line_alt_escn, 2813 debug_str_alt_escn 2814 ); 2815 } 2816 } 2817#if 0 2818 if (dwarf1d_img && dwarf1l_img) { 2819 ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz, 2820 dwarf1l_img, dwarf1l_sz ); 2821 } 2822#endif 2823 /* TOPLEVEL */ 2824 2825 } /* "Find interesting sections, read the symbol table(s), read any debug 2826 information" (a local scope) */ 2827 2828 /* TOPLEVEL */ 2829 res = True; 2830 2831 /* If reading Dwarf3 variable type/location info, print a line 2832 showing the number of variables read for each object. 2833 (Currently disabled -- is a sanity-check mechanism for 2834 exp-sgcheck.) */ 2835 if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) { 2836 UWord nVars = 0; 2837 if (di->varinfo) { 2838 for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) { 2839 OSet* /* of DiAddrRange */ scope 2840 = *(OSet**)VG_(indexXA)(di->varinfo, j); 2841 vg_assert(scope); 2842 VG_(OSetGen_ResetIter)( scope ); 2843 while (True) { 2844 DiAddrRange* range = VG_(OSetGen_Next)( scope ); 2845 if (!range) break; 2846 vg_assert(range->vars); 2847 Word w = VG_(sizeXA)(range->vars); 2848 vg_assert(w >= 0); 2849 if (0) VG_(printf)("range %#lx %#lx %ld\n", 2850 range->aMin, range->aMax, w); 2851 nVars += (UWord)w; 2852 } 2853 } 2854 } 2855 VG_(umsg)("VARINFO: %7lu vars %7ld text_size %s\n", 2856 nVars, di->text_size, di->fsm.filename); 2857 } 2858 /* TOPLEVEL */ 2859 2860 out: 2861 { 2862 /* Last, but not least, detach from the image(s). */ 2863 if (mimg) ML_(img_done)(mimg); 2864 if (dimg) ML_(img_done)(dimg); 2865 if (aimg) ML_(img_done)(aimg); 2866 2867 if (svma_ranges) VG_(deleteXA)(svma_ranges); 2868 2869 return res; 2870 } /* out: */ 2871 2872 /* NOTREACHED */ 2873} 2874 2875#endif // defined(VGO_linux) 2876 2877/*--------------------------------------------------------------------*/ 2878/*--- end ---*/ 2879/*--------------------------------------------------------------------*/ 2880