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