1/* Report modules by examining dynamic linker data structures. 2 Copyright (C) 2008 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. */ 77static bool 78auxv_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 size_t i; 127 for (i = 0; i < size / sizeof (Elf64_auxv_t); ++i) 128 { 129 if (check64 (i)) 130 { 131 *elfclass = ELFCLASS64; 132 return true; 133 } 134 135 if (check32 (i)) 136 { 137 *elfclass = ELFCLASS32; 138 return true; 139 } 140 } 141 for (; i < size / sizeof (Elf64_auxv_t); ++i) 142 if (check32 (i)) 143 { 144 *elfclass = ELFCLASS32; 145 return true; 146 } 147 148 return false; 149} 150 151/* This is a Dwfl_Memory_Callback that wraps another memory callback. 152 If the underlying callback cannot fill the data, then this will 153 fall back to fetching data from module files. */ 154 155struct integrated_memory_callback 156{ 157 Dwfl_Memory_Callback *memory_callback; 158 void *memory_callback_arg; 159 void *buffer; 160}; 161 162static bool 163integrated_memory_callback (Dwfl *dwfl, int ndx, 164 void **buffer, size_t *buffer_available, 165 GElf_Addr vaddr, 166 size_t minread, 167 void *arg) 168{ 169 struct integrated_memory_callback *info = arg; 170 171 if (ndx == -1) 172 { 173 /* Called for cleanup. */ 174 if (info->buffer != NULL) 175 { 176 /* The last probe buffer came from the underlying callback. 177 Let it do its cleanup. */ 178 assert (*buffer == info->buffer); /* XXX */ 179 *buffer = info->buffer; 180 info->buffer = NULL; 181 return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available, 182 vaddr, minread, 183 info->memory_callback_arg); 184 } 185 *buffer = NULL; 186 *buffer_available = 0; 187 return false; 188 } 189 190 if (*buffer != NULL) 191 /* For a final-read request, we only use the underlying callback. */ 192 return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available, 193 vaddr, minread, info->memory_callback_arg); 194 195 /* Let the underlying callback try to fill this request. */ 196 if ((*info->memory_callback) (dwfl, ndx, &info->buffer, buffer_available, 197 vaddr, minread, info->memory_callback_arg)) 198 { 199 *buffer = info->buffer; 200 return true; 201 } 202 203 /* Now look for module text covering this address. */ 204 205 Dwfl_Module *mod; 206 (void) INTUSE(dwfl_addrsegment) (dwfl, vaddr, &mod); 207 if (mod == NULL) 208 return false; 209 210 Dwarf_Addr bias; 211 Elf_Scn *scn = INTUSE(dwfl_module_address_section) (mod, &vaddr, &bias); 212 if (unlikely (scn == NULL)) 213 { 214#if 0 // XXX would have to handle ndx=-1 cleanup calls passed down. 215 /* If we have no sections we can try to fill it from the module file 216 based on its phdr mappings. */ 217 if (likely (mod->e_type != ET_REL) && mod->main.elf != NULL) 218 return INTUSE(dwfl_elf_phdr_memory_callback) 219 (dwfl, 0, buffer, buffer_available, 220 vaddr - mod->main.bias, minread, mod->main.elf); 221#endif 222 return false; 223 } 224 225 Elf_Data *data = elf_rawdata (scn, NULL); 226 if (unlikely (data == NULL)) 227 // XXX throw error? 228 return false; 229 230 if (unlikely (data->d_size < vaddr)) 231 return false; 232 233 /* Provide as much data as we have. */ 234 void *contents = data->d_buf + vaddr; 235 size_t avail = data->d_size - vaddr; 236 if (unlikely (avail < minread)) 237 return false; 238 239 /* If probing for a string, make sure it's terminated. */ 240 if (minread == 0 && unlikely (memchr (contents, '\0', avail) == NULL)) 241 return false; 242 243 /* We have it! */ 244 *buffer = contents; 245 *buffer_available = avail; 246 return true; 247} 248 249static size_t 250addrsize (uint_fast8_t elfclass) 251{ 252 return elfclass * 4; 253} 254 255/* Report a module for each struct link_map in the linked list at r_map 256 in the struct r_debug at R_DEBUG_VADDR. 257 258 For each link_map entry, if an existing module resides at its address, 259 this just modifies that module's name and suggested file name. If 260 no such module exists, this calls dwfl_report_elf on the l_name string. 261 262 Returns the number of modules found, or -1 for errors. */ 263 264static int 265report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, 266 Dwfl *dwfl, GElf_Addr r_debug_vaddr, 267 Dwfl_Memory_Callback *memory_callback, 268 void *memory_callback_arg) 269{ 270 /* Skip r_version, to aligned r_map field. */ 271 GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass); 272 273 void *buffer = NULL; 274 size_t buffer_available = 0; 275 inline int release_buffer (int result) 276 { 277 if (buffer != NULL) 278 (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0, 279 memory_callback_arg); 280 return result; 281 } 282 283 GElf_Addr addrs[4]; 284 inline bool read_addrs (GElf_Addr vaddr, size_t n) 285 { 286 size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read. */ 287 288 /* Read a new buffer if the old one doesn't cover these words. */ 289 if (buffer == NULL 290 || vaddr < read_vaddr 291 || vaddr - read_vaddr + nb > buffer_available) 292 { 293 release_buffer (0); 294 295 read_vaddr = vaddr; 296 int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL); 297 if (unlikely (segndx < 0) 298 || unlikely (! (*memory_callback) (dwfl, segndx, 299 &buffer, &buffer_available, 300 vaddr, nb, memory_callback_arg))) 301 return true; 302 } 303 304 const union 305 { 306 Elf32_Addr a32[n]; 307 Elf64_Addr a64[n]; 308 } *in = vaddr - read_vaddr + buffer; 309 310 if (elfclass == ELFCLASS32) 311 { 312 if (elfdata == ELFDATA2MSB) 313 for (size_t i = 0; i < n; ++i) 314 addrs[i] = BE32 (in->a32[i]); 315 else 316 for (size_t i = 0; i < n; ++i) 317 addrs[i] = LE32 (in->a32[i]); 318 } 319 else 320 { 321 if (elfdata == ELFDATA2MSB) 322 for (size_t i = 0; i < n; ++i) 323 addrs[i] = BE64 (in->a64[i]); 324 else 325 for (size_t i = 0; i < n; ++i) 326 addrs[i] = LE64 (in->a64[i]); 327 } 328 329 return false; 330 } 331 332 if (unlikely (read_addrs (read_vaddr, 1))) 333 return release_buffer (-1); 334 335 GElf_Addr next = addrs[0]; 336 337 Dwfl_Module **lastmodp = &dwfl->modulelist; 338 int result = 0; 339 while (next != 0) 340 { 341 if (read_addrs (next, 4)) 342 return release_buffer (-1); 343 344 GElf_Addr l_addr = addrs[0]; 345 GElf_Addr l_name = addrs[1]; 346 GElf_Addr l_ld = addrs[2]; 347 next = addrs[3]; 348 349 /* Fetch the string at the l_name address. */ 350 const char *name = NULL; 351 if (buffer != NULL 352 && read_vaddr <= l_name 353 && l_name + 1 - read_vaddr < buffer_available 354 && memchr (l_name - read_vaddr + buffer, '\0', 355 buffer_available - (l_name - read_vaddr)) != NULL) 356 name = l_name - read_vaddr + buffer; 357 else 358 { 359 release_buffer (0); 360 read_vaddr = l_name; 361 int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_name, NULL); 362 if (likely (segndx >= 0) 363 && (*memory_callback) (dwfl, segndx, 364 &buffer, &buffer_available, 365 l_name, 0, memory_callback_arg)) 366 name = buffer; 367 } 368 369 if (name != NULL && name[0] == '\0') 370 name = NULL; 371 372 /* If content-sniffing already reported a module covering 373 the same area, find that existing module to adjust. 374 The l_ld address is the only one we know for sure 375 to be within the module's own segments (its .dynamic). */ 376 Dwfl_Module *mod; 377 int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_ld, &mod); 378 if (unlikely (segndx < 0)) 379 return release_buffer (-1); 380 381 if (mod != NULL) 382 { 383 /* We have a module. We can give it a better name from l_name. */ 384 if (name != NULL && mod->name[0] == '[') 385 { 386 char *newname = strdup (basename (name)); 387 if (newname != NULL) 388 { 389 free (mod->name); 390 mod->name = newname; 391 } 392 } 393 394 if (name == NULL && mod->name[0] == '/') 395 name = mod->name; 396 397 /* If we don't have a file for it already, we can pre-install 398 the full file name from l_name. Opening the file by this 399 name will be the fallback when no build ID match is found. 400 XXX hook for sysroot */ 401 if (name != NULL 402 && mod->main.elf == NULL 403 && 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 444static GElf_Addr 445consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry, 446 uint_fast8_t *elfclass, uint_fast8_t *elfdata, 447 Dwfl_Memory_Callback *memory_callback, 448 void *memory_callback_arg) 449{ 450 GElf_Ehdr ehdr; 451 if (unlikely (gelf_getehdr (mod->main.elf, &ehdr) == NULL)) 452 return 0; 453 454 if (at_entry != 0) 455 { 456 /* If we have an AT_ENTRY value, reject this executable if 457 its entry point address could not have supplied that. */ 458 459 if (ehdr.e_entry == 0) 460 return 0; 461 462 if (mod->e_type == ET_EXEC) 463 { 464 if (ehdr.e_entry != at_entry) 465 return 0; 466 } 467 else 468 { 469 /* It could be a PIE. */ 470 } 471 } 472 473 // XXX this could be saved in the file cache: phdr vaddr, DT_DEBUG d_val vaddr 474 /* Find the vaddr of the DT_DEBUG's d_ptr. This is the memory 475 address where &r_debug was written at runtime. */ 476 GElf_Xword align = mod->dwfl->segment_align; 477 GElf_Addr d_val_vaddr = 0; 478 for (uint_fast16_t i = 0; i < ehdr.e_phnum; ++i) 479 { 480 GElf_Phdr phdr_mem; 481 GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem); 482 if (phdr == NULL) 483 break; 484 485 if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align)) 486 align = phdr->p_align; 487 488 if (at_phdr != 0 489 && phdr->p_type == PT_LOAD 490 && (phdr->p_offset & -align) == (ehdr.e_phoff & -align)) 491 { 492 /* This is the segment that would map the phdrs. 493 If we have an AT_PHDR value, reject this executable 494 if its phdr mapping could not have supplied that. */ 495 if (mod->e_type == ET_EXEC) 496 { 497 if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr) 498 return 0; 499 } 500 else 501 { 502 /* It could be a PIE. If the AT_PHDR value and our 503 phdr address don't match modulo ALIGN, then this 504 could not have been the right PIE. */ 505 if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align) 506 != (at_phdr & -align)) 507 return 0; 508 509 /* Calculate the bias applied to the PIE's p_vaddr values. */ 510 GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset 511 + phdr->p_vaddr)); 512 513 /* Final sanity check: if we have an AT_ENTRY value, 514 reject this PIE unless its biased e_entry matches. */ 515 if (at_entry != 0 && at_entry != ehdr.e_entry + bias) 516 return 0; 517 518 /* If we're changing the module's address range, 519 we've just invalidated the module lookup table. */ 520 if (bias != mod->main.bias) 521 { 522 mod->low_addr -= mod->main.bias; 523 mod->high_addr -= mod->main.bias; 524 mod->main.bias = bias; 525 mod->low_addr += bias; 526 mod->high_addr += bias; 527 528 free (mod->dwfl->lookup_module); 529 mod->dwfl->lookup_module = NULL; 530 } 531 } 532 } 533 534 if (phdr->p_type == PT_DYNAMIC) 535 { 536 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset, 537 phdr->p_filesz, ELF_T_DYN); 538 if (data == NULL) 539 continue; 540 const size_t entsize = gelf_fsize (mod->main.elf, 541 ELF_T_DYN, 1, EV_CURRENT); 542 const size_t n = data->d_size / entsize; 543 for (size_t j = 0; j < n; ++j) 544 { 545 GElf_Dyn dyn_mem; 546 GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 547 if (dyn != NULL && dyn->d_tag == DT_DEBUG) 548 { 549 d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2; 550 break; 551 } 552 } 553 } 554 } 555 556 if (d_val_vaddr != 0) 557 { 558 /* Now we have the final address from which to read &r_debug. */ 559 d_val_vaddr += mod->main.bias; 560 561 void *buffer = NULL; 562 size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]); 563 564 Dwfl_Module *m; 565 int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, &m); 566 assert (m == mod); 567 568 if ((*memory_callback) (mod->dwfl, segndx, 569 &buffer, &buffer_available, 570 d_val_vaddr, buffer_available, 571 memory_callback_arg)) 572 { 573 const union 574 { 575 Elf32_Addr a32; 576 Elf64_Addr a64; 577 } *u = buffer; 578 579 GElf_Addr vaddr; 580 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) 581 vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB 582 ? BE32 (u->a32) : LE32 (u->a32)); 583 else 584 vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB 585 ? BE64 (u->a64) : LE64 (u->a64)); 586 587 (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0, 588 memory_callback_arg); 589 590 591 if (*elfclass == ELFCLASSNONE) 592 *elfclass = ehdr.e_ident[EI_CLASS]; 593 else if (*elfclass != ehdr.e_ident[EI_CLASS]) 594 return 0; 595 596 if (*elfdata == ELFDATANONE) 597 *elfdata = ehdr.e_ident[EI_DATA]; 598 else if (*elfdata != ehdr.e_ident[EI_DATA]) 599 return 0; 600 601 return vaddr; 602 } 603 } 604 605 return 0; 606} 607 608/* Try to find an existing executable module with a DT_DEBUG. */ 609static GElf_Addr 610find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry, 611 uint_fast8_t *elfclass, uint_fast8_t *elfdata, 612 Dwfl_Memory_Callback *memory_callback, 613 void *memory_callback_arg) 614{ 615 for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next) 616 if (mod->main.elf != NULL) 617 { 618 GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry, 619 elfclass, elfdata, 620 memory_callback, 621 memory_callback_arg); 622 if (r_debug_vaddr != 0) 623 return r_debug_vaddr; 624 } 625 626 return 0; 627} 628 629 630int 631dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, 632 Dwfl_Memory_Callback *memory_callback, 633 void *memory_callback_arg) 634{ 635 GElf_Addr r_debug_vaddr = 0; 636 637 uint_fast8_t elfclass = ELFCLASSNONE; 638 uint_fast8_t elfdata = ELFDATANONE; 639 if (likely (auxv != NULL) 640 && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata))) 641 { 642 GElf_Addr entry = 0; 643 GElf_Addr phdr = 0; 644 GElf_Xword phent = 0; 645 GElf_Xword phnum = 0; 646 647#define AUXV_SCAN(NN, BL) do \ 648 { \ 649 const Elf##NN##_auxv_t *av = auxv; \ 650 for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i) \ 651 { \ 652 Elf##NN##_Addr val = BL##NN (av[i].a_un.a_val); \ 653 if (av[i].a_type == BL##NN (AT_ENTRY)) \ 654 entry = val; \ 655 else if (av[i].a_type == BL##NN (AT_PHDR)) \ 656 phdr = val; \ 657 else if (av[i].a_type == BL##NN (AT_PHNUM)) \ 658 phnum = val; \ 659 else if (av[i].a_type == BL##NN (AT_PHENT)) \ 660 phent = val; \ 661 else if (av[i].a_type == BL##NN (AT_PAGESZ)) \ 662 { \ 663 if (val > 1 \ 664 && (dwfl->segment_align == 0 \ 665 || val < dwfl->segment_align)) \ 666 dwfl->segment_align = val; \ 667 } \ 668 } \ 669 } \ 670 while (0) 671 672 if (elfclass == ELFCLASS32) 673 { 674 if (elfdata == ELFDATA2MSB) 675 AUXV_SCAN (32, BE); 676 else 677 AUXV_SCAN (32, LE); 678 } 679 else 680 { 681 if (elfdata == ELFDATA2MSB) 682 AUXV_SCAN (64, BE); 683 else 684 AUXV_SCAN (64, LE); 685 } 686 687 /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC. */ 688 GElf_Addr dyn_vaddr = 0; 689 GElf_Xword dyn_filesz = 0; 690 if (phdr != 0 && phnum != 0) 691 { 692 Dwfl_Module *phdr_mod; 693 int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod); 694 Elf_Data in = 695 { 696 .d_type = ELF_T_PHDR, 697 .d_version = EV_CURRENT, 698 .d_size = phnum * phent, 699 .d_buf = NULL 700 }; 701 if ((*memory_callback) (dwfl, phdr_segndx, &in.d_buf, &in.d_size, 702 phdr, phnum * phent, memory_callback_arg)) 703 { 704 union 705 { 706 Elf32_Phdr p32; 707 Elf64_Phdr p64; 708 char data[phnum * phent]; 709 } buf; 710 Elf_Data out = 711 { 712 .d_type = ELF_T_PHDR, 713 .d_version = EV_CURRENT, 714 .d_size = phnum * phent, 715 .d_buf = &buf 716 }; 717 in.d_size = out.d_size; 718 if (likely ((elfclass == ELFCLASS32 719 ? elf32_xlatetom : elf64_xlatetom) 720 (&out, &in, elfdata) != NULL)) 721 { 722 /* We are looking for PT_DYNAMIC. */ 723 const union 724 { 725 Elf32_Phdr p32[phnum]; 726 Elf64_Phdr p64[phnum]; 727 } *u = (void *) &buf; 728 if (elfclass == ELFCLASS32) 729 { 730 for (size_t i = 0; i < phnum; ++i) 731 if (u->p32[i].p_type == PT_DYNAMIC) 732 { 733 dyn_vaddr = u->p32[i].p_vaddr; 734 dyn_filesz = u->p32[i].p_filesz; 735 break; 736 } 737 } 738 else 739 { 740 for (size_t i = 0; i < phnum; ++i) 741 if (u->p64[i].p_type == PT_DYNAMIC) 742 { 743 dyn_vaddr = u->p64[i].p_vaddr; 744 dyn_filesz = u->p64[i].p_filesz; 745 break; 746 } 747 } 748 } 749 750 (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0, 751 memory_callback_arg); 752 } 753 else 754 /* We could not read the executable's phdrs from the 755 memory image. If we have a presupplied executable, 756 we can still use the AT_PHDR and AT_ENTRY values to 757 verify it, and to adjust its bias if it's a PIE. 758 759 If there was an ET_EXEC module presupplied that contains 760 the AT_PHDR address, then we only consider that one. 761 We'll either accept it if its phdr location and e_entry 762 make sense or reject it if they don't. If there is no 763 presupplied ET_EXEC, then look for a presupplied module, 764 which might be a PIE (ET_DYN) that needs its bias adjusted. */ 765 r_debug_vaddr = ((phdr_mod == NULL 766 || phdr_mod->main.elf == NULL 767 || phdr_mod->e_type != ET_EXEC) 768 ? find_executable (dwfl, phdr, entry, 769 &elfclass, &elfdata, 770 memory_callback, 771 memory_callback_arg) 772 : consider_executable (phdr_mod, phdr, entry, 773 &elfclass, &elfdata, 774 memory_callback, 775 memory_callback_arg)); 776 } 777 778 /* If we found PT_DYNAMIC, search it for DT_DEBUG. */ 779 if (dyn_filesz != 0) 780 { 781 Elf_Data in = 782 { 783 .d_type = ELF_T_DYN, 784 .d_version = EV_CURRENT, 785 .d_size = dyn_filesz, 786 .d_buf = NULL 787 }; 788 int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL); 789 if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size, 790 dyn_vaddr, dyn_filesz, memory_callback_arg)) 791 { 792 union 793 { 794 Elf32_Dyn d32; 795 Elf64_Dyn d64; 796 char data[dyn_filesz]; 797 } buf; 798 Elf_Data out = 799 { 800 .d_type = ELF_T_DYN, 801 .d_version = EV_CURRENT, 802 .d_size = dyn_filesz, 803 .d_buf = &buf 804 }; 805 in.d_size = out.d_size; 806 if (likely ((elfclass == ELFCLASS32 807 ? elf32_xlatetom : elf64_xlatetom) 808 (&out, &in, elfdata) != NULL)) 809 { 810 /* We are looking for PT_DYNAMIC. */ 811 const union 812 { 813 Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)]; 814 Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)]; 815 } *u = (void *) &buf; 816 if (elfclass == ELFCLASS32) 817 { 818 size_t n = dyn_filesz / sizeof (Elf32_Dyn); 819 for (size_t i = 0; i < n; ++i) 820 if (u->d32[i].d_tag == DT_DEBUG) 821 { 822 r_debug_vaddr = u->d32[i].d_un.d_val; 823 break; 824 } 825 } 826 else 827 { 828 size_t n = dyn_filesz / sizeof (Elf64_Dyn); 829 for (size_t i = 0; i < n; ++i) 830 if (u->d64[i].d_tag == DT_DEBUG) 831 { 832 r_debug_vaddr = u->d64[i].d_un.d_val; 833 break; 834 } 835 } 836 } 837 838 (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0, 839 memory_callback_arg); 840 } 841 } 842 } 843 else 844 /* We have to look for a presupplied executable file to determine 845 the vaddr of its dynamic section and DT_DEBUG therein. */ 846 r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata, 847 memory_callback, memory_callback_arg); 848 849 if (r_debug_vaddr == 0) 850 return 0; 851 852 /* For following pointers from struct link_map, we will use an 853 integrated memory access callback that can consult module text 854 elided from the core file. This is necessary when the l_name 855 pointer for the dynamic linker's own entry is a pointer into the 856 executable's .interp section. */ 857 struct integrated_memory_callback mcb = 858 { 859 .memory_callback = memory_callback, 860 .memory_callback_arg = memory_callback_arg 861 }; 862 863 /* Now we can follow the dynamic linker's library list. */ 864 return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr, 865 &integrated_memory_callback, &mcb); 866} 867INTDEF (dwfl_link_map_report) 868