Blame backends/common-reloc.c

Packit Service 97d2fb
/* Common code for ebl reloc functions.
Packit Service 97d2fb
   Copyright (C) 2005, 2006 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
#include "libebl_CPU.h"
Packit Service 97d2fb
#include <assert.h>
Packit Service 97d2fb
Packit Service 97d2fb
#define R_TYPE(name)		PASTE (RELOC_PREFIX, name)
Packit Service 97d2fb
#define PASTE(a, b)		PASTE_1 (a, b)
Packit Service 97d2fb
#define PASTE_1(a, b)		a##b
Packit Service 97d2fb
#define R_NAME(name)		R_NAME_1 (RELOC_PREFIX, name)
Packit Service 97d2fb
#define R_NAME_1(prefix, type)	R_NAME_2 (prefix, type)
Packit Service 97d2fb
#define R_NAME_2(prefix, type)	#prefix #type
Packit Service 97d2fb
Packit Service 97d2fb
#define RELOC_TYPES		STRINGIFIED_PASTE (BACKEND, reloc.def)
Packit Service 97d2fb
#define STRINGIFIED_PASTE(a, b)	STRINGIFY (PASTE (a, b))
Packit Service 97d2fb
#define STRINGIFY(x)		STRINGIFY_1 (x)
Packit Service 97d2fb
#define STRINGIFY_1(x)		#x
Packit Service 97d2fb
Packit Service 97d2fb
/* Provide a table of reloc type names, in a PIC-friendly fashion.  */
Packit Service 97d2fb
Packit Service 97d2fb
static const struct EBLHOOK(reloc_nametable)
Packit Service 97d2fb
{
Packit Service 97d2fb
  char zero[1];
Packit Service 97d2fb
#define	RELOC_TYPE(type, uses) \
Packit Service 97d2fb
  char name_##type[sizeof R_NAME (type)];
Packit Service 97d2fb
#include RELOC_TYPES
Packit Service 97d2fb
#undef RELOC_TYPE
Packit Service 97d2fb
} EBLHOOK(reloc_nametable) =
Packit Service 97d2fb
  {
Packit Service 97d2fb
    { '\0' },
Packit Service 97d2fb
#define	RELOC_TYPE(type, uses) R_NAME (type),
Packit Service 97d2fb
#include RELOC_TYPES
Packit Service 97d2fb
#undef RELOC_TYPE
Packit Service 97d2fb
  };
Packit Service 97d2fb
#define reloc_namestr (&EBLHOOK(reloc_nametable).zero)
Packit Service 97d2fb
Packit Service 97d2fb
static const uint_fast16_t EBLHOOK(reloc_nameidx)[] =
Packit Service 97d2fb
{
Packit Service 97d2fb
#define	RELOC_TYPE(type, uses) \
Packit Service 97d2fb
  [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type),
Packit Service 97d2fb
#include RELOC_TYPES
Packit Service 97d2fb
#undef RELOC_TYPE
Packit Service 97d2fb
};
Packit Service 97d2fb
#define nreloc \
Packit Service 97d2fb
  ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0]))
Packit Service 97d2fb
Packit Service 97d2fb
#define REL	(1 << (ET_REL - 1))
Packit Service 97d2fb
#define EXEC	(1 << (ET_EXEC - 1))
Packit Service 97d2fb
#define DYN	(1 << (ET_DYN - 1))
Packit Service 97d2fb
static const uint8_t EBLHOOK(reloc_valid)[] =
Packit Service 97d2fb
{
Packit Service 97d2fb
#define	RELOC_TYPE(type, uses) [R_TYPE (type)] = uses,
Packit Service 97d2fb
#include RELOC_TYPES
Packit Service 97d2fb
#undef RELOC_TYPE
Packit Service 97d2fb
};
Packit Service 97d2fb
#undef REL
Packit Service 97d2fb
#undef EXEC
Packit Service 97d2fb
#undef DYN
Packit Service 97d2fb
Packit Service 97d2fb
const char *
Packit Service 97d2fb
EBLHOOK(reloc_type_name) (int reloc,
Packit Service 97d2fb
			  char *buf __attribute__ ((unused)),
Packit Service 97d2fb
			  size_t len __attribute__ ((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
#ifdef RELOC_TYPE_ID
Packit Service 97d2fb
  reloc = RELOC_TYPE_ID (reloc);
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
  if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
Packit Service 97d2fb
    return reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
Packit Service 97d2fb
  return NULL;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
bool
Packit Service 97d2fb
EBLHOOK(reloc_type_check) (int reloc)
Packit Service 97d2fb
{
Packit Service 97d2fb
#ifdef RELOC_TYPE_ID
Packit Service 97d2fb
  reloc = RELOC_TYPE_ID (reloc);
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
  return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
bool
Packit Service 97d2fb
EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
Packit Service 97d2fb
{
Packit Service 97d2fb
  uint8_t uses;
Packit Service 97d2fb
Packit Service 97d2fb
  GElf_Ehdr ehdr_mem;
Packit Service 97d2fb
  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
Packit Service 97d2fb
  assert (ehdr != NULL);
Packit Service 97d2fb
  uint8_t type = ehdr->e_type;
Packit Service 97d2fb
Packit Service 97d2fb
#ifdef RELOC_TYPE_ID
Packit Service 97d2fb
  reloc = RELOC_TYPE_ID (reloc);
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
  uses = EBLHOOK(reloc_valid)[reloc];
Packit Service 97d2fb
  return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
#ifndef NO_COPY_RELOC
Packit Service 97d2fb
bool
Packit Service 97d2fb
EBLHOOK(copy_reloc_p) (int reloc)
Packit Service 97d2fb
{
Packit Service 97d2fb
  return reloc == R_TYPE (COPY);
Packit Service 97d2fb
}
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
bool
Packit Service 97d2fb
EBLHOOK(none_reloc_p) (int reloc)
Packit Service 97d2fb
{
Packit Service 97d2fb
  return reloc == R_TYPE (NONE);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
#ifndef NO_RELATIVE_RELOC
Packit Service 97d2fb
bool
Packit Service 97d2fb
EBLHOOK(relative_reloc_p) (int reloc)
Packit Service 97d2fb
{
Packit Service 97d2fb
  return reloc == R_TYPE (RELATIVE);
Packit Service 97d2fb
}
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
static void
Packit Service 97d2fb
EBLHOOK(init_reloc) (Ebl *ebl)
Packit Service 97d2fb
{
Packit Service 97d2fb
  ebl->reloc_type_name = EBLHOOK(reloc_type_name);
Packit Service 97d2fb
  ebl->reloc_type_check = EBLHOOK(reloc_type_check);
Packit Service 97d2fb
  ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
Packit Service 97d2fb
  ebl->none_reloc_p = EBLHOOK(none_reloc_p);
Packit Service 97d2fb
#ifndef NO_COPY_RELOC
Packit Service 97d2fb
  ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
Packit Service 97d2fb
#endif
Packit Service 97d2fb
#ifndef NO_RELATIVE_RELOC
Packit Service 97d2fb
  ebl->relative_reloc_p = EBLHOOK(relative_reloc_p);
Packit Service 97d2fb
#endif
Packit Service 97d2fb
}