1da0c48c4Sopenharmony_ci/* Return build ID information for a module. 2da0c48c4Sopenharmony_ci Copyright (C) 2007-2010, 2014 Red Hat, Inc. 3da0c48c4Sopenharmony_ci This file is part of elfutils. 4da0c48c4Sopenharmony_ci 5da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 6da0c48c4Sopenharmony_ci it under the terms of either 7da0c48c4Sopenharmony_ci 8da0c48c4Sopenharmony_ci * the GNU Lesser General Public License as published by the Free 9da0c48c4Sopenharmony_ci Software Foundation; either version 3 of the License, or (at 10da0c48c4Sopenharmony_ci your option) any later version 11da0c48c4Sopenharmony_ci 12da0c48c4Sopenharmony_ci or 13da0c48c4Sopenharmony_ci 14da0c48c4Sopenharmony_ci * the GNU General Public License as published by the Free 15da0c48c4Sopenharmony_ci Software Foundation; either version 2 of the License, or (at 16da0c48c4Sopenharmony_ci your option) any later version 17da0c48c4Sopenharmony_ci 18da0c48c4Sopenharmony_ci or both in parallel, as here. 19da0c48c4Sopenharmony_ci 20da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 21da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 22da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23da0c48c4Sopenharmony_ci General Public License for more details. 24da0c48c4Sopenharmony_ci 25da0c48c4Sopenharmony_ci You should have received copies of the GNU General Public License and 26da0c48c4Sopenharmony_ci the GNU Lesser General Public License along with this program. If 27da0c48c4Sopenharmony_ci not, see <http://www.gnu.org/licenses/>. */ 28da0c48c4Sopenharmony_ci 29da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 30da0c48c4Sopenharmony_ci# include <config.h> 31da0c48c4Sopenharmony_ci#endif 32da0c48c4Sopenharmony_ci 33da0c48c4Sopenharmony_ci#include "libdwflP.h" 34da0c48c4Sopenharmony_ci 35da0c48c4Sopenharmony_cistatic int 36da0c48c4Sopenharmony_cifound_build_id (Dwfl_Module *mod, bool set, 37da0c48c4Sopenharmony_ci const void *bits, int len, GElf_Addr vaddr) 38da0c48c4Sopenharmony_ci{ 39da0c48c4Sopenharmony_ci if (!set) 40da0c48c4Sopenharmony_ci /* When checking bits, we do not compare VADDR because the 41da0c48c4Sopenharmony_ci address found in a debuginfo file may not match the main 42da0c48c4Sopenharmony_ci file as modified by prelink. */ 43da0c48c4Sopenharmony_ci return 1 + (mod->build_id_len == len 44da0c48c4Sopenharmony_ci && !memcmp (bits, mod->build_id_bits, len)); 45da0c48c4Sopenharmony_ci 46da0c48c4Sopenharmony_ci void *copy = malloc (len); 47da0c48c4Sopenharmony_ci if (unlikely (copy == NULL)) 48da0c48c4Sopenharmony_ci { 49da0c48c4Sopenharmony_ci __libdwfl_seterrno (DWFL_E_NOMEM); 50da0c48c4Sopenharmony_ci return -1; 51da0c48c4Sopenharmony_ci } 52da0c48c4Sopenharmony_ci 53da0c48c4Sopenharmony_ci mod->build_id_bits = memcpy (copy, bits, len); 54da0c48c4Sopenharmony_ci mod->build_id_vaddr = vaddr; 55da0c48c4Sopenharmony_ci mod->build_id_len = len; 56da0c48c4Sopenharmony_ci return len; 57da0c48c4Sopenharmony_ci} 58da0c48c4Sopenharmony_ci 59da0c48c4Sopenharmony_ciint 60da0c48c4Sopenharmony_ciinternal_function 61da0c48c4Sopenharmony_ci__libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf) 62da0c48c4Sopenharmony_ci{ 63da0c48c4Sopenharmony_ci const void *build_id_bits; 64da0c48c4Sopenharmony_ci GElf_Addr build_id_elfaddr; 65da0c48c4Sopenharmony_ci int build_id_len; 66da0c48c4Sopenharmony_ci 67da0c48c4Sopenharmony_ci /* For mod == NULL use dwelf_elf_gnu_build_id directly. */ 68da0c48c4Sopenharmony_ci assert (mod != NULL); 69da0c48c4Sopenharmony_ci 70da0c48c4Sopenharmony_ci int result = __libdwfl_find_elf_build_id (mod, elf, &build_id_bits, 71da0c48c4Sopenharmony_ci &build_id_elfaddr, &build_id_len); 72da0c48c4Sopenharmony_ci if (result <= 0) 73da0c48c4Sopenharmony_ci return result; 74da0c48c4Sopenharmony_ci 75da0c48c4Sopenharmony_ci GElf_Addr build_id_vaddr = build_id_elfaddr + (build_id_elfaddr != 0 76da0c48c4Sopenharmony_ci ? mod->main_bias : 0); 77da0c48c4Sopenharmony_ci return found_build_id (mod, set, build_id_bits, build_id_len, build_id_vaddr); 78da0c48c4Sopenharmony_ci} 79da0c48c4Sopenharmony_ci 80da0c48c4Sopenharmony_ciNEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138) 81da0c48c4Sopenharmony_ciint 82da0c48c4Sopenharmony_cidwfl_module_build_id (Dwfl_Module *mod, 83da0c48c4Sopenharmony_ci const unsigned char **bits, GElf_Addr *vaddr) 84da0c48c4Sopenharmony_ci{ 85da0c48c4Sopenharmony_ci if (mod == NULL) 86da0c48c4Sopenharmony_ci return -1; 87da0c48c4Sopenharmony_ci 88da0c48c4Sopenharmony_ci if (mod->build_id_len == 0 && mod->main.elf != NULL) 89da0c48c4Sopenharmony_ci { 90da0c48c4Sopenharmony_ci /* We have the file, but have not examined it yet. */ 91da0c48c4Sopenharmony_ci int result = __libdwfl_find_build_id (mod, true, mod->main.elf); 92da0c48c4Sopenharmony_ci if (result <= 0) 93da0c48c4Sopenharmony_ci { 94da0c48c4Sopenharmony_ci mod->build_id_len = -1; /* Cache negative result. */ 95da0c48c4Sopenharmony_ci return result; 96da0c48c4Sopenharmony_ci } 97da0c48c4Sopenharmony_ci } 98da0c48c4Sopenharmony_ci 99da0c48c4Sopenharmony_ci if (mod->build_id_len <= 0) 100da0c48c4Sopenharmony_ci return 0; 101da0c48c4Sopenharmony_ci 102da0c48c4Sopenharmony_ci *bits = mod->build_id_bits; 103da0c48c4Sopenharmony_ci *vaddr = mod->build_id_vaddr; 104da0c48c4Sopenharmony_ci return mod->build_id_len; 105da0c48c4Sopenharmony_ci} 106da0c48c4Sopenharmony_ciNEW_INTDEF (dwfl_module_build_id) 107da0c48c4Sopenharmony_ci 108da0c48c4Sopenharmony_ci#ifdef SYMBOL_VERSIONING 109da0c48c4Sopenharmony_ciCOMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end) 110da0c48c4Sopenharmony_ci 111da0c48c4Sopenharmony_ciint 112da0c48c4Sopenharmony_ci_compat_vaddr_at_end_dwfl_module_build_id (Dwfl_Module *mod, 113da0c48c4Sopenharmony_ci const unsigned char **bits, 114da0c48c4Sopenharmony_ci GElf_Addr *vaddr) 115da0c48c4Sopenharmony_ci{ 116da0c48c4Sopenharmony_ci int result = INTUSE(dwfl_module_build_id) (mod, bits, vaddr); 117da0c48c4Sopenharmony_ci if (result > 0) 118da0c48c4Sopenharmony_ci *vaddr += (result + 3) & -4; 119da0c48c4Sopenharmony_ci return result; 120da0c48c4Sopenharmony_ci} 121da0c48c4Sopenharmony_ci#endif 122