1 /* Report modules by examining dynamic linker data structures. 2 Copyright (C) 2008-2010 Red Hat, Inc. 3 This file is part of Red Hat elfutils. 4 5 Red Hat elfutils is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by the 7 Free Software Foundation; version 2 of the License. 8 9 Red Hat elfutils is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along 15 with Red Hat elfutils; if not, write to the Free Software Foundation, 16 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 17 18 In addition, as a special exception, Red Hat, Inc. gives You the 19 additional right to link the code of Red Hat elfutils with code licensed 20 under any Open Source Initiative certified open source license 21 (http://www.opensource.org/licenses/index.php) which requires the 22 distribution of source code with any binary distribution and to 23 distribute linked combinations of the two. Non-GPL Code permitted under 24 this exception must only link to the code of Red Hat elfutils through 25 those well defined interfaces identified in the file named EXCEPTION 26 found in the source code files (the "Approved Interfaces"). The files 27 of Non-GPL Code may instantiate templates or use macros or inline 28 functions from the Approved Interfaces without causing the resulting 29 work to be covered by the GNU General Public License. Only Red Hat, 30 Inc. may make changes or additions to the list of Approved Interfaces. 31 Red Hat's grant of this exception is conditioned upon your not adding 32 any new exceptions. If you wish to add a new Approved Interface or 33 exception, please contact Red Hat. You must obey the GNU General Public 34 License in all respects for all of the Red Hat elfutils code and other 35 code used in conjunction with Red Hat elfutils except the Non-GPL Code 36 covered by this exception. If you modify this file, you may extend this 37 exception to your version of the file, but you are not obligated to do 38 so. If you do not wish to provide this exception without modification, 39 you must delete this exception statement from your version and license 40 this file solely under the GPL without exception. 41 42 Red Hat elfutils is an included package of the Open Invention Network. 43 An included package of the Open Invention Network is a package for which 44 Open Invention Network licensees cross-license their patents. No patent 45 license is granted, either expressly or impliedly, by designation as an 46 included package. Should you wish to participate in the Open Invention 47 Network licensing program, please visit www.openinventionnetwork.com 48 <http://www.openinventionnetwork.com>. */ 49 50 #include <config.h> 51 #include "libdwflP.h" 52 53 #include <byteswap.h> 54 #include <endian.h> 55 56 /* This element is always provided and always has a constant value. 57 This makes it an easy thing to scan for to discern the format. */ 58 #define PROBE_TYPE AT_PHENT 59 #define PROBE_VAL32 sizeof (Elf32_Phdr) 60 #define PROBE_VAL64 sizeof (Elf64_Phdr) 61 62 #if BYTE_ORDER == BIG_ENDIAN 63 # define BE32(x) (x) 64 # define BE64(x) (x) 65 # define LE32(x) bswap_32 (x) 66 # define LE64(x) bswap_64 (x) 67 #else 68 # define LE32(x) (x) 69 # define LE64(x) (x) 70 # define BE32(x) bswap_32 (x) 71 # define BE64(x) bswap_64 (x) 72 #endif 73 74 75 /* Examine an auxv data block and determine its format. 76 Return true iff we figured it out. */ 77 static bool 78 auxv_format_probe (const void *auxv, size_t size, 79 uint_fast8_t *elfclass, uint_fast8_t *elfdata) 80 { 81 const union 82 { 83 char buf[size]; 84 Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)]; 85 Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)]; 86 } *u = auxv; 87 88 inline bool check64 (size_t i) 89 { 90 if (u->a64[i].a_type == BE64 (PROBE_TYPE) 91 && u->a64[i].a_un.a_val == BE64 (PROBE_VAL64)) 92 { 93 *elfdata = ELFDATA2MSB; 94 return true; 95 } 96 97 if (u->a64[i].a_type == LE64 (PROBE_TYPE) 98 && u->a64[i].a_un.a_val == LE64 (PROBE_VAL64)) 99 { 100 *elfdata = ELFDATA2LSB; 101 return true; 102 } 103 104 return false; 105 } 106 107 inline bool check32 (size_t i) 108 { 109 if (u->a32[i].a_type == BE32 (PROBE_TYPE) 110 && u->a32[i].a_un.a_val == BE32 (PROBE_VAL32)) 111 { 112 *elfdata = ELFDATA2MSB; 113 return true; 114 } 115 116 if (u->a32[i].a_type == LE32 (PROBE_TYPE) 117 && u->a32[i].a_un.a_val == LE32 (PROBE_VAL32)) 118 { 119 *elfdata = ELFDATA2LSB; 120 return true; 121 } 122 123 return false; 124 } 125 126 for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i) 127 { 128 if (check64 (i)) 129 { 130 *elfclass = ELFCLASS64; 131 return true; 132 } 133 134 if (check32 (i * 2) || check32 (i * 2 + 1)) 135 { 136 *elfclass = ELFCLASS32; 137 return true; 138 } 139 } 140 141 return false; 142 } 143 144 /* This is a Dwfl_Memory_Callback that wraps another memory callback. 146 If the underlying callback cannot fill the data, then this will 147 fall back to fetching data from module files. */ 148 149 struct integrated_memory_callback 150 { 151 Dwfl_Memory_Callback *memory_callback; 152 void *memory_callback_arg; 153 void *buffer; 154 }; 155 156 static bool 157 integrated_memory_callback (Dwfl *dwfl, int ndx, 158 void **buffer, size_t *buffer_available, 159 GElf_Addr vaddr, 160 size_t minread, 161 void *arg) 162 { 163 struct integrated_memory_callback *info = arg; 164 165 if (ndx == -1) 166 { 167 /* Called for cleanup. */ 168 if (info->buffer != NULL) 169 { 170 /* The last probe buffer came from the underlying callback. 171 Let it do its cleanup. */ 172 assert (*buffer == info->buffer); /* XXX */ 173 *buffer = info->buffer; 174 info->buffer = NULL; 175 return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available, 176 vaddr, minread, 177 info->memory_callback_arg); 178 } 179 *buffer = NULL; 180 *buffer_available = 0; 181 return false; 182 } 183 184 if (*buffer != NULL) 185 /* For a final-read request, we only use the underlying callback. */ 186 return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available, 187 vaddr, minread, info->memory_callback_arg); 188 189 /* Let the underlying callback try to fill this request. */ 190 if ((*info->memory_callback) (dwfl, ndx, &info->buffer, buffer_available, 191 vaddr, minread, info->memory_callback_arg)) 192 { 193 *buffer = info->buffer; 194 return true; 195 } 196 197 /* Now look for module text covering this address. */ 198 199 Dwfl_Module *mod; 200 (void) INTUSE(dwfl_addrsegment) (dwfl, vaddr, &mod); 201 if (mod == NULL) 202 return false; 203 204 Dwarf_Addr bias; 205 Elf_Scn *scn = INTUSE(dwfl_module_address_section) (mod, &vaddr, &bias); 206 if (unlikely (scn == NULL)) 207 { 208 #if 0 // XXX would have to handle ndx=-1 cleanup calls passed down. 209 /* If we have no sections we can try to fill it from the module file 210 based on its phdr mappings. */ 211 if (likely (mod->e_type != ET_REL) && mod->main.elf != NULL) 212 return INTUSE(dwfl_elf_phdr_memory_callback) 213 (dwfl, 0, buffer, buffer_available, 214 vaddr - mod->main.bias, minread, mod->main.elf); 215 #endif 216 return false; 217 } 218 219 Elf_Data *data = elf_rawdata (scn, NULL); 220 if (unlikely (data == NULL)) 221 // XXX throw error? 222 return false; 223 224 if (unlikely (data->d_size < vaddr)) 225 return false; 226 227 /* Provide as much data as we have. */ 228 void *contents = data->d_buf + vaddr; 229 size_t avail = data->d_size - vaddr; 230 if (unlikely (avail < minread)) 231 return false; 232 233 /* If probing for a string, make sure it's terminated. */ 234 if (minread == 0 && unlikely (memchr (contents, '\0', avail) == NULL)) 235 return false; 236 237 /* We have it! */ 238 *buffer = contents; 239 *buffer_available = avail; 240 return true; 241 } 242 243 static size_t 245 addrsize (uint_fast8_t elfclass) 246 { 247 return elfclass * 4; 248 } 249 250 /* Report a module for each struct link_map in the linked list at r_map 251 in the struct r_debug at R_DEBUG_VADDR. 252 253 For each link_map entry, if an existing module resides at its address, 254 this just modifies that module's name and suggested file name. If 255 no such module exists, this calls dwfl_report_elf on the l_name string. 256 257 Returns the number of modules found, or -1 for errors. */ 258 259 static int 260 report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, 261 Dwfl *dwfl, GElf_Addr r_debug_vaddr, 262 Dwfl_Memory_Callback *memory_callback, 263 void *memory_callback_arg) 264 { 265 /* Skip r_version, to aligned r_map field. */ 266 GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass); 267 268 void *buffer = NULL; 269 size_t buffer_available = 0; 270 inline int release_buffer (int result) 271 { 272 if (buffer != NULL) 273 (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0, 274 memory_callback_arg); 275 return result; 276 } 277 278 GElf_Addr addrs[4]; 279 inline bool read_addrs (GElf_Addr vaddr, size_t n) 280 { 281 size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read. */ 282 283 /* Read a new buffer if the old one doesn't cover these words. */ 284 if (buffer == NULL 285 || vaddr < read_vaddr 286 || vaddr - read_vaddr + nb > buffer_available) 287 { 288 release_buffer (0); 289 290 read_vaddr = vaddr; 291 int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL); 292 if (unlikely (segndx < 0) 293 || unlikely (! (*memory_callback) (dwfl, segndx, 294 &buffer, &buffer_available, 295 vaddr, nb, memory_callback_arg))) 296 return true; 297 } 298 299 const union 300 { 301 Elf32_Addr a32[n]; 302 Elf64_Addr a64[n]; 303 } *in = vaddr - read_vaddr + buffer; 304 305 if (elfclass == ELFCLASS32) 306 { 307 if (elfdata == ELFDATA2MSB) 308 for (size_t i = 0; i < n; ++i) 309 addrs[i] = BE32 (in->a32[i]); 310 else 311 for (size_t i = 0; i < n; ++i) 312 addrs[i] = LE32 (in->a32[i]); 313 } 314 else 315 { 316 if (elfdata == ELFDATA2MSB) 317 for (size_t i = 0; i < n; ++i) 318 addrs[i] = BE64 (in->a64[i]); 319 else 320 for (size_t i = 0; i < n; ++i) 321 addrs[i] = LE64 (in->a64[i]); 322 } 323 324 return false; 325 } 326 327 if (unlikely (read_addrs (read_vaddr, 1))) 328 return release_buffer (-1); 329 330 GElf_Addr next = addrs[0]; 331 332 Dwfl_Module **lastmodp = &dwfl->modulelist; 333 int result = 0; 334 335 /* There can't be more elements in the link_map list than there are 336 segments. DWFL->lookup_elts is probably twice that number, so it 337 is certainly above the upper bound. If we iterate too many times, 338 there must be a loop in the pointers due to link_map clobberation. */ 339 size_t iterations = 0; 340 while (next != 0 && ++iterations < dwfl->lookup_elts) 341 { 342 if (read_addrs (next, 4)) 343 return release_buffer (-1); 344 345 GElf_Addr l_addr = addrs[0]; 346 GElf_Addr l_name = addrs[1]; 347 GElf_Addr l_ld = addrs[2]; 348 next = addrs[3]; 349 350 /* If a clobbered or truncated memory image has no useful pointer, 351 just skip this element. */ 352 if (l_ld == 0) 353 continue; 354 355 /* Fetch the string at the l_name address. */ 356 const char *name = NULL; 357 if (buffer != NULL 358 && read_vaddr <= l_name 359 && l_name + 1 - read_vaddr < buffer_available 360 && memchr (l_name - read_vaddr + buffer, '\0', 361 buffer_available - (l_name - read_vaddr)) != NULL) 362 name = l_name - read_vaddr + buffer; 363 else 364 { 365 release_buffer (0); 366 read_vaddr = l_name; 367 int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_name, NULL); 368 if (likely (segndx >= 0) 369 && (*memory_callback) (dwfl, segndx, 370 &buffer, &buffer_available, 371 l_name, 0, memory_callback_arg)) 372 name = buffer; 373 } 374 375 if (name != NULL && name[0] == '\0') 376 name = NULL; 377 378 /* If content-sniffing already reported a module covering 379 the same area, find that existing module to adjust. 380 The l_ld address is the only one we know for sure 381 to be within the module's own segments (its .dynamic). */ 382 Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (dwfl, l_ld); 383 if (mod != NULL) 384 { 385 /* We have a module. We can give it a better name from l_name. */ 386 if (name != NULL && mod->name[0] == '[') 387 { 388 char *newname = strdup (basename (name)); 389 if (newname != NULL) 390 { 391 free (mod->name); 392 mod->name = newname; 393 } 394 } 395 396 if (name == NULL && mod->name[0] == '/') 397 name = mod->name; 398 399 /* If we don't have a file for it already, we can pre-install 400 the full file name from l_name. Opening the file by this 401 name will be the fallback when no build ID match is found. 402 XXX hook for sysroot */ 403 if (name != NULL && mod->main.name == NULL) 404 mod->main.name = strdup (name); 405 } 406 else if (name != NULL) 407 { 408 /* We have to find the file's phdrs to compute along with l_addr 409 what its runtime address boundaries are. */ 410 411 // XXX hook for sysroot 412 mod = INTUSE(dwfl_report_elf) (dwfl, basename (name), 413 name, -1, l_addr); 414 } 415 416 if (mod != NULL) 417 { 418 ++result; 419 420 /* Move this module to the end of the list, so that we end 421 up with a list in the same order as the link_map chain. */ 422 if (mod->next != NULL) 423 { 424 if (*lastmodp != mod) 425 { 426 lastmodp = &dwfl->modulelist; 427 while (*lastmodp != mod) 428 lastmodp = &(*lastmodp)->next; 429 } 430 *lastmodp = mod->next; 431 mod->next = NULL; 432 while (*lastmodp != NULL) 433 lastmodp = &(*lastmodp)->next; 434 *lastmodp = mod; 435 } 436 437 lastmodp = &mod->next; 438 } 439 } 440 441 return release_buffer (result); 442 } 443 444 static GElf_Addr 446 consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry, 447 uint_fast8_t *elfclass, uint_fast8_t *elfdata, 448 Dwfl_Memory_Callback *memory_callback, 449 void *memory_callback_arg) 450 { 451 GElf_Ehdr ehdr; 452 if (unlikely (gelf_getehdr (mod->main.elf, &ehdr) == NULL)) 453 return 0; 454 455 if (at_entry != 0) 456 { 457 /* If we have an AT_ENTRY value, reject this executable if 458 its entry point address could not have supplied that. */ 459 460 if (ehdr.e_entry == 0) 461 return 0; 462 463 if (mod->e_type == ET_EXEC) 464 { 465 if (ehdr.e_entry != at_entry) 466 return 0; 467 } 468 else 469 { 470 /* It could be a PIE. */ 471 } 472 } 473 474 // XXX this could be saved in the file cache: phdr vaddr, DT_DEBUG d_val vaddr 475 /* Find the vaddr of the DT_DEBUG's d_ptr. This is the memory 476 address where &r_debug was written at runtime. */ 477 GElf_Xword align = mod->dwfl->segment_align; 478 GElf_Addr d_val_vaddr = 0; 479 for (uint_fast16_t i = 0; i < ehdr.e_phnum; ++i) 480 { 481 GElf_Phdr phdr_mem; 482 GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem); 483 if (phdr == NULL) 484 break; 485 486 if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align)) 487 align = phdr->p_align; 488 489 if (at_phdr != 0 490 && phdr->p_type == PT_LOAD 491 && (phdr->p_offset & -align) == (ehdr.e_phoff & -align)) 492 { 493 /* This is the segment that would map the phdrs. 494 If we have an AT_PHDR value, reject this executable 495 if its phdr mapping could not have supplied that. */ 496 if (mod->e_type == ET_EXEC) 497 { 498 if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr) 499 return 0; 500 } 501 else 502 { 503 /* It could be a PIE. If the AT_PHDR value and our 504 phdr address don't match modulo ALIGN, then this 505 could not have been the right PIE. */ 506 if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align) 507 != (at_phdr & -align)) 508 return 0; 509 510 /* Calculate the bias applied to the PIE's p_vaddr values. */ 511 GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset 512 + phdr->p_vaddr)); 513 514 /* Final sanity check: if we have an AT_ENTRY value, 515 reject this PIE unless its biased e_entry matches. */ 516 if (at_entry != 0 && at_entry != ehdr.e_entry + bias) 517 return 0; 518 519 /* If we're changing the module's address range, 520 we've just invalidated the module lookup table. */ 521 GElf_Addr mod_bias = dwfl_adjusted_address (mod, 0); 522 if (bias != mod_bias) 523 { 524 mod->low_addr -= mod_bias; 525 mod->high_addr -= mod_bias; 526 mod->low_addr += bias; 527 mod->high_addr += bias; 528 529 free (mod->dwfl->lookup_module); 530 mod->dwfl->lookup_module = NULL; 531 } 532 } 533 } 534 535 if (phdr->p_type == PT_DYNAMIC) 536 { 537 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset, 538 phdr->p_filesz, ELF_T_DYN); 539 if (data == NULL) 540 continue; 541 const size_t entsize = gelf_fsize (mod->main.elf, 542 ELF_T_DYN, 1, EV_CURRENT); 543 const size_t n = data->d_size / entsize; 544 for (size_t j = 0; j < n; ++j) 545 { 546 GElf_Dyn dyn_mem; 547 GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 548 if (dyn != NULL && dyn->d_tag == DT_DEBUG) 549 { 550 d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2; 551 break; 552 } 553 } 554 } 555 } 556 557 if (d_val_vaddr != 0) 558 { 559 /* Now we have the final address from which to read &r_debug. */ 560 d_val_vaddr = dwfl_adjusted_address (mod, d_val_vaddr); 561 562 void *buffer = NULL; 563 size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]); 564 565 int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, NULL); 566 567 if ((*memory_callback) (mod->dwfl, segndx, 568 &buffer, &buffer_available, 569 d_val_vaddr, buffer_available, 570 memory_callback_arg)) 571 { 572 const union 573 { 574 Elf32_Addr a32; 575 Elf64_Addr a64; 576 } *u = buffer; 577 578 GElf_Addr vaddr; 579 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) 580 vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB 581 ? BE32 (u->a32) : LE32 (u->a32)); 582 else 583 vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB 584 ? BE64 (u->a64) : LE64 (u->a64)); 585 586 (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0, 587 memory_callback_arg); 588 589 if (*elfclass == ELFCLASSNONE) 590 *elfclass = ehdr.e_ident[EI_CLASS]; 591 else if (*elfclass != ehdr.e_ident[EI_CLASS]) 592 return 0; 593 594 if (*elfdata == ELFDATANONE) 595 *elfdata = ehdr.e_ident[EI_DATA]; 596 else if (*elfdata != ehdr.e_ident[EI_DATA]) 597 return 0; 598 599 return vaddr; 600 } 601 } 602 603 return 0; 604 } 605 606 /* Try to find an existing executable module with a DT_DEBUG. */ 607 static GElf_Addr 608 find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry, 609 uint_fast8_t *elfclass, uint_fast8_t *elfdata, 610 Dwfl_Memory_Callback *memory_callback, 611 void *memory_callback_arg) 612 { 613 for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next) 614 if (mod->main.elf != NULL) 615 { 616 GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry, 617 elfclass, elfdata, 618 memory_callback, 619 memory_callback_arg); 620 if (r_debug_vaddr != 0) 621 return r_debug_vaddr; 622 } 623 624 return 0; 625 } 626 627 629 int 630 dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, 631 Dwfl_Memory_Callback *memory_callback, 632 void *memory_callback_arg) 633 { 634 GElf_Addr r_debug_vaddr = 0; 635 636 uint_fast8_t elfclass = ELFCLASSNONE; 637 uint_fast8_t elfdata = ELFDATANONE; 638 if (likely (auxv != NULL) 639 && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata))) 640 { 641 GElf_Addr entry = 0; 642 GElf_Addr phdr = 0; 643 GElf_Xword phent = 0; 644 GElf_Xword phnum = 0; 645 646 #define AUXV_SCAN(NN, BL) do \ 647 { \ 648 const Elf##NN##_auxv_t *av = auxv; \ 649 for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i) \ 650 { \ 651 Elf##NN##_Addr val = BL##NN (av[i].a_un.a_val); \ 652 if (av[i].a_type == BL##NN (AT_ENTRY)) \ 653 entry = val; \ 654 else if (av[i].a_type == BL##NN (AT_PHDR)) \ 655 phdr = val; \ 656 else if (av[i].a_type == BL##NN (AT_PHNUM)) \ 657 phnum = val; \ 658 else if (av[i].a_type == BL##NN (AT_PHENT)) \ 659 phent = val; \ 660 else if (av[i].a_type == BL##NN (AT_PAGESZ)) \ 661 { \ 662 if (val > 1 \ 663 && (dwfl->segment_align == 0 \ 664 || val < dwfl->segment_align)) \ 665 dwfl->segment_align = val; \ 666 } \ 667 } \ 668 } \ 669 while (0) 670 671 if (elfclass == ELFCLASS32) 672 { 673 if (elfdata == ELFDATA2MSB) 674 AUXV_SCAN (32, BE); 675 else 676 AUXV_SCAN (32, LE); 677 } 678 else 679 { 680 if (elfdata == ELFDATA2MSB) 681 AUXV_SCAN (64, BE); 682 else 683 AUXV_SCAN (64, LE); 684 } 685 686 /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC. */ 687 GElf_Addr dyn_vaddr = 0; 688 GElf_Xword dyn_filesz = 0; 689 GElf_Addr dyn_bias = (GElf_Addr) -1; 690 691 inline bool consider_phdr (GElf_Word type, 692 GElf_Addr vaddr, GElf_Xword filesz) 693 { 694 switch (type) 695 { 696 case PT_PHDR: 697 if (dyn_bias == (GElf_Addr) -1 698 /* Do a sanity check on the putative address. */ 699 && ((vaddr & (dwfl->segment_align - 1)) 700 == (phdr & (dwfl->segment_align - 1)))) 701 { 702 dyn_bias = phdr - vaddr; 703 return dyn_vaddr != 0; 704 } 705 break; 706 707 case PT_DYNAMIC: 708 dyn_vaddr = vaddr; 709 dyn_filesz = filesz; 710 return dyn_bias != (GElf_Addr) -1; 711 } 712 713 return false; 714 } 715 716 if (phdr != 0 && phnum != 0) 717 { 718 Dwfl_Module *phdr_mod; 719 int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod); 720 Elf_Data in = 721 { 722 .d_type = ELF_T_PHDR, 723 .d_version = EV_CURRENT, 724 .d_size = phnum * phent, 725 .d_buf = NULL 726 }; 727 if ((*memory_callback) (dwfl, phdr_segndx, &in.d_buf, &in.d_size, 728 phdr, phnum * phent, memory_callback_arg)) 729 { 730 union 731 { 732 Elf32_Phdr p32; 733 Elf64_Phdr p64; 734 char data[phnum * phent]; 735 } buf; 736 Elf_Data out = 737 { 738 .d_type = ELF_T_PHDR, 739 .d_version = EV_CURRENT, 740 .d_size = phnum * phent, 741 .d_buf = &buf 742 }; 743 in.d_size = out.d_size; 744 if (likely ((elfclass == ELFCLASS32 745 ? elf32_xlatetom : elf64_xlatetom) 746 (&out, &in, elfdata) != NULL)) 747 { 748 /* We are looking for PT_DYNAMIC. */ 749 const union 750 { 751 Elf32_Phdr p32[phnum]; 752 Elf64_Phdr p64[phnum]; 753 } *u = (void *) &buf; 754 if (elfclass == ELFCLASS32) 755 { 756 for (size_t i = 0; i < phnum; ++i) 757 if (consider_phdr (u->p32[i].p_type, 758 u->p32[i].p_vaddr, 759 u->p32[i].p_filesz)) 760 break; 761 } 762 else 763 { 764 for (size_t i = 0; i < phnum; ++i) 765 if (consider_phdr (u->p64[i].p_type, 766 u->p64[i].p_vaddr, 767 u->p64[i].p_filesz)) 768 break; 769 } 770 } 771 772 (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0, 773 memory_callback_arg); 774 } 775 else 776 /* We could not read the executable's phdrs from the 777 memory image. If we have a presupplied executable, 778 we can still use the AT_PHDR and AT_ENTRY values to 779 verify it, and to adjust its bias if it's a PIE. 780 781 If there was an ET_EXEC module presupplied that contains 782 the AT_PHDR address, then we only consider that one. 783 We'll either accept it if its phdr location and e_entry 784 make sense or reject it if they don't. If there is no 785 presupplied ET_EXEC, then look for a presupplied module, 786 which might be a PIE (ET_DYN) that needs its bias adjusted. */ 787 r_debug_vaddr = ((phdr_mod == NULL 788 || phdr_mod->main.elf == NULL 789 || phdr_mod->e_type != ET_EXEC) 790 ? find_executable (dwfl, phdr, entry, 791 &elfclass, &elfdata, 792 memory_callback, 793 memory_callback_arg) 794 : consider_executable (phdr_mod, phdr, entry, 795 &elfclass, &elfdata, 796 memory_callback, 797 memory_callback_arg)); 798 } 799 800 /* If we found PT_DYNAMIC, search it for DT_DEBUG. */ 801 if (dyn_filesz != 0) 802 { 803 if (dyn_bias != (GElf_Addr) -1) 804 dyn_vaddr += dyn_bias; 805 806 Elf_Data in = 807 { 808 .d_type = ELF_T_DYN, 809 .d_version = EV_CURRENT, 810 .d_size = dyn_filesz, 811 .d_buf = NULL 812 }; 813 int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL); 814 if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size, 815 dyn_vaddr, dyn_filesz, memory_callback_arg)) 816 { 817 union 818 { 819 Elf32_Dyn d32; 820 Elf64_Dyn d64; 821 char data[dyn_filesz]; 822 } buf; 823 Elf_Data out = 824 { 825 .d_type = ELF_T_DYN, 826 .d_version = EV_CURRENT, 827 .d_size = dyn_filesz, 828 .d_buf = &buf 829 }; 830 in.d_size = out.d_size; 831 if (likely ((elfclass == ELFCLASS32 832 ? elf32_xlatetom : elf64_xlatetom) 833 (&out, &in, elfdata) != NULL)) 834 { 835 /* We are looking for DT_DEBUG. */ 836 const union 837 { 838 Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)]; 839 Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)]; 840 } *u = (void *) &buf; 841 if (elfclass == ELFCLASS32) 842 { 843 size_t n = dyn_filesz / sizeof (Elf32_Dyn); 844 for (size_t i = 0; i < n; ++i) 845 if (u->d32[i].d_tag == DT_DEBUG) 846 { 847 r_debug_vaddr = u->d32[i].d_un.d_val; 848 break; 849 } 850 } 851 else 852 { 853 size_t n = dyn_filesz / sizeof (Elf64_Dyn); 854 for (size_t i = 0; i < n; ++i) 855 if (u->d64[i].d_tag == DT_DEBUG) 856 { 857 r_debug_vaddr = u->d64[i].d_un.d_val; 858 break; 859 } 860 } 861 } 862 863 (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0, 864 memory_callback_arg); 865 } 866 } 867 } 868 else 869 /* We have to look for a presupplied executable file to determine 870 the vaddr of its dynamic section and DT_DEBUG therein. */ 871 r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata, 872 memory_callback, memory_callback_arg); 873 874 if (r_debug_vaddr == 0) 875 return 0; 876 877 /* For following pointers from struct link_map, we will use an 878 integrated memory access callback that can consult module text 879 elided from the core file. This is necessary when the l_name 880 pointer for the dynamic linker's own entry is a pointer into the 881 executable's .interp section. */ 882 struct integrated_memory_callback mcb = 883 { 884 .memory_callback = memory_callback, 885 .memory_callback_arg = memory_callback_arg 886 }; 887 888 /* Now we can follow the dynamic linker's library list. */ 889 return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr, 890 &integrated_memory_callback, &mcb); 891 } 892 INTDEF (dwfl_link_map_report) 893