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