Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/elfxx-kvx.c
Line
Count
Source (jump to first uncovered line)
1
/* KVX-specific support for ELF.
2
   Copyright (C) 2009-2025 Free Software Foundation, Inc.
3
   Contributed by Kalray SA.
4
5
   This file is part of BFD, the Binary File Descriptor library.
6
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; see the file COPYING3. If not,
19
   see <http://www.gnu.org/licenses/>.  */
20
21
#include "sysdep.h"
22
#include "elfxx-kvx.h"
23
#include <stdarg.h>
24
#include <string.h>
25
26
/* Return non-zero if the indicated VALUE has overflowed the maximum
27
   range expressible by a unsigned number with the indicated number of
28
   BITS.  */
29
30
static bfd_reloc_status_type
31
kvx_unsigned_overflow (bfd_vma value, unsigned int bits)
32
0
{
33
0
  bfd_vma lim;
34
0
  if (bits >= sizeof (bfd_vma) * 8)
35
0
    return bfd_reloc_ok;
36
0
  lim = (bfd_vma) 1 << bits;
37
0
  if (value >= lim)
38
0
    return bfd_reloc_overflow;
39
0
  return bfd_reloc_ok;
40
0
}
41
42
/* Return non-zero if the indicated VALUE has overflowed the maximum
43
   range expressible by an signed number with the indicated number of
44
   BITS.  */
45
46
static bfd_reloc_status_type
47
kvx_signed_overflow (bfd_vma value, unsigned int bits)
48
0
{
49
0
  bfd_vma lim;
50
51
0
  if (bits >= sizeof (bfd_vma) * 8)
52
0
    return bfd_reloc_ok;
53
0
  lim = (bfd_vma) 1 << (bits - 1);
54
0
  if (value + lim >= lim * 2)
55
0
    return bfd_reloc_overflow;
56
0
  return bfd_reloc_ok;
57
0
}
58
59
/* Insert the addend/value into the instruction or data object being
60
   relocated.  */
61
bfd_reloc_status_type
62
_bfd_kvx_elf_put_addend (bfd *abfd,
63
       bfd_byte *address,
64
       bfd_reloc_code_real_type r_type ATTRIBUTE_UNUSED,
65
       reloc_howto_type *howto,
66
       bfd_signed_vma addend)
67
0
{
68
0
  bfd_reloc_status_type status = bfd_reloc_ok;
69
0
  bfd_vma contents;
70
0
  int size;
71
72
0
  size = bfd_get_reloc_size (howto);
73
0
  switch (size)
74
0
    {
75
0
    case 2:
76
0
      contents = bfd_get_16 (abfd, address);
77
0
      break;
78
0
    case 4:
79
0
      if (howto->src_mask != 0xffffffff)
80
  /* Must be 32-bit instruction, always little-endian.  */
81
0
  contents = bfd_getl32 (address);
82
0
      else
83
  /* Must be 32-bit data (endianness dependent).  */
84
0
  contents = bfd_get_32 (abfd, address);
85
0
      break;
86
0
    case 8:
87
0
      contents = bfd_get_64 (abfd, address);
88
0
      break;
89
0
    default:
90
0
      abort ();
91
0
    }
92
93
0
  switch (howto->complain_on_overflow)
94
0
    {
95
0
    case complain_overflow_dont:
96
0
      break;
97
0
    case complain_overflow_signed:
98
0
      status = kvx_signed_overflow (addend,
99
0
            howto->bitsize + howto->rightshift);
100
0
      break;
101
0
    case complain_overflow_unsigned:
102
0
      status = kvx_unsigned_overflow (addend,
103
0
              howto->bitsize + howto->rightshift);
104
0
      break;
105
0
    case complain_overflow_bitfield:
106
0
    default:
107
0
      abort ();
108
0
    }
109
110
0
  addend >>= howto->rightshift;
111
112
  /* FIXME KVX : AARCH64 is "redoing" what the link_relocate bfd
113
   * function does ie. extract bitfields and apply then to the
114
   * existing content (insn) (howto's job) Not sure exactly
115
   * why. Maybe because we need this even when not applying reloc
116
   * against a input_bfd (eg. when doing PLT).  On KVX, we have not
117
   * reached a point where we would need to write similar
118
   * functions for each insn. So we'll simply enrich the default
119
   * case for handling a bit more than "right aligned bitfields"
120
   * 
121
   * Beware that this won't be able to apply generic howto !
122
   */
123
124
  /* if (howto->dst_mask & (howto->dst_mask + 1)) */
125
  /*  return bfd_reloc_notsupported; */
126
0
  addend <<= howto->bitpos;
127
0
  contents = ((contents & ~howto->dst_mask) | (addend & howto->dst_mask));
128
129
0
  switch (size)
130
0
    {
131
0
    case 2:
132
0
      bfd_put_16 (abfd, contents, address);
133
0
      break;
134
0
    case 4:
135
0
      if (howto->dst_mask != 0xffffffff)
136
  /* must be 32-bit instruction, always little-endian */
137
0
  bfd_putl32 (contents, address);
138
0
      else
139
  /* must be 32-bit data (endianness dependent) */
140
0
  bfd_put_32 (abfd, contents, address);
141
0
      break;
142
0
    case 8:
143
0
      bfd_put_64 (abfd, contents, address);
144
0
      break;
145
0
    default:
146
0
      abort ();
147
0
    }
148
149
0
  return status;
150
0
}
151
152
bool
153
_bfd_kvx_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
154
0
{
155
0
  int offset;
156
0
  size_t size;
157
158
0
  switch (note->descsz)
159
0
    {
160
0
    case 680: /* sizeof(struct elf_prstatus) on Linux/kvx.  */
161
      /* pr_cursig */
162
0
      elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
163
164
      /* pr_pid */
165
0
      elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
166
167
      /* pr_reg */
168
0
      offset = 112;
169
0
      size = 560;
170
0
      break;
171
172
0
    default:
173
0
      return false;
174
0
    }
175
176
  /* Make a ".reg/999" section.  */
177
0
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
178
0
            note->descpos + offset);
179
0
}
180
181
bool
182
_bfd_kvx_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
183
0
{
184
0
  switch (note->descsz)
185
0
    {
186
0
    case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/kvx.  */
187
0
      elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
188
0
      elf_tdata (abfd)->core->program
189
0
  = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
190
0
      elf_tdata (abfd)->core->command
191
0
  = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
192
0
      break;
193
194
0
    default:
195
0
      return false;
196
0
    }
197
198
  /* Note that for some reason, a spurious space is tacked
199
     onto the end of the args in some (at least one anyway)
200
     implementations, so strip it off if it exists.  */
201
202
0
  {
203
0
    char *command = elf_tdata (abfd)->core->command;
204
0
    int n = strlen (command);
205
206
0
    if (n > 0 && command[n - 1] == ' ')
207
0
      command[n - 1] = 0;
208
0
  }
209
210
0
  return true;
211
0
}