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