Define bfd_elf32_get_synthetic_symtab for x32
[deliverable/binutils-gdb.git] / bfd / elf32-sh64-com.c
CommitLineData
ef230218 1/* SuperH SH64-specific support for 32-bit ELF
4b95cf5c 2 Copyright (C) 2000-2014 Free Software Foundation, Inc.
b34976b6 3
9cba27b2 4 This file is part of BFD, the Binary File Descriptor library.
b34976b6 5
9cba27b2
JT
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
9cba27b2 9 (at your option) any later version.
b34976b6 10
9cba27b2
JT
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
b34976b6 15
9cba27b2
JT
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
9cba27b2
JT
20
21#define SH64_ELF
22
9cba27b2 23#include "sysdep.h"
3db64b00 24#include "bfd.h"
9cba27b2
JT
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf/sh.h"
f0abc2a1 28#include "elf32-sh64.h"
9cba27b2
JT
29#include "../opcodes/sh64-opc.h"
30
b34976b6 31static bfd_boolean sh64_address_in_cranges
09fd220b 32 (asection *cranges, bfd_vma, sh64_elf_crange *);
9cba27b2
JT
33
34/* Ordering functions of a crange, for the qsort and bsearch calls and for
35 different endianness. */
36
37int
09fd220b 38_bfd_sh64_crange_qsort_cmpb (const void *p1, const void *p2)
9cba27b2
JT
39{
40 bfd_vma a1 = bfd_getb32 (p1);
41 bfd_vma a2 = bfd_getb32 (p2);
42
43 /* Preserve order if there's ambiguous contents. */
44 if (a1 == a2)
45 return (char *) p1 - (char *) p2;
46
47 return a1 - a2;
48}
49
50int
09fd220b 51_bfd_sh64_crange_qsort_cmpl (const void *p1, const void *p2)
9cba27b2
JT
52{
53 bfd_vma a1 = (bfd_vma) bfd_getl32 (p1);
54 bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
55
56 /* Preserve order if there's ambiguous contents. */
57 if (a1 == a2)
58 return (char *) p1 - (char *) p2;
59
60 return a1 - a2;
61}
62
63int
09fd220b 64_bfd_sh64_crange_bsearch_cmpb (const void *p1, const void *p2)
9cba27b2
JT
65{
66 bfd_vma a1 = *(bfd_vma *) p1;
67 bfd_vma a2 = (bfd_vma) bfd_getb32 (p2);
68 bfd_size_type size
69 = (bfd_size_type) bfd_getb32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
70
71 if (a1 >= a2 + size)
72 return 1;
73 if (a1 < a2)
74 return -1;
75 return 0;
76}
77
78int
09fd220b 79_bfd_sh64_crange_bsearch_cmpl (const void *p1, const void *p2)
9cba27b2
JT
80{
81 bfd_vma a1 = *(bfd_vma *) p1;
82 bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
83 bfd_size_type size
84 = (bfd_size_type) bfd_getl32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
85
86 if (a1 >= a2 + size)
87 return 1;
88 if (a1 < a2)
89 return -1;
90 return 0;
91}
92
93/* Check whether a specific address is specified within a .cranges
94 section. Return FALSE if not found, and TRUE if found, and the region
95 filled into RANGEP if non-NULL. */
96
b34976b6 97static bfd_boolean
09fd220b
KK
98sh64_address_in_cranges (asection *cranges, bfd_vma addr,
99 sh64_elf_crange *rangep)
9cba27b2
JT
100{
101 bfd_byte *cranges_contents;
102 bfd_byte *found_rangep;
eea6121a 103 bfd_size_type cranges_size = cranges->size;
9cba27b2
JT
104
105 /* If the size is not a multiple of the cranges entry size, then
106 something is badly wrong. */
107 if ((cranges_size % SH64_CRANGE_SIZE) != 0)
b34976b6 108 return FALSE;
9cba27b2
JT
109
110 /* If this section has relocations, then we can't do anything sane. */
111 if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
b34976b6 112 return FALSE;
9cba27b2
JT
113
114 /* Has some kind soul (or previous call) left processed, sorted contents
115 for us? */
116 if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
117 && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
118 cranges_contents = cranges->contents;
119 else
120 {
eea6121a
AM
121 if (!bfd_malloc_and_get_section (cranges->owner, cranges,
122 &cranges_contents))
9cba27b2
JT
123 goto error_return;
124
125 /* Is it sorted? */
126 if (elf_section_data (cranges)->this_hdr.sh_type
127 != SHT_SH5_CR_SORTED)
128 /* Nope. Lets sort it. */
129 qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
130 SH64_CRANGE_SIZE,
131 bfd_big_endian (cranges->owner)
132 ? _bfd_sh64_crange_qsort_cmpb : _bfd_sh64_crange_qsort_cmpl);
133
134 /* Let's keep it around. */
135 cranges->contents = cranges_contents;
136 bfd_set_section_flags (cranges->owner, cranges,
137 bfd_get_section_flags (cranges->owner, cranges)
138 | SEC_IN_MEMORY);
139
140 /* It's sorted now. */
141 elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
142 }
143
144 /* Try and find a matching range. */
145 found_rangep
146 = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE,
147 SH64_CRANGE_SIZE,
148 bfd_big_endian (cranges->owner)
149 ? _bfd_sh64_crange_bsearch_cmpb
150 : _bfd_sh64_crange_bsearch_cmpl);
151
152 /* Fill in a few return values if we found a matching range. */
153 if (found_rangep)
154 {
155 enum sh64_elf_cr_type cr_type
156 = bfd_get_16 (cranges->owner,
157 SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
158 bfd_vma cr_addr
159 = bfd_get_32 (cranges->owner,
160 SH64_CRANGE_CR_ADDR_OFFSET
161 + (char *) found_rangep);
162 bfd_size_type cr_size
163 = bfd_get_32 (cranges->owner,
164 SH64_CRANGE_CR_SIZE_OFFSET
165 + (char *) found_rangep);
166
167 rangep->cr_addr = cr_addr;
168 rangep->cr_size = cr_size;
169 rangep->cr_type = cr_type;
170
b34976b6 171 return TRUE;
9cba27b2
JT
172 }
173
174 /* There is a .cranges section, but it does not have a descriptor
175 matching this address. */
b34976b6 176 return FALSE;
9cba27b2
JT
177
178error_return:
eea6121a
AM
179 if (cranges_contents != NULL)
180 free (cranges_contents);
b34976b6 181 return FALSE;
9cba27b2
JT
182}
183
184/* Determine what ADDR points to in SEC, and fill in a range descriptor in
185 *RANGEP if it's non-NULL. */
186
187enum sh64_elf_cr_type
09fd220b 188sh64_get_contents_type (asection *sec, bfd_vma addr, sh64_elf_crange *rangep)
9cba27b2
JT
189{
190 asection *cranges;
191
192 /* Fill in the range with the boundaries of the section as a default. */
193 if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
194 && elf_elfheader (sec->owner)->e_type == ET_EXEC)
195 {
196 rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
eea6121a 197 rangep->cr_size = sec->size;
9cba27b2
JT
198 rangep->cr_type = CRT_NONE;
199 }
200 else
b34976b6 201 return FALSE;
9cba27b2
JT
202
203 /* If none of the pertinent bits are set, then it's a SHcompact (or at
204 least not SHmedia). */
205 if ((elf_section_data (sec)->this_hdr.sh_flags
206 & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
207 {
208 enum sh64_elf_cr_type cr_type
209 = ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
210 ? CRT_SH5_ISA16 : CRT_DATA);
211 rangep->cr_type = cr_type;
212 return cr_type;
213 }
214
215 /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia. */
216 if ((elf_section_data (sec)->this_hdr.sh_flags
217 & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
218 {
219 rangep->cr_type = CRT_SH5_ISA32;
220 return CRT_SH5_ISA32;
221 }
222
223 /* Otherwise, we have to look up the .cranges section. */
224 cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);
225
226 if (cranges == NULL)
227 /* A mixed section but there's no .cranges section. This is probably
228 bad input; it does not comply to specs. */
229 return CRT_NONE;
230
231 /* If this call fails, we will still have CRT_NONE in rangep->cr_type
232 and that will be suitable to return. */
233 sh64_address_in_cranges (cranges, addr, rangep);
234
235 return rangep->cr_type;
236}
237
238/* This is a simpler exported interface for the benefit of gdb et al. */
239
b34976b6 240bfd_boolean
09fd220b 241sh64_address_is_shmedia (asection *sec, bfd_vma addr)
9cba27b2
JT
242{
243 sh64_elf_crange dummy;
244 return sh64_get_contents_type (sec, addr, &dummy) == CRT_SH5_ISA32;
245}
This page took 0.596274 seconds and 4 git commands to generate.