offline.c revision e4c22ea004c02a58f5db5eb53794275344c17958
1d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath/* Recover relocatibility for addresses computed from debug information. 2aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper Copyright (C) 2005, 2006, 2007 Red Hat, Inc. 3361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper This file is part of Red Hat elfutils. 4d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 5361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is free software; you can redistribute it and/or modify 6361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper it under the terms of the GNU General Public License as published by the 7361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Free Software Foundation; version 2 of the License. 8d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 9361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is distributed in the hope that it will be useful, but 10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 13361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper You should have received a copy of the GNU General Public License along 15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper with Red Hat elfutils; if not, write to the Free Software Foundation, 161e9ef50681e20ef14c2ba38aef37a71ff148be08Ulrich Drepper Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 17361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 18361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper In addition, as a special exception, Red Hat, Inc. gives You the 19361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper additional right to link the code of Red Hat elfutils with code licensed 20361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper under any Open Source Initiative certified open source license 21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper (http://www.opensource.org/licenses/index.php) which requires the 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper distribution of source code with any binary distribution and to 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper distribute linked combinations of the two. Non-GPL Code permitted under 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper this exception must only link to the code of Red Hat elfutils through 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper those well defined interfaces identified in the file named EXCEPTION 26361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper found in the source code files (the "Approved Interfaces"). The files 27361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper of Non-GPL Code may instantiate templates or use macros or inline 28361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper functions from the Approved Interfaces without causing the resulting 29361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper work to be covered by the GNU General Public License. Only Red Hat, 30361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Inc. may make changes or additions to the list of Approved Interfaces. 31361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat's grant of this exception is conditioned upon your not adding 32361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper any new exceptions. If you wish to add a new Approved Interface or 33361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper exception, please contact Red Hat. You must obey the GNU General Public 34361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper License in all respects for all of the Red Hat elfutils code and other 35361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper code used in conjunction with Red Hat elfutils except the Non-GPL Code 36361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper covered by this exception. If you modify this file, you may extend this 37361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper exception to your version of the file, but you are not obligated to do 38361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper so. If you do not wish to provide this exception without modification, 39361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper you must delete this exception statement from your version and license 40361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper this file solely under the GPL without exception. 41361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 42361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is an included package of the Open Invention Network. 43361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper An included package of the Open Invention Network is a package for which 44361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Open Invention Network licensees cross-license their patents. No patent 45361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper license is granted, either expressly or impliedly, by designation as an 46361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper included package. Should you wish to participate in the Open Invention 47361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Network licensing program, please visit www.openinventionnetwork.com 48361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper <http://www.openinventionnetwork.com>. */ 49d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 50d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath#include "libdwflP.h" 51b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper#include <fcntl.h> 52d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath#include <unistd.h> 53d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 54d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath/* Since dwfl_report_elf lays out the sections already, this will only be 55d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath called when the section headers of the debuginfo file are being 56e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath consulted instead, or for the section placed at 0. With binutils 57e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath strip-to-debug, the symbol table is in the debuginfo file and relocation 58e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath looks there. */ 59d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathint 60d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathdwfl_offline_section_address (Dwfl_Module *mod, 61d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath void **userdata __attribute__ ((unused)), 62d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath const char *modname __attribute__ ((unused)), 63d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Dwarf_Addr base __attribute__ ((unused)), 64d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath const char *secname __attribute__ ((unused)), 65d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Elf32_Word shndx, 66d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath const GElf_Shdr *shdr __attribute__ ((unused)), 67d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath Dwarf_Addr *addr) 68d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath{ 699aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (mod->e_type == ET_REL); 70d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath assert (shdr->sh_addr == 0); 71d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath assert (shdr->sh_flags & SHF_ALLOC); 72d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 73e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (mod->debug.elf == NULL) 74e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We are only here because sh_addr is zero even though layout is complete. 75e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath The first section in the first file under -e is placed at 0. */ 76e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return 0; 77e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 789aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath /* The section numbers might not match between the two files. 799aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath The best we can rely on is the order of SHF_ALLOC sections. */ 809aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 81b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf_Scn *ourscn = elf_getscn (mod->debug.elf, shndx); 829aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath Elf_Scn *scn = NULL; 839aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath uint_fast32_t skip_alloc = 0; 84b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper while ((scn = elf_nextscn (mod->debug.elf, scn)) != ourscn) 859aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 869aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (scn != NULL); 879aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr shdr_mem; 889aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem); 899aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (unlikely (sh == NULL)) 909aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 919aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (sh->sh_flags & SHF_ALLOC) 929aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath ++skip_alloc; 939aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 949aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 959aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath scn = NULL; 969aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) 979aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 989aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath GElf_Shdr shdr_mem; 99b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper GElf_Shdr *main_shdr = gelf_getshdr (scn, &shdr_mem); 1009aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if (unlikely (main_shdr == NULL)) 1019aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 1029aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0) 1039aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 1049aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath assert (main_shdr->sh_flags == shdr->sh_flags); 1059aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath *addr = main_shdr->sh_addr; 1069aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return 0; 1079aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 1089aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 109aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper 1109aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath /* This should never happen. */ 1119aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath return -1; 112d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath} 113d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathINTDEF (dwfl_offline_section_address) 114d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 115b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper/* Forward declarations. */ 116b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module *process_elf (Dwfl *dwfl, const char *name, 117b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, Elf *elf); 118b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module *process_archive (Dwfl *dwfl, const char *name, 119b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, Elf *elf, 120b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, 121b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)); 122b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 123e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Report one module for an ELF file, or many for an archive. 124e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath Always consumes ELF and FD. */ 125b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 126b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_file (Dwfl *dwfl, const char *name, const char *file_name, int fd, 127b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf, int (*predicate) (const char *module, 128b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)) 129d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath{ 130b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper switch (elf_kind (elf)) 131b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 132b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper default: 133b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_NONE: 134b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (elf == NULL ? DWFL_E_LIBELF : DWFL_E_BADELF); 135b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 136b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 137b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_ELF: 138b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return process_elf (dwfl, name, file_name, fd, elf); 139b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 140b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper case ELF_K_AR: 141b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return process_archive (dwfl, name, file_name, fd, elf, predicate); 142b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 143b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 144d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 145e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Report the open ELF file as a module. Always consumes ELF and FD. */ 146b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 147b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, 148b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf) 149b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 150b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, 151b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper dwfl->offline_next_address); 152d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod != NULL) 153d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 154d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath /* If this is an ET_EXEC file with fixed addresses, the address range 155d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath it consumed may or may not intersect with the arbitrary range we 156d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath will use for relocatable modules. Make sure we always use a free 157687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath range for the offline allocations. If this module did use 158687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath offline_next_address, it may have rounded it up for the module's 159687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath alignment requirements. */ 160687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath if ((dwfl->offline_next_address >= mod->low_addr 161687d7e9bd154a4b1f22b5e3ed7c6c904e421e871Roland McGrath || mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE) 162d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE) 163d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE; 164d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 165d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath /* Don't keep the file descriptor around. */ 166d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0) 167d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 168d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath close (mod->main.fd); 169d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath mod->main.fd = -1; 170d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 171d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 172d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 173d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath return mod; 174d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath} 175b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 176e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath/* Always consumes MEMBER. Returns elf_next result on success. 177e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath For errors returns ELF_C_NULL with *MOD set to null. */ 178e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrathstatic Elf_Cmd 179b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_archive_member (Dwfl *dwfl, const char *name, const char *file_name, 180b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, const char *file), 181e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath int fd, Elf *member, Dwfl_Module **mod) 182b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 183b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const Elf_Arhdr *h = elf_getarhdr (member); 184b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (h == NULL)) 185b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 186b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_LIBELF); 187e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath fail: 188b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 189b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper *mod = NULL; 190e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 191b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 192b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 193b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (!strcmp (h->ar_name, "/") || !strcmp (h->ar_name, "//")) 194b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 195e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath skip:; 196e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* Skip this and go to the next. */ 197e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath Elf_Cmd result = elf_next (member); 198b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 199e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return result; 200b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 201b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 202b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper char *member_name; 203b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (asprintf (&member_name, "%s(%s)", file_name, h->ar_name) < 0)) 204b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 205b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper nomem: 206b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_NOMEM); 207b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (member); 208b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper *mod = NULL; 209e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 210b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 211b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 212b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper char *module_name = NULL; 213b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (name == NULL || name[0] == '\0') 214b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper name = h->ar_name; 215b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper else if (unlikely (asprintf (&module_name, "%s:%s", name, h->ar_name) < 0)) 216b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 217b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 218b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper goto nomem; 219b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 220b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper else 221b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper name = module_name; 222b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 223b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (predicate != NULL) 224b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 225b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper /* Let the predicate decide whether to use this one. */ 226b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int want = (*predicate) (name, member_name); 227b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (want <= 0) 228b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 229b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 230b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (module_name); 231b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (unlikely (want < 0)) 232b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 233b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_CB); 234e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath goto fail; 235b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 236e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath goto skip; 237b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 238b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 239b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 240e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We let __libdwfl_report_elf cache the fd in mod->main.fd, 241e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath though it's the same fd for all the members. 242e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath On module teardown we will close it only on the last Elf reference. */ 243e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath *mod = process_file (dwfl, name, member_name, fd, member, predicate); 244b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (member_name); 245b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper free (module_name); 246e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 247e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (*mod == NULL) /* process_file called elf_end. */ 248e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return ELF_C_NULL; 249e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 250e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* Advance the archive-reading offset for the next iteration. */ 251e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath return elf_next (member); 252b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 253b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 254b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper/* Report each member of the archive as its own module. */ 255b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperstatic Dwfl_Module * 256b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperprocess_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd, 257b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *archive, 258b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, const char *file)) 259b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 260b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 261b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = NULL; 262e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath while (process_archive_member (dwfl, name, file_name, predicate, 263e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath fd, elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, 264e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath archive), &mod) != ELF_C_NULL) 265e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath ; 266e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 267e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath /* We can drop the archive Elf handle even if we're still using members 268e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath in live modules. When the last module's elf_end on a member returns 269e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath zero, that module will close FD. If no modules survived the predicate, 270e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath we are all done with the file right here. */ 271e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath if (elf_end (archive) == 0) 272b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper close (fd); 273e4c22ea004c02a58f5db5eb53794275344c17958Roland McGrath 274b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return mod; 275b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 276b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 277b597dfad924980dede10d7c19d87900b6172e599Ulrich DrepperDwfl_Module * 278b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperinternal_function 279b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper__libdwfl_report_offline (Dwfl *dwfl, const char *name, 280b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd, bool closefd, 281b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper int (*predicate) (const char *module, 282b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file)) 283b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 284b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL); 285b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Dwfl_Module *mod = process_file (dwfl, name, file_name, fd, elf, predicate); 286b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (mod == NULL) 287b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 288b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf_end (elf); 289b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (closefd) 290b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper close (fd); 291b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 292b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return mod; 293b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 294b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 295b597dfad924980dede10d7c19d87900b6172e599Ulrich DrepperDwfl_Module * 296b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperdwfl_report_offline (Dwfl *dwfl, const char *name, 297b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *file_name, int fd) 298b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper{ 299b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (dwfl == NULL) 300b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 301b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 302b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper bool closefd = false; 303b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (fd < 0) 304b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 305b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper closefd = true; 306b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper fd = open64 (file_name, O_RDONLY); 307b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (fd < 0) 308b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 309b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper __libdwfl_seterrno (DWFL_E_ERRNO); 310b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return NULL; 311b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 312b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 313b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 314b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return __libdwfl_report_offline (dwfl, name, file_name, fd, closefd, NULL); 315b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper} 316d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathINTDEF (dwfl_report_offline) 317