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