1 /* BFD back-end for TMS320C30 a.out binaries.
2    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
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 2 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 "bfd.h"
39 #include "sysdep.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
tic30_aout_set_sizes(bfd * abfd)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
tic30_aout_fix_pcrel_16(bfd * abfd,arelent * reloc_entry,asymbol * symbol ATTRIBUTE_UNUSED,void * data,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd ATTRIBUTE_UNUSED,char ** error_message ATTRIBUTE_UNUSED)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
tic30_aout_fix_16(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)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
tic30_aout_fix_32(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)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 *
tic30_aout_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)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 *
tic30_aout_reloc_howto(bfd * abfd,struct reloc_std_external * relocs,int * r_index,int * r_extern,int * r_pcrel)274 tic30_aout_reloc_howto (bfd *abfd,
275 			struct reloc_std_external *relocs,
276 			int *r_index,
277 			int *r_extern,
278 			int *r_pcrel)
279 {
280   unsigned int r_length;
281   unsigned int r_pcrel_done;
282   int index;
283 
284   *r_pcrel = 0;
285   if (bfd_header_big_endian (abfd))
286     {
287       *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]);
288       *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
289       r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
290       r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG);
291     }
292   else
293     {
294       *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]);
295       *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
296       r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
297       r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
298     }
299   index = r_length + 4 * r_pcrel_done;
300   return tic30_aout_howto_table + index;
301 }
302 
303 /* These macros will get 24-bit values from the bfd definition.
304    Big-endian only.  */
305 #define bfd_getb_24(BFD,ADDR)			\
306  (bfd_get_8 (BFD, ADDR    ) << 16) |		\
307  (bfd_get_8 (BFD, ADDR + 1) <<  8) |		\
308  (bfd_get_8 (BFD, ADDR + 2)      )
309 
310 #define bfd_putb_24(BFD,DATA,ADDR)				\
311  bfd_put_8 (BFD, (bfd_byte) ((DATA >> 16) & 0xFF), ADDR    );	\
312  bfd_put_8 (BFD, (bfd_byte) ((DATA >>  8) & 0xFF), ADDR + 1);	\
313  bfd_put_8 (BFD, (bfd_byte) ( DATA        & 0xFF), ADDR + 2)
314 
315 /* Set parameters about this a.out file that are machine-dependent.
316    This routine is called from some_aout_object_p just before it returns.  */
317 
318 static const bfd_target *
tic30_aout_callback(bfd * abfd)319 tic30_aout_callback (bfd *abfd)
320 {
321   struct internal_exec *execp = exec_hdr (abfd);
322   unsigned int arch_align_power;
323   unsigned long arch_align;
324 
325   /* Calculate the file positions of the parts of a newly read aout header.  */
326   obj_textsec (abfd)->size = N_TXTSIZE (*execp);
327 
328   /* The virtual memory addresses of the sections.  */
329   obj_textsec (abfd)->vma = N_TXTADDR (*execp);
330   obj_datasec (abfd)->vma = N_DATADDR (*execp);
331   obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
332 
333   obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
334   obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
335   obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
336 
337   /* The file offsets of the sections.  */
338   obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
339   obj_datasec (abfd)->filepos = N_DATOFF (*execp);
340 
341   /* The file offsets of the relocation info.  */
342   obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
343   obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
344 
345   /* The file offsets of the string table and symbol table.  */
346   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
347   obj_str_filepos (abfd) = N_STROFF (*execp);
348 
349   /* Determine the architecture and machine type of the object file.  */
350 #ifdef SET_ARCH_MACH
351   SET_ARCH_MACH (abfd, *execp);
352 #else
353   bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0L);
354 #endif
355 
356   /* Now that we know the architecture, set the alignments of the
357      sections.  This is normally done by NAME (aout,new_section_hook),
358      but when the initial sections were created the architecture had
359      not yet been set.  However, for backward compatibility, we don't
360      set the alignment power any higher than as required by the size
361      of the section.  */
362   arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
363   arch_align = 1 << arch_align_power;
364   if ((BFD_ALIGN (obj_textsec (abfd)->size, arch_align)
365        == obj_textsec (abfd)->size)
366       && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
367 	  == obj_datasec (abfd)->size)
368       && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
369 	  == obj_bsssec (abfd)->size))
370     {
371       obj_textsec (abfd)->alignment_power = arch_align_power;
372       obj_datasec (abfd)->alignment_power = arch_align_power;
373       obj_bsssec (abfd)->alignment_power = arch_align_power;
374     }
375   return abfd->xvec;
376 }
377 
378 static bfd_reloc_status_type
tic30_aout_relocate_contents(reloc_howto_type * howto,bfd * input_bfd,bfd_vma relocation,bfd_byte * location)379 tic30_aout_relocate_contents (reloc_howto_type *howto,
380 			      bfd *input_bfd,
381 			      bfd_vma relocation,
382 			      bfd_byte *location)
383 {
384   bfd_vma x;
385   bfd_boolean overflow;
386 
387   if (howto->size < 0)
388     relocation = -relocation;
389 
390   switch (howto->size)
391     {
392     default:
393     case 0:
394       abort ();
395       break;
396     case 1:
397       x = bfd_get_16 (input_bfd, location);
398       break;
399     case 2:
400       x = bfd_getb_24 (input_bfd, location);
401       break;
402     case 3:
403       x = bfd_get_8 (input_bfd, location);
404       break;
405     case 4:
406       x = bfd_get_32 (input_bfd, location);
407       break;
408     }
409 
410   overflow = FALSE;
411 
412   if (howto->complain_on_overflow != complain_overflow_dont)
413     {
414       bfd_vma check;
415       bfd_signed_vma signed_check;
416       bfd_vma add;
417       bfd_signed_vma signed_add;
418 
419       if (howto->rightshift == 0)
420 	{
421 	  check = relocation;
422 	  signed_check = (bfd_signed_vma) relocation;
423 	}
424       else
425 	{
426 	  check = relocation >> howto->rightshift;
427 	  if ((bfd_signed_vma) relocation >= 0)
428 	    signed_check = check;
429 	  else
430 	    signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
431 	}
432       add = x & howto->src_mask;
433       signed_add = add;
434       if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
435 	signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
436       if (howto->bitpos == 0)
437 	{
438 	  check += add;
439 	  signed_check += signed_add;
440 	}
441       else
442 	{
443 	  check += add >> howto->bitpos;
444 	  if (signed_add >= 0)
445 	    signed_check += add >> howto->bitpos;
446 	  else
447 	    signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos)));
448 	}
449       switch (howto->complain_on_overflow)
450 	{
451 	case complain_overflow_signed:
452 	  {
453 	    bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
454 	    bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
455 
456 	    if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
457 	      overflow = TRUE;
458 	  }
459 	  break;
460 	case complain_overflow_unsigned:
461 	  {
462 	    bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
463 
464 	    if (check > reloc_unsigned_max)
465 	      overflow = TRUE;
466 	  }
467 	  break;
468 	case complain_overflow_bitfield:
469 	  {
470 	    bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
471 
472 	    if ((check & ~reloc_bits) != 0
473 		&& (((bfd_vma) signed_check & ~reloc_bits)
474 		    != ((bfd_vma) -1 & ~reloc_bits)))
475 	      overflow = TRUE;
476 	  }
477 	  break;
478 	default:
479 	  abort ();
480 	}
481     }
482   relocation >>= (bfd_vma) howto->rightshift;
483   relocation <<= (bfd_vma) howto->bitpos;
484   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask));
485   switch (howto->size)
486     {
487     default:
488     case 0:
489       abort ();
490       break;
491     case 1:
492       bfd_put_16 (input_bfd, x, location);
493       break;
494     case 2:
495       bfd_putb_24 (input_bfd, x, location);
496       break;
497     case 3:
498       bfd_put_8 (input_bfd, x, location);
499       break;
500     case 4:
501       bfd_put_32 (input_bfd, x, location);
502       break;
503     }
504   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
505 }
506 
507 static bfd_reloc_status_type
tic30_aout_final_link_relocate(reloc_howto_type * howto,bfd * input_bfd,asection * input_section,bfd_byte * contents,bfd_vma address,bfd_vma value,bfd_vma addend)508 tic30_aout_final_link_relocate (reloc_howto_type *howto,
509 				bfd *input_bfd,
510 				asection *input_section,
511 				bfd_byte *contents,
512 				bfd_vma address,
513 				bfd_vma value,
514 				bfd_vma addend)
515 {
516   bfd_vma relocation;
517 
518   if (address > bfd_get_section_limit (input_bfd, input_section))
519     return bfd_reloc_outofrange;
520 
521   relocation = value + addend;
522   if (howto->pc_relative)
523     {
524       relocation -= (input_section->output_section->vma + input_section->output_offset);
525       if (howto->pcrel_offset)
526 	relocation -= address;
527     }
528   return tic30_aout_relocate_contents (howto, input_bfd, relocation,
529 				       contents + address);
530 }
531 
532 /* Finish up the reading of an a.out file header.  */
533 
534 static const bfd_target *
tic30_aout_object_p(bfd * abfd)535 tic30_aout_object_p (bfd *abfd)
536 {
537   struct external_exec exec_bytes;	/* Raw exec header from file.  */
538   struct internal_exec exec;		/* Cleaned-up exec header.  */
539   const bfd_target *target;
540   bfd_size_type amt = EXEC_BYTES_SIZE;
541 
542   if (bfd_bread (& exec_bytes, amt, abfd) != amt)
543     {
544       if (bfd_get_error () != bfd_error_system_call)
545 	bfd_set_error (bfd_error_wrong_format);
546       return 0;
547     }
548 
549 #ifdef SWAP_MAGIC
550   exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
551 #else
552   exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
553 #endif /* SWAP_MAGIC */
554 
555   if (N_BADMAG (exec))
556     return 0;
557 #ifdef MACHTYPE_OK
558   if (!(MACHTYPE_OK (N_MACHTYPE (exec))))
559     return 0;
560 #endif
561 
562   NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec);
563 
564 #ifdef SWAP_MAGIC
565   /* Swap_exec_header_in read in a_info with the wrong byte order.  */
566   exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
567 #endif
568 
569   target = NAME (aout, some_aout_object_p) (abfd, &exec, tic30_aout_callback);
570 
571 #ifdef ENTRY_CAN_BE_ZERO
572   /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
573      means that it isn't obvious if EXEC_P should be set.
574      All of the following must be true for an executable:
575      There must be no relocations, the bfd can be neither an
576      archive nor an archive element, and the file must be executable.  */
577 
578   if (exec.a_trsize + exec.a_drsize == 0
579       && bfd_get_format (abfd) == bfd_object && abfd->my_archive == NULL)
580     {
581       struct stat buf;
582 #ifndef S_IXUSR
583 #define S_IXUSR 0100		/* Execute by owner.  */
584 #endif
585       if (stat (abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
586 	abfd->flags |= EXEC_P;
587     }
588 #endif
589 
590   return target;
591 }
592 
593 /* Copy private section data.  This actually does nothing with the
594    sections.  It copies the subformat field.  We copy it here, because
595    we need to know whether this is a QMAGIC file before we set the
596    section contents, and copy_private_bfd_data is not called until
597    after the section contents have been set.  */
598 
599 static bfd_boolean
MY_bfd_copy_private_section_data(bfd * ibfd,asection * isec ATTRIBUTE_UNUSED,bfd * obfd,asection * osec ATTRIBUTE_UNUSED)600 MY_bfd_copy_private_section_data (bfd *ibfd,
601 				  asection *isec ATTRIBUTE_UNUSED,
602 				  bfd *obfd,
603 				  asection *osec ATTRIBUTE_UNUSED)
604 {
605   if (bfd_get_flavour (obfd) == bfd_target_aout_flavour)
606     obj_aout_subformat (obfd) = obj_aout_subformat (ibfd);
607   return TRUE;
608 }
609 
610 /* Write an object file.
611    Section contents have already been written.  We write the
612    file header, symbols, and relocation.  */
613 
614 static bfd_boolean
tic30_aout_write_object_contents(bfd * abfd)615 tic30_aout_write_object_contents (bfd *abfd)
616 {
617   struct external_exec exec_bytes;
618   struct internal_exec *execp = exec_hdr (abfd);
619 
620   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
621 
622   {
623     bfd_size_type text_size;	/* Dummy vars.  */
624     file_ptr text_end;
625 
626     if (adata (abfd).magic == undecided_magic)
627       NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
628 
629     execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
630     execp->a_entry = bfd_get_start_address (abfd);
631 
632     execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * obj_reloc_entry_size (abfd));
633     execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * obj_reloc_entry_size (abfd));
634     NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes);
635 
636     if (adata (abfd).exec_bytes_size > 0)
637       {
638 	bfd_size_type amt;
639 
640 	if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
641 	  return FALSE;
642 	amt = adata (abfd).exec_bytes_size;
643 	if (bfd_bwrite (& exec_bytes, amt, abfd) != amt)
644 	  return FALSE;
645       }
646 
647     /* Now write out reloc info, followed by syms and strings.  */
648     if (bfd_get_outsymbols (abfd) != (asymbol **) NULL
649 	&& bfd_get_symcount (abfd) != 0)
650       {
651 	if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*execp)), SEEK_SET) != 0)
652 	  return FALSE;
653 
654 	if (!NAME (aout, write_syms) (abfd))
655 	  return FALSE;
656       }
657 
658     if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0)
659       return FALSE;
660     if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd)))
661       return FALSE;
662 
663     if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0)
664       return FALSE;
665     if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
666       return FALSE;
667   }
668 
669   return TRUE;
670 }
671 
672 #ifndef MY_final_link_callback
673 
674 /* Callback for the final_link routine to set the section offsets.  */
675 
676 static void
MY_final_link_callback(bfd * abfd,file_ptr * ptreloff,file_ptr * pdreloff,file_ptr * psymoff)677 MY_final_link_callback (bfd *abfd,
678 			file_ptr *ptreloff,
679 			file_ptr *pdreloff,
680 			file_ptr *psymoff)
681 {
682   struct internal_exec *execp = exec_hdr (abfd);
683 
684   *ptreloff = obj_datasec (abfd)->filepos + execp->a_data;
685   *pdreloff = *ptreloff + execp->a_trsize;
686   *psymoff = *pdreloff + execp->a_drsize;;
687 }
688 
689 #endif
690 
691 #ifndef MY_bfd_final_link
692 
693 /* Final link routine.  We need to use a call back to get the correct
694    offsets in the output file.  */
695 
696 static bfd_boolean
MY_bfd_final_link(bfd * abfd,struct bfd_link_info * info)697 MY_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
698 {
699   struct internal_exec *execp = exec_hdr (abfd);
700   file_ptr pos;
701   bfd_vma vma = 0;
702   int pad;
703 
704   /* Set the executable header size to 0, as we don't want one for an
705      output.  */
706   adata (abfd).exec_bytes_size = 0;
707   pos = adata (abfd).exec_bytes_size;
708   /* Text.  */
709   vma = info->create_object_symbols_section->vma;
710   pos += vma;
711   obj_textsec (abfd)->filepos = pos;
712   obj_textsec (abfd)->vma = vma;
713   obj_textsec (abfd)->user_set_vma = 1;
714   pos += obj_textsec (abfd)->size;
715   vma += obj_textsec (abfd)->size;
716 
717   /* Data.  */
718   if (abfd->flags & D_PAGED)
719     {
720       if (info->create_object_symbols_section->next->vma > 0)
721 	obj_datasec (abfd)->vma = info->create_object_symbols_section->next->vma;
722       else
723 	obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
724     }
725   else
726     obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
727 
728   if (obj_datasec (abfd)->vma < vma)
729     obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
730 
731   obj_datasec (abfd)->user_set_vma = 1;
732   vma = obj_datasec (abfd)->vma;
733   obj_datasec (abfd)->filepos = vma + adata (abfd).exec_bytes_size;
734   execp->a_text = vma - obj_textsec (abfd)->vma;
735   obj_textsec (abfd)->size = execp->a_text;
736 
737   /* Since BSS follows data immediately, see if it needs alignment.  */
738   vma += obj_datasec (abfd)->size;
739   pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
740   obj_datasec (abfd)->size += pad;
741   pos += obj_datasec (abfd)->size;
742   execp->a_data = obj_datasec (abfd)->size;
743 
744   /* BSS.  */
745   obj_bsssec (abfd)->vma = vma;
746   obj_bsssec (abfd)->user_set_vma = 1;
747 
748   /* We are fully resized, so don't readjust in final_link.  */
749   adata (abfd).magic = z_magic;
750 
751   return NAME (aout, final_link) (abfd, info, MY_final_link_callback);
752 }
753 
754 #endif
755 
756 static enum machine_type
tic30_aout_machine_type(enum bfd_architecture arch,unsigned long machine ATTRIBUTE_UNUSED,bfd_boolean * unknown)757 tic30_aout_machine_type (enum bfd_architecture arch,
758 			 unsigned long machine ATTRIBUTE_UNUSED,
759 			 bfd_boolean *unknown)
760 {
761   enum machine_type arch_flags;
762 
763   arch_flags = M_UNKNOWN;
764   *unknown = TRUE;
765 
766   switch (arch)
767     {
768     case bfd_arch_tic30:
769       *unknown = FALSE;
770       break;
771     default:
772       arch_flags = M_UNKNOWN;
773     }
774   if (arch_flags != M_UNKNOWN)
775     *unknown = FALSE;
776   return arch_flags;
777 }
778 
779 static bfd_boolean
tic30_aout_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long machine)780 tic30_aout_set_arch_mach (bfd *abfd,
781 			  enum bfd_architecture arch,
782 			  unsigned long machine)
783 {
784   if (!bfd_default_set_arch_mach (abfd, arch, machine))
785     return FALSE;
786   if (arch != bfd_arch_unknown)
787     {
788       bfd_boolean unknown;
789       tic30_aout_machine_type (arch, machine, &unknown);
790       if (unknown)
791 	return FALSE;
792     }
793   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
794   return (*aout_backend_info (abfd)->set_sizes) (abfd);
795 }
796 
797 /* We assume BFD generic archive files.  */
798 #ifndef	MY_openr_next_archived_file
799 #define	MY_openr_next_archived_file	bfd_generic_openr_next_archived_file
800 #endif
801 #ifndef MY_get_elt_at_index
802 #define MY_get_elt_at_index		_bfd_generic_get_elt_at_index
803 #endif
804 #ifndef	MY_generic_stat_arch_elt
805 #define	MY_generic_stat_arch_elt	bfd_generic_stat_arch_elt
806 #endif
807 #ifndef	MY_slurp_armap
808 #define	MY_slurp_armap			bfd_slurp_bsd_armap
809 #endif
810 #ifndef	MY_slurp_extended_name_table
811 #define	MY_slurp_extended_name_table	_bfd_slurp_extended_name_table
812 #endif
813 #ifndef MY_construct_extended_name_table
814 #define MY_construct_extended_name_table \
815   _bfd_archive_bsd_construct_extended_name_table
816 #endif
817 #ifndef	MY_write_armap
818 #define	MY_write_armap			bsd_write_armap
819 #endif
820 #ifndef MY_read_ar_hdr
821 #define MY_read_ar_hdr			_bfd_generic_read_ar_hdr
822 #endif
823 #ifndef	MY_truncate_arname
824 #define	MY_truncate_arname		bfd_bsd_truncate_arname
825 #endif
826 #ifndef MY_update_armap_timestamp
827 #define MY_update_armap_timestamp 	_bfd_archive_bsd_update_armap_timestamp
828 #endif
829 
830 /* No core file defined here -- configure in trad-core.c separately.  */
831 #ifndef	MY_core_file_failing_command
832 #define	MY_core_file_failing_command 	_bfd_nocore_core_file_failing_command
833 #endif
834 #ifndef	MY_core_file_failing_signal
835 #define	MY_core_file_failing_signal	_bfd_nocore_core_file_failing_signal
836 #endif
837 #ifndef	MY_core_file_matches_executable_p
838 #define	MY_core_file_matches_executable_p	\
839 				_bfd_nocore_core_file_matches_executable_p
840 #endif
841 #ifndef	MY_core_file_p
842 #define	MY_core_file_p			_bfd_dummy_target
843 #endif
844 
845 #ifndef MY_bfd_debug_info_start
846 #define MY_bfd_debug_info_start		bfd_void
847 #endif
848 #ifndef MY_bfd_debug_info_end
849 #define MY_bfd_debug_info_end		bfd_void
850 #endif
851 #ifndef MY_bfd_debug_info_accumulate
852 #define MY_bfd_debug_info_accumulate	\
853 		(void (*) (bfd*, struct bfd_section *)) bfd_void
854 #endif
855 
856 #ifndef MY_core_file_failing_command
857 #define MY_core_file_failing_command NAME (aout, core_file_failing_command)
858 #endif
859 #ifndef MY_core_file_failing_signal
860 #define MY_core_file_failing_signal NAME (aout, core_file_failing_signal)
861 #endif
862 #ifndef MY_core_file_matches_executable_p
863 #define MY_core_file_matches_executable_p NAME (aout, core_file_matches_executable_p)
864 #endif
865 #ifndef MY_set_section_contents
866 #define MY_set_section_contents NAME (aout, set_section_contents)
867 #endif
868 #ifndef MY_get_section_contents
869 #define MY_get_section_contents aout_32_get_section_contents
870 #endif
871 #ifndef MY_get_section_contents_in_window
872 #define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
873 #endif
874 #ifndef MY_new_section_hook
875 #define MY_new_section_hook NAME (aout, new_section_hook)
876 #endif
877 #ifndef MY_get_symtab_upper_bound
878 #define MY_get_symtab_upper_bound NAME (aout, get_symtab_upper_bound)
879 #endif
880 #ifndef MY_canonicalize_symtab
881 #define MY_canonicalize_symtab NAME (aout, canonicalize_symtab)
882 #endif
883 #ifndef MY_get_reloc_upper_bound
884 #define MY_get_reloc_upper_bound NAME (aout, get_reloc_upper_bound)
885 #endif
886 #ifndef MY_canonicalize_reloc
887 #define MY_canonicalize_reloc NAME (aout, canonicalize_reloc)
888 #endif
889 #ifndef MY_make_empty_symbol
890 #define MY_make_empty_symbol NAME (aout, make_empty_symbol)
891 #endif
892 #ifndef MY_print_symbol
893 #define MY_print_symbol NAME (aout, print_symbol)
894 #endif
895 #ifndef MY_get_symbol_info
896 #define MY_get_symbol_info NAME (aout, get_symbol_info)
897 #endif
898 #ifndef MY_get_lineno
899 #define MY_get_lineno NAME (aout, get_lineno)
900 #endif
901 #ifndef MY_set_arch_mach
902 #define MY_set_arch_mach tic30_aout_set_arch_mach
903 #endif
904 #ifndef MY_find_nearest_line
905 #define MY_find_nearest_line NAME (aout, find_nearest_line)
906 #endif
907 #ifndef MY_find_inliner_info
908 #define MY_find_inliner_info _bfd_nosymbols_find_inliner_info
909 #endif
910 #ifndef MY_sizeof_headers
911 #define MY_sizeof_headers NAME (aout, sizeof_headers)
912 #endif
913 #ifndef MY_bfd_get_relocated_section_contents
914 #define MY_bfd_get_relocated_section_contents \
915 			bfd_generic_get_relocated_section_contents
916 #endif
917 #ifndef MY_bfd_relax_section
918 #define MY_bfd_relax_section bfd_generic_relax_section
919 #endif
920 #ifndef MY_bfd_gc_sections
921 #define MY_bfd_gc_sections bfd_generic_gc_sections
922 #endif
923 #ifndef MY_bfd_merge_sections
924 #define MY_bfd_merge_sections bfd_generic_merge_sections
925 #endif
926 #ifndef MY_bfd_is_group_section
927 #define MY_bfd_is_group_section bfd_generic_is_group_section
928 #endif
929 #ifndef MY_bfd_discard_group
930 #define MY_bfd_discard_group bfd_generic_discard_group
931 #endif
932 #ifndef MY_section_already_linked
933 #define MY_section_already_linked \
934   _bfd_generic_section_already_linked
935 #endif
936 #ifndef MY_bfd_reloc_type_lookup
937 #define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup
938 #endif
939 #ifndef MY_bfd_make_debug_symbol
940 #define MY_bfd_make_debug_symbol 0
941 #endif
942 #ifndef MY_read_minisymbols
943 #define MY_read_minisymbols NAME (aout, read_minisymbols)
944 #endif
945 #ifndef MY_minisymbol_to_symbol
946 #define MY_minisymbol_to_symbol NAME (aout, minisymbol_to_symbol)
947 #endif
948 #ifndef MY_bfd_link_hash_table_create
949 #define MY_bfd_link_hash_table_create NAME (aout, link_hash_table_create)
950 #endif
951 #ifndef MY_bfd_link_hash_table_free
952 #define MY_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
953 #endif
954 #ifndef MY_bfd_link_add_symbols
955 #define MY_bfd_link_add_symbols NAME (aout, link_add_symbols)
956 #endif
957 #ifndef MY_bfd_link_just_syms
958 #define MY_bfd_link_just_syms _bfd_generic_link_just_syms
959 #endif
960 #ifndef MY_bfd_link_split_section
961 #define MY_bfd_link_split_section  _bfd_generic_link_split_section
962 #endif
963 
964 #ifndef MY_bfd_copy_private_bfd_data
965 #define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
966 #endif
967 
968 #ifndef MY_bfd_merge_private_bfd_data
969 #define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
970 #endif
971 
972 #ifndef MY_bfd_copy_private_symbol_data
973 #define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
974 #endif
975 
976 #ifndef MY_bfd_copy_private_header_data
977 #define MY_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
978 #endif
979 
980 #ifndef MY_bfd_print_private_bfd_data
981 #define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
982 #endif
983 
984 #ifndef MY_bfd_set_private_flags
985 #define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
986 #endif
987 
988 #ifndef MY_bfd_is_local_label_name
989 #define MY_bfd_is_local_label_name bfd_generic_is_local_label_name
990 #endif
991 
992 #ifndef MY_bfd_is_target_special_symbol
993 #define MY_bfd_is_target_special_symbol  \
994   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
995 #endif
996 
997 #ifndef MY_bfd_free_cached_info
998 #define MY_bfd_free_cached_info NAME (aout, bfd_free_cached_info)
999 #endif
1000 
1001 #ifndef MY_close_and_cleanup
1002 #define MY_close_and_cleanup MY_bfd_free_cached_info
1003 #endif
1004 
1005 #ifndef MY_get_dynamic_symtab_upper_bound
1006 #define MY_get_dynamic_symtab_upper_bound \
1007   _bfd_nodynamic_get_dynamic_symtab_upper_bound
1008 #endif
1009 #ifndef MY_canonicalize_dynamic_symtab
1010 #define MY_canonicalize_dynamic_symtab \
1011   _bfd_nodynamic_canonicalize_dynamic_symtab
1012 #endif
1013 #ifndef MY_get_synthetic_symtab
1014 #define MY_get_synthetic_symtab \
1015   _bfd_nodynamic_get_synthetic_symtab
1016 #endif
1017 #ifndef MY_get_dynamic_reloc_upper_bound
1018 #define MY_get_dynamic_reloc_upper_bound \
1019   _bfd_nodynamic_get_dynamic_reloc_upper_bound
1020 #endif
1021 #ifndef MY_canonicalize_dynamic_reloc
1022 #define MY_canonicalize_dynamic_reloc \
1023   _bfd_nodynamic_canonicalize_dynamic_reloc
1024 #endif
1025 
1026 /* Aout symbols normally have leading underscores.  */
1027 #ifndef MY_symbol_leading_char
1028 #define MY_symbol_leading_char '_'
1029 #endif
1030 
1031 /* Aout archives normally use spaces for padding.  */
1032 #ifndef AR_PAD_CHAR
1033 #define AR_PAD_CHAR ' '
1034 #endif
1035 
1036 #ifndef MY_BFD_TARGET
1037 const bfd_target tic30_aout_vec =
1038 {
1039   TARGETNAME,			/* Name.  */
1040   bfd_target_aout_flavour,
1041   BFD_ENDIAN_BIG,		/* Target byte order (big).  */
1042   BFD_ENDIAN_BIG,		/* Target headers byte order (big).  */
1043   (HAS_RELOC |			/* Object flags.  */
1044    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1045   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
1046   MY_symbol_leading_char,
1047   AR_PAD_CHAR,			/* AR_pad_char.  */
1048   15,				/* AR_max_namelen.  */
1049   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1050   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1051   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
1052   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1053   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1054   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers.  */
1055   {_bfd_dummy_target, MY_object_p,		/* bfd_check_format.  */
1056    bfd_generic_archive_p, MY_core_file_p},
1057   {bfd_false, MY_mkobject,			/* bfd_set_format.  */
1058    _bfd_generic_mkarchive, bfd_false},
1059   {bfd_false, MY_write_object_contents,		/* bfd_write_contents.  */
1060    _bfd_write_archive_contents, bfd_false},
1061 
1062   BFD_JUMP_TABLE_GENERIC (MY),
1063   BFD_JUMP_TABLE_COPY (MY),
1064   BFD_JUMP_TABLE_CORE (MY),
1065   BFD_JUMP_TABLE_ARCHIVE (MY),
1066   BFD_JUMP_TABLE_SYMBOLS (MY),
1067   BFD_JUMP_TABLE_RELOCS (MY),
1068   BFD_JUMP_TABLE_WRITE (MY),
1069   BFD_JUMP_TABLE_LINK (MY),
1070   BFD_JUMP_TABLE_DYNAMIC (MY),
1071 
1072   NULL,
1073 
1074   MY_backend_data
1075 };
1076 #endif /* MY_BFD_TARGET */
1077