readelf.c revision 402c9eed11b9b60c6e134d05db938e395466cf99
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-2008 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 Stabs reader greatly improved by Nick Nethercote, Apr 02. 33 This module was also extensively hacked on by Jeremy Fitzhardinge 34 and Tom Hughes. 35*/ 36 37#include "pub_core_basics.h" 38#include "pub_core_vki.h" 39#include "pub_core_debuginfo.h" 40#include "pub_core_libcbase.h" 41#include "pub_core_libcprint.h" 42#include "pub_core_libcassert.h" 43#include "pub_core_libcfile.h" 44#include "pub_core_aspacemgr.h" /* for mmaping debuginfo files */ 45#include "pub_core_machine.h" /* VG_ELF_CLASS */ 46#include "pub_core_options.h" 47#include "pub_core_oset.h" 48#include "pub_core_tooliface.h" /* VG_(needs) */ 49#include "pub_core_xarray.h" 50#include "priv_misc.h" /* dinfo_zalloc/free/strdup */ 51#include "priv_d3basics.h" 52#include "priv_tytypes.h" 53#include "priv_storage.h" 54#include "priv_readelf.h" /* self */ 55#include "priv_readdwarf.h" /* 'cos ELF contains DWARF */ 56#include "priv_readdwarf3.h" 57#include "priv_readstabs.h" /* and stabs, if we're unlucky */ 58 59/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ 60#include <elf.h> 61/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ 62 63/*------------------------------------------------------------*/ 64/*--- 32/64-bit parameterisation ---*/ 65/*------------------------------------------------------------*/ 66 67/* For all the ELF macros and types which specify '32' or '64', 68 select the correct variant for this platform and give it 69 an 'XX' name. Then use the 'XX' variant consistently in 70 the rest of this file. 71*/ 72#if VG_WORDSIZE == 4 73# define ElfXX_Ehdr Elf32_Ehdr 74# define ElfXX_Shdr Elf32_Shdr 75# define ElfXX_Phdr Elf32_Phdr 76# define ElfXX_Sym Elf32_Sym 77# define ElfXX_Word Elf32_Word 78# define ElfXX_Addr Elf32_Addr 79# define ElfXX_Dyn Elf32_Dyn 80# define ELFXX_ST_BIND ELF32_ST_BIND 81# define ELFXX_ST_TYPE ELF32_ST_TYPE 82 83#elif VG_WORDSIZE == 8 84# define ElfXX_Ehdr Elf64_Ehdr 85# define ElfXX_Shdr Elf64_Shdr 86# define ElfXX_Phdr Elf64_Phdr 87# define ElfXX_Sym Elf64_Sym 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 110/* Identify an ELF object file by peering at the first few bytes of 111 it. */ 112 113Bool ML_(is_elf_object_file)( void* image, SizeT n_image ) 114{ 115 ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image; 116 Int ok = 1; 117 118 if (n_image < sizeof(ElfXX_Ehdr)) 119 return False; 120 121 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F 122 && ehdr->e_ident[EI_MAG1] == 'E' 123 && ehdr->e_ident[EI_MAG2] == 'L' 124 && ehdr->e_ident[EI_MAG3] == 'F'); 125 ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS 126 && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX 127 && ehdr->e_ident[EI_VERSION] == EV_CURRENT); 128 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN); 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 135 if (ok) 136 return True; 137 else 138 return False; 139} 140 141 142/* Show a raw ELF symbol, given its in-image address and name. */ 143 144static 145void show_raw_elf_symbol ( Int i, 146 ElfXX_Sym* sym, Char* sym_name, Addr sym_svma, 147 Bool ppc64_linux_format ) 148{ 149 HChar* space = ppc64_linux_format ? " " : ""; 150 VG_(printf)("raw symbol [%4d]: ", i); 151 switch (ELFXX_ST_BIND(sym->st_info)) { 152 case STB_LOCAL: VG_(printf)("LOC "); break; 153 case STB_GLOBAL: VG_(printf)("GLO "); break; 154 case STB_WEAK: VG_(printf)("WEA "); break; 155 case STB_LOPROC: VG_(printf)("lop "); break; 156 case STB_HIPROC: VG_(printf)("hip "); break; 157 default: VG_(printf)("??? "); break; 158 } 159 switch (ELFXX_ST_TYPE(sym->st_info)) { 160 case STT_NOTYPE: VG_(printf)("NOT "); break; 161 case STT_OBJECT: VG_(printf)("OBJ "); break; 162 case STT_FUNC: VG_(printf)("FUN "); break; 163 case STT_SECTION: VG_(printf)("SEC "); break; 164 case STT_FILE: VG_(printf)("FIL "); break; 165 case STT_LOPROC: VG_(printf)("lop "); break; 166 case STT_HIPROC: VG_(printf)("hip "); break; 167 default: VG_(printf)("??? "); break; 168 } 169 VG_(printf)(": svma %#010lx, %ssz %4ld %s\n", 170 sym_svma, space, sym->st_size + 0UL, 171 ( sym->st_name ? sym_name : (Char*)"NONAME" ) ); 172} 173 174 175/* Decide whether SYM is something we should collect, and if so, copy 176 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux 177 this is straightforward - the name, address, size are copied out 178 unchanged. 179 180 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK 181 below): we assume that the .bss is mapped immediately after .data, 182 and so accept any data symbol which exists in the range [start of 183 .data, size of .data + size of .bss). I don't know if this is 184 really correct/justifiable, or not. 185 186 For ppc64-linux it's more complex. If the symbol is seen to be in 187 the .opd section, it is taken to be a function descriptor, and so 188 a dereference is attempted, in order to get hold of the real entry 189 point address. Also as part of the dereference, there is an attempt 190 to calculate the TOC pointer (R2 value) associated with the symbol. 191 192 To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0), 193 if the symbol is seen to be outside the .opd section and its name 194 starts with a dot, an .opd deference is not attempted, and no TOC 195 pointer is calculated, but the the leading dot is removed from the 196 name. 197 198 As a result, on ppc64-linux, the caller of this function may have 199 to piece together the real size, address, name of the symbol from 200 multiple calls to this function. Ugly and confusing. 201*/ 202static 203Bool get_elf_symbol_info ( 204 /* INPUTS */ 205 struct _DebugInfo* di, /* containing DebugInfo */ 206 ElfXX_Sym* sym, /* ELF symbol */ 207 Char* sym_name, /* name */ 208 Addr sym_svma, /* address as stated in the object file */ 209 UChar* opd_img, /* oimage of .opd sec (ppc64-linux only) */ 210 PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */ 211 /* OUTPUTS */ 212 Char** sym_name_out, /* name we should record */ 213 Addr* sym_avma_out, /* addr we should record */ 214 Int* sym_size_out, /* symbol size */ 215 Addr* sym_tocptr_out, /* ppc64-linux only: R2 value to be 216 used on entry */ 217 Bool* from_opd_out, /* ppc64-linux only: did we deref an 218 .opd entry? */ 219 Bool* is_text_out /* is this a text symbol? */ 220 ) 221{ 222 Bool plausible, is_in_opd; 223 Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss; 224 225 /* Set defaults */ 226 *sym_name_out = sym_name; 227 *sym_avma_out = sym_svma; /* we will bias this shortly */ 228 *is_text_out = True; 229 *sym_size_out = (Int)sym->st_size; 230 *sym_tocptr_out = 0; /* unknown/inapplicable */ 231 *from_opd_out = False; 232 233 /* Figure out if we're interested in the symbol. Firstly, is it of 234 the right flavour? */ 235 plausible 236 = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL 237 || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL 238 || ELFXX_ST_BIND(sym->st_info) == STB_WEAK 239 ) 240 && 241 (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC 242 || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT 243 ); 244 245 /* Now bias sym_avma_out accordingly */ 246#if 0 247 /* This works, but seems a bit crude */ 248 if (ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT) { 249 *is_text_out = False; 250 *sym_avma_out += di->data_bias; 251 } else { 252 *is_text_out = True; 253 *sym_avma_out += di->text_bias; 254 } 255#else 256 /* Try to figure out exactly which section the symbol is from and 257 bias accordingly. Screws up if the previously deduced section 258 svma address ranges are wrong. */ 259 if (di->text_present 260 && di->text_size > 0 261 && sym_svma >= di->text_svma 262 && sym_svma < di->text_svma + di->text_size) { 263 *is_text_out = True; 264 *sym_avma_out += di->text_bias; 265 } else 266 if (di->data_present 267 && di->data_size > 0 268 && sym_svma >= di->data_svma 269 && sym_svma < di->data_svma + di->data_size) { 270 *is_text_out = False; 271 *sym_avma_out += di->data_bias; 272 } else 273 if (di->sdata_present 274 && di->sdata_size > 0 275 && sym_svma >= di->sdata_svma 276 && sym_svma < di->sdata_svma + di->sdata_size) { 277 *is_text_out = False; 278 *sym_avma_out += di->sdata_bias; 279 } else 280 if (di->rodata_present 281 && di->rodata_size > 0 282 && sym_svma >= di->rodata_svma 283 && sym_svma < di->rodata_svma + di->rodata_size) { 284 *is_text_out = False; 285 *sym_avma_out += di->rodata_bias; 286 } else 287 if (di->bss_present 288 && di->bss_size > 0 289 && sym_svma >= di->bss_svma 290 && sym_svma < di->bss_svma + di->bss_size) { 291 *is_text_out = False; 292 *sym_avma_out += di->bss_bias; 293 } else 294 if (di->sbss_present 295 && di->sbss_size > 0 296 && sym_svma >= di->sbss_svma 297 && sym_svma < di->sbss_svma + di->sbss_size) { 298 *is_text_out = False; 299 *sym_avma_out += di->sbss_bias; 300 } else { 301 /* Assume it's in .text. Is this a good idea? */ 302 *is_text_out = True; 303 *sym_avma_out += di->text_bias; 304 } 305#endif 306 307# if defined(VGP_ppc64_linux) 308 /* Allow STT_NOTYPE in the very special case where we're running on 309 ppc64-linux and the symbol is one which the .opd-chasing hack 310 below will chase. */ 311 if (!plausible 312 && *is_text_out 313 && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE 314 && sym->st_size > 0 315 && di->opd_present 316 && di->opd_size > 0 317 && *sym_avma_out >= di->opd_avma 318 && *sym_avma_out < di->opd_avma + di->opd_size) 319 plausible = True; 320# endif 321 322 if (!plausible) 323 return False; 324 325 /* Ignore if nameless, or zero-sized. */ 326 if (sym->st_name == (ElfXX_Word)0 327 || /* VG_(strlen)(sym_name) == 0 */ 328 /* equivalent but cheaper ... */ 329 sym_name[0] == 0 330 || sym->st_size == 0) { 331 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name); 332 return False; 333 } 334 335 /* This seems to significantly reduce the number of junk 336 symbols, and particularly reduces the number of 337 overlapping address ranges. Don't ask me why ... */ 338 if ((Int)sym->st_value == 0) { 339 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name); 340 return False; 341 } 342 343 /* If it's apparently in a GOT or PLT, it's really a reference to a 344 symbol defined elsewhere, so ignore it. */ 345 if (di->got_present 346 && di->got_size > 0 347 && *sym_avma_out >= di->got_avma 348 && *sym_avma_out < di->got_avma + di->got_size) { 349 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name); 350 return False; 351 } 352 if (di->plt_present 353 && di->plt_size > 0 354 && *sym_avma_out >= di->plt_avma 355 && *sym_avma_out < di->plt_avma + di->plt_size) { 356 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name); 357 return False; 358 } 359 360 /* ppc64-linux nasty hack: if the symbol is in an .opd section, 361 then really what we have is the address of a function 362 descriptor. So use the first word of that as the function's 363 text. 364 365 See thread starting at 366 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html 367 */ 368 is_in_opd = False; 369 370 if (di->opd_present 371 && di->opd_size > 0 372 && *sym_avma_out >= di->opd_avma 373 && *sym_avma_out < di->opd_avma + di->opd_size) { 374# if !defined(VGP_ppc64_linux) 375 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name); 376 return False; 377# else 378 Int offset_in_opd; 379 ULong* fn_descr; 380 Bool details = 1||False; 381 382 if (details) 383 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n", 384 (void*)(opd_bias), (void*)*sym_avma_out); 385 386 if (!VG_IS_8_ALIGNED(*sym_avma_out)) { 387 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name); 388 return False; 389 } 390 391 /* *sym_avma_out is a vma pointing into the .opd section. We 392 know the vma of the opd section start, so we can figure out 393 how far into the opd section this is. */ 394 395 offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma); 396 if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) { 397 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name); 398 return False; 399 } 400 401 /* Now we want to know what's at that offset in the .opd 402 section. We can't look in the running image since it won't 403 necessarily have been mapped. But we can consult the oimage. 404 opd_img is the start address of the .opd in the oimage. 405 Hence: */ 406 407 fn_descr = (ULong*)(opd_img + offset_in_opd); 408 409 if (details) 410 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n", 411 offset_in_opd, fn_descr); 412 if (details) 413 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0])); 414 415 /* opd_bias is the what we have to add to SVMAs found in .opd to 416 get plausible .text AVMAs for the entry point, and .data 417 AVMAs (presumably) for the TOC locations. We use the caller 418 supplied value (which is di->text_bias) for both of these. 419 Not sure why that is correct - it seems to work, and sounds 420 OK for fn_descr[0], but surely we need to use the data bias 421 and not the text bias for fn_descr[1] ? Oh Well. 422 */ 423 *sym_avma_out = fn_descr[0] + opd_bias; 424 *sym_tocptr_out = fn_descr[1] + opd_bias; 425 *from_opd_out = True; 426 is_in_opd = True; 427 428 /* Do a final sanity check: if the symbol falls outside the 429 DebugInfo's mapped range, ignore it. Since *sym_avma_out has 430 been updated, that can be achieved simply by falling through 431 to the test below. */ 432 433# endif /* ppc64-linux nasty hack */ 434 } 435 436 /* Here's yet another ppc64-linux hack. Get rid of leading dot if 437 the symbol is outside .opd. */ 438# if defined(VGP_ppc64_linux) 439 if (di->opd_size > 0 440 && !is_in_opd 441 && sym_name[0] == '.') { 442 vg_assert(!(*from_opd_out)); 443 *sym_name_out = &sym_name[1]; 444 } 445# endif 446 447 /* If no part of the symbol falls within the mapped range, 448 ignore it. */ 449 450 in_text 451 = di->text_present 452 && di->text_size > 0 453 && !(*sym_avma_out + *sym_size_out <= di->text_avma 454 || *sym_avma_out >= di->text_avma + di->text_size); 455 456 in_data 457 = di->data_present 458 && di->data_size > 0 459 && !(*sym_avma_out + *sym_size_out <= di->data_avma 460 || *sym_avma_out >= di->data_avma + di->data_size); 461 462 in_sdata 463 = di->sdata_present 464 && di->sdata_size > 0 465 && !(*sym_avma_out + *sym_size_out <= di->sdata_avma 466 || *sym_avma_out >= di->sdata_avma + di->sdata_size); 467 468 in_rodata 469 = di->rodata_present 470 && di->rodata_size > 0 471 && !(*sym_avma_out + *sym_size_out <= di->rodata_avma 472 || *sym_avma_out >= di->rodata_avma + di->rodata_size); 473 474 in_bss 475 = di->bss_present 476 && di->bss_size > 0 477 && !(*sym_avma_out + *sym_size_out <= di->bss_avma 478 || *sym_avma_out >= di->bss_avma + di->bss_size); 479 480 in_sbss 481 = di->sbss_present 482 && di->sbss_size > 0 483 && !(*sym_avma_out + *sym_size_out <= di->sbss_avma 484 || *sym_avma_out >= di->sbss_avma + di->sbss_size); 485 486 487 if (*is_text_out) { 488 /* This used to reject any symbol falling outside the text 489 segment ("if (!in_text) ..."). Now it is relaxed slightly, 490 to reject only symbols which fall outside the area mapped 491 r-x. This is in accordance with r7427. See 492 "Comment_Regarding_Text_Range_Checks" in storage.c for 493 background. */ 494 Bool in_rx; 495 vg_assert(di->have_rx_map); 496 in_rx = (!(*sym_avma_out + *sym_size_out <= di->rx_map_avma 497 || *sym_avma_out >= di->rx_map_avma + di->rx_map_size)); 498 if (in_text) 499 vg_assert(in_rx); 500 if (!in_rx) { 501 TRACE_SYMTAB( 502 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n", 503 *sym_avma_out, *sym_avma_out + *sym_size_out, 504 di->text_avma, 505 di->text_avma + di->text_size); 506 return False; 507 } 508 } else { 509 if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) { 510 TRACE_SYMTAB( 511 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata / .bss / .sbss svma ranges\n", 512 *sym_avma_out, *sym_avma_out + *sym_size_out); 513 return False; 514 } 515 } 516 517# if defined(VGP_ppc64_linux) 518 /* It's crucial that we never add symbol addresses in the .opd 519 section. This would completely mess up function redirection and 520 intercepting. This assert ensures that any symbols that make it 521 into the symbol table on ppc64-linux don't point into .opd. */ 522 if (di->opd_present && di->opd_size > 0) { 523 vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma 524 || *sym_avma_out >= di->opd_avma + di->opd_size); 525 } 526# endif 527 528 /* Acquire! */ 529 return True; 530} 531 532 533/* Read an ELF symbol table (normal or dynamic). This one is for the 534 "normal" case ({x86,amd64,ppc32}-linux). */ 535static 536__attribute__((unused)) /* not referred to on all targets */ 537void read_elf_symtab__normal( 538 struct _DebugInfo* di, UChar* tab_name, 539 ElfXX_Sym* symtab_img, SizeT symtab_szB, 540 UChar* strtab_img, SizeT strtab_szB, 541 UChar* opd_img /* ppc64-linux only */ 542 ) 543{ 544 Word i; 545 Addr sym_svma, sym_avma_really; 546 Char *sym_name, *sym_name_really; 547 Int sym_size; 548 Addr sym_tocptr; 549 Bool from_opd, is_text; 550 DiSym risym; 551 ElfXX_Sym *sym; 552 553 if (strtab_img == NULL || symtab_img == NULL) { 554 Char buf[80]; 555 vg_assert(VG_(strlen)(tab_name) < 40); 556 VG_(sprintf)(buf, " object doesn't have a %s", tab_name); 557 ML_(symerr)(di, False, buf); 558 return; 559 } 560 561 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%ld entries) ---\n", 562 tab_name, symtab_szB/sizeof(ElfXX_Sym) ); 563 564 /* Perhaps should start at i = 1; ELF docs suggest that entry 565 0 always denotes 'unknown symbol'. */ 566 for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) { 567 sym = & symtab_img[i]; 568 sym_name = (UChar*)(strtab_img + sym->st_name); 569 sym_svma = sym->st_value; 570 571 if (di->trace_symtab) 572 show_raw_elf_symbol(i, sym, sym_name, sym_svma, False); 573 574 if (get_elf_symbol_info(di, sym, sym_name, sym_svma, 575 opd_img, di->text_bias, 576 &sym_name_really, 577 &sym_avma_really, 578 &sym_size, 579 &sym_tocptr, 580 &from_opd, &is_text)) { 581 582 risym.addr = sym_avma_really; 583 risym.size = sym_size; 584 risym.name = ML_(addStr) ( di, sym_name_really, -1 ); 585 risym.tocptr = sym_tocptr; 586 risym.isText = is_text; 587 vg_assert(risym.name != NULL); 588 vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */ 589 ML_(addSym) ( di, &risym ); 590 591 if (di->trace_symtab) { 592 VG_(printf)(" rec(%c) [%4ld]: " 593 " val %#010lx, sz %4d %s\n", 594 is_text ? 't' : 'd', 595 i, 596 risym.addr, 597 (Int)risym.size, 598 (HChar*)risym.name 599 ); 600 } 601 602 } 603 } 604} 605 606 607/* Read an ELF symbol table (normal or dynamic). This one is for 608 ppc64-linux, which requires special treatment. */ 609 610typedef 611 struct { 612 Addr addr; 613 UChar* name; 614 } 615 TempSymKey; 616 617typedef 618 struct { 619 TempSymKey key; 620 Addr tocptr; 621 Int size; 622 Bool from_opd; 623 Bool is_text; 624 } 625 TempSym; 626 627static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) { 628 if (key1->addr < elem2->key.addr) return -1; 629 if (key1->addr > elem2->key.addr) return 1; 630 return (Word)VG_(strcmp)(key1->name, elem2->key.name); 631} 632 633static 634__attribute__((unused)) /* not referred to on all targets */ 635void read_elf_symtab__ppc64_linux( 636 struct _DebugInfo* di, UChar* tab_name, 637 ElfXX_Sym* symtab_img, SizeT symtab_szB, 638 UChar* strtab_img, SizeT strtab_szB, 639 UChar* opd_img /* ppc64-linux only */ 640 ) 641{ 642 Word i; 643 Int old_size; 644 Addr sym_svma, sym_avma_really; 645 Char *sym_name, *sym_name_really; 646 Int sym_size; 647 Addr sym_tocptr, old_tocptr; 648 Bool from_opd, modify_size, modify_tocptr, is_text; 649 DiSym risym; 650 ElfXX_Sym *sym; 651 OSet *oset; 652 TempSymKey key; 653 TempSym *elem; 654 TempSym *prev; 655 656 if (strtab_img == NULL || symtab_img == NULL) { 657 Char buf[80]; 658 vg_assert(VG_(strlen)(tab_name) < 40); 659 VG_(sprintf)(buf, " object doesn't have a %s", tab_name); 660 ML_(symerr)(di, False, buf); 661 return; 662 } 663 664 TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%ld entries) ---\n", 665 tab_name, symtab_szB/sizeof(ElfXX_Sym) ); 666 667 oset = VG_(OSetGen_Create)( offsetof(TempSym,key), 668 (OSetCmp_t)cmp_TempSymKey, 669 ML_(dinfo_zalloc), "di.respl.1", 670 ML_(dinfo_free) ); 671 vg_assert(oset); 672 673 /* Perhaps should start at i = 1; ELF docs suggest that entry 674 0 always denotes 'unknown symbol'. */ 675 for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) { 676 sym = & symtab_img[i]; 677 sym_name = (Char*)(strtab_img + sym->st_name); 678 sym_svma = sym->st_value; 679 680 if (di->trace_symtab) 681 show_raw_elf_symbol(i, sym, sym_name, sym_svma, True); 682 683 if (get_elf_symbol_info(di, sym, sym_name, sym_svma, 684 opd_img, di->text_bias, 685 &sym_name_really, 686 &sym_avma_really, 687 &sym_size, 688 &sym_tocptr, 689 &from_opd, &is_text)) { 690 691 /* Check if we've seen this (name,addr) key before. */ 692 key.addr = sym_avma_really; 693 key.name = sym_name_really; 694 prev = VG_(OSetGen_Lookup)( oset, &key ); 695 696 if (prev) { 697 698 /* Seen it before. Fold in whatever new info we can. */ 699 modify_size = False; 700 modify_tocptr = False; 701 old_size = 0; 702 old_tocptr = 0; 703 704 if (prev->from_opd && !from_opd 705 && (prev->size == 24 || prev->size == 16) 706 && sym_size != prev->size) { 707 /* Existing one is an opd-redirect, with a bogus size, 708 so the only useful new fact we have is the real size 709 of the symbol. */ 710 modify_size = True; 711 old_size = prev->size; 712 prev->size = sym_size; 713 } 714 else 715 if (!prev->from_opd && from_opd 716 && (sym_size == 24 || sym_size == 16)) { 717 /* Existing one is non-opd, new one is opd. What we 718 can acquire from the new one is the TOC ptr to be 719 used. Since the existing sym is non-toc, it 720 shouldn't currently have an known TOC ptr. */ 721 vg_assert(prev->tocptr == 0); 722 modify_tocptr = True; 723 old_tocptr = prev->tocptr; 724 prev->tocptr = sym_tocptr; 725 } 726 else { 727 /* ignore. can we do better here? */ 728 } 729 730 /* Only one or the other is possible (I think) */ 731 vg_assert(!(modify_size && modify_tocptr)); 732 733 if (modify_size && di->trace_symtab) { 734 VG_(printf)(" modify (old sz %4d) " 735 " val %#010lx, toc %#010lx, sz %4d %s\n", 736 old_size, 737 prev->key.addr, 738 prev->tocptr, 739 (Int) prev->size, 740 (HChar*)prev->key.name 741 ); 742 } 743 if (modify_tocptr && di->trace_symtab) { 744 VG_(printf)(" modify (upd tocptr) " 745 " val %#010lx, toc %#010lx, sz %4d %s\n", 746 prev->key.addr, 747 prev->tocptr, 748 (Int) prev->size, 749 (HChar*)prev->key.name 750 ); 751 } 752 753 } else { 754 755 /* A new (name,addr) key. Add and continue. */ 756 elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym)); 757 vg_assert(elem); 758 elem->key = key; 759 elem->tocptr = sym_tocptr; 760 elem->size = sym_size; 761 elem->from_opd = from_opd; 762 elem->is_text = is_text; 763 VG_(OSetGen_Insert)(oset, elem); 764 if (di->trace_symtab) { 765 VG_(printf)(" to-oset [%4ld]: " 766 " val %#010lx, toc %#010lx, sz %4d %s\n", 767 i, 768 elem->key.addr, 769 elem->tocptr, 770 (Int) elem->size, 771 (HChar*)elem->key.name 772 ); 773 } 774 775 } 776 } 777 } 778 779 /* All the syms that matter are in the oset. Now pull them out, 780 build a "standard" symbol table, and nuke the oset. */ 781 782 i = 0; 783 VG_(OSetGen_ResetIter)( oset ); 784 785 while ( (elem = VG_(OSetGen_Next)(oset)) ) { 786 risym.addr = elem->key.addr; 787 risym.size = elem->size; 788 risym.name = ML_(addStr) ( di, elem->key.name, -1 ); 789 risym.tocptr = elem->tocptr; 790 risym.isText = elem->is_text; 791 vg_assert(risym.name != NULL); 792 793 ML_(addSym) ( di, &risym ); 794 if (di->trace_symtab) { 795 VG_(printf)(" rec(%c) [%4ld]: " 796 " val %#010lx, toc %#010lx, sz %4d %s\n", 797 risym.isText ? 't' : 'd', 798 i, 799 risym.addr, 800 risym.tocptr, 801 (Int) risym.size, 802 (HChar*)risym.name 803 ); 804 } 805 i++; 806 } 807 808 VG_(OSetGen_Destroy)( oset ); 809} 810 811 812/* 813 * This routine for calculating the CRC for a separate debug file 814 * is GPLed code borrowed from GNU binutils. 815 */ 816static UInt 817calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len) 818{ 819 static const UInt crc32_table[256] = 820 { 821 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 822 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 823 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 824 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 825 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 826 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 827 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 828 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 829 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 830 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 831 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 832 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 833 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 834 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 835 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 836 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 837 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 838 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 839 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 840 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 841 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 842 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 843 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 844 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 845 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 846 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 847 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 848 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 849 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 850 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 851 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 852 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 853 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 854 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 855 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 856 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 857 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 858 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 859 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 860 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 861 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 862 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 863 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 864 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 865 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 866 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 867 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 868 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 869 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 870 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 871 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 872 0x2d02ef8d 873 }; 874 const UChar *end; 875 876 crc = ~crc & 0xffffffff; 877 for (end = buf + len; buf < end; ++ buf) 878 crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); 879 return ~crc & 0xffffffff;; 880} 881 882/* 883 * Try and open a separate debug file, ignoring any where the CRC does 884 * not match the value from the main object file. 885 */ 886static 887Addr open_debug_file( Char* name, UInt crc, /*OUT*/UWord* size ) 888{ 889 SysRes fd, sres; 890 struct vg_stat stat_buf; 891 UInt calccrc; 892 893 fd = VG_(open)(name, VKI_O_RDONLY, 0); 894 if (fd.isError) 895 return 0; 896 897 if (VG_(fstat)(fd.res, &stat_buf) != 0) { 898 VG_(close)(fd.res); 899 return 0; 900 } 901 902 if (VG_(clo_verbosity) > 1) 903 VG_(message)(Vg_DebugMsg, "Reading debug info from %s ..", name); 904 905 *size = stat_buf.st_size; 906 907 sres = VG_(am_mmap_file_float_valgrind) 908 ( *size, VKI_PROT_READ, fd.res, 0 ); 909 910 VG_(close)(fd.res); 911 912 if (sres.isError) 913 return 0; 914 915 calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sres.res, *size); 916 if (calccrc != crc) { 917 SysRes res = VG_(am_munmap_valgrind)(sres.res, *size); 918 vg_assert(!res.isError); 919 if (VG_(clo_verbosity) > 1) 920 VG_(message)(Vg_DebugMsg, 921 ".. CRC mismatch (computed %08x wanted %08x)", calccrc, crc); 922 return 0; 923 } 924 925 return sres.res; 926} 927 928/* 929 * Try to find a separate debug file for a given object file. 930 */ 931static 932Addr find_debug_file( struct _DebugInfo* di, 933 Char* objpath, Char* debugname, 934 UInt crc, /*OUT*/UWord* size ) 935{ 936 Char *objdir = ML_(dinfo_strdup)("di.fdf.1", objpath); 937 Char *objdirptr; 938 Char *debugpath; 939 Addr addr = 0; 940 941 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL) 942 *objdirptr = '\0'; 943 944 debugpath = ML_(dinfo_zalloc)( 945 "di.fdf.2", 946 VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32); 947 948 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname); 949 950 if ((addr = open_debug_file(debugpath, crc, size)) == 0) { 951 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname); 952 if ((addr = open_debug_file(debugpath, crc, size)) == 0) { 953 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname); 954 addr = open_debug_file(debugpath, crc, size); 955 } 956 } 957 958 if (addr) { 959 TRACE_SYMTAB("\n"); 960 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath); 961 } 962 963 ML_(dinfo_free)(debugpath); 964 ML_(dinfo_free)(objdir); 965 966 return addr; 967} 968 969 970static Bool contained_within ( Addr outer, UWord n_outer, 971 Addr inner, UWord n_inner ) 972{ 973 if (n_outer == 0 || n_inner == 0) 974 return False; 975 /* Simplistic .. assumes no wraparound (reasonably enough) */ 976 if (inner >= outer && inner+n_inner <= outer+n_outer) 977 return True; 978 return False; 979} 980 981static void* INDEX_BIS ( void* base, Word idx, Word scale ) { 982 return (void*)( ((UChar*)base) + idx * scale ); 983} 984 985 986/* Find the file offset corresponding to SVMA by using the program 987 headers. This is taken from binutils-2.17/binutils/readelf.c 988 offset_from_vma(). */ 989static 990Word file_offset_from_svma ( /*OUT*/Bool* ok, 991 Addr svma, 992 ElfXX_Phdr* phdr_img, 993 Word phdr_nent, 994 Word phdr_ent_szB ) 995{ 996 Word i; 997 ElfXX_Phdr* seg; 998 for (i = 0; i < phdr_nent; i++) { 999 seg = INDEX_BIS( phdr_img, i, phdr_ent_szB ); 1000 if (seg->p_type != PT_LOAD) 1001 continue; 1002 if (svma >= (seg->p_vaddr & -seg->p_align) 1003 && svma + 1 <= seg->p_vaddr + seg->p_filesz) { 1004 *ok = True; 1005 return svma - seg->p_vaddr + seg->p_offset; 1006 } 1007 } 1008 *ok = False; 1009 return 0; 1010} 1011 1012/* The central function for reading ELF debug info. For the 1013 object/exe specified by the DebugInfo, find ELF sections, then read 1014 the symbols, line number info, file name info, CFA (stack-unwind 1015 info) and anything else we want, into the tables within the 1016 supplied DebugInfo. 1017*/ 1018Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) 1019{ 1020 Bool res, ok; 1021 SysRes fd, sres; 1022 Word i; 1023 1024 /* Image addresses for the ELF file we're working with. */ 1025 Addr oimage = 0; 1026 UWord n_oimage = 0; 1027 1028 /* Ditto for any ELF debuginfo file that we might happen to load. */ 1029 Addr dimage = 0; 1030 UWord n_dimage = 0; 1031 1032 /* ELF header for the main file. Should == oimage since is at 1033 start of file. */ 1034 ElfXX_Ehdr* ehdr_img = NULL; 1035 1036 /* Program header table image addr, # entries, entry size */ 1037 ElfXX_Phdr* phdr_img = NULL; 1038 UWord phdr_nent = 0; 1039 UWord phdr_ent_szB = 0; 1040 1041 /* Section header image addr, # entries, entry size. Also the 1042 associated string table. */ 1043 ElfXX_Shdr* shdr_img = NULL; 1044 UWord shdr_nent = 0; 1045 UWord shdr_ent_szB = 0; 1046 UChar* shdr_strtab_img = NULL; 1047 1048 /* SVMAs covered by rx and rw segments and corresponding bias. */ 1049 Addr rx_svma_base = 0; 1050 Addr rx_svma_limit = 0; 1051 PtrdiffT rx_bias = 0; 1052 Addr rw_svma_base = 0; 1053 Addr rw_svma_limit = 0; 1054 PtrdiffT rw_bias = 0; 1055 1056 vg_assert(di); 1057 vg_assert(di->have_rx_map == True); 1058 vg_assert(di->have_rw_map == True); 1059 vg_assert(di->rx_map_size > 0); 1060 vg_assert(di->rw_map_size > 0); 1061 vg_assert(di->have_dinfo == False); 1062 vg_assert(di->filename); 1063 vg_assert(!di->memname); 1064 vg_assert(!di->symtab); 1065 vg_assert(!di->loctab); 1066 vg_assert(!di->cfsi); 1067 vg_assert(!di->cfsi_exprs); 1068 vg_assert(!di->strchunks); 1069 vg_assert(!di->soname); 1070 1071 /* If these don't hold true, it means that m_syswrap/m_aspacemgr 1072 managed to do a mapping where the start isn't page aligned. 1073 Which sounds pretty bogus to me. */ 1074 vg_assert(VG_IS_PAGE_ALIGNED(di->rx_map_avma)); 1075 vg_assert(VG_IS_PAGE_ALIGNED(di->rw_map_avma)); 1076 1077 /* ---------------------------------------------------------- 1078 At this point, there is very little information in the 1079 DebugInfo. We only know that something that looks like an ELF 1080 file has been mapped rx-ishly as recorded with the di->*rx_map* 1081 fields and has also been mapped rw-ishly as recorded with the 1082 di->*rw_map* fields. First we examine the file's ELF Program 1083 Header, and, by comparing that against the di->*r{w,x}_map* 1084 info, try to figure out the AVMAs for the sections we care 1085 about, that should have been mapped: text, data, sdata, bss got, 1086 plt, and toc. 1087 ---------------------------------------------------------- */ 1088 1089 oimage = (Addr)NULL; 1090 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)) 1091 VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)", 1092 di->filename, di->rx_map_avma ); 1093 1094 /* mmap the object image aboard, so that we can read symbols and 1095 line number info out of it. It will be munmapped immediately 1096 thereafter; it is only aboard transiently. */ 1097 1098 fd = VG_(open)(di->filename, VKI_O_RDONLY, 0); 1099 if (fd.isError) { 1100 ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!"); 1101 return False; 1102 } 1103 1104 { Long n_oimageLL = VG_(fsize)(fd.res); 1105 if (n_oimageLL <= 0) { 1106 ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!"); 1107 VG_(close)(fd.res); 1108 return False; 1109 } 1110 n_oimage = (UWord)(ULong)n_oimageLL; 1111 } 1112 1113 sres = VG_(am_mmap_file_float_valgrind) 1114 ( n_oimage, VKI_PROT_READ, fd.res, 0 ); 1115 1116 VG_(close)(fd.res); 1117 1118 if (sres.isError) { 1119 VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", di->filename ); 1120 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded" ); 1121 return False; 1122 } 1123 1124 oimage = sres.res; 1125 /* Check against wraparound. am_mmap_file_float_valgrind should 1126 not produce a wrapped-around mapping. */ 1127 vg_assert(n_oimage > 0); 1128 vg_assert(oimage + n_oimage > oimage); 1129 1130 if (0) { 1131 VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n", 1132 (void*)oimage, (void*)(oimage + (UWord)n_oimage)); 1133 } 1134 1135 /* Ok, the object image is safely in oimage[0 .. n_oimage-1]. Now 1136 verify that it is a valid ELF .so or executable image. */ 1137 res = False; 1138 ok = (n_oimage >= sizeof(ElfXX_Ehdr)); 1139 ehdr_img = (ElfXX_Ehdr*)oimage; 1140 1141 if (ok) 1142 ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage); 1143 1144 if (!ok) { 1145 ML_(symerr)(di, True, "Invalid ELF Header"); 1146 goto out; 1147 } 1148 1149 /* Find where the program and section header tables are, and give 1150 up if either is missing or outside the image (bogus). */ 1151 phdr_img = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff ); 1152 phdr_nent = ehdr_img->e_phnum; 1153 phdr_ent_szB = ehdr_img->e_phentsize; 1154 1155 shdr_img = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff ); 1156 shdr_nent = ehdr_img->e_shnum; 1157 shdr_ent_szB = ehdr_img->e_shentsize; 1158 1159 TRACE_SYMTAB("------ Basic facts about the object ------\n"); 1160 TRACE_SYMTAB("object: img %p n_oimage %ld\n", 1161 (void*)oimage, n_oimage); 1162 TRACE_SYMTAB("phdr: img %p nent %ld ent_szB %ld\n", 1163 phdr_img, phdr_nent, phdr_ent_szB); 1164 TRACE_SYMTAB("shdr: img %p nent %ld ent_szB %ld\n", 1165 shdr_img, shdr_nent, shdr_ent_szB); 1166 1167 if (phdr_nent == 0 1168 || !contained_within( 1169 oimage, n_oimage, 1170 (Addr)phdr_img, phdr_nent * phdr_ent_szB)) { 1171 ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table"); 1172 goto out; 1173 } 1174 1175 if (shdr_nent == 0 1176 || !contained_within( 1177 oimage, n_oimage, 1178 (Addr)shdr_img, shdr_nent * shdr_ent_szB)) { 1179 ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table"); 1180 goto out; 1181 } 1182 1183 /* Also find the section header's string table, and validate. */ 1184 /* checked previously by is_elf_object_file: */ 1185 vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF ); 1186 1187 shdr_strtab_img 1188 = (UChar*)( ((UChar*)ehdr_img) 1189 + shdr_img[ehdr_img->e_shstrndx].sh_offset); 1190 if (!contained_within( oimage, n_oimage, 1191 (Addr)shdr_strtab_img, 1192 1/*bogus, but we don't know the real size*/ )) { 1193 ML_(symerr)(di, True, "Invalid ELF Section Header String Table"); 1194 goto out; 1195 } 1196 1197 TRACE_SYMTAB("shdr: string table at %p\n", shdr_strtab_img ); 1198 1199 /* Do another amazingly tedious thing: find out the .soname for 1200 this object. Apparently requires looking through the program 1201 header table. */ 1202 TRACE_SYMTAB("\n"); 1203 TRACE_SYMTAB("------ Looking for the soname ------\n"); 1204 vg_assert(di->soname == NULL); 1205 { 1206 ElfXX_Addr prev_svma = 0; 1207 1208 for (i = 0; i < phdr_nent; i++) { 1209 ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB ); 1210 1211 /* Make sure the PT_LOADable entries are in order */ 1212 if (phdr->p_type == PT_LOAD) { 1213 TRACE_SYMTAB("PT_LOAD in order?: %#lx %#lx\n", 1214 prev_svma + 0UL, 1215 phdr->p_vaddr + 0UL); 1216 if (phdr->p_vaddr < prev_svma) { 1217 ML_(symerr)(di, True, 1218 "ELF Program Headers are not in ascending order"); 1219 goto out; 1220 } 1221 prev_svma = phdr->p_vaddr; 1222 if (rx_svma_limit == 0 1223 && phdr->p_offset >= di->rx_map_foff 1224 && phdr->p_offset < di->rx_map_foff + di->rx_map_size 1225 && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) { 1226 rx_svma_base = phdr->p_vaddr; 1227 rx_svma_limit = phdr->p_vaddr + phdr->p_memsz; 1228 rx_bias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr; 1229 } 1230 else if (rw_svma_limit == 0 1231 && phdr->p_offset >= di->rw_map_foff 1232 && phdr->p_offset < di->rw_map_foff + di->rw_map_size 1233 && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) { 1234 rw_svma_base = phdr->p_vaddr; 1235 rw_svma_limit = phdr->p_vaddr + phdr->p_memsz; 1236 rw_bias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr; 1237 } 1238 } 1239 1240 /* Try to get the soname. If there isn't one, use "NONE". 1241 The seginfo needs to have some kind of soname in order to 1242 facilitate writing redirect functions, since all redirect 1243 specifications require a soname (pattern). */ 1244 if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) { 1245 ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img) 1246 + phdr->p_offset); 1247 Word stroff = -1; 1248 UChar* strtab = NULL; 1249 Word j; 1250 for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) { 1251 switch (dyn_img[j].d_tag) { 1252 case DT_SONAME: { 1253 stroff = dyn_img[j].d_un.d_val; 1254 break; 1255 } 1256 case DT_STRTAB: { 1257 Bool ok2 = False; 1258 Word offset = file_offset_from_svma( 1259 &ok2, 1260 dyn_img[j].d_un.d_ptr, 1261 phdr_img, 1262 phdr_nent, phdr_ent_szB 1263 ); 1264 if (ok2 && strtab == NULL) { 1265 vg_assert(offset >= 0 && offset <= n_oimage); 1266 strtab = ((UChar*)ehdr_img) + offset; 1267 } 1268 break; 1269 } 1270 default: 1271 break; 1272 } 1273 } 1274 if (stroff != -1 && strtab != NULL) { 1275 TRACE_SYMTAB("Found soname = %s\n", strtab+stroff); 1276 di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff); 1277 } 1278 } 1279 } /* for (i = 0; i < phdr_nent; i++) ... */ 1280 } /* look for the soname */ 1281 1282 /* If, after looking at all the program headers, we still didn't 1283 find a soname, add a fake one. */ 1284 if (di->soname == NULL) { 1285 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n"); 1286 di->soname = "NONE"; 1287 } 1288 1289 vg_assert(rx_svma_limit != 0); 1290 vg_assert(rw_svma_limit != 0); 1291 1292 /* Now read the section table. */ 1293 TRACE_SYMTAB("\n"); 1294 TRACE_SYMTAB("------ Examining the section headers " 1295 "and program headers ------\n"); 1296 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n", 1297 di->rx_map_avma, 1298 di->rx_map_foff, di->rx_map_foff + di->rx_map_size - 1 ); 1299 TRACE_SYMTAB("rx: contains svmas %#lx .. %#lx with bias %#lx\n", 1300 rx_svma_base, rx_svma_limit - 1, rx_bias ); 1301 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n", 1302 di->rw_map_avma, 1303 di->rw_map_foff, di->rw_map_foff + di->rw_map_size - 1 ); 1304 TRACE_SYMTAB("rw: contains svmas %#lx .. %#lx with bias %#lx\n", 1305 rw_svma_base, rw_svma_limit - 1, rw_bias ); 1306 1307 for (i = 0; i < shdr_nent; i++) { 1308 ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB ); 1309 UChar* name = shdr_strtab_img + shdr->sh_name; 1310 Addr svma = shdr->sh_addr; 1311 OffT foff = shdr->sh_offset; 1312 UWord size = shdr->sh_size; 1313 UInt alyn = shdr->sh_addralign; 1314 Bool bits = !(shdr->sh_type == SHT_NOBITS); 1315 Bool inrx = svma >= rx_svma_base && svma < rx_svma_limit; 1316 Bool inrw = svma >= rw_svma_base && svma < rw_svma_limit; 1317 1318 TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld " 1319 " svma %p name \"%s\"\n", 1320 i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn, 1321 foff, foff+size-1, (void*)svma, name ); 1322 1323 /* Check for sane-sized segments. SHT_NOBITS sections have zero 1324 size in the file. */ 1325 if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) { 1326 ML_(symerr)(di, True, "ELF Section extends beyond image end"); 1327 goto out; 1328 } 1329 1330 /* Check for a sane alignment value. */ 1331 if (alyn > 0 && -1 == VG_(log2)(alyn)) { 1332 ML_(symerr)(di, True, "ELF Section contains invalid " 1333 ".sh_addralign value"); 1334 goto out; 1335 } 1336 1337# define BAD(_secname) \ 1338 do { ML_(symerr)(di, True, \ 1339 "Can't make sense of " _secname \ 1340 " section mapping"); \ 1341 goto out; \ 1342 } while (0) 1343 1344 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd 1345 and .eh_frame */ 1346 1347 /* Accept .text where mapped as rx (code), even if zero-sized */ 1348 if (0 == VG_(strcmp)(name, ".text")) { 1349 if (inrx && size >= 0 && !di->text_present) { 1350 di->text_present = True; 1351 di->text_svma = svma; 1352 di->text_avma = svma + rx_bias; 1353 di->text_size = size; 1354 di->text_bias = rx_bias; 1355 di->text_debug_svma = svma; 1356 di->text_debug_bias = rx_bias; 1357 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n", 1358 di->text_svma, 1359 di->text_svma + di->text_size - 1); 1360 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n", 1361 di->text_avma, 1362 di->text_avma + di->text_size - 1); 1363 TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias); 1364 } else { 1365 BAD(".text"); 1366 } 1367 } 1368 1369 /* Accept .data where mapped as rw (data), even if zero-sized */ 1370 if (0 == VG_(strcmp)(name, ".data")) { 1371 if (inrw && size >= 0 && !di->data_present) { 1372 di->data_present = True; 1373 di->data_svma = svma; 1374 di->data_avma = svma + rw_bias; 1375 di->data_size = size; 1376 di->data_bias = rw_bias; 1377 di->data_debug_svma = svma; 1378 di->data_debug_bias = rw_bias; 1379 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n", 1380 di->data_svma, 1381 di->data_svma + di->data_size - 1); 1382 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n", 1383 di->data_avma, 1384 di->data_avma + di->data_size - 1); 1385 TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias); 1386 } else { 1387 BAD(".data"); 1388 } 1389 } 1390 1391 /* Accept .sdata where mapped as rw (data) */ 1392 if (0 == VG_(strcmp)(name, ".sdata")) { 1393 if (inrw && size > 0 && !di->sdata_present) { 1394 di->sdata_present = True; 1395 di->sdata_svma = svma; 1396 di->sdata_avma = svma + rw_bias; 1397 di->sdata_size = size; 1398 di->sdata_bias = rw_bias; 1399 di->sdata_debug_svma = svma; 1400 di->sdata_debug_bias = rw_bias; 1401 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n", 1402 di->sdata_svma, 1403 di->sdata_svma + di->sdata_size - 1); 1404 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n", 1405 di->sdata_avma, 1406 di->sdata_avma + di->sdata_size - 1); 1407 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias); 1408 } else { 1409 BAD(".sdata"); 1410 } 1411 } 1412 1413 /* Accept .rodata where mapped as rx (data), even if zero-sized */ 1414 if (0 == VG_(strcmp)(name, ".rodata")) { 1415 if (inrx && size >= 0 && !di->rodata_present) { 1416 di->rodata_present = True; 1417 di->rodata_svma = svma; 1418 di->rodata_avma = svma + rx_bias; 1419 di->rodata_size = size; 1420 di->rodata_bias = rx_bias; 1421 di->rodata_debug_svma = svma; 1422 di->rodata_debug_bias = rw_bias; 1423 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n", 1424 di->rodata_svma, 1425 di->rodata_svma + di->rodata_size - 1); 1426 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n", 1427 di->rodata_avma, 1428 di->rodata_avma + di->rodata_size - 1); 1429 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias); 1430 } else { 1431 BAD(".rodata"); 1432 } 1433 } 1434 1435 /* Accept .bss where mapped as rw (data), even if zero-sized */ 1436 if (0 == VG_(strcmp)(name, ".bss")) { 1437 if (inrw && size >= 0 && !di->bss_present) { 1438 di->bss_present = True; 1439 di->bss_svma = svma; 1440 di->bss_avma = svma + rw_bias; 1441 di->bss_size = size; 1442 di->bss_bias = rw_bias; 1443 di->bss_debug_svma = svma; 1444 di->bss_debug_bias = rw_bias; 1445 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n", 1446 di->bss_svma, 1447 di->bss_svma + di->bss_size - 1); 1448 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n", 1449 di->bss_avma, 1450 di->bss_avma + di->bss_size - 1); 1451 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias); 1452 } else 1453 1454 /* Now one from the wtf?! department ... */ 1455 if (inrx && (!inrw) && size >= 0 && !di->bss_present) { 1456 /* File contains a .bss, but it got mapped as rx only. 1457 This is very strange. For now, just pretend we didn't 1458 see it :-) */ 1459 di->bss_present = False; 1460 di->bss_svma = 0; 1461 di->bss_avma = 0; 1462 di->bss_size = 0; 1463 di->bss_bias = 0; 1464 di->bss_debug_svma = 0; 1465 di->bss_debug_bias = 0; 1466 if (!VG_(clo_xml)) { 1467 VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is " 1468 "mapped r-x only - ignoring .bss syms"); 1469 VG_(message)(Vg_UserMsg, " %s", di->filename 1470 ? di->filename 1471 : (UChar*)"(null?!)" ); 1472 } 1473 } else 1474 1475 if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) { 1476 /* File contains a .bss, but it didn't get mapped. Ignore. */ 1477 di->bss_present = False; 1478 di->bss_svma = 0; 1479 di->bss_avma = 0; 1480 di->bss_size = 0; 1481 di->bss_bias = 0; 1482 } else { 1483 BAD(".bss"); 1484 } 1485 } 1486 1487 /* Accept .sbss where mapped as rw (data) */ 1488 if (0 == VG_(strcmp)(name, ".sbss")) { 1489 if (inrw && size > 0 && !di->sbss_present) { 1490 di->sbss_present = True; 1491 di->sbss_svma = svma; 1492 di->sbss_avma = svma + rw_bias; 1493 di->sbss_size = size; 1494 di->sbss_bias = rw_bias; 1495 di->sbss_debug_svma = svma; 1496 di->sbss_debug_bias = rw_bias; 1497 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n", 1498 di->sbss_svma, 1499 di->sbss_svma + di->sbss_size - 1); 1500 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n", 1501 di->sbss_avma, 1502 di->sbss_avma + di->sbss_size - 1); 1503 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias); 1504 } else { 1505 BAD(".sbss"); 1506 } 1507 } 1508 1509 /* Accept .got where mapped as rw (data) */ 1510 if (0 == VG_(strcmp)(name, ".got")) { 1511 if (inrw && size > 0 && !di->got_present) { 1512 di->got_present = True; 1513 di->got_avma = svma + rw_bias; 1514 di->got_size = size; 1515 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma); 1516 } else { 1517 BAD(".got"); 1518 } 1519 } 1520 1521 /* Accept .got.plt where mapped as rw (data) */ 1522 if (0 == VG_(strcmp)(name, ".got.plt")) { 1523 if (inrw && size > 0 && !di->gotplt_present) { 1524 di->gotplt_present = True; 1525 di->gotplt_avma = svma + rw_bias; 1526 di->gotplt_size = size; 1527 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma); 1528 } else if (size != 0) { 1529 BAD(".got.plt"); 1530 } 1531 } 1532 1533 /* PLT is different on different platforms, it seems. */ 1534# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) 1535 /* Accept .plt where mapped as rx (code) */ 1536 if (0 == VG_(strcmp)(name, ".plt")) { 1537 if (inrx && size > 0 && !di->plt_present) { 1538 di->plt_present = True; 1539 di->plt_avma = svma + rx_bias; 1540 di->plt_size = size; 1541 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); 1542 } else { 1543 BAD(".plt"); 1544 } 1545 } 1546# elif defined(VGP_ppc32_linux) 1547 /* Accept .plt where mapped as rw (data) */ 1548 if (0 == VG_(strcmp)(name, ".plt")) { 1549 if (inrw && size > 0 && !di->plt_present) { 1550 di->plt_present = True; 1551 di->plt_avma = svma + rw_bias; 1552 di->plt_size = size; 1553 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); 1554 } else { 1555 BAD(".plt"); 1556 } 1557 } 1558# elif defined(VGP_ppc64_linux) 1559 /* Accept .plt where mapped as rw (data), or unmapped */ 1560 if (0 == VG_(strcmp)(name, ".plt")) { 1561 if (inrw && size > 0 && !di->plt_present) { 1562 di->plt_present = True; 1563 di->plt_avma = svma + rw_bias; 1564 di->plt_size = size; 1565 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); 1566 } else 1567 if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) { 1568 /* File contains a .plt, but it didn't get mapped. 1569 Presumably it is not required on this platform. At 1570 least don't reject the situation as invalid. */ 1571 di->plt_present = True; 1572 di->plt_avma = 0; 1573 di->plt_size = 0; 1574 } else { 1575 BAD(".plt"); 1576 } 1577 } 1578# else 1579# error "Unsupported platform" 1580# endif 1581 1582 /* Accept .opd where mapped as rw (data) */ 1583 if (0 == VG_(strcmp)(name, ".opd")) { 1584 if (inrw && size > 0 && !di->opd_present) { 1585 di->opd_present = True; 1586 di->opd_avma = svma + rw_bias; 1587 di->opd_size = size; 1588 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma); 1589 } else { 1590 BAD(".opd"); 1591 } 1592 } 1593 1594 /* Accept .eh_frame where mapped as rx (code). This seems to be 1595 the common case. However, if that doesn't pan out, try for 1596 rw (data) instead. */ 1597 if (0 == VG_(strcmp)(name, ".eh_frame")) { 1598 if (inrx && size > 0 && !di->ehframe_present) { 1599 di->ehframe_present = True; 1600 di->ehframe_avma = svma + rx_bias; 1601 di->ehframe_size = size; 1602 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma); 1603 } else 1604 if (inrw && size > 0 && !di->ehframe_present) { 1605 di->ehframe_present = True; 1606 di->ehframe_avma = svma + rw_bias; 1607 di->ehframe_size = size; 1608 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma); 1609 } else { 1610 BAD(".eh_frame"); 1611 } 1612 } 1613 1614# undef BAD 1615 1616 } 1617 1618 if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n", 1619 di->text_avma, di->text_size, di->text_bias); 1620 1621 if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir)) 1622 VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx", 1623 di->text_avma - di->text_bias, 1624 di->text_avma ); 1625 1626 TRACE_SYMTAB("\n"); 1627 TRACE_SYMTAB("------ Finding image addresses " 1628 "for debug-info sections ------\n"); 1629 1630 /* Find interesting sections, read the symbol table(s), read any debug 1631 information */ 1632 { 1633 /* IMAGE addresses: pointers to start of sections in the 1634 transiently loaded oimage, not in the fragments of the file 1635 mapped in by the guest's dynamic linker. */ 1636 UChar* strtab_img = NULL; /* .strtab */ 1637 ElfXX_Sym* symtab_img = NULL; /* .symtab */ 1638 UChar* dynstr_img = NULL; /* .dynstr */ 1639 ElfXX_Sym* dynsym_img = NULL; /* .dynsym */ 1640 UChar* debuglink_img = NULL; /* .gnu_debuglink */ 1641 UChar* stab_img = NULL; /* .stab (stabs) */ 1642 UChar* stabstr_img = NULL; /* .stabstr (stabs) */ 1643 UChar* debug_line_img = NULL; /* .debug_line (dwarf2) */ 1644 UChar* debug_info_img = NULL; /* .debug_info (dwarf2) */ 1645 UChar* debug_abbv_img = NULL; /* .debug_abbrev (dwarf2) */ 1646 UChar* debug_str_img = NULL; /* .debug_str (dwarf2) */ 1647 UChar* debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */ 1648 UChar* debug_loc_img = NULL; /* .debug_loc (dwarf2) */ 1649 UChar* dwarf1d_img = NULL; /* .debug (dwarf1) */ 1650 UChar* dwarf1l_img = NULL; /* .line (dwarf1) */ 1651 UChar* ehframe_img = NULL; /* .eh_frame (dwarf2) */ 1652 UChar* opd_img = NULL; /* .opd (dwarf2, 1653 ppc64-linux) */ 1654 /* Section sizes, in bytes */ 1655 SizeT strtab_sz = 0; 1656 SizeT symtab_sz = 0; 1657 SizeT dynstr_sz = 0; 1658 SizeT dynsym_sz = 0; 1659 SizeT debuglink_sz = 0; 1660 SizeT stab_sz = 0; 1661 SizeT stabstr_sz = 0; 1662 SizeT debug_line_sz = 0; 1663 SizeT debug_info_sz = 0; 1664 SizeT debug_abbv_sz = 0; 1665 SizeT debug_str_sz = 0; 1666 SizeT debug_ranges_sz = 0; 1667 SizeT debug_loc_sz = 0; 1668 SizeT dwarf1d_sz = 0; 1669 SizeT dwarf1l_sz = 0; 1670 SizeT ehframe_sz = 0; 1671 SizeT opd_sz_unused = 0; 1672 1673 /* Find all interesting sections */ 1674 1675 /* What FIND does: it finds the section called SEC_NAME. The 1676 size of it is assigned to SEC_SIZE. The address of the 1677 section in the transiently loaded oimage is assigned to 1678 SEC_FILEA. Even for sections which are marked loadable, the 1679 client's ld.so may not have loaded them yet, so there is no 1680 guarantee that we can safely prod around in any such area). 1681 Because the entire object file is transiently mapped aboard 1682 for inspection, it's always safe to inspect that area. */ 1683 1684 for (i = 0; i < ehdr_img->e_shnum; i++) { 1685 1686# define FIND(sec_name, sec_size, sec_img) \ 1687 do { ElfXX_Shdr* shdr \ 1688 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \ 1689 if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \ 1690 + shdr->sh_name)) { \ 1691 Bool nobits; \ 1692 sec_img = (void*)(oimage + shdr->sh_offset); \ 1693 sec_size = shdr->sh_size; \ 1694 nobits = shdr->sh_type == SHT_NOBITS; \ 1695 TRACE_SYMTAB( "%18s: img %p .. %p\n", \ 1696 sec_name, (UChar*)sec_img, \ 1697 ((UChar*)sec_img) + sec_size - 1); \ 1698 /* SHT_NOBITS sections have zero size in the file. */ \ 1699 if ( shdr->sh_offset \ 1700 + (nobits ? 0 : sec_size) > n_oimage ) { \ 1701 ML_(symerr)(di, True, \ 1702 " section beyond image end?!"); \ 1703 goto out; \ 1704 } \ 1705 } \ 1706 } while (0); 1707 1708 /* NAME SIZE IMAGE addr */ 1709 FIND(".dynsym", dynsym_sz, dynsym_img) 1710 FIND(".dynstr", dynstr_sz, dynstr_img) 1711 FIND(".symtab", symtab_sz, symtab_img) 1712 FIND(".strtab", strtab_sz, strtab_img) 1713 1714 FIND(".gnu_debuglink", debuglink_sz, debuglink_img) 1715 1716 FIND(".stab", stab_sz, stab_img) 1717 FIND(".stabstr", stabstr_sz, stabstr_img) 1718 1719 FIND(".debug_line", debug_line_sz, debug_line_img) 1720 FIND(".debug_info", debug_info_sz, debug_info_img) 1721 FIND(".debug_abbrev", debug_abbv_sz, debug_abbv_img) 1722 FIND(".debug_str", debug_str_sz, debug_str_img) 1723 FIND(".debug_ranges", debug_ranges_sz, debug_ranges_img) 1724 FIND(".debug_loc", debug_loc_sz, debug_loc_img) 1725 1726 FIND(".debug", dwarf1d_sz, dwarf1d_img) 1727 FIND(".line", dwarf1l_sz, dwarf1l_img) 1728 FIND(".eh_frame", ehframe_sz, ehframe_img) 1729 1730 FIND(".opd", opd_sz_unused, opd_img) 1731 1732# undef FIND 1733 } 1734 1735 /* Did we find a debuglink section? */ 1736 if (debuglink_img != NULL) { 1737 UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4); 1738 UInt crc; 1739 1740 vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz); 1741 1742 /* Extract the CRC from the debuglink section */ 1743 crc = *(UInt *)(debuglink_img + crc_offset); 1744 1745 /* See if we can find a matching debug file */ 1746 dimage = find_debug_file( di, di->filename, debuglink_img, 1747 crc, &n_dimage ); 1748 1749 if (dimage != 0 1750 && n_dimage >= sizeof(ElfXX_Ehdr) 1751 && ML_(is_elf_object_file)((void*)dimage, n_dimage)) { 1752 1753 /* Pull out and validate program header and section header info */ 1754 ElfXX_Ehdr* ehdr_dimg = (ElfXX_Ehdr*)dimage; 1755 ElfXX_Phdr* phdr_dimg = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg) 1756 + ehdr_dimg->e_phoff ); 1757 UWord phdr_dnent = ehdr_dimg->e_phnum; 1758 UWord phdr_dent_szB = ehdr_dimg->e_phentsize; 1759 ElfXX_Shdr* shdr_dimg = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg) 1760 + ehdr_dimg->e_shoff ); 1761 UWord shdr_dnent = ehdr_dimg->e_shnum; 1762 UWord shdr_dent_szB = ehdr_dimg->e_shentsize; 1763 UChar* shdr_strtab_dimg = NULL; 1764 1765 /* SVMAs covered by rx and rw segments and corresponding bias. */ 1766 Addr rx_dsvma_base = 0; 1767 Addr rx_dsvma_limit = 0; 1768 PtrdiffT rx_dbias = 0; 1769 Addr rw_dsvma_base = 0; 1770 Addr rw_dsvma_limit = 0; 1771 PtrdiffT rw_dbias = 0; 1772 1773 Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1; 1774 1775 if (phdr_dnent == 0 1776 || !contained_within( 1777 dimage, n_dimage, 1778 (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) { 1779 ML_(symerr)(di, True, 1780 "Missing or invalid ELF Program Header Table" 1781 " (debuginfo file)"); 1782 goto out; 1783 } 1784 1785 if (shdr_dnent == 0 1786 || !contained_within( 1787 dimage, n_dimage, 1788 (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) { 1789 ML_(symerr)(di, True, 1790 "Missing or invalid ELF Section Header Table" 1791 " (debuginfo file)"); 1792 goto out; 1793 } 1794 1795 /* Also find the section header's string table, and validate. */ 1796 /* checked previously by is_elf_object_file: */ 1797 vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF ); 1798 1799 shdr_strtab_dimg 1800 = (UChar*)( ((UChar*)ehdr_dimg) 1801 + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset); 1802 if (!contained_within( 1803 dimage, n_dimage, 1804 (Addr)shdr_strtab_dimg, 1805 1/*bogus, but we don't know the real size*/ )) { 1806 ML_(symerr)(di, True, 1807 "Invalid ELF Section Header String Table" 1808 " (debuginfo file)"); 1809 goto out; 1810 } 1811 1812 need_symtab = (NULL == symtab_img); 1813 need_stabs = (NULL == stab_img); 1814 need_dwarf2 = (NULL == debug_info_img); 1815 need_dwarf1 = (NULL == dwarf1d_img); 1816 1817 for (i = 0; i < ehdr_dimg->e_phnum; i++) { 1818 ElfXX_Phdr* phdr 1819 = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff), 1820 i, phdr_ent_szB ); 1821 if (phdr->p_type == PT_LOAD) { 1822 if (rx_dsvma_limit == 0 1823 && phdr->p_offset >= di->rx_map_foff 1824 && phdr->p_offset < di->rx_map_foff + di->rx_map_size 1825 && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) { 1826 rx_dsvma_base = phdr->p_vaddr; 1827 rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz; 1828 rx_dbias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr; 1829 } 1830 else if (rw_dsvma_limit == 0 1831 && phdr->p_offset >= di->rw_map_foff 1832 && phdr->p_offset < di->rw_map_foff + di->rw_map_size 1833 && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) { 1834 rw_dsvma_base = phdr->p_vaddr; 1835 rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz; 1836 rw_dbias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr; 1837 } 1838 } 1839 } 1840 1841 /* Find all interesting sections */ 1842 for (i = 0; i < ehdr_dimg->e_shnum; i++) { 1843 1844 /* Find debug svma and bias information for sections 1845 we found in the main file. */ 1846 1847# define FIND(sec, seg) \ 1848 do { ElfXX_Shdr* shdr \ 1849 = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \ 1850 if (di->sec##_present \ 1851 && 0 == VG_(strcmp)("." #sec, \ 1852 shdr_strtab_dimg + shdr->sh_name)) { \ 1853 vg_assert(di->sec##_size == shdr->sh_size); \ 1854 vg_assert(di->sec##_avma + shdr->sh_addr + seg##_dbias); \ 1855 di->sec##_debug_svma = shdr->sh_addr; \ 1856 di->sec##_debug_bias = seg##_dbias; \ 1857 TRACE_SYMTAB("acquiring ." #sec " debug svma = %#lx .. %#lx\n", \ 1858 di->sec##_debug_svma, \ 1859 di->sec##_debug_svma + di->sec##_size - 1); \ 1860 TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \ 1861 di->sec##_debug_bias); \ 1862 } \ 1863 } while (0); 1864 1865 /* SECTION SEGMENT */ 1866 FIND(text, rx) 1867 FIND(data, rw) 1868 FIND(sdata, rw) 1869 FIND(rodata, rw) 1870 FIND(bss, rw) 1871 FIND(sbss, rw) 1872 1873# undef FIND 1874 1875 /* Same deal as previous FIND, except only do it for those 1876 sections for which we didn't find anything useful in 1877 the main file. */ 1878 1879# define FIND(condition, sec_name, sec_size, sec_img) \ 1880 do { ElfXX_Shdr* shdr \ 1881 = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \ 1882 if (condition \ 1883 && 0 == VG_(strcmp)(sec_name, \ 1884 shdr_strtab_dimg + shdr->sh_name)) { \ 1885 Bool nobits; \ 1886 if (0 != sec_img) \ 1887 VG_(core_panic)("repeated section!\n"); \ 1888 sec_img = (void*)(dimage + shdr->sh_offset); \ 1889 sec_size = shdr->sh_size; \ 1890 nobits = shdr->sh_type == SHT_NOBITS; \ 1891 TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \ 1892 sec_name, \ 1893 (UChar*)sec_img, \ 1894 ((UChar*)sec_img) + sec_size - 1); \ 1895 /* SHT_NOBITS sections have zero size in the file. */ \ 1896 if ( shdr->sh_offset \ 1897 + (nobits ? 0 : sec_size) > n_dimage ) { \ 1898 ML_(symerr)(di, True, \ 1899 " section beyond image end?!"); \ 1900 goto out; \ 1901 } \ 1902 } \ 1903 } while (0); 1904 1905 /* NEEDED? NAME SIZE IMAGE addr */ 1906 FIND(need_symtab, ".symtab", symtab_sz, symtab_img) 1907 FIND(need_symtab, ".strtab", strtab_sz, strtab_img) 1908 FIND(need_stabs, ".stab", stab_sz, stab_img) 1909 FIND(need_stabs, ".stabstr", stabstr_sz, stabstr_img) 1910 FIND(need_dwarf2, ".debug_line", debug_line_sz, debug_line_img) 1911 FIND(need_dwarf2, ".debug_info", debug_info_sz, debug_info_img) 1912 FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img) 1913 FIND(need_dwarf2, ".debug_str", debug_str_sz, debug_str_img) 1914 FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz, 1915 debug_ranges_img) 1916 FIND(need_dwarf2, ".debug_loc", debug_loc_sz, debug_loc_img) 1917 FIND(need_dwarf1, ".debug", dwarf1d_sz, dwarf1d_img) 1918 FIND(need_dwarf1, ".line", dwarf1l_sz, dwarf1l_img) 1919 1920# undef FIND 1921 } 1922 } 1923 } 1924 1925 /* Check some sizes */ 1926 vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0); 1927 vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0); 1928 1929 /* Read symbols */ 1930 { 1931 void (*read_elf_symtab)(struct _DebugInfo*,UChar*, 1932 ElfXX_Sym*,SizeT, 1933 UChar*,SizeT, 1934 UChar*); 1935# if defined(VGP_ppc64_linux) 1936 read_elf_symtab = read_elf_symtab__ppc64_linux; 1937# else 1938 read_elf_symtab = read_elf_symtab__normal; 1939# endif 1940 read_elf_symtab(di, "symbol table", 1941 symtab_img, symtab_sz, 1942 strtab_img, strtab_sz, 1943 opd_img); 1944 1945 read_elf_symtab(di, "dynamic symbol table", 1946 dynsym_img, dynsym_sz, 1947 dynstr_img, dynstr_sz, 1948 opd_img); 1949 } 1950 1951 /* Read .eh_frame (call-frame-info) if any */ 1952 if (ehframe_img) { 1953 vg_assert(ehframe_sz == di->ehframe_size); 1954 ML_(read_callframe_info_dwarf3)( di, ehframe_img ); 1955 } 1956 1957 /* Read the stabs and/or dwarf2 debug information, if any. It 1958 appears reading stabs stuff on amd64-linux doesn't work, so 1959 we ignore it. */ 1960# if !defined(VGP_amd64_linux) 1961 if (stab_img && stabstr_img) { 1962 ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz, 1963 stabstr_img, stabstr_sz ); 1964 } 1965# endif 1966 /* jrs 2006-01-01: icc-8.1 has been observed to generate 1967 binaries without debug_str sections. Don't preclude 1968 debuginfo reading for that reason, but, in 1969 read_unitinfo_dwarf2, do check that debugstr is non-NULL 1970 before using it. */ 1971 if (debug_info_img && debug_abbv_img && debug_line_img 1972 /* && debug_str_img */) { 1973 1974 /* The old reader: line numbers and unwind info only */ 1975 ML_(read_debuginfo_dwarf3) ( di, 1976 debug_info_img, debug_info_sz, 1977 debug_abbv_img, debug_abbv_sz, 1978 debug_line_img, debug_line_sz, 1979 debug_str_img, debug_str_sz ); 1980 1981 /* The new reader: read the DIEs in .debug_info to acquire 1982 information on variable types and locations. But only if 1983 the tool asks for it, or the user requests it on the 1984 command line. */ 1985 if (VG_(needs).var_info /* the tool requires it */ 1986 || VG_(clo_read_var_info) /* the user asked for it */) { 1987 ML_(new_dwarf3_reader)( 1988 di, debug_info_img, debug_info_sz, 1989 debug_abbv_img, debug_abbv_sz, 1990 debug_line_img, debug_line_sz, 1991 debug_str_img, debug_str_sz, 1992 debug_ranges_img, debug_ranges_sz, 1993 debug_loc_img, debug_loc_sz 1994 ); 1995 } 1996 } 1997 if (dwarf1d_img && dwarf1l_img) { 1998 ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz, 1999 dwarf1l_img, dwarf1l_sz ); 2000 } 2001 } 2002 res = True; 2003 2004 out: { 2005 SysRes m_res; 2006 2007 /* Last, but not least, heave the image(s) back overboard. */ 2008 if (dimage) { 2009 m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage ); 2010 vg_assert(!m_res.isError); 2011 } 2012 m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage ); 2013 vg_assert(!m_res.isError); 2014 return res; 2015 } 2016} 2017 2018 2019/*--------------------------------------------------------------------*/ 2020/*--- end ---*/ 2021/*--------------------------------------------------------------------*/ 2022