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