OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [elf32-sh64-com.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Hitachi SH64-specific support for 32-bit ELF
2
   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3
 
4
   This file is part of BFD, the Binary File Descriptor library.
5
 
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
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
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.
15
 
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
18
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
 
20
#define SH64_ELF
21
 
22
#include "bfd.h"
23
#include "sysdep.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/sh.h"
27
#include "../opcodes/sh64-opc.h"
28
 
29
static boolean sh64_address_in_cranges
30
  PARAMS ((asection *cranges, bfd_vma, sh64_elf_crange *));
31
 
32
/* Ordering functions of a crange, for the qsort and bsearch calls and for
33
   different endianness.  */
34
 
35
int
36
_bfd_sh64_crange_qsort_cmpb (p1, p2)
37
     const PTR p1;
38
     const PTR p2;
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
 
50
int
51
_bfd_sh64_crange_qsort_cmpl (p1, p2)
52
     const PTR p1;
53
     const PTR p2;
54
{
55
  bfd_vma a1 = (bfd_vma) bfd_getl32 (p1);
56
  bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
57
 
58
  /* Preserve order if there's ambiguous contents.  */
59
  if (a1 == a2)
60
    return (char *) p1 - (char *) p2;
61
 
62
  return a1 - a2;
63
}
64
 
65
int
66
_bfd_sh64_crange_bsearch_cmpb (p1, p2)
67
     const PTR p1;
68
     const PTR p2;
69
{
70
  bfd_vma a1 = *(bfd_vma *) p1;
71
  bfd_vma a2 = (bfd_vma) bfd_getb32 (p2);
72
  bfd_size_type size
73
    = (bfd_size_type) bfd_getb32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
74
 
75
  if (a1 >= a2 + size)
76
    return 1;
77
  if (a1 < a2)
78
    return -1;
79
  return 0;
80
}
81
 
82
int
83
_bfd_sh64_crange_bsearch_cmpl (p1, p2)
84
     const PTR p1;
85
     const PTR p2;
86
{
87
  bfd_vma a1 = *(bfd_vma *) p1;
88
  bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
89
  bfd_size_type size
90
    = (bfd_size_type) bfd_getl32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
91
 
92
  if (a1 >= a2 + size)
93
    return 1;
94
  if (a1 < a2)
95
    return -1;
96
  return 0;
97
}
98
 
99
/* Check whether a specific address is specified within a .cranges
100
   section.  Return FALSE if not found, and TRUE if found, and the region
101
   filled into RANGEP if non-NULL.  */
102
 
103
static boolean
104
sh64_address_in_cranges (cranges, addr, rangep)
105
     asection *cranges;
106
     bfd_vma addr;
107
     sh64_elf_crange *rangep;
108
{
109
  bfd_byte *cranges_contents;
110
  bfd_byte *found_rangep;
111
  bfd_size_type cranges_size = bfd_section_size (cranges->owner, cranges);
112
 
113
  /* If the size is not a multiple of the cranges entry size, then
114
     something is badly wrong.  */
115
  if ((cranges_size % SH64_CRANGE_SIZE) != 0)
116
    return false;
117
 
118
  /* If this section has relocations, then we can't do anything sane.  */
119
  if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
120
    return false;
121
 
122
  /* Has some kind soul (or previous call) left processed, sorted contents
123
     for us?  */
124
  if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
125
      && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
126
    cranges_contents = cranges->contents;
127
  else
128
    {
129
      cranges_contents
130
        = bfd_malloc (cranges->_cooked_size == 0
131
                      ? cranges->_cooked_size : cranges->_raw_size);
132
      if (cranges_contents == NULL)
133
        return false;
134
 
135
      if (! bfd_get_section_contents (cranges->owner, cranges,
136
                                      cranges_contents, (file_ptr) 0,
137
                                      cranges_size))
138
        goto error_return;
139
 
140
      /* Is it sorted?  */
141
      if (elf_section_data (cranges)->this_hdr.sh_type
142
          != SHT_SH5_CR_SORTED)
143
        /* Nope.  Lets sort it.  */
144
        qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
145
               SH64_CRANGE_SIZE,
146
               bfd_big_endian (cranges->owner)
147
               ? _bfd_sh64_crange_qsort_cmpb : _bfd_sh64_crange_qsort_cmpl);
148
 
149
      /* Let's keep it around.  */
150
      cranges->contents = cranges_contents;
151
      bfd_set_section_flags (cranges->owner, cranges,
152
                             bfd_get_section_flags (cranges->owner, cranges)
153
                             | SEC_IN_MEMORY);
154
 
155
      /* It's sorted now.  */
156
      elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
157
    }
158
 
159
  /* Try and find a matching range.  */
160
  found_rangep
161
    = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE,
162
               SH64_CRANGE_SIZE,
163
               bfd_big_endian (cranges->owner)
164
               ? _bfd_sh64_crange_bsearch_cmpb
165
               : _bfd_sh64_crange_bsearch_cmpl);
166
 
167
  /* Fill in a few return values if we found a matching range.  */
168
  if (found_rangep)
169
    {
170
      enum sh64_elf_cr_type cr_type
171
        = bfd_get_16 (cranges->owner,
172
                      SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
173
      bfd_vma cr_addr
174
        = bfd_get_32 (cranges->owner,
175
                      SH64_CRANGE_CR_ADDR_OFFSET
176
                      + (char *) found_rangep);
177
      bfd_size_type cr_size
178
        = bfd_get_32 (cranges->owner,
179
                      SH64_CRANGE_CR_SIZE_OFFSET
180
                      + (char *) found_rangep);
181
 
182
      rangep->cr_addr = cr_addr;
183
      rangep->cr_size = cr_size;
184
      rangep->cr_type = cr_type;
185
 
186
      return true;
187
    }
188
 
189
  /* There is a .cranges section, but it does not have a descriptor
190
     matching this address.  */
191
  return false;
192
 
193
error_return:
194
  free (cranges_contents);
195
  return false;
196
}
197
 
198
/* Determine what ADDR points to in SEC, and fill in a range descriptor in
199
   *RANGEP if it's non-NULL.  */
200
 
201
enum sh64_elf_cr_type
202
sh64_get_contents_type (sec, addr, rangep)
203
     asection *sec;
204
     bfd_vma addr;
205
     sh64_elf_crange *rangep;
206
{
207
  asection *cranges;
208
 
209
  /* Fill in the range with the boundaries of the section as a default.  */
210
  if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
211
      && elf_elfheader (sec->owner)->e_type == ET_EXEC)
212
    {
213
      rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
214
      rangep->cr_size = bfd_section_size (sec->owner, sec);
215
      rangep->cr_type = CRT_NONE;
216
    }
217
  else
218
    return false;
219
 
220
  /* If none of the pertinent bits are set, then it's a SHcompact (or at
221
     least not SHmedia).  */
222
  if ((elf_section_data (sec)->this_hdr.sh_flags
223
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
224
    {
225
      enum sh64_elf_cr_type cr_type
226
        = ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
227
           ? CRT_SH5_ISA16 : CRT_DATA);
228
      rangep->cr_type = cr_type;
229
      return cr_type;
230
    }
231
 
232
  /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia.  */
233
  if ((elf_section_data (sec)->this_hdr.sh_flags
234
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
235
    {
236
      rangep->cr_type = CRT_SH5_ISA32;
237
      return CRT_SH5_ISA32;
238
    }
239
 
240
  /* Otherwise, we have to look up the .cranges section.  */
241
  cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);
242
 
243
  if (cranges == NULL)
244
    /* A mixed section but there's no .cranges section.  This is probably
245
       bad input; it does not comply to specs.  */
246
    return CRT_NONE;
247
 
248
  /* If this call fails, we will still have CRT_NONE in rangep->cr_type
249
     and that will be suitable to return.  */
250
  sh64_address_in_cranges (cranges, addr, rangep);
251
 
252
  return rangep->cr_type;
253
}
254
 
255
/* This is a simpler exported interface for the benefit of gdb et al.  */
256
 
257
boolean
258
sh64_address_is_shmedia (sec, addr)
259
     asection *sec;
260
     bfd_vma addr;
261
{
262
  sh64_elf_crange dummy;
263
  return sh64_get_contents_type (sec, addr, &dummy) == CRT_SH5_ISA32;
264
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.