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