Blame libdwfl/dwfl_module_build_id.c

Packit Service 97d2fb
/* Return build ID information for a module.
Packit Service 97d2fb
   Copyright (C) 2007-2010, 2014 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of either
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU Lesser General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 3 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 2 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or both in parallel, as here.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 97d2fb
   General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received copies of the GNU General Public License and
Packit Service 97d2fb
   the GNU Lesser General Public License along with this program.  If
Packit Service 97d2fb
   not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#ifdef HAVE_CONFIG_H
Packit Service 97d2fb
# include <config.h>
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
#include "libdwflP.h"
Packit Service 97d2fb
Packit Service 97d2fb
static int
Packit Service 97d2fb
found_build_id (Dwfl_Module *mod, bool set,
Packit Service 97d2fb
		const void *bits, int len, GElf_Addr vaddr)
Packit Service 97d2fb
{
Packit Service 97d2fb
  if (!set)
Packit Service 97d2fb
    /* When checking bits, we do not compare VADDR because the
Packit Service 97d2fb
       address found in a debuginfo file may not match the main
Packit Service 97d2fb
       file as modified by prelink.  */
Packit Service 97d2fb
    return 1 + (mod->build_id_len == len
Packit Service 97d2fb
		&& !memcmp (bits, mod->build_id_bits, len));
Packit Service 97d2fb
Packit Service 97d2fb
  void *copy = malloc (len);
Packit Service 97d2fb
  if (unlikely (copy == NULL))
Packit Service 97d2fb
    {
Packit Service 97d2fb
      __libdwfl_seterrno (DWFL_E_NOMEM);
Packit Service 97d2fb
      return -1;
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  mod->build_id_bits = memcpy (copy, bits, len);
Packit Service 97d2fb
  mod->build_id_vaddr = vaddr;
Packit Service 97d2fb
  mod->build_id_len = len;
Packit Service 97d2fb
  return len;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
internal_function
Packit Service 97d2fb
__libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const void *build_id_bits;
Packit Service 97d2fb
  GElf_Addr build_id_elfaddr;
Packit Service 97d2fb
  int build_id_len;
Packit Service 97d2fb
Packit Service 97d2fb
  /* For mod == NULL use dwelf_elf_gnu_build_id directly.  */
Packit Service 97d2fb
  assert (mod != NULL);
Packit Service 97d2fb
Packit Service 97d2fb
  int result = __libdwfl_find_elf_build_id (mod, elf, &build_id_bits,
Packit Service 97d2fb
					    &build_id_elfaddr, &build_id_len);
Packit Service 97d2fb
  if (result <= 0)
Packit Service 97d2fb
    return result;
Packit Service 97d2fb
Packit Service 97d2fb
  GElf_Addr build_id_vaddr = build_id_elfaddr + (build_id_elfaddr != 0
Packit Service 97d2fb
						 ? mod->main_bias : 0);
Packit Service 97d2fb
  return found_build_id (mod, set, build_id_bits, build_id_len, build_id_vaddr);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
dwfl_module_build_id (Dwfl_Module *mod,
Packit Service 97d2fb
		      const unsigned char **bits, GElf_Addr *vaddr)
Packit Service 97d2fb
{
Packit Service 97d2fb
  if (mod == NULL)
Packit Service 97d2fb
    return -1;
Packit Service 97d2fb
Packit Service 97d2fb
  if (mod->build_id_len == 0 && mod->main.elf != NULL)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      /* We have the file, but have not examined it yet.  */
Packit Service 97d2fb
      int result = __libdwfl_find_build_id (mod, true, mod->main.elf);
Packit Service 97d2fb
      if (result <= 0)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	  mod->build_id_len = -1;	/* Cache negative result.  */
Packit Service 97d2fb
	  return result;
Packit Service 97d2fb
	}
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  if (mod->build_id_len <= 0)
Packit Service 97d2fb
    return 0;
Packit Service 97d2fb
Packit Service 97d2fb
  *bits = mod->build_id_bits;
Packit Service 97d2fb
  *vaddr = mod->build_id_vaddr;
Packit Service 97d2fb
  return mod->build_id_len;
Packit Service 97d2fb
}
Packit Service 97d2fb
INTDEF (dwfl_module_build_id)
Packit Service 97d2fb
NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
Packit Service 97d2fb
Packit Service 97d2fb
#ifdef SYMBOL_VERSIONING
Packit Service 97d2fb
COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
_compat_vaddr_at_end_dwfl_module_build_id (Dwfl_Module *mod,
Packit Service 97d2fb
					   const unsigned char **bits,
Packit Service 97d2fb
					   GElf_Addr *vaddr)
Packit Service 97d2fb
{
Packit Service 97d2fb
  int result = INTUSE(dwfl_module_build_id) (mod, bits, vaddr);
Packit Service 97d2fb
  if (result > 0)
Packit Service 97d2fb
    *vaddr += (result + 3) & -4;
Packit Service 97d2fb
  return result;
Packit Service 97d2fb
}
Packit Service 97d2fb
#endif