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