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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [mach-o-i386.c] - Blame information for rev 303

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* Intel i386 Mach-O support for BFD.
2
   Copyright 2009
3
   Free Software Foundation, Inc.
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; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "mach-o.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "libiberty.h"
27 161 khays
#include "mach-o/reloc.h"
28 14 khays
 
29
#define bfd_mach_o_object_p bfd_mach_o_i386_object_p
30
#define bfd_mach_o_core_p bfd_mach_o_i386_core_p
31
#define bfd_mach_o_mkobject bfd_mach_o_i386_mkobject
32
 
33
static const bfd_target *
34
bfd_mach_o_i386_object_p (bfd *abfd)
35
{
36
  return bfd_mach_o_header_p (abfd, 0, BFD_MACH_O_CPU_TYPE_I386);
37
}
38
 
39
static const bfd_target *
40
bfd_mach_o_i386_core_p (bfd *abfd)
41
{
42
  return bfd_mach_o_header_p (abfd,
43
                              BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_I386);
44
}
45
 
46
static bfd_boolean
47
bfd_mach_o_i386_mkobject (bfd *abfd)
48
{
49
  bfd_mach_o_data_struct *mdata;
50
 
51
  if (!bfd_mach_o_mkobject_init (abfd))
52
    return FALSE;
53
 
54
  mdata = bfd_mach_o_get_data (abfd);
55
  mdata->header.magic = BFD_MACH_O_MH_MAGIC;
56
  mdata->header.cputype = BFD_MACH_O_CPU_TYPE_I386;
57
  mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_X86_ALL;
58
  mdata->header.byteorder = BFD_ENDIAN_LITTLE;
59
  mdata->header.version = 1;
60
 
61
  return TRUE;
62
}
63
 
64
static reloc_howto_type i386_howto_table[]=
65
{
66 166 khays
  /* 0 */
67 14 khays
  HOWTO(BFD_RELOC_32, 0, 2, 32, FALSE, 0,
68
        complain_overflow_bitfield,
69
        NULL, "32",
70
        FALSE, 0xffffffff, 0xffffffff, FALSE),
71
  HOWTO(BFD_RELOC_16, 0, 1, 16, FALSE, 0,
72
        complain_overflow_bitfield,
73
        NULL, "16",
74
        FALSE, 0xffff, 0xffff, FALSE),
75
  HOWTO(BFD_RELOC_8, 0, 0, 8, FALSE, 0,
76
        complain_overflow_bitfield,
77
        NULL, "8",
78
        FALSE, 0xff, 0xff, FALSE),
79
  HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0,
80
        complain_overflow_bitfield,
81
        NULL, "DISP32",
82
        FALSE, 0xffffffff, 0xffffffff, TRUE),
83 166 khays
  /* 4 */
84 14 khays
  HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0,
85
        complain_overflow_bitfield,
86
        NULL, "DISP16",
87
        FALSE, 0xffff, 0xffff, TRUE),
88
  HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, FALSE, 0,
89
        complain_overflow_bitfield,
90
        NULL, "SECTDIFF_32",
91
        FALSE, 0xffffffff, 0xffffffff, FALSE),
92 166 khays
  HOWTO(BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 2, 32, FALSE, 0,
93
        complain_overflow_bitfield,
94
        NULL, "LSECTDIFF_32",
95
        FALSE, 0xffffffff, 0xffffffff, FALSE),
96 14 khays
  HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 2, 32, FALSE, 0,
97
        complain_overflow_bitfield,
98
        NULL, "PAIR_32",
99
        FALSE, 0xffffffff, 0xffffffff, FALSE),
100 166 khays
  /* 8 */
101
  HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 1, 16, FALSE, 0,
102
        complain_overflow_bitfield,
103
        NULL, "SECTDIFF_16",
104
        FALSE, 0xffff, 0xffff, FALSE),
105
  HOWTO(BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 1, 16, FALSE, 0,
106
        complain_overflow_bitfield,
107
        NULL, "LSECTDIFF_16",
108
        FALSE, 0xffff, 0xffff, FALSE),
109
  HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 1, 16, FALSE, 0,
110
        complain_overflow_bitfield,
111
        NULL, "PAIR_16",
112
        FALSE, 0xffff, 0xffff, FALSE),
113 14 khays
};
114
 
115
static bfd_boolean
116
bfd_mach_o_i386_swap_reloc_in (arelent *res, bfd_mach_o_reloc_info *reloc)
117
{
118
  if (reloc->r_scattered)
119
    {
120
      switch (reloc->r_type)
121
        {
122
        case BFD_MACH_O_GENERIC_RELOC_PAIR:
123 166 khays
          if (reloc->r_length == 2)
124
            {
125
              res->howto = &i386_howto_table[7];
126
              res->address = res[-1].address;
127
              return TRUE;
128
            }
129
          else if (reloc->r_length == 1)
130
            {
131
              res->howto = &i386_howto_table[10];
132
              res->address = res[-1].address;
133
              return TRUE;
134
            }
135
          return FALSE;
136 14 khays
        case BFD_MACH_O_GENERIC_RELOC_SECTDIFF:
137 166 khays
          if (reloc->r_length == 2)
138
            {
139
              res->howto = &i386_howto_table[5];
140
              return TRUE;
141
            }
142
          else if (reloc->r_length == 1)
143
            {
144
              res->howto = &i386_howto_table[8];
145
              return TRUE;
146
            }
147
          return FALSE;
148 14 khays
        case BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF:
149 166 khays
          if (reloc->r_length == 2)
150
            {
151
              res->howto = &i386_howto_table[6];
152
              return TRUE;
153
            }
154
          else if (reloc->r_length == 1)
155
            {
156
              res->howto = &i386_howto_table[9];
157
              return TRUE;
158
            }
159
          return FALSE;
160 14 khays
        default:
161
          return FALSE;
162
        }
163
    }
164
  else
165
    {
166
      switch (reloc->r_type)
167
        {
168
        case BFD_MACH_O_GENERIC_RELOC_VANILLA:
169
          switch ((reloc->r_length << 1) | reloc->r_pcrel)
170
            {
171
            case 0: /* len = 0, pcrel = 0  */
172
              res->howto = &i386_howto_table[2];
173
              return TRUE;
174
            case 2: /* len = 1, pcrel = 0  */
175
              res->howto = &i386_howto_table[1];
176
              return TRUE;
177
            case 3: /* len = 1, pcrel = 1  */
178
              res->howto = &i386_howto_table[4];
179
              return TRUE;
180
            case 4: /* len = 2, pcrel = 0  */
181
              res->howto = &i386_howto_table[0];
182
              return TRUE;
183
            case 5: /* len = 2, pcrel = 1  */
184
              res->howto = &i386_howto_table[3];
185
              return TRUE;
186
            default:
187
              return FALSE;
188
            }
189
          break;
190
        default:
191
          return FALSE;
192
        }
193
    }
194
}
195
 
196
static bfd_boolean
197
bfd_mach_o_i386_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
198
{
199
  rinfo->r_address = rel->address;
200
  switch (rel->howto->type)
201
    {
202
    case BFD_RELOC_32:
203
    case BFD_RELOC_32_PCREL:
204
    case BFD_RELOC_16:
205
    case BFD_RELOC_16_PCREL:
206
    case BFD_RELOC_8:
207
      rinfo->r_scattered = 0;
208
      rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_VANILLA;
209
      rinfo->r_pcrel = rel->howto->pc_relative;
210
      rinfo->r_length = rel->howto->size; /* Correct in practice.  */
211
      if ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
212
        {
213
          rinfo->r_extern = 0;
214
          rinfo->r_value = (*rel->sym_ptr_ptr)->section->target_index;
215
        }
216
      else
217
        {
218
          rinfo->r_extern = 1;
219
          rinfo->r_value = (*rel->sym_ptr_ptr)->udata.i;
220
        }
221
      break;
222
    case BFD_RELOC_MACH_O_SECTDIFF:
223
      rinfo->r_scattered = 1;
224
      rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_SECTDIFF;
225
      rinfo->r_pcrel = 0;
226 166 khays
      rinfo->r_length = rel->howto->size;
227 14 khays
      rinfo->r_extern = 0;
228 166 khays
      rinfo->r_value = rel->addend;
229 14 khays
      break;
230 166 khays
    case BFD_RELOC_MACH_O_LOCAL_SECTDIFF:
231
      rinfo->r_scattered = 1;
232
      rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF;
233
      rinfo->r_pcrel = 0;
234
      rinfo->r_length = rel->howto->size;
235
      rinfo->r_extern = 0;
236
      rinfo->r_value = rel->addend;
237
      break;
238 14 khays
    case BFD_RELOC_MACH_O_PAIR:
239
      rinfo->r_address = 0;
240
      rinfo->r_scattered = 1;
241
      rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_PAIR;
242
      rinfo->r_pcrel = 0;
243 166 khays
      rinfo->r_length = rel->howto->size;
244 14 khays
      rinfo->r_extern = 0;
245 166 khays
      rinfo->r_value = rel->addend;
246 14 khays
      break;
247
    default:
248
      return FALSE;
249
    }
250
  return TRUE;
251
}
252
 
253
static reloc_howto_type *
254
bfd_mach_o_i386_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
255
                                       bfd_reloc_code_real_type code)
256
{
257
  unsigned int i;
258
 
259
  for (i = 0; i < sizeof (i386_howto_table) / sizeof (*i386_howto_table); i++)
260
    if (code == i386_howto_table[i].type)
261
      return &i386_howto_table[i];
262
  return NULL;
263
}
264
 
265
static reloc_howto_type *
266
bfd_mach_o_i386_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
267
                                       const char *name ATTRIBUTE_UNUSED)
268
{
269
  return NULL;
270
}
271
 
272
static bfd_boolean
273
bfd_mach_o_i386_print_thread (bfd *abfd, bfd_mach_o_thread_flavour *thread,
274
                              void *vfile, char *buf)
275
{
276
  FILE *file = (FILE *)vfile;
277
 
278
  switch (thread->flavour)
279
    {
280
    case BFD_MACH_O_x86_THREAD_STATE:
281
      if (thread->size < (8 + 16 * 4))
282
        return FALSE;
283
      fprintf (file, "   x86_THREAD_STATE:\n");
284
      fprintf (file, "    flavor: 0x%08lx  count: 0x%08lx\n",
285
               (unsigned long)bfd_get_32 (abfd, buf + 0),
286
               (unsigned long)bfd_get_32 (abfd, buf + 4));
287
      fprintf (file, "     eax: %08lx  ebx: %08lx  ecx: %08lx  edx: %08lx\n",
288
               (unsigned long)bfd_get_32 (abfd, buf + 8),
289
               (unsigned long)bfd_get_32 (abfd, buf + 12),
290
               (unsigned long)bfd_get_32 (abfd, buf + 16),
291
               (unsigned long)bfd_get_32 (abfd, buf + 20));
292
      fprintf (file, "     edi: %08lx  esi: %08lx  ebp: %08lx  esp: %08lx\n",
293
               (unsigned long)bfd_get_32 (abfd, buf + 24),
294
               (unsigned long)bfd_get_32 (abfd, buf + 28),
295
               (unsigned long)bfd_get_32 (abfd, buf + 32),
296
               (unsigned long)bfd_get_32 (abfd, buf + 36));
297
      fprintf (file, "      ss: %08lx  flg: %08lx  eip: %08lx   cs: %08lx\n",
298
               (unsigned long)bfd_get_32 (abfd, buf + 40),
299
               (unsigned long)bfd_get_32 (abfd, buf + 44),
300
               (unsigned long)bfd_get_32 (abfd, buf + 48),
301
               (unsigned long)bfd_get_32 (abfd, buf + 52));
302
      fprintf (file, "      ds: %08lx   es: %08lx   fs: %08lx   gs: %08lx\n",
303
               (unsigned long)bfd_get_32 (abfd, buf + 56),
304
               (unsigned long)bfd_get_32 (abfd, buf + 60),
305
               (unsigned long)bfd_get_32 (abfd, buf + 64),
306
               (unsigned long)bfd_get_32 (abfd, buf + 68));
307
      return TRUE;
308
    case BFD_MACH_O_x86_FLOAT_STATE:
309
      if (thread->size < 8)
310
        return FALSE;
311
      fprintf (file, "   x86_FLOAT_STATE:\n");
312
      fprintf (file, "    flavor: 0x%08lx  count: 0x%08lx\n",
313
               (unsigned long)bfd_get_32 (abfd, buf + 0),
314
               (unsigned long)bfd_get_32 (abfd, buf + 4));
315
      return TRUE;
316
    case BFD_MACH_O_x86_EXCEPTION_STATE:
317
      if (thread->size < 8 + 3 * 4)
318
        return FALSE;
319
      fprintf (file, "   x86_EXCEPTION_STATE:\n");
320
      fprintf (file, "    flavor: 0x%08lx  count: 0x%08lx\n",
321
               (unsigned long)bfd_get_32 (abfd, buf + 0),
322
               (unsigned long)bfd_get_32 (abfd, buf + 4));
323
      fprintf (file, "    trapno: %08lx  err: %08lx  faultaddr: %08lx\n",
324
               (unsigned long)bfd_get_32 (abfd, buf + 8),
325
               (unsigned long)bfd_get_32 (abfd, buf + 12),
326
               (unsigned long)bfd_get_32 (abfd, buf + 16));
327
      return TRUE;
328
    default:
329
      break;
330
    }
331
  return FALSE;
332
}
333
 
334 166 khays
static const mach_o_section_name_xlat text_section_names_xlat[] =
335
  {
336
    {   ".symbol_stub",                 "__symbol_stub",
337
        SEC_CODE | SEC_LOAD,            BFD_MACH_O_S_SYMBOL_STUBS,
338
        BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
339
                                        0},
340
    {   ".picsymbol_stub",              "__picsymbol_stub",
341
        SEC_CODE | SEC_LOAD,            BFD_MACH_O_S_SYMBOL_STUBS,
342
        BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
343
                                        0},
344
    { NULL, NULL, 0, 0, 0, 0}
345
  };
346
 
347
static const mach_o_section_name_xlat data_section_names_xlat[] =
348
  {
349
    /* The first two are recognized by i386, but not emitted for x86 by
350
       modern GCC.  */
351
    {   ".non_lazy_symbol_pointer",     "__nl_symbol_ptr",
352
        SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
353
        BFD_MACH_O_S_ATTR_NONE,         2},
354
    {   ".lazy_symbol_pointer",         "__la_symbol_ptr",
355
        SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
356
        BFD_MACH_O_S_ATTR_NONE,         2},
357
    {   ".lazy_symbol_pointer2",        "__la_sym_ptr2",
358
        SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
359
        BFD_MACH_O_S_ATTR_NONE,         2},
360
    {   ".lazy_symbol_pointer3",        "__la_sym_ptr3",
361
        SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
362
        BFD_MACH_O_S_ATTR_NONE,         2},
363
    { NULL, NULL, 0, 0, 0, 0}
364
  };
365
 
366
static const mach_o_section_name_xlat import_section_names_xlat[] =
367
  {
368
    {   ".picsymbol_stub3",             "__jump_table",
369
        SEC_CODE | SEC_LOAD,            BFD_MACH_O_S_SYMBOL_STUBS,
370
        BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
371
        | BFD_MACH_O_S_SELF_MODIFYING_CODE,
372
                                        6},
373
    {   ".non_lazy_symbol_pointer_x86", "__pointers",
374
        SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
375
        BFD_MACH_O_S_ATTR_NONE,         2},
376
    { NULL, NULL, 0, 0, 0, 0}
377
  };
378
 
379
const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] =
380
  {
381
    { "__TEXT", text_section_names_xlat },
382
    { "__DATA", data_section_names_xlat },
383
    { "__IMPORT", import_section_names_xlat },
384
    { NULL, NULL }
385
  };
386
 
387 14 khays
#define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in
388
#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out
389
#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread
390
 
391 166 khays
#define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat
392
#define bfd_mach_o_section_type_valid_for_tgt NULL
393
 
394 14 khays
#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup 
395
#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup
396
 
397
#define TARGET_NAME             mach_o_i386_vec
398
#define TARGET_STRING           "mach-o-i386"
399
#define TARGET_ARCHITECTURE     bfd_arch_i386
400
#define TARGET_BIG_ENDIAN       0
401
#define TARGET_ARCHIVE          0
402 166 khays
#define TARGET_PRIORITY         0
403 14 khays
#include "mach-o-target.c"

powered by: WebSVN 2.1.0

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