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