offline.c revision 904aec2c2f62b729a536c2259274fdd440b0d923
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); 51d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 52e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (mod->debug.elf == NULL) 53e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We are only here because sh_addr is zero even though layout is complete. 54e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath The first section in the first file under -e is placed at 0. */ 55e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return 0; 56e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 579aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath /* The section numbers might not match between the two files. 589aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath The best we can rely on is the order of SHF_ALLOC sections. */ 599aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 60b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf_Scn *ourscn = elf_getscn (mod->debug.elf, shndx); 619aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath Elf_Scn *scn = NULL; 629aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath uint_fast32_t skip_alloc = 0; 63b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper while ((scn = elf_nextscn (mod->debug.elf, scn)) != ourscn) 649aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 659aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (scn != NULL); 669aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr shdr_mem; 679aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem); 689aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (unlikely (sh == NULL)) 699aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 709aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (sh->sh_flags & SHF_ALLOC) 719aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath ++skip_alloc; 729aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 739aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 749aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath scn = NULL; 759aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) 769aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 779aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr shdr_mem; 78b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper GElf_Shdr *main_shdr = gelf_getshdr (scn, &shdr_mem); 799aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (unlikely (main_shdr == NULL)) 809aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 819aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0) 829aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 839aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (main_shdr->sh_flags == shdr->sh_flags); 849aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath *addr = main_shdr->sh_addr; 859aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return 0; 869aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 879aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 88aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper 899aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath /* This should never happen. */ 909aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 91d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath} 92d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathINTDEF (dwfl_offline_section_address) 93d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 94b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper/* Forward declarations. */ 95b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module *process_elf (Dwfl *dwfl, const char *name, 96b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, Elf *elf); 97b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module *process_archive (Dwfl *dwfl, const char *name, 98b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, Elf *elf, 99b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, 100b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)); 101b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 102e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Report one module for an ELF file, or many for an archive. 103e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath Always consumes ELF and FD. */ 104b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 105b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_file (Dwfl *dwfl, const char *name, const char *file_name, int fd, 106b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf, int (*predicate) (const char *module, 107b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)) 108d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath{ 109b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper switch (elf_kind (elf)) 110b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 111b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper default: 112b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_NONE: 113b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (elf == NULL ? DWFL_E_LIBELF : DWFL_E_BADELF); 114b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 115b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 116b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_ELF: 117b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return process_elf (dwfl, name, file_name, fd, elf); 118b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 119b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_AR: 120b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return process_archive (dwfl, name, file_name, fd, elf, predicate); 121b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 122b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 123d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 124e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Report the open ELF file as a module. Always consumes ELF and FD. */ 125b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 126b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, 127b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf) 128b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 129b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, 130904aec2c2f62b729a536c2259274fdd440b0d923Jan Kratochvil dwfl->offline_next_address, true, 131904aec2c2f62b729a536c2259274fdd440b0d923Jan Kratochvil false); 132d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod != NULL) 133d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 134d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath /* If this is an ET_EXEC file with fixed addresses, the address range 135d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath it consumed may or may not intersect with the arbitrary range we 136d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath will use for relocatable modules. Make sure we always use a free 137687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath range for the offline allocations. If this module did use 138687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath offline_next_address, it may have rounded it up for the module's 139687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath alignment requirements. */ 140687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath if ((dwfl->offline_next_address >= mod->low_addr 141687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath || mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE) 142d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE) 143d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE; 144d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 145d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath /* Don't keep the file descriptor around. */ 146d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0) 147d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 148d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath close (mod->main.fd); 149d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath mod->main.fd = -1; 150d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 151d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 152d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 153d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath return mod; 154d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath} 155b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 156e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Always consumes MEMBER. Returns elf_next result on success. 157e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath For errors returns ELF_C_NULL with *MOD set to null. */ 158e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrathstatic Elf_Cmd 159b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_archive_member (Dwfl *dwfl, const char *name, const char *file_name, 160b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, const char *file), 161e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath int fd, Elf *member, Dwfl_Module **mod) 162b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 163b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const Elf_Arhdr *h = elf_getarhdr (member); 164b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (h == NULL)) 165b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 166b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_LIBELF); 167e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath fail: 168b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 169b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper *mod = NULL; 170e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 171b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 172b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 173e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata if (!strcmp (h->ar_name, "/") || !strcmp (h->ar_name, "//") 174e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata || !strcmp (h->ar_name, "/SYM64/")) 175b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 176e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath skip:; 177e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* Skip this and go to the next. */ 178e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath Elf_Cmd result = elf_next (member); 179b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 180e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return result; 181b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 182b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 183b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper char *member_name; 184b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (asprintf (&member_name, "%s(%s)", file_name, h->ar_name) < 0)) 185b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 186b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper nomem: 187b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_NOMEM); 188b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 189b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper *mod = NULL; 190e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 191b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 192b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 193b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper char *module_name = NULL; 194b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (name == NULL || name[0] == '\0') 195b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper name = h->ar_name; 196b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper else if (unlikely (asprintf (&module_name, "%s:%s", name, h->ar_name) < 0)) 197b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 198b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 199b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper goto nomem; 200b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 201b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper else 202b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper name = module_name; 203b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 204b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (predicate != NULL) 205b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 206b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper /* Let the predicate decide whether to use this one. */ 207b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int want = (*predicate) (name, member_name); 208b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (want <= 0) 209b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 210b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 211b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (module_name); 212b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (want < 0)) 213b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 214b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_CB); 215e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath goto fail; 216b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 217e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath goto skip; 218b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 219b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 220b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 221e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We let __libdwfl_report_elf cache the fd in mod->main.fd, 222e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath though it's the same fd for all the members. 223e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath On module teardown we will close it only on the last Elf reference. */ 224e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath *mod = process_file (dwfl, name, member_name, fd, member, predicate); 225b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 226b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (module_name); 227e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 228e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (*mod == NULL) /* process_file called elf_end. */ 229e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 230e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 231e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* Advance the archive-reading offset for the next iteration. */ 232e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return elf_next (member); 233b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 234b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 235b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper/* Report each member of the archive as its own module. */ 236b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 237b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd, 238b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *archive, 239b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, const char *file)) 240b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 241b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 242b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = NULL; 243b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath Elf *member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive); 244b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath if (unlikely (member == NULL)) /* Empty archive. */ 245b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath { 246b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath __libdwfl_seterrno (DWFL_E_BADELF); 247b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath return NULL; 248b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath } 249b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath 250e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath while (process_archive_member (dwfl, name, file_name, predicate, 251b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath fd, member, &mod) != ELF_C_NULL) 252b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive); 253e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 254e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We can drop the archive Elf handle even if we're still using members 255e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath in live modules. When the last module's elf_end on a member returns 256e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath zero, that module will close FD. If no modules survived the predicate, 257e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath we are all done with the file right here. */ 258b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath if (mod != NULL /* If no modules, caller will clean up. */ 259b28a894209451b93ba830f56e40871e44e9c7c28Roland McGrath && elf_end (archive) == 0) 260b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper close (fd); 261e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 262b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return mod; 263b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 264b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 265b597dfad924980dede10d7c19d87900b6172e599Ulrich DrepperDwfl_Module * 266b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperinternal_function 267b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper__libdwfl_report_offline (Dwfl *dwfl, const char *name, 268b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, bool closefd, 269b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, 270b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)) 271b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 272bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath Elf *elf; 273bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, true); 274bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath if (error != DWFL_E_NOERROR) 275bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath { 276bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath __libdwfl_seterrno (error); 277bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath return NULL; 278bca43152aa0bcb31b9442c407bf2b86379761c50Roland McGrath } 279b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = process_file (dwfl, name, file_name, fd, elf, predicate); 280b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (mod == NULL) 281b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 282b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (elf); 283b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (closefd) 284b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper close (fd); 285b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 286b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return mod; 287b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 288b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 289b597dfad924980dede10d7c19d87900b6172e599Ulrich DrepperDwfl_Module * 290b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperdwfl_report_offline (Dwfl *dwfl, const char *name, 291b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd) 292b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 293b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (dwfl == NULL) 294b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 295b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 296b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper bool closefd = false; 297b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (fd < 0) 298b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 299b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper closefd = true; 300b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper fd = open64 (file_name, O_RDONLY); 301b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (fd < 0) 302b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 303b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_ERRNO); 304b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 305b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 306b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 307b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 308b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return __libdwfl_report_offline (dwfl, name, file_name, fd, closefd, NULL); 309b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 310d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathINTDEF (dwfl_report_offline) 311