Branch data Line data Source code
1 : : /* LoongArch specific symbolic name handling.
2 : : Copyright (C) 2022 Hengqi Chen
3 : : This file is part of elfutils.
4 : :
5 : : This file is free software; you can redistribute it and/or modify
6 : : it under the terms of either
7 : :
8 : : * the GNU Lesser General Public License as published by the Free
9 : : Software Foundation; either version 3 of the License, or (at
10 : : your option) any later version
11 : :
12 : : or
13 : :
14 : : * the GNU General Public License as published by the Free
15 : : Software Foundation; either version 2 of the License, or (at
16 : : your option) any later version
17 : :
18 : : or both in parallel, as here.
19 : :
20 : : elfutils is distributed in the hope that it will be useful, but
21 : : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : : General Public License for more details.
24 : :
25 : : You should have received copies of the GNU General Public License and
26 : : the GNU Lesser General Public License along with this program. If
27 : : not, see <http://www.gnu.org/licenses/>. */
28 : :
29 : : #ifdef HAVE_CONFIG_H
30 : : # include <config.h>
31 : : #endif
32 : :
33 : : #include <assert.h>
34 : : #include <elf.h>
35 : : #include <stddef.h>
36 : : #include <string.h>
37 : :
38 : : #define BACKEND loongarch_
39 : : #include "libebl_CPU.h"
40 : :
41 : :
42 : : /* Check for the simple reloc types. */
43 : : Elf_Type
44 : 0 : loongarch_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
45 : : int *addsub)
46 : : {
47 [ # # # # : 0 : switch (type)
# # # #
# ]
48 : : {
49 : : case R_LARCH_32:
50 : : return ELF_T_WORD;
51 : : case R_LARCH_64:
52 : : return ELF_T_XWORD;
53 : 0 : case R_LARCH_ADD16:
54 : 0 : *addsub = 1;
55 : 0 : return ELF_T_HALF;
56 : 0 : case R_LARCH_ADD32:
57 : 0 : *addsub = 1;
58 : 0 : return ELF_T_WORD;
59 : 0 : case R_LARCH_ADD64:
60 : 0 : *addsub = 1;
61 : 0 : return ELF_T_XWORD;
62 : 0 : case R_LARCH_SUB16:
63 : 0 : *addsub = -1;
64 : 0 : return ELF_T_HALF;
65 : 0 : case R_LARCH_SUB32:
66 : 0 : *addsub = -1;
67 : 0 : return ELF_T_WORD;
68 : 0 : case R_LARCH_SUB64:
69 : 0 : *addsub = -1;
70 : 0 : return ELF_T_XWORD;
71 : : default:
72 : : return ELF_T_NUM;
73 : : }
74 : : }
75 : :
76 : : bool
77 : 0 : loongarch_machine_flag_check (GElf_Word flags)
78 : : {
79 : 0 : return ((flags &~ (EF_LARCH_ABI_MODIFIER_MASK
80 : 0 : | EF_LARCH_OBJABI_V1)) == 0);
81 : : }
82 : :
83 : : /* Check whether given symbol's st_value and st_size are OK despite failing
84 : : normal checks. */
85 : : bool
86 : 0 : loongarch_check_special_symbol (Elf *elf, const GElf_Sym *sym,
87 : : const char *name, const GElf_Shdr *destshdr)
88 : : {
89 [ # # ]: 0 : if (name != NULL
90 [ # # ]: 0 : && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
91 : : {
92 : 0 : size_t shstrndx;
93 [ # # ]: 0 : if (elf_getshdrstrndx (elf, &shstrndx) != 0)
94 : 0 : return false;
95 : 0 : const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name);
96 [ # # ]: 0 : if (sname != NULL
97 [ # # # # ]: 0 : && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0))
98 : : {
99 : : Elf_Scn *scn = NULL;
100 [ # # ]: 0 : while ((scn = elf_nextscn (elf, scn)) != NULL)
101 : : {
102 : 0 : GElf_Shdr shdr_mem;
103 : 0 : GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
104 [ # # ]: 0 : if (shdr != NULL)
105 : : {
106 : 0 : sname = elf_strptr (elf, shstrndx, shdr->sh_name);
107 [ # # # # ]: 0 : if (sname != NULL && strcmp (sname, ".got") == 0)
108 : 0 : return (sym->st_value >= shdr->sh_addr
109 [ # # # # ]: 0 : && sym->st_value < shdr->sh_addr + shdr->sh_size);
110 : : }
111 : : }
112 : : }
113 : : }
114 : :
115 : : return false;
116 : : }
|