daily update
[external/binutils.git] / bfd / aout-tic30.c
1 /* BFD back-end for TMS320C30 a.out binaries.
2    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
3    Free Software Foundation, Inc.
4    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
5
6    This file is part of BFD, the Binary File Descriptor library.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22
23 #define TARGET_IS_BIG_ENDIAN_P
24 #define N_HEADER_IN_TEXT(x)     1
25 #define TEXT_START_ADDR         1024
26 #define TARGET_PAGE_SIZE        128
27 #define SEGMENT_SIZE            TARGET_PAGE_SIZE
28 #define DEFAULT_ARCH            bfd_arch_tic30
29 #define ARCH_SIZE 32
30
31 /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
32    remove whitespace added here, and thus will fail to concatenate
33    the tokens.  */
34 #define MY(OP) CONCAT2 (tic30_aout_,OP)
35 #define TARGETNAME "a.out-tic30"
36 #define NAME(x,y) CONCAT3 (tic30_aout,_32_,y)
37
38 #include "sysdep.h"
39 #include "bfd.h"
40 #include "libaout.h"
41 #include "aout/aout64.h"
42 #include "aout/stab_gnu.h"
43 #include "aout/ar.h"
44
45 #define MY_reloc_howto(BFD, REL, IN, EX, PC)   tic30_aout_reloc_howto (BFD, REL, & IN, & EX, & PC)
46
47 #define MY_final_link_relocate    tic30_aout_final_link_relocate
48 #define MY_object_p               tic30_aout_object_p
49 #define MY_mkobject               NAME (aout,mkobject)
50 #define MY_write_object_contents  tic30_aout_write_object_contents
51 #define MY_set_sizes              tic30_aout_set_sizes
52
53 #ifndef MY_exec_hdr_flags
54 #define MY_exec_hdr_flags 1
55 #endif
56
57 #ifndef MY_backend_data
58
59 #ifndef MY_zmagic_contiguous
60 #define MY_zmagic_contiguous 0
61 #endif
62 #ifndef MY_text_includes_header
63 #define MY_text_includes_header 0
64 #endif
65 #ifndef MY_entry_is_text_address
66 #define MY_entry_is_text_address 0
67 #endif
68 #ifndef MY_exec_header_not_counted
69 #define MY_exec_header_not_counted 1
70 #endif
71 #ifndef MY_add_dynamic_symbols
72 #define MY_add_dynamic_symbols 0
73 #endif
74 #ifndef MY_add_one_symbol
75 #define MY_add_one_symbol 0
76 #endif
77 #ifndef MY_link_dynamic_object
78 #define MY_link_dynamic_object 0
79 #endif
80 #ifndef MY_write_dynamic_symbol
81 #define MY_write_dynamic_symbol 0
82 #endif
83 #ifndef MY_check_dynamic_reloc
84 #define MY_check_dynamic_reloc 0
85 #endif
86 #ifndef MY_finish_dynamic_link
87 #define MY_finish_dynamic_link 0
88 #endif
89
90 static bfd_boolean
91 tic30_aout_set_sizes (bfd *abfd)
92 {
93   adata (abfd).page_size = TARGET_PAGE_SIZE;
94
95 #ifdef SEGMENT_SIZE
96   adata (abfd).segment_size = SEGMENT_SIZE;
97 #else
98   adata (abfd).segment_size = TARGET_PAGE_SIZE;
99 #endif
100
101 #ifdef ZMAGIC_DISK_BLOCK_SIZE
102   adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
103 #else
104   adata (abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE;
105 #endif
106
107   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
108
109   return TRUE;
110 }
111
112 static const struct aout_backend_data tic30_aout_backend_data =
113 {
114   MY_zmagic_contiguous,
115   MY_text_includes_header,
116   MY_entry_is_text_address,
117   MY_exec_hdr_flags,
118   0,                            /* Text vma?  */
119   MY_set_sizes,
120   MY_exec_header_not_counted,
121   MY_add_dynamic_symbols,
122   MY_add_one_symbol,
123   MY_link_dynamic_object,
124   MY_write_dynamic_symbol,
125   MY_check_dynamic_reloc,
126   MY_finish_dynamic_link
127 };
128 #define MY_backend_data &tic30_aout_backend_data
129 #endif
130
131 static reloc_howto_type *
132   tic30_aout_reloc_howto (bfd *, struct reloc_std_external *, int *, int *, int *);
133 static bfd_reloc_status_type
134   tic30_aout_final_link_relocate
135     (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
136
137 /* FIXME: This is wrong.  aoutx.h should really only be included by
138    aout32.c.  */
139
140 #include "aoutx.h"
141
142 /* This function is used to work out pc-relative offsets for the
143    TMS320C30.  The data already placed by md_pcrel_from within gas is
144    useless for a relocation, so we just get the offset value and place
145    a version of this within the object code.
146    tic30_aout_final_link_relocate will then calculate the required
147    relocation to add on to the value in the object code.  */
148
149 static bfd_reloc_status_type
150 tic30_aout_fix_pcrel_16 (bfd *abfd,
151                          arelent *reloc_entry,
152                          asymbol *symbol ATTRIBUTE_UNUSED,
153                          void * data,
154                          asection *input_section ATTRIBUTE_UNUSED,
155                          bfd *output_bfd ATTRIBUTE_UNUSED,
156                          char **error_message ATTRIBUTE_UNUSED)
157 {
158   bfd_vma relocation = 1;
159   bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1);
160
161   /* The byte before the location of the fix contains bits 23-16 of
162      the pcrel instruction.  Bit 21 is set for a delayed instruction
163      which requires on offset of 3 instead of 1.  */
164   if (offset_data & 0x20)
165     relocation -= 3;
166   else
167     relocation -= 1;
168   bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
169   return bfd_reloc_ok;
170 }
171
172 /* This function is used as a callback for 16-bit relocs.  This is
173    required for relocations between segments.  A line in aoutx.h
174    requires that any relocations for the data section should point to
175    the end of the aligned text section, plus an offset.  By default,
176    this does not happen, therefore this function takes care of
177    that.  */
178
179 static bfd_reloc_status_type
180 tic30_aout_fix_16 (bfd *abfd,
181                    arelent *reloc_entry,
182                    asymbol *symbol,
183                    void * data,
184                    asection *input_section ATTRIBUTE_UNUSED,
185                    bfd *output_bfd,
186                    char **error_message ATTRIBUTE_UNUSED)
187 {
188   bfd_vma relocation;
189
190   /* Make sure that the symbol's section is defined.  */
191   if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
192     return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
193   /* Get the size of the input section and turn it into the TMS320C30
194      32-bit address format.  */
195   relocation = (symbol->section->vma >> 2);
196   relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
197   bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
198   return bfd_reloc_ok;
199 }
200
201 /* This function does the same thing as tic30_aout_fix_16 except for 32
202    bit relocations.  */
203
204 static bfd_reloc_status_type
205 tic30_aout_fix_32 (bfd *abfd,
206                    arelent *reloc_entry,
207                    asymbol *symbol,
208                    void * data,
209                    asection *input_section ATTRIBUTE_UNUSED,
210                    bfd *output_bfd,
211                    char **error_message ATTRIBUTE_UNUSED)
212 {
213   bfd_vma relocation;
214
215   /* Make sure that the symbol's section is defined.  */
216   if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
217     return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
218   /* Get the size of the input section and turn it into the TMS320C30
219      32-bit address format.  */
220   relocation = (symbol->section->vma >> 2);
221   relocation += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
222   bfd_put_32 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
223   return bfd_reloc_ok;
224 }
225
226 /* This table lists the relocation types for the TMS320C30.  There are
227    only a few relocations required, and all must be divided by 4 (>>
228    2) to get the 32-bit addresses in the format the TMS320C30 likes
229    it.  */
230 reloc_howto_type tic30_aout_howto_table[] =
231 {
232   EMPTY_HOWTO (-1),
233   HOWTO (1, 2, 1, 16, FALSE, 0, 0, tic30_aout_fix_16,
234          "16", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE),
235   HOWTO (2, 2, 2, 24, FALSE, 0, complain_overflow_bitfield, NULL,
236          "24", FALSE, 0x00FFFFFF, 0x00FFFFFF, FALSE),
237   HOWTO (3, 18, 3, 24, FALSE, 0, complain_overflow_bitfield, NULL,
238          "LDP", FALSE, 0x00FF0000, 0x000000FF, FALSE),
239   HOWTO (4, 2, 4, 32, FALSE, 0, complain_overflow_bitfield, tic30_aout_fix_32,
240          "32", FALSE, 0xFFFFFFFF, 0xFFFFFFFF, FALSE),
241   HOWTO (5, 2, 1, 16, TRUE, 0, complain_overflow_signed,
242          tic30_aout_fix_pcrel_16, "PCREL", TRUE, 0x0000FFFF, 0x0000FFFF, TRUE),
243   EMPTY_HOWTO (-1),
244   EMPTY_HOWTO (-1),
245   EMPTY_HOWTO (-1),
246   EMPTY_HOWTO (-1),
247   EMPTY_HOWTO (-1)
248 };
249
250
251 static reloc_howto_type *
252 tic30_aout_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
253                               bfd_reloc_code_real_type code)
254 {
255   switch (code)
256     {
257     case BFD_RELOC_8:
258     case BFD_RELOC_TIC30_LDP:
259       return &tic30_aout_howto_table[3];
260     case BFD_RELOC_16:
261       return &tic30_aout_howto_table[1];
262     case BFD_RELOC_24:
263       return &tic30_aout_howto_table[2];
264     case BFD_RELOC_16_PCREL:
265       return &tic30_aout_howto_table[5];
266     case BFD_RELOC_32:
267       return &tic30_aout_howto_table[4];
268     default:
269       return NULL;
270     }
271 }
272
273 static reloc_howto_type *
274 tic30_aout_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
275                               const char *r_name)
276 {
277   unsigned int i;
278
279   for (i = 0;
280        i < (sizeof (tic30_aout_howto_table)
281             / sizeof (tic30_aout_howto_table[0]));
282        i++)
283     if (tic30_aout_howto_table[i].name != NULL
284         && strcasecmp (tic30_aout_howto_table[i].name, r_name) == 0)
285       return &tic30_aout_howto_table[i];
286
287   return NULL;
288 }
289
290 static reloc_howto_type *
291 tic30_aout_reloc_howto (bfd *abfd,
292                         struct reloc_std_external *relocs,
293                         int *r_index,
294                         int *r_extern,
295                         int *r_pcrel)
296 {
297   unsigned int r_length;
298   unsigned int r_pcrel_done;
299   int index;
300
301   *r_pcrel = 0;
302   if (bfd_header_big_endian (abfd))
303     {
304       *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]);
305       *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
306       r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
307       r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG);
308     }
309   else
310     {
311       *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]);
312       *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
313       r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
314       r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
315     }
316   index = r_length + 4 * r_pcrel_done;
317   return tic30_aout_howto_table + index;
318 }
319
320 /* These macros will get 24-bit values from the bfd definition.
321    Big-endian only.  */
322 #define bfd_getb_24(BFD,ADDR)                   \
323  (bfd_get_8 (BFD, ADDR    ) << 16) |            \
324  (bfd_get_8 (BFD, ADDR + 1) <<  8) |            \
325  (bfd_get_8 (BFD, ADDR + 2)      )
326
327 #define bfd_putb_24(BFD,DATA,ADDR)                              \
328  bfd_put_8 (BFD, (bfd_byte) ((DATA >> 16) & 0xFF), ADDR    );   \
329  bfd_put_8 (BFD, (bfd_byte) ((DATA >>  8) & 0xFF), ADDR + 1);   \
330  bfd_put_8 (BFD, (bfd_byte) ( DATA        & 0xFF), ADDR + 2)
331
332 /* Set parameters about this a.out file that are machine-dependent.
333    This routine is called from some_aout_object_p just before it returns.  */
334
335 static const bfd_target *
336 tic30_aout_callback (bfd *abfd)
337 {
338   struct internal_exec *execp = exec_hdr (abfd);
339   unsigned int arch_align_power;
340   unsigned long arch_align;
341
342   /* Calculate the file positions of the parts of a newly read aout header.  */
343   obj_textsec (abfd)->size = N_TXTSIZE (*execp);
344
345   /* The virtual memory addresses of the sections.  */
346   obj_textsec (abfd)->vma = N_TXTADDR (*execp);
347   obj_datasec (abfd)->vma = N_DATADDR (*execp);
348   obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
349
350   obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
351   obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
352   obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
353
354   /* The file offsets of the sections.  */
355   obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
356   obj_datasec (abfd)->filepos = N_DATOFF (*execp);
357
358   /* The file offsets of the relocation info.  */
359   obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
360   obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
361
362   /* The file offsets of the string table and symbol table.  */
363   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
364   obj_str_filepos (abfd) = N_STROFF (*execp);
365
366   /* Determine the architecture and machine type of the object file.  */
367 #ifdef SET_ARCH_MACH
368   SET_ARCH_MACH (abfd, *execp);
369 #else
370   bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0L);
371 #endif
372
373   /* Now that we know the architecture, set the alignments of the
374      sections.  This is normally done by NAME (aout,new_section_hook),
375      but when the initial sections were created the architecture had
376      not yet been set.  However, for backward compatibility, we don't
377      set the alignment power any higher than as required by the size
378      of the section.  */
379   arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
380   arch_align = 1 << arch_align_power;
381   if ((BFD_ALIGN (obj_textsec (abfd)->size, arch_align)
382        == obj_textsec (abfd)->size)
383       && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
384           == obj_datasec (abfd)->size)
385       && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
386           == obj_bsssec (abfd)->size))
387     {
388       obj_textsec (abfd)->alignment_power = arch_align_power;
389       obj_datasec (abfd)->alignment_power = arch_align_power;
390       obj_bsssec (abfd)->alignment_power = arch_align_power;
391     }
392   return abfd->xvec;
393 }
394
395 static bfd_reloc_status_type
396 tic30_aout_relocate_contents (reloc_howto_type *howto,
397                               bfd *input_bfd,
398                               bfd_vma relocation,
399                               bfd_byte *location)
400 {
401   bfd_vma x;
402   bfd_boolean overflow;
403
404   if (howto->size < 0)
405     relocation = -relocation;
406
407   switch (howto->size)
408     {
409     default:
410     case 0:
411       abort ();
412       break;
413     case 1:
414       x = bfd_get_16 (input_bfd, location);
415       break;
416     case 2:
417       x = bfd_getb_24 (input_bfd, location);
418       break;
419     case 3:
420       x = bfd_get_8 (input_bfd, location);
421       break;
422     case 4:
423       x = bfd_get_32 (input_bfd, location);
424       break;
425     }
426
427   overflow = FALSE;
428
429   if (howto->complain_on_overflow != complain_overflow_dont)
430     {
431       bfd_vma check;
432       bfd_signed_vma signed_check;
433       bfd_vma add;
434       bfd_signed_vma signed_add;
435
436       if (howto->rightshift == 0)
437         {
438           check = relocation;
439           signed_check = (bfd_signed_vma) relocation;
440         }
441       else
442         {
443           check = relocation >> howto->rightshift;
444           if ((bfd_signed_vma) relocation >= 0)
445             signed_check = check;
446           else
447             signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
448         }
449       add = x & howto->src_mask;
450       signed_add = add;
451       if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
452         signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
453       if (howto->bitpos == 0)
454         {
455           check += add;
456           signed_check += signed_add;
457         }
458       else
459         {
460           check += add >> howto->bitpos;
461           if (signed_add >= 0)
462             signed_check += add >> howto->bitpos;
463           else
464             signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos)));
465         }
466       switch (howto->complain_on_overflow)
467         {
468         case complain_overflow_signed:
469           {
470             bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
471             bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
472
473             if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
474               overflow = TRUE;
475           }
476           break;
477         case complain_overflow_unsigned:
478           {
479             bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
480
481             if (check > reloc_unsigned_max)
482               overflow = TRUE;
483           }
484           break;
485         case complain_overflow_bitfield:
486           {
487             bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
488
489             if ((check & ~reloc_bits) != 0
490                 && (((bfd_vma) signed_check & ~reloc_bits)
491                     != ((bfd_vma) -1 & ~reloc_bits)))
492               overflow = TRUE;
493           }
494           break;
495         default:
496           abort ();
497         }
498     }
499   relocation >>= (bfd_vma) howto->rightshift;
500   relocation <<= (bfd_vma) howto->bitpos;
501   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask));
502   switch (howto->size)
503     {
504     default:
505     case 0:
506       abort ();
507       break;
508     case 1:
509       bfd_put_16 (input_bfd, x, location);
510       break;
511     case 2:
512       bfd_putb_24 (input_bfd, x, location);
513       break;
514     case 3:
515       bfd_put_8 (input_bfd, x, location);
516       break;
517     case 4:
518       bfd_put_32 (input_bfd, x, location);
519       break;
520     }
521   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
522 }
523
524 static bfd_reloc_status_type
525 tic30_aout_final_link_relocate (reloc_howto_type *howto,
526                                 bfd *input_bfd,
527                                 asection *input_section,
528                                 bfd_byte *contents,
529                                 bfd_vma address,
530                                 bfd_vma value,
531                                 bfd_vma addend)
532 {
533   bfd_vma relocation;
534
535   if (address > bfd_get_section_limit (input_bfd, input_section))
536     return bfd_reloc_outofrange;
537
538   relocation = value + addend;
539   if (howto->pc_relative)
540     {
541       relocation -= (input_section->output_section->vma + input_section->output_offset);
542       if (howto->pcrel_offset)
543         relocation -= address;
544     }
545   return tic30_aout_relocate_contents (howto, input_bfd, relocation,
546                                        contents + address);
547 }
548
549 /* Finish up the reading of an a.out file header.  */
550
551 static const bfd_target *
552 tic30_aout_object_p (bfd *abfd)
553 {
554   struct external_exec exec_bytes;      /* Raw exec header from file.  */
555   struct internal_exec exec;            /* Cleaned-up exec header.  */
556   const bfd_target *target;
557   bfd_size_type amt = EXEC_BYTES_SIZE;
558
559   if (bfd_bread (& exec_bytes, amt, abfd) != amt)
560     {
561       if (bfd_get_error () != bfd_error_system_call)
562         bfd_set_error (bfd_error_wrong_format);
563       return 0;
564     }
565
566 #ifdef SWAP_MAGIC
567   exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
568 #else
569   exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
570 #endif /* SWAP_MAGIC */
571
572   if (N_BADMAG (exec))
573     return 0;
574 #ifdef MACHTYPE_OK
575   if (!(MACHTYPE_OK (N_MACHTYPE (exec))))
576     return 0;
577 #endif
578
579   NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec);
580
581 #ifdef SWAP_MAGIC
582   /* Swap_exec_header_in read in a_info with the wrong byte order.  */
583   exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
584 #endif
585
586   target = NAME (aout, some_aout_object_p) (abfd, &exec, tic30_aout_callback);
587
588 #ifdef ENTRY_CAN_BE_ZERO
589   /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
590      means that it isn't obvious if EXEC_P should be set.
591      All of the following must be true for an executable:
592      There must be no relocations, the bfd can be neither an
593      archive nor an archive element, and the file must be executable.  */
594
595   if (exec.a_trsize + exec.a_drsize == 0
596       && bfd_get_format (abfd) == bfd_object && abfd->my_archive == NULL)
597     {
598       struct stat buf;
599 #ifndef S_IXUSR
600 #define S_IXUSR 0100            /* Execute by owner.  */
601 #endif
602       if (stat (abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
603         abfd->flags |= EXEC_P;
604     }
605 #endif
606
607   return target;
608 }
609
610 /* Copy private section data.  This actually does nothing with the
611    sections.  It copies the subformat field.  We copy it here, because
612    we need to know whether this is a QMAGIC file before we set the
613    section contents, and copy_private_bfd_data is not called until
614    after the section contents have been set.  */
615
616 static bfd_boolean
617 MY_bfd_copy_private_section_data (bfd *ibfd,
618                                   asection *isec ATTRIBUTE_UNUSED,
619                                   bfd *obfd,
620                                   asection *osec ATTRIBUTE_UNUSED)
621 {
622   if (bfd_get_flavour (obfd) == bfd_target_aout_flavour)
623     obj_aout_subformat (obfd) = obj_aout_subformat (ibfd);
624   return TRUE;
625 }
626
627 /* Write an object file.
628    Section contents have already been written.  We write the
629    file header, symbols, and relocation.  */
630
631 static bfd_boolean
632 tic30_aout_write_object_contents (bfd *abfd)
633 {
634   struct external_exec exec_bytes;
635   struct internal_exec *execp = exec_hdr (abfd);
636
637   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
638
639   {
640     bfd_size_type text_size;    /* Dummy vars.  */
641     file_ptr text_end;
642
643     if (adata (abfd).magic == undecided_magic)
644       NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
645
646     execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
647     execp->a_entry = bfd_get_start_address (abfd);
648
649     execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * obj_reloc_entry_size (abfd));
650     execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * obj_reloc_entry_size (abfd));
651     NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes);
652
653     if (adata (abfd).exec_bytes_size > 0)
654       {
655         bfd_size_type amt;
656
657         if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
658           return FALSE;
659         amt = adata (abfd).exec_bytes_size;
660         if (bfd_bwrite (& exec_bytes, amt, abfd) != amt)
661           return FALSE;
662       }
663
664     /* Now write out reloc info, followed by syms and strings.  */
665     if (bfd_get_outsymbols (abfd) != (asymbol **) NULL
666         && bfd_get_symcount (abfd) != 0)
667       {
668         if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*execp)), SEEK_SET) != 0)
669           return FALSE;
670
671         if (!NAME (aout, write_syms) (abfd))
672           return FALSE;
673       }
674
675     if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0)
676       return FALSE;
677     if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd)))
678       return FALSE;
679
680     if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0)
681       return FALSE;
682     if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
683       return FALSE;
684   }
685
686   return TRUE;
687 }
688
689 #ifndef MY_final_link_callback
690
691 /* Callback for the final_link routine to set the section offsets.  */
692
693 static void
694 MY_final_link_callback (bfd *abfd,
695                         file_ptr *ptreloff,
696                         file_ptr *pdreloff,
697                         file_ptr *psymoff)
698 {
699   struct internal_exec *execp = exec_hdr (abfd);
700
701   *ptreloff = obj_datasec (abfd)->filepos + execp->a_data;
702   *pdreloff = *ptreloff + execp->a_trsize;
703   *psymoff = *pdreloff + execp->a_drsize;;
704 }
705
706 #endif
707
708 #ifndef MY_bfd_final_link
709
710 /* Final link routine.  We need to use a call back to get the correct
711    offsets in the output file.  */
712
713 static bfd_boolean
714 MY_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
715 {
716   struct internal_exec *execp = exec_hdr (abfd);
717   file_ptr pos;
718   bfd_vma vma = 0;
719   int pad;
720
721   /* Set the executable header size to 0, as we don't want one for an
722      output.  */
723   adata (abfd).exec_bytes_size = 0;
724   pos = adata (abfd).exec_bytes_size;
725   /* Text.  */
726   vma = info->create_object_symbols_section->vma;
727   pos += vma;
728   obj_textsec (abfd)->filepos = pos;
729   obj_textsec (abfd)->vma = vma;
730   obj_textsec (abfd)->user_set_vma = 1;
731   pos += obj_textsec (abfd)->size;
732   vma += obj_textsec (abfd)->size;
733
734   /* Data.  */
735   if (abfd->flags & D_PAGED)
736     {
737       if (info->create_object_symbols_section->next->vma > 0)
738         obj_datasec (abfd)->vma = info->create_object_symbols_section->next->vma;
739       else
740         obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
741     }
742   else
743     obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
744
745   if (obj_datasec (abfd)->vma < vma)
746     obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
747
748   obj_datasec (abfd)->user_set_vma = 1;
749   vma = obj_datasec (abfd)->vma;
750   obj_datasec (abfd)->filepos = vma + adata (abfd).exec_bytes_size;
751   execp->a_text = vma - obj_textsec (abfd)->vma;
752   obj_textsec (abfd)->size = execp->a_text;
753
754   /* Since BSS follows data immediately, see if it needs alignment.  */
755   vma += obj_datasec (abfd)->size;
756   pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
757   obj_datasec (abfd)->size += pad;
758   pos += obj_datasec (abfd)->size;
759   execp->a_data = obj_datasec (abfd)->size;
760
761   /* BSS.  */
762   obj_bsssec (abfd)->vma = vma;
763   obj_bsssec (abfd)->user_set_vma = 1;
764
765   /* We are fully resized, so don't readjust in final_link.  */
766   adata (abfd).magic = z_magic;
767
768   return NAME (aout, final_link) (abfd, info, MY_final_link_callback);
769 }
770
771 #endif
772
773 static enum machine_type
774 tic30_aout_machine_type (enum bfd_architecture arch,
775                          unsigned long machine ATTRIBUTE_UNUSED,
776                          bfd_boolean *unknown)
777 {
778   enum machine_type arch_flags;
779
780   arch_flags = M_UNKNOWN;
781   *unknown = TRUE;
782
783   switch (arch)
784     {
785     case bfd_arch_tic30:
786       *unknown = FALSE;
787       break;
788     default:
789       arch_flags = M_UNKNOWN;
790     }
791   if (arch_flags != M_UNKNOWN)
792     *unknown = FALSE;
793   return arch_flags;
794 }
795
796 static bfd_boolean
797 tic30_aout_set_arch_mach (bfd *abfd,
798                           enum bfd_architecture arch,
799                           unsigned long machine)
800 {
801   if (!bfd_default_set_arch_mach (abfd, arch, machine))
802     return FALSE;
803   if (arch != bfd_arch_unknown)
804     {
805       bfd_boolean unknown;
806       tic30_aout_machine_type (arch, machine, &unknown);
807       if (unknown)
808         return FALSE;
809     }
810   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
811   return (*aout_backend_info (abfd)->set_sizes) (abfd);
812 }
813
814 /* We assume BFD generic archive files.  */
815 #ifndef MY_openr_next_archived_file
816 #define MY_openr_next_archived_file     bfd_generic_openr_next_archived_file
817 #endif
818 #ifndef MY_get_elt_at_index
819 #define MY_get_elt_at_index             _bfd_generic_get_elt_at_index
820 #endif
821 #ifndef MY_generic_stat_arch_elt
822 #define MY_generic_stat_arch_elt        bfd_generic_stat_arch_elt
823 #endif
824 #ifndef MY_slurp_armap
825 #define MY_slurp_armap                  bfd_slurp_bsd_armap
826 #endif
827 #ifndef MY_slurp_extended_name_table
828 #define MY_slurp_extended_name_table    _bfd_slurp_extended_name_table
829 #endif
830 #ifndef MY_construct_extended_name_table
831 #define MY_construct_extended_name_table \
832   _bfd_archive_bsd_construct_extended_name_table
833 #endif
834 #ifndef MY_write_armap
835 #define MY_write_armap                  bsd_write_armap
836 #endif
837 #ifndef MY_read_ar_hdr
838 #define MY_read_ar_hdr                  _bfd_generic_read_ar_hdr
839 #endif
840 #ifndef MY_truncate_arname
841 #define MY_truncate_arname              bfd_bsd_truncate_arname
842 #endif
843 #ifndef MY_update_armap_timestamp
844 #define MY_update_armap_timestamp       _bfd_archive_bsd_update_armap_timestamp
845 #endif
846
847 /* No core file defined here -- configure in trad-core.c separately.  */
848 #ifndef MY_core_file_failing_command
849 #define MY_core_file_failing_command    _bfd_nocore_core_file_failing_command
850 #endif
851 #ifndef MY_core_file_failing_signal
852 #define MY_core_file_failing_signal     _bfd_nocore_core_file_failing_signal
853 #endif
854 #ifndef MY_core_file_matches_executable_p
855 #define MY_core_file_matches_executable_p       \
856                                 _bfd_nocore_core_file_matches_executable_p
857 #endif
858 #ifndef MY_core_file_p
859 #define MY_core_file_p                  _bfd_dummy_target
860 #endif
861
862 #ifndef MY_bfd_debug_info_start
863 #define MY_bfd_debug_info_start         bfd_void
864 #endif
865 #ifndef MY_bfd_debug_info_end
866 #define MY_bfd_debug_info_end           bfd_void
867 #endif
868 #ifndef MY_bfd_debug_info_accumulate
869 #define MY_bfd_debug_info_accumulate    \
870                 (void (*) (bfd*, struct bfd_section *)) bfd_void
871 #endif
872
873 #ifndef MY_core_file_failing_command
874 #define MY_core_file_failing_command NAME (aout, core_file_failing_command)
875 #endif
876 #ifndef MY_core_file_failing_signal
877 #define MY_core_file_failing_signal NAME (aout, core_file_failing_signal)
878 #endif
879 #ifndef MY_core_file_matches_executable_p
880 #define MY_core_file_matches_executable_p NAME (aout, core_file_matches_executable_p)
881 #endif
882 #ifndef MY_set_section_contents
883 #define MY_set_section_contents NAME (aout, set_section_contents)
884 #endif
885 #ifndef MY_get_section_contents
886 #define MY_get_section_contents aout_32_get_section_contents
887 #endif
888 #ifndef MY_get_section_contents_in_window
889 #define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
890 #endif
891 #ifndef MY_new_section_hook
892 #define MY_new_section_hook NAME (aout, new_section_hook)
893 #endif
894 #ifndef MY_get_symtab_upper_bound
895 #define MY_get_symtab_upper_bound NAME (aout, get_symtab_upper_bound)
896 #endif
897 #ifndef MY_canonicalize_symtab
898 #define MY_canonicalize_symtab NAME (aout, canonicalize_symtab)
899 #endif
900 #ifndef MY_get_reloc_upper_bound
901 #define MY_get_reloc_upper_bound NAME (aout, get_reloc_upper_bound)
902 #endif
903 #ifndef MY_canonicalize_reloc
904 #define MY_canonicalize_reloc NAME (aout, canonicalize_reloc)
905 #endif
906 #ifndef MY_make_empty_symbol
907 #define MY_make_empty_symbol NAME (aout, make_empty_symbol)
908 #endif
909 #ifndef MY_print_symbol
910 #define MY_print_symbol NAME (aout, print_symbol)
911 #endif
912 #ifndef MY_get_symbol_info
913 #define MY_get_symbol_info NAME (aout, get_symbol_info)
914 #endif
915 #ifndef MY_get_lineno
916 #define MY_get_lineno NAME (aout, get_lineno)
917 #endif
918 #ifndef MY_set_arch_mach
919 #define MY_set_arch_mach tic30_aout_set_arch_mach
920 #endif
921 #ifndef MY_find_nearest_line
922 #define MY_find_nearest_line NAME (aout, find_nearest_line)
923 #endif
924 #ifndef MY_find_inliner_info
925 #define MY_find_inliner_info _bfd_nosymbols_find_inliner_info
926 #endif
927 #ifndef MY_sizeof_headers
928 #define MY_sizeof_headers NAME (aout, sizeof_headers)
929 #endif
930 #ifndef MY_bfd_get_relocated_section_contents
931 #define MY_bfd_get_relocated_section_contents \
932                         bfd_generic_get_relocated_section_contents
933 #endif
934 #ifndef MY_bfd_relax_section
935 #define MY_bfd_relax_section bfd_generic_relax_section
936 #endif
937 #ifndef MY_bfd_gc_sections
938 #define MY_bfd_gc_sections bfd_generic_gc_sections
939 #endif
940 #ifndef MY_bfd_merge_sections
941 #define MY_bfd_merge_sections bfd_generic_merge_sections
942 #endif
943 #ifndef MY_bfd_is_group_section
944 #define MY_bfd_is_group_section bfd_generic_is_group_section
945 #endif
946 #ifndef MY_bfd_discard_group
947 #define MY_bfd_discard_group bfd_generic_discard_group
948 #endif
949 #ifndef MY_section_already_linked
950 #define MY_section_already_linked \
951   _bfd_generic_section_already_linked
952 #endif
953 #ifndef MY_bfd_reloc_type_lookup
954 #define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup
955 #endif
956 #ifndef MY_bfd_reloc_name_lookup
957 #define MY_bfd_reloc_name_lookup tic30_aout_reloc_name_lookup
958 #endif
959 #ifndef MY_bfd_make_debug_symbol
960 #define MY_bfd_make_debug_symbol 0
961 #endif
962 #ifndef MY_read_minisymbols
963 #define MY_read_minisymbols NAME (aout, read_minisymbols)
964 #endif
965 #ifndef MY_minisymbol_to_symbol
966 #define MY_minisymbol_to_symbol NAME (aout, minisymbol_to_symbol)
967 #endif
968 #ifndef MY_bfd_link_hash_table_create
969 #define MY_bfd_link_hash_table_create NAME (aout, link_hash_table_create)
970 #endif
971 #ifndef MY_bfd_link_hash_table_free
972 #define MY_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
973 #endif
974 #ifndef MY_bfd_link_add_symbols
975 #define MY_bfd_link_add_symbols NAME (aout, link_add_symbols)
976 #endif
977 #ifndef MY_bfd_link_just_syms
978 #define MY_bfd_link_just_syms _bfd_generic_link_just_syms
979 #endif
980 #ifndef MY_bfd_link_split_section
981 #define MY_bfd_link_split_section  _bfd_generic_link_split_section
982 #endif
983
984 #ifndef MY_bfd_copy_private_bfd_data
985 #define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
986 #endif
987
988 #ifndef MY_bfd_merge_private_bfd_data
989 #define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
990 #endif
991
992 #ifndef MY_bfd_copy_private_symbol_data
993 #define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
994 #endif
995
996 #ifndef MY_bfd_copy_private_header_data
997 #define MY_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
998 #endif
999
1000 #ifndef MY_bfd_print_private_bfd_data
1001 #define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
1002 #endif
1003
1004 #ifndef MY_bfd_set_private_flags
1005 #define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
1006 #endif
1007
1008 #ifndef MY_bfd_is_local_label_name
1009 #define MY_bfd_is_local_label_name bfd_generic_is_local_label_name
1010 #endif
1011
1012 #ifndef MY_bfd_is_target_special_symbol
1013 #define MY_bfd_is_target_special_symbol  \
1014   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1015 #endif
1016
1017 #ifndef MY_bfd_free_cached_info
1018 #define MY_bfd_free_cached_info NAME (aout, bfd_free_cached_info)
1019 #endif
1020
1021 #ifndef MY_close_and_cleanup
1022 #define MY_close_and_cleanup MY_bfd_free_cached_info
1023 #endif
1024
1025 #ifndef MY_get_dynamic_symtab_upper_bound
1026 #define MY_get_dynamic_symtab_upper_bound \
1027   _bfd_nodynamic_get_dynamic_symtab_upper_bound
1028 #endif
1029 #ifndef MY_canonicalize_dynamic_symtab
1030 #define MY_canonicalize_dynamic_symtab \
1031   _bfd_nodynamic_canonicalize_dynamic_symtab
1032 #endif
1033 #ifndef MY_get_synthetic_symtab
1034 #define MY_get_synthetic_symtab \
1035   _bfd_nodynamic_get_synthetic_symtab
1036 #endif
1037 #ifndef MY_get_dynamic_reloc_upper_bound
1038 #define MY_get_dynamic_reloc_upper_bound \
1039   _bfd_nodynamic_get_dynamic_reloc_upper_bound
1040 #endif
1041 #ifndef MY_canonicalize_dynamic_reloc
1042 #define MY_canonicalize_dynamic_reloc \
1043   _bfd_nodynamic_canonicalize_dynamic_reloc
1044 #endif
1045
1046 /* Aout symbols normally have leading underscores.  */
1047 #ifndef MY_symbol_leading_char
1048 #define MY_symbol_leading_char '_'
1049 #endif
1050
1051 /* Aout archives normally use spaces for padding.  */
1052 #ifndef AR_PAD_CHAR
1053 #define AR_PAD_CHAR ' '
1054 #endif
1055
1056 #ifndef MY_BFD_TARGET
1057 const bfd_target tic30_aout_vec =
1058 {
1059   TARGETNAME,                   /* Name.  */
1060   bfd_target_aout_flavour,
1061   BFD_ENDIAN_BIG,               /* Target byte order (big).  */
1062   BFD_ENDIAN_BIG,               /* Target headers byte order (big).  */
1063   (HAS_RELOC |                  /* Object flags.  */
1064    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1065   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),        /* Section flags.  */
1066   MY_symbol_leading_char,
1067   AR_PAD_CHAR,                  /* AR_pad_char.  */
1068   15,                           /* AR_max_namelen.  */
1069   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1070   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1071   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Data.  */
1072   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1073   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1074   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Headers.  */
1075   {_bfd_dummy_target, MY_object_p,              /* bfd_check_format.  */
1076    bfd_generic_archive_p, MY_core_file_p},
1077   {bfd_false, MY_mkobject,                      /* bfd_set_format.  */
1078    _bfd_generic_mkarchive, bfd_false},
1079   {bfd_false, MY_write_object_contents,         /* bfd_write_contents.  */
1080    _bfd_write_archive_contents, bfd_false},
1081
1082   BFD_JUMP_TABLE_GENERIC (MY),
1083   BFD_JUMP_TABLE_COPY (MY),
1084   BFD_JUMP_TABLE_CORE (MY),
1085   BFD_JUMP_TABLE_ARCHIVE (MY),
1086   BFD_JUMP_TABLE_SYMBOLS (MY),
1087   BFD_JUMP_TABLE_RELOCS (MY),
1088   BFD_JUMP_TABLE_WRITE (MY),
1089   BFD_JUMP_TABLE_LINK (MY),
1090   BFD_JUMP_TABLE_DYNAMIC (MY),
1091
1092   NULL,
1093
1094   MY_backend_data
1095 };
1096 #endif /* MY_BFD_TARGET */