1d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath/* Recover relocatibility for addresses computed from debug information. 2e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata Copyright (C) 2005-2009, 2012 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 7d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 28d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 29d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath#include "libdwflP.h" 30b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper#include <fcntl.h> 31d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath#include <unistd.h> 32d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 33d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath/* Since dwfl_report_elf lays out the sections already, this will only be 34d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath called when the section headers of the debuginfo file are being 35e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath consulted instead, or for the section placed at 0. With binutils 36e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath strip-to-debug, the symbol table is in the debuginfo file and relocation 37e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath looks there. */ 38d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathint 39d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathdwfl_offline_section_address (Dwfl_Module *mod, 40d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath void **userdata __attribute__ ((unused)), 41d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath const char *modname __attribute__ ((unused)), 42d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Dwarf_Addr base __attribute__ ((unused)), 43d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath const char *secname __attribute__ ((unused)), 44d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Elf32_Word shndx, 45d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath const GElf_Shdr *shdr __attribute__ ((unused)), 46d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Dwarf_Addr *addr) 47d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath{ 489aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (mod->e_type == ET_REL); 49d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath assert (shdr->sh_addr == 0); 50d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath assert (shdr->sh_flags & SHF_ALLOC); 5127304cb338070ef53ee3db61e3e50cd57efe243aMark Wielaard assert (shndx != 0); 52d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 53e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (mod->debug.elf == NULL) 54e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We are only here because sh_addr is zero even though layout is complete. 55e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath The first section in the first file under -e is placed at 0. */ 56e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return 0; 57e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 589aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath /* The section numbers might not match between the two files. 599aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath The best we can rely on is the order of SHF_ALLOC sections. */ 609aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 61b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf_Scn *ourscn = elf_getscn (mod->debug.elf, shndx); 629aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath Elf_Scn *scn = NULL; 639aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath uint_fast32_t skip_alloc = 0; 64b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper while ((scn = elf_nextscn (mod->debug.elf, scn)) != ourscn) 659aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 669aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (scn != NULL); 679aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr shdr_mem; 689aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem); 699aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (unlikely (sh == NULL)) 709aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 719aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (sh->sh_flags & SHF_ALLOC) 729aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath ++skip_alloc; 739aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 749aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 759aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath scn = NULL; 769aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) 779aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 789aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr shdr_mem; 79b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper GElf_Shdr *main_shdr = gelf_getshdr (scn, &shdr_mem); 809aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (unlikely (main_shdr == NULL)) 819aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 829aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0) 839aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 849aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (main_shdr->sh_flags == shdr->sh_flags); 859aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath *addr = main_shdr->sh_addr; 869aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return 0; 879aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 889aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 89aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper 909aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath /* This should never happen. */ 919aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 92d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath} 93d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathINTDEF (dwfl_offline_section_address) 94d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 95b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper/* Forward declarations. */ 96b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module *process_elf (Dwfl *dwfl, const char *name, 97b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, Elf *elf); 98b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module *process_archive (Dwfl *dwfl, const char *name, 99b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, Elf *elf, 100b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, 101b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)); 102b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 103e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Report one module for an ELF file, or many for an archive. 104e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath Always consumes ELF and FD. */ 105b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 106b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_file (Dwfl *dwfl, const char *name, const char *file_name, int fd, 107b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf, int (*predicate) (const char *module, 108b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)) 109d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath{ 110b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper switch (elf_kind (elf)) 111b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 112b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper default: 113b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_NONE: 114b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (elf == NULL ? DWFL_E_LIBELF : DWFL_E_BADELF); 115b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 116b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 117b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_ELF: 118b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return process_elf (dwfl, name, file_name, fd, elf); 119b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 120b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_AR: 121b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return process_archive (dwfl, name, file_name, fd, elf, predicate); 122b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 123b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 124d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 125e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Report the open ELF file as a module. Always consumes ELF and FD. */ 126b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 127b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, 128b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf) 129b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 130b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, 131904aec2c2f62b729a536c2259274fdd440b0d923Jan Kratochvil dwfl->offline_next_address, true, 132904aec2c2f62b729a536c2259274fdd440b0d923Jan Kratochvil false); 133d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod != NULL) 134d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 135d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath /* If this is an ET_EXEC file with fixed addresses, the address range 136d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath it consumed may or may not intersect with the arbitrary range we 137d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath will use for relocatable modules. Make sure we always use a free 138687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath range for the offline allocations. If this module did use 139687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath offline_next_address, it may have rounded it up for the module's 140687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath alignment requirements. */ 141687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath if ((dwfl->offline_next_address >= mod->low_addr 142687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath || mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE) 143d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE) 144d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE; 145d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 146d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath /* Don't keep the file descriptor around. */ 147d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0) 148d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 149d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath close (mod->main.fd); 150d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath mod->main.fd = -1; 151d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 152d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 153d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 154d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath return mod; 155d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath} 156b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 157e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Always consumes MEMBER. Returns elf_next result on success. 158e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath For errors returns ELF_C_NULL with *MOD set to null. */ 159e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrathstatic Elf_Cmd 160b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_archive_member (Dwfl *dwfl, const char *name, const char *file_name, 161b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, const char *file), 162e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath int fd, Elf *member, Dwfl_Module **mod) 163b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 164b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const Elf_Arhdr *h = elf_getarhdr (member); 165b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (h == NULL)) 166b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 167b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_LIBELF); 168e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath fail: 169b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 170b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper *mod = NULL; 171e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 172b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 173b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 174e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata if (!strcmp (h->ar_name, "/") || !strcmp (h->ar_name, "//") 175e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata || !strcmp (h->ar_name, "/SYM64/")) 176b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 177e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath skip:; 178e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* Skip this and go to the next. */ 179e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath Elf_Cmd result = elf_next (member); 180b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 181e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return result; 182b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 183b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 184b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper char *member_name; 185b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (asprintf (&member_name, "%s(%s)", file_name, h->ar_name) < 0)) 186b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 187b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper nomem: 188b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_NOMEM); 189b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 190b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper *mod = NULL; 191e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 192b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 193b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 194b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper char *module_name = NULL; 195b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (name == NULL || name[0] == '\0') 196b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper name = h->ar_name; 197b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper else if (unlikely (asprintf (&module_name, "%s:%s", name, h->ar_name) < 0)) 198b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 199b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 200b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper goto nomem; 201b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 202b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper else 203b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper name = module_name; 204b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 205b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (predicate != NULL) 206b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 207b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper /* Let the predicate decide whether to use this one. */ 208b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int want = (*predicate) (name, member_name); 209b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (want <= 0) 210b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 211b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 212b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (module_name); 213b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (want < 0)) 214b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 215b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_CB); 216e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath goto fail; 217b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 218e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath goto skip; 219b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 220b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 221b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 222e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We let __libdwfl_report_elf cache the fd in mod->main.fd, 223e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath though it's the same fd for all the members. 224e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath On module teardown we will close it only on the last Elf reference. */ 225e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath *mod = process_file (dwfl, name, member_name, fd, member, predicate); 226b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 227b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (module_name); 228e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 229e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (*mod == NULL) /* process_file called elf_end. */ 230e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 231e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 232e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* Advance the archive-reading offset for the next iteration. */ 233e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return elf_next (member); 234b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 235b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 236b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper/* Report each member of the archive as its own module. */ 237b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 238b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd, 239b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *archive, 240b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, const char *file)) 241b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 242b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 243b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = NULL; 244b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath Elf *member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive); 245b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath if (unlikely (member == NULL)) /* Empty archive. */ 246b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath { 247b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath __libdwfl_seterrno (DWFL_E_BADELF); 248b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath return NULL; 249b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath } 250b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath 251e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath while (process_archive_member (dwfl, name, file_name, predicate, 252b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath fd, member, &mod) != ELF_C_NULL) 253b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive); 254e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 255e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We can drop the archive Elf handle even if we're still using members 256e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath in live modules. When the last module's elf_end on a member returns 257e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath zero, that module will close FD. If no modules survived the predicate, 258e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath we are all done with the file right here. */ 259b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath if (mod != NULL /* If no modules, caller will clean up. */ 260b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath && elf_end (archive) == 0) 261b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper close (fd); 262e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 263b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return mod; 264b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 265b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 266b597dfad924980dede10d7c19d87900b6172e599Ulrich DrepperDwfl_Module * 267b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperinternal_function 268b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper__libdwfl_report_offline (Dwfl *dwfl, const char *name, 269b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, bool closefd, 270b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, 271b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)) 272b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 273bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath Elf *elf; 274bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, true); 275bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath if (error != DWFL_E_NOERROR) 276bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath { 277bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath __libdwfl_seterrno (error); 278bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath return NULL; 279bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath } 280b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = process_file (dwfl, name, file_name, fd, elf, predicate); 281b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (mod == NULL) 282b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 283b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (elf); 284b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (closefd) 285b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper close (fd); 286b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 287b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return mod; 288b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 289b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 290b597dfad924980dede10d7c19d87900b6172e599Ulrich DrepperDwfl_Module * 291b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperdwfl_report_offline (Dwfl *dwfl, const char *name, 292b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd) 293b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 294b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (dwfl == NULL) 295b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 296b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 297b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper bool closefd = false; 298b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (fd < 0) 299b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 300b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper closefd = true; 3013425454a10d307fae891fb667cf7969e945cde79Josh Stone fd = open (file_name, O_RDONLY); 302b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (fd < 0) 303b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 304b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_ERRNO); 305b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 306b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 307b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 308b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 309b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return __libdwfl_report_offline (dwfl, name, file_name, fd, closefd, NULL); 310b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 311d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathINTDEF (dwfl_report_offline) 312