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