Fix memory leak in RiscV assembler.
[binutils-gdb.git] / bfd / elfxx-kvx.c
blobc3c6cdad282c8b99f6f18ed9ad9e5fc4824cc1f1
1 /* KVX-specific support for ELF.
2 Copyright (C) 2009-2023 Free Software Foundation, Inc.
3 Contributed by Kalray SA.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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/>. */
21 #include "sysdep.h"
22 #include "elfxx-kvx.h"
23 #include <stdarg.h>
24 #include <string.h>
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. */
30 static bfd_reloc_status_type
31 kvx_unsigned_overflow (bfd_vma value, unsigned int bits)
33 bfd_vma lim;
34 if (bits >= sizeof (bfd_vma) * 8)
35 return bfd_reloc_ok;
36 lim = (bfd_vma) 1 << bits;
37 if (value >= lim)
38 return bfd_reloc_overflow;
39 return bfd_reloc_ok;
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. */
46 static bfd_reloc_status_type
47 kvx_signed_overflow (bfd_vma value, unsigned int bits)
49 bfd_vma lim;
51 if (bits >= sizeof (bfd_vma) * 8)
52 return bfd_reloc_ok;
53 lim = (bfd_vma) 1 << (bits - 1);
54 if (value + lim >= lim * 2)
55 return bfd_reloc_overflow;
56 return bfd_reloc_ok;
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)
68 bfd_reloc_status_type status = bfd_reloc_ok;
69 bfd_vma contents;
70 int size;
72 size = bfd_get_reloc_size (howto);
73 switch (size)
75 case 2:
76 contents = bfd_get_16 (abfd, address);
77 break;
78 case 4:
79 if (howto->src_mask != 0xffffffff)
80 /* Must be 32-bit instruction, always little-endian. */
81 contents = bfd_getl32 (address);
82 else
83 /* Must be 32-bit data (endianness dependent). */
84 contents = bfd_get_32 (abfd, address);
85 break;
86 case 8:
87 contents = bfd_get_64 (abfd, address);
88 break;
89 default:
90 abort ();
93 switch (howto->complain_on_overflow)
95 case complain_overflow_dont:
96 break;
97 case complain_overflow_signed:
98 status = kvx_signed_overflow (addend,
99 howto->bitsize + howto->rightshift);
100 break;
101 case complain_overflow_unsigned:
102 status = kvx_unsigned_overflow (addend,
103 howto->bitsize + howto->rightshift);
104 break;
105 case complain_overflow_bitfield:
106 default:
107 abort ();
110 addend >>= howto->rightshift;
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"
121 * Beware that this won't be able to apply generic howto !
124 /* if (howto->dst_mask & (howto->dst_mask + 1)) */
125 /* return bfd_reloc_notsupported; */
126 addend <<= howto->bitpos;
127 contents = ((contents & ~howto->dst_mask) | (addend & howto->dst_mask));
129 switch (size)
131 case 2:
132 bfd_put_16 (abfd, contents, address);
133 break;
134 case 4:
135 if (howto->dst_mask != 0xffffffff)
136 /* must be 32-bit instruction, always little-endian */
137 bfd_putl32 (contents, address);
138 else
139 /* must be 32-bit data (endianness dependent) */
140 bfd_put_32 (abfd, contents, address);
141 break;
142 case 8:
143 bfd_put_64 (abfd, contents, address);
144 break;
145 default:
146 abort ();
149 return status;
152 bool
153 _bfd_kvx_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
155 int offset;
156 size_t size;
158 switch (note->descsz)
160 case 680: /* sizeof(struct elf_prstatus) on Linux/kvx. */
161 /* pr_cursig */
162 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
164 /* pr_pid */
165 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
167 /* pr_reg */
168 offset = 112;
169 size = 560;
170 break;
172 default:
173 return false;
176 /* Make a ".reg/999" section. */
177 return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
178 note->descpos + offset);
181 bool
182 _bfd_kvx_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
184 switch (note->descsz)
186 case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/kvx. */
187 elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
188 elf_tdata (abfd)->core->program
189 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
190 elf_tdata (abfd)->core->command
191 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
192 break;
194 default:
195 return false;
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. */
203 char *command = elf_tdata (abfd)->core->command;
204 int n = strlen (command);
206 if (n > 0 && command[n - 1] == ' ')
207 command[n - 1] = 0;
210 return true;