Blame backends/aarch64_symbol.c

Packit 032894
/* AArch64 specific symbolic name handling.
Packit 032894
   Copyright (C) 2013, 2015, 2017 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifdef HAVE_CONFIG_H
Packit 032894
# include <config.h>
Packit 032894
#endif
Packit 032894
Packit 032894
#include <elf.h>
Packit 032894
#include <stddef.h>
Packit 032894
#include <string.h>
Packit 032894
Packit 032894
#define BACKEND		aarch64_
Packit 032894
#include "libebl_CPU.h"
Packit 032894
Packit 032894
Packit 032894
/* Check for the simple reloc types.  */
Packit 032894
Elf_Type
Packit 032894
aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
Packit 032894
			   int *addsub __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  switch (type)
Packit 032894
    {
Packit 032894
    case R_AARCH64_ABS64:
Packit 032894
      return ELF_T_XWORD;
Packit 032894
    case R_AARCH64_ABS32:
Packit 032894
      return ELF_T_WORD;
Packit 032894
    case R_AARCH64_ABS16:
Packit 032894
      return ELF_T_HALF;
Packit 032894
Packit 032894
    default:
Packit 032894
      return ELF_T_NUM;
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
/* If this is the _GLOBAL_OFFSET_TABLE_ symbol, then it should point in
Packit 032894
   the .got even if there is a .got.plt section.
Packit 032894
   https://sourceware.org/ml/libc-ports/2013-06/msg00057.html
Packit 032894
   https://bugzilla.redhat.com/show_bug.cgi?id=1201778
Packit 032894
 */
Packit 032894
bool
Packit 032894
aarch64_check_special_symbol (Elf *elf, const GElf_Sym *sym,
Packit 032894
                              const char *name, const GElf_Shdr *destshdr)
Packit 032894
{
Packit 032894
  if (name != NULL
Packit 032894
      && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
Packit 032894
    {
Packit 032894
      size_t shstrndx;
Packit 032894
      if (elf_getshdrstrndx (elf, &shstrndx) != 0)
Packit 032894
	return false;
Packit 032894
      const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name);
Packit 032894
      if (sname != NULL
Packit 032894
	  && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0))
Packit 032894
	{
Packit 032894
	  Elf_Scn *scn = NULL;
Packit 032894
	  while ((scn = elf_nextscn (elf, scn)) != NULL)
Packit 032894
	    {
Packit 032894
	      GElf_Shdr shdr_mem;
Packit 032894
	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
Packit 032894
	      if (shdr != NULL)
Packit 032894
		{
Packit 032894
		  sname = elf_strptr (elf, shstrndx, shdr->sh_name);
Packit 032894
		  if (sname != NULL && strcmp (sname, ".got") == 0)
Packit 032894
		    return (sym->st_value >= shdr->sh_addr
Packit 032894
			    && sym->st_value < shdr->sh_addr + shdr->sh_size);
Packit 032894
		}
Packit 032894
	    }
Packit 032894
	}
Packit 032894
    }
Packit 032894
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
/* A data mapping symbol is a symbol with "$d" name or "$d.<any...>" name,
Packit 032894
   STT_NOTYPE, STB_LOCAL and st_size of zero. The indicate the stat of a
Packit 032894
   sequence of data items.  */
Packit 032894
bool
Packit 032894
aarch64_data_marker_symbol (const GElf_Sym *sym, const char *sname)
Packit 032894
{
Packit 032894
  return (sym != NULL && sname != NULL
Packit 032894
	  && sym->st_size == 0 && GELF_ST_BIND (sym->st_info) == STB_LOCAL
Packit 032894
	  && GELF_ST_TYPE (sym->st_info) == STT_NOTYPE
Packit 032894
	  && (strcmp (sname, "$d") == 0 || strncmp (sname, "$d.", 3) == 0));
Packit 032894
}