125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Alpha specific symbolic name handling.
225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   Copyright (C) 2002-2011 Red Hat, Inc.
303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   This file is part of elfutils.
425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   This file is free software; you can redistribute it and/or modify
703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   it under the terms of either
825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
903333823c75a1c1887e923828113a1b0fd12020cElliott Hughes     * the GNU Lesser General Public License as published by the Free
1003333823c75a1c1887e923828113a1b0fd12020cElliott Hughes       Software Foundation; either version 3 of the License, or (at
1103333823c75a1c1887e923828113a1b0fd12020cElliott Hughes       your option) any later version
1203333823c75a1c1887e923828113a1b0fd12020cElliott Hughes
1303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   or
1403333823c75a1c1887e923828113a1b0fd12020cElliott Hughes
1503333823c75a1c1887e923828113a1b0fd12020cElliott Hughes     * the GNU General Public License as published by the Free
1603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes       Software Foundation; either version 2 of the License, or (at
1703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes       your option) any later version
1803333823c75a1c1887e923828113a1b0fd12020cElliott Hughes
1903333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   or both in parallel, as here.
2003333823c75a1c1887e923828113a1b0fd12020cElliott Hughes
2103333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   elfutils is distributed in the hope that it will be useful, but
2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   WITHOUT ANY WARRANTY; without even the implied warranty of
2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   General Public License for more details.
2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
2603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   You should have received copies of the GNU General Public License and
2703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   the GNU Lesser General Public License along with this program.  If
2803333823c75a1c1887e923828113a1b0fd12020cElliott Hughes   not, see <http://www.gnu.org/licenses/>.  */
2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H
3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h>
3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif
3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <elf.h>
3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stddef.h>
3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h>
3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define BACKEND		alpha_
3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "libebl_CPU.h"
4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
4225b3c049e70834cf33790a28643ab058b507b35cBen Chengconst char *
4325b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng			size_t len __attribute__ ((unused)))
4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  switch (tag)
4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
4825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case DT_ALPHA_PLTRO:
4925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return "ALPHA_PLTRO";
5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng    default:
5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return NULL;
5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5625b3c049e70834cf33790a28643ab058b507b35cBen Chengbool
5725b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_dynamic_tag_check (int64_t tag)
5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return tag == DT_ALPHA_PLTRO;
6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Check for the simple reloc types.  */
6325b3c049e70834cf33790a28643ab058b507b35cBen ChengElf_Type
6425b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  switch (type)
6725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
6825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case R_ALPHA_REFLONG:
6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return ELF_T_WORD;
7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case R_ALPHA_REFQUAD:
7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return ELF_T_XWORD;
7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    default:
7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return ELF_T_NUM;
7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Check whether SHF_MASKPROC flags are valid.  */
7925b3c049e70834cf33790a28643ab058b507b35cBen Chengbool
8025b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_machine_section_flag_check (GElf_Xword sh_flags)
8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return (sh_flags &~ (SHF_ALPHA_GPREL)) == 0;
8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
8525b3c049e70834cf33790a28643ab058b507b35cBen Chengbool
8625b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_check_special_section (Ebl *ebl,
8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng			     int ndx __attribute__ ((unused)),
8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng			     const GElf_Shdr *shdr,
8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng			     const char *sname __attribute__ ((unused)))
9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if ((shdr->sh_flags
9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng       & (SHF_WRITE | SHF_EXECINSTR)) == (SHF_WRITE | SHF_EXECINSTR)
9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      && shdr->sh_addr != 0)
9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* This is ordinarily flagged, but is valid for an old-style PLT.
9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	 Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it.
9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	 Its d_ptr should match the .plt section's sh_addr.  */
9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      Elf_Scn *scn = NULL;
10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  GElf_Shdr scn_shdr;
10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (likely (gelf_getshdr (scn, &scn_shdr) != NULL)
10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      && scn_shdr.sh_type == SHT_DYNAMIC
10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      && scn_shdr.sh_entsize != 0)
10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    {
10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      GElf_Addr pltgot = 0;
10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      Elf_Data *data = elf_getdata (scn, NULL);
11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      if (data != NULL)
11125b3c049e70834cf33790a28643ab058b507b35cBen Cheng		for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i)
11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  {
11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng		    GElf_Dyn dyn;
11425b3c049e70834cf33790a28643ab058b507b35cBen Cheng		    if (unlikely (gelf_getdyn (data, i, &dyn) == NULL))
11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng		      break;
11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng		    if (dyn.d_tag == DT_PLTGOT)
11725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		      pltgot = dyn.d_un.d_ptr;
11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng		    else if (dyn.d_tag == DT_ALPHA_PLTRO && dyn.d_un.d_val != 0)
11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng		      return false; /* This PLT should not be writable.  */
12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  }
12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      return pltgot == shdr->sh_addr;
12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    }
12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
12625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return false;
12725b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Check whether given symbol's st_value and st_size are OK despite failing
13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   normal checks.  */
13125b3c049e70834cf33790a28643ab058b507b35cBen Chengbool
13225b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_check_special_symbol (Elf *elf __attribute__ ((unused)),
13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    GElf_Ehdr *ehdr __attribute__ ((unused)),
13425b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    const GElf_Sym *sym __attribute__ ((unused)),
13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    const char *name,
13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    const GElf_Shdr *destshdr __attribute__ ((unused)))
13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (name == NULL)
13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    return false;
14025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    /* On Alpha any place in the section is valid.  */
14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng    return true;
14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return false;
14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Check whether only valid bits are set on the st_other symbol flag.
14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   Standard ST_VISIBILITY have already been masked off.  */
15025b3c049e70834cf33790a28643ab058b507b35cBen Chengbool
15125b3c049e70834cf33790a28643ab058b507b35cBen Chengalpha_check_st_other_bits (unsigned char st_other)
15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return ((((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	   || ((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD))
15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  && (st_other &~ STO_ALPHA_STD_GPLOAD) == 0);
15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
157