1 /*  MSP430-specific support for 32-bit ELF
2     Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3     Contributed by Dmitry Diky <diwil@mail.ru>
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 02111-1307, USA.  */
20 
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libiberty.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/msp430.h"
27 
28 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
29   PARAMS ((bfd *, bfd_reloc_code_real_type));
30 
31 static void msp430_info_to_howto_rela
32   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
33 
34 static asection *elf32_msp430_gc_mark_hook
35   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
36 	   struct elf_link_hash_entry *, Elf_Internal_Sym *));
37 
38 static bfd_boolean elf32_msp430_gc_sweep_hook
39   PARAMS ((bfd *, struct bfd_link_info *, asection *,
40 	   const Elf_Internal_Rela *));
41 
42 static bfd_boolean elf32_msp430_check_relocs
43   PARAMS ((bfd *, struct bfd_link_info *, asection *,
44 	   const Elf_Internal_Rela *));
45 
46 static bfd_reloc_status_type msp430_final_link_relocate
47   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
48 	   Elf_Internal_Rela *, bfd_vma));
49 
50 static bfd_boolean elf32_msp430_relocate_section
51   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
52 	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
53 
54 static void bfd_elf_msp430_final_write_processing
55   PARAMS ((bfd *, bfd_boolean));
56 
57 static bfd_boolean elf32_msp430_object_p
58   PARAMS ((bfd *));
59 
60 static void elf32_msp430_post_process_headers
61   PARAMS ((bfd *, struct bfd_link_info *));
62 
63 /* Use RELA instead of REL.  */
64 #undef USE_REL
65 
66 static reloc_howto_type elf_msp430_howto_table[] =
67 {
68   HOWTO (R_MSP430_NONE,		/* type */
69 	 0,			/* rightshift */
70 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
71 	 32,			/* bitsize */
72 	 FALSE,			/* pc_relative */
73 	 0,			/* bitpos */
74 	 complain_overflow_bitfield,	/* complain_on_overflow */
75 	 bfd_elf_generic_reloc,	/* special_function */
76 	 "R_MSP430_NONE",	/* name */
77 	 FALSE,			/* partial_inplace */
78 	 0,			/* src_mask */
79 	 0,			/* dst_mask */
80 	 FALSE),		/* pcrel_offset */
81 
82   HOWTO (R_MSP430_32,		/* type */
83 	 0,			/* rightshift */
84 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
85 	 32,			/* bitsize */
86 	 FALSE,			/* pc_relative */
87 	 0,			/* bitpos */
88 	 complain_overflow_bitfield,	/* complain_on_overflow */
89 	 bfd_elf_generic_reloc,	/* special_function */
90 	 "R_MSP430_32",		/* name */
91 	 FALSE,			/* partial_inplace */
92 	 0xffffffff,		/* src_mask */
93 	 0xffffffff,		/* dst_mask */
94 	 FALSE),		/* pcrel_offset */
95 
96   /* A 13 bit PC relative relocation.  */
97   HOWTO (R_MSP430_10_PCREL,	/* type */
98 	 1,			/* rightshift */
99 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
100 	 10,			/* bitsize */
101 	 TRUE,			/* pc_relative */
102 	 0,			/* bitpos */
103 	 complain_overflow_bitfield,	/* complain_on_overflow */
104 	 bfd_elf_generic_reloc,	/* special_function */
105 	 "R_MSP430_13_PCREL",	/* name */
106 	 FALSE,			/* partial_inplace */
107 	 0xfff,			/* src_mask */
108 	 0xfff,			/* dst_mask */
109 	 TRUE),			/* pcrel_offset */
110 
111   /* A 16 bit absolute relocation.  */
112   HOWTO (R_MSP430_16,		/* type */
113 	 0,			/* rightshift */
114 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
115 	 16,			/* bitsize */
116 	 FALSE,			/* pc_relative */
117 	 0,			/* bitpos */
118 	 complain_overflow_dont,/* complain_on_overflow */
119 	 bfd_elf_generic_reloc,	/* special_function */
120 	 "R_MSP430_16",		/* name */
121 	 FALSE,			/* partial_inplace */
122 	 0xffff,		/* src_mask */
123 	 0xffff,		/* dst_mask */
124 	 FALSE),		/* pcrel_offset */
125 
126   /* A 16 bit absolute relocation for command address.  */
127   HOWTO (R_MSP430_16_PCREL,	/* type */
128 	 1,			/* rightshift */
129 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
130 	 16,			/* bitsize */
131 	 TRUE,			/* pc_relative */
132 	 0,			/* bitpos */
133 	 complain_overflow_dont,/* complain_on_overflow */
134 	 bfd_elf_generic_reloc,	/* special_function */
135 	 "R_MSP430_16_PCREL",	/* name */
136 	 FALSE,			/* partial_inplace */
137 	 0xffff,		/* src_mask */
138 	 0xffff,		/* dst_mask */
139 	 TRUE),			/* pcrel_offset */
140 
141   /* A 16 bit absolute relocation, byte operations.  */
142   HOWTO (R_MSP430_16_BYTE,	/* type */
143 	 0,			/* rightshift */
144 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
145 	 16,			/* bitsize */
146 	 FALSE,			/* pc_relative */
147 	 0,			/* bitpos */
148 	 complain_overflow_dont,/* complain_on_overflow */
149 	 bfd_elf_generic_reloc,	/* special_function */
150 	 "R_MSP430_16_BYTE",	/* name */
151 	 FALSE,			/* partial_inplace */
152 	 0xffff,		/* src_mask */
153 	 0xffff,		/* dst_mask */
154 	 FALSE),		/* pcrel_offset */
155 
156   /* A 16 bit absolute relocation for command address.  */
157   HOWTO (R_MSP430_16_PCREL_BYTE,/* type */
158 	 1,			/* rightshift */
159 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
160 	 16,			/* bitsize */
161 	 TRUE,			/* pc_relative */
162 	 0,			/* bitpos */
163 	 complain_overflow_dont,/* complain_on_overflow */
164 	 bfd_elf_generic_reloc,	/* special_function */
165 	 "R_MSP430_16_PCREL_BYTE",	/* name */
166 	 FALSE,			/* partial_inplace */
167 	 0xffff,		/* src_mask */
168 	 0xffff,		/* dst_mask */
169 	 TRUE)			/* pcrel_offset */
170 };
171 
172 /* Map BFD reloc types to MSP430 ELF reloc types.  */
173 
174 struct msp430_reloc_map
175 {
176   bfd_reloc_code_real_type bfd_reloc_val;
177   unsigned int elf_reloc_val;
178 };
179 
180 static const struct msp430_reloc_map msp430_reloc_map[] =
181   {
182     {BFD_RELOC_NONE, R_MSP430_NONE},
183     {BFD_RELOC_32, R_MSP430_32},
184     {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL},
185     {BFD_RELOC_16, R_MSP430_16_BYTE},
186     {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL},
187     {BFD_RELOC_MSP430_16, R_MSP430_16},
188     {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
189     {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE}
190   };
191 
192 static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup(abfd,code)193 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
194      bfd *abfd ATTRIBUTE_UNUSED;
195      bfd_reloc_code_real_type code;
196 {
197   unsigned int i;
198 
199   for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
200     if (msp430_reloc_map[i].bfd_reloc_val == code)
201       return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
202 
203   return NULL;
204 }
205 
206 /* Set the howto pointer for an MSP430 ELF reloc.  */
207 
208 static void
msp430_info_to_howto_rela(abfd,cache_ptr,dst)209 msp430_info_to_howto_rela (abfd, cache_ptr, dst)
210      bfd *abfd ATTRIBUTE_UNUSED;
211      arelent *cache_ptr;
212      Elf_Internal_Rela *dst;
213 {
214   unsigned int r_type;
215 
216   r_type = ELF32_R_TYPE (dst->r_info);
217   BFD_ASSERT (r_type < (unsigned int) R_MSP430_max);
218   cache_ptr->howto = &elf_msp430_howto_table[r_type];
219 }
220 
221 static asection *
elf32_msp430_gc_mark_hook(sec,info,rel,h,sym)222 elf32_msp430_gc_mark_hook (sec, info, rel, h, sym)
223      asection *sec;
224      struct bfd_link_info *info ATTRIBUTE_UNUSED;
225      Elf_Internal_Rela *rel;
226      struct elf_link_hash_entry *h;
227      Elf_Internal_Sym *sym;
228 {
229   if (h != NULL)
230     {
231       switch (ELF32_R_TYPE (rel->r_info))
232 	{
233 	default:
234 	  switch (h->root.type)
235 	    {
236 	    case bfd_link_hash_defined:
237 	    case bfd_link_hash_defweak:
238 	      return h->root.u.def.section;
239 
240 	    case bfd_link_hash_common:
241 	      return h->root.u.c.p->section;
242 
243 	    default:
244 	      break;
245 	    }
246 	}
247     }
248   else
249     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
250 
251   return NULL;
252 }
253 
254 static bfd_boolean
elf32_msp430_gc_sweep_hook(abfd,info,sec,relocs)255 elf32_msp430_gc_sweep_hook (abfd, info, sec, relocs)
256      bfd *abfd ATTRIBUTE_UNUSED;
257      struct bfd_link_info *info ATTRIBUTE_UNUSED;
258      asection *sec ATTRIBUTE_UNUSED;
259      const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
260 {
261   /* We don't use got and plt entries for msp430.  */
262   return TRUE;
263 }
264 
265 /* Look through the relocs for a section during the first phase.
266    Since we don't do .gots or .plts, we just need to consider the
267    virtual table relocs for gc.  */
268 
269 static bfd_boolean
elf32_msp430_check_relocs(abfd,info,sec,relocs)270 elf32_msp430_check_relocs (abfd, info, sec, relocs)
271      bfd *abfd;
272      struct bfd_link_info *info;
273      asection *sec;
274      const Elf_Internal_Rela *relocs;
275 {
276   Elf_Internal_Shdr *symtab_hdr;
277   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
278   const Elf_Internal_Rela *rel;
279   const Elf_Internal_Rela *rel_end;
280 
281   if (info->relocatable)
282     return TRUE;
283 
284   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
285   sym_hashes = elf_sym_hashes (abfd);
286   sym_hashes_end =
287       sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
288   if (!elf_bad_symtab (abfd))
289     sym_hashes_end -= symtab_hdr->sh_info;
290 
291   rel_end = relocs + sec->reloc_count;
292   for (rel = relocs; rel < rel_end; rel++)
293     {
294       struct elf_link_hash_entry *h;
295       unsigned long r_symndx;
296 
297       r_symndx = ELF32_R_SYM (rel->r_info);
298       if (r_symndx < symtab_hdr->sh_info)
299 	h = NULL;
300       else
301 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
302     }
303 
304   return TRUE;
305 }
306 
307 /* Perform a single relocation.  By default we use the standard BFD
308    routines, but a few relocs, we have to do them ourselves.  */
309 
310 static bfd_reloc_status_type
msp430_final_link_relocate(howto,input_bfd,input_section,contents,rel,relocation)311 msp430_final_link_relocate (howto, input_bfd, input_section,
312 			    contents, rel, relocation)
313      reloc_howto_type *howto;
314      bfd *input_bfd;
315      asection *input_section;
316      bfd_byte *contents;
317      Elf_Internal_Rela *rel;
318      bfd_vma relocation;
319 {
320   bfd_reloc_status_type r = bfd_reloc_ok;
321   bfd_vma x;
322   bfd_signed_vma srel;
323 
324   switch (howto->type)
325     {
326     case R_MSP430_10_PCREL:
327       contents += rel->r_offset;
328       srel = (bfd_signed_vma) relocation;
329       srel += rel->r_addend;
330       srel -= rel->r_offset;
331       srel -= 2;		/* Branch instructions add 2 to the PC...  */
332       srel -= (input_section->output_section->vma +
333 	       input_section->output_offset);
334 
335       if (srel & 1)
336 	return bfd_reloc_outofrange;
337 
338       /* MSP430 addresses commands as words.  */
339       srel >>= 1;
340 
341       /* Check for an overflow.  */
342       if (srel < -512 || srel > 511)
343 	return bfd_reloc_overflow;
344 
345       x = bfd_get_16 (input_bfd, contents);
346       x = (x & 0xfc00) | (srel & 0x3ff);
347       bfd_put_16 (input_bfd, x, contents);
348       break;
349 
350     case R_MSP430_16_PCREL:
351       contents += rel->r_offset;
352       srel = (bfd_signed_vma) relocation;
353       srel += rel->r_addend;
354       srel -= rel->r_offset;
355       /* Only branch instructions add 2 to the PC...  */
356       srel -= (input_section->output_section->vma +
357 	       input_section->output_offset);
358 
359       if (srel & 1)
360 	return bfd_reloc_outofrange;
361 
362       bfd_put_16 (input_bfd, srel & 0xffff, contents);
363       break;
364 
365     case R_MSP430_16_PCREL_BYTE:
366       contents += rel->r_offset;
367       srel = (bfd_signed_vma) relocation;
368       srel += rel->r_addend;
369       srel -= rel->r_offset;
370       /* Only branch instructions add 2 to the PC...  */
371       srel -= (input_section->output_section->vma +
372 	       input_section->output_offset);
373 
374       bfd_put_16 (input_bfd, srel & 0xffff, contents);
375       break;
376 
377     case R_MSP430_16_BYTE:
378       contents += rel->r_offset;
379       srel = (bfd_signed_vma) relocation;
380       srel += rel->r_addend;
381       bfd_put_16 (input_bfd, srel & 0xffff, contents);
382       break;
383 
384     case R_MSP430_16:
385       contents += rel->r_offset;
386       srel = (bfd_signed_vma) relocation;
387       srel += rel->r_addend;
388 
389       if (srel & 1)
390 	return bfd_reloc_notsupported;
391 
392       bfd_put_16 (input_bfd, srel & 0xffff, contents);
393       break;
394 
395     default:
396       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
397 				    contents, rel->r_offset,
398 				    relocation, rel->r_addend);
399     }
400 
401   return r;
402 }
403 
404 /* Relocate an MSP430 ELF section.  */
405 
406 static bfd_boolean
elf32_msp430_relocate_section(output_bfd,info,input_bfd,input_section,contents,relocs,local_syms,local_sections)407 elf32_msp430_relocate_section (output_bfd, info, input_bfd, input_section,
408 			       contents, relocs, local_syms, local_sections)
409      bfd *output_bfd ATTRIBUTE_UNUSED;
410      struct bfd_link_info *info;
411      bfd *input_bfd;
412      asection *input_section;
413      bfd_byte *contents;
414      Elf_Internal_Rela *relocs;
415      Elf_Internal_Sym *local_syms;
416      asection **local_sections;
417 {
418   Elf_Internal_Shdr *symtab_hdr;
419   struct elf_link_hash_entry **sym_hashes;
420   Elf_Internal_Rela *rel;
421   Elf_Internal_Rela *relend;
422 
423   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
424   sym_hashes = elf_sym_hashes (input_bfd);
425   relend = relocs + input_section->reloc_count;
426 
427   for (rel = relocs; rel < relend; rel++)
428     {
429       reloc_howto_type *howto;
430       unsigned long r_symndx;
431       Elf_Internal_Sym *sym;
432       asection *sec;
433       struct elf_link_hash_entry *h;
434       bfd_vma relocation;
435       bfd_reloc_status_type r;
436       const char *name = NULL;
437       int r_type;
438 
439       /* This is a final link.  */
440 
441       r_type = ELF32_R_TYPE (rel->r_info);
442       r_symndx = ELF32_R_SYM (rel->r_info);
443       howto = elf_msp430_howto_table + ELF32_R_TYPE (rel->r_info);
444       h = NULL;
445       sym = NULL;
446       sec = NULL;
447 
448       if (r_symndx < symtab_hdr->sh_info)
449 	{
450 	  sym = local_syms + r_symndx;
451 	  sec = local_sections[r_symndx];
452 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
453 
454 	  name = bfd_elf_string_from_elf_section
455 	      (input_bfd, symtab_hdr->sh_link, sym->st_name);
456 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
457 	}
458       else
459 	{
460 	  bfd_boolean unresolved_reloc, warned;
461 
462 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
463 				   r_symndx, symtab_hdr, sym_hashes,
464 				   h, sec, relocation,
465 				   unresolved_reloc, warned);
466 	}
467 
468       r = msp430_final_link_relocate (howto, input_bfd, input_section,
469 				      contents, rel, relocation);
470 
471       if (r != bfd_reloc_ok)
472 	{
473 	  const char *msg = (const char *) NULL;
474 
475 	  switch (r)
476 	    {
477 	    case bfd_reloc_overflow:
478 	      r = info->callbacks->reloc_overflow
479 		  (info, name, howto->name, (bfd_vma) 0,
480 		   input_bfd, input_section, rel->r_offset);
481 	      break;
482 
483 	    case bfd_reloc_undefined:
484 	      r = info->callbacks->undefined_symbol
485 		  (info, name, input_bfd, input_section, rel->r_offset, TRUE);
486 	      break;
487 
488 	    case bfd_reloc_outofrange:
489 	      msg = _("internal error: out of range error");
490 	      break;
491 
492 	    case bfd_reloc_notsupported:
493 	      msg = _("internal error: unsupported relocation error");
494 	      break;
495 
496 	    case bfd_reloc_dangerous:
497 	      msg = _("internal error: dangerous relocation");
498 	      break;
499 
500 	    default:
501 	      msg = _("internal error: unknown error");
502 	      break;
503 	    }
504 
505 	  if (msg)
506 	    r = info->callbacks->warning
507 		(info, msg, name, input_bfd, input_section, rel->r_offset);
508 
509 	  if (!r)
510 	    return FALSE;
511 	}
512 
513     }
514 
515   return TRUE;
516 }
517 
518 /* The final processing done just before writing out a MSP430 ELF object
519    file.  This gets the MSP430 architecture right based on the machine
520    number.  */
521 
522 static void
bfd_elf_msp430_final_write_processing(abfd,linker)523 bfd_elf_msp430_final_write_processing (abfd, linker)
524      bfd *abfd;
525      bfd_boolean linker ATTRIBUTE_UNUSED;
526 {
527   unsigned long val;
528 
529   switch (bfd_get_mach (abfd))
530     {
531     default:
532     case bfd_mach_msp110:
533       val = E_MSP430_MACH_MSP430x11x1;
534       break;
535 
536     case bfd_mach_msp11:
537       val = E_MSP430_MACH_MSP430x11;
538       break;
539 
540     case bfd_mach_msp12:
541       val = E_MSP430_MACH_MSP430x12;
542       break;
543 
544     case bfd_mach_msp13:
545       val = E_MSP430_MACH_MSP430x13;
546       break;
547 
548     case bfd_mach_msp14:
549       val = E_MSP430_MACH_MSP430x14;
550       break;
551 
552     case bfd_mach_msp15:
553       val = E_MSP430_MACH_MSP430x15;
554       break;
555 
556     case bfd_mach_msp16:
557       val = E_MSP430_MACH_MSP430x16;
558       break;
559 
560     case bfd_mach_msp31:
561       val = E_MSP430_MACH_MSP430x31;
562       break;
563 
564     case bfd_mach_msp32:
565       val = E_MSP430_MACH_MSP430x32;
566       break;
567 
568     case bfd_mach_msp33:
569       val = E_MSP430_MACH_MSP430x33;
570       break;
571 
572     case bfd_mach_msp41:
573       val = E_MSP430_MACH_MSP430x41;
574       break;
575 
576     case bfd_mach_msp42:
577       val = E_MSP430_MACH_MSP430x42;
578       break;
579 
580     case bfd_mach_msp43:
581       val = E_MSP430_MACH_MSP430x43;
582       break;
583 
584     case bfd_mach_msp44:
585       val = E_MSP430_MACH_MSP430x44;
586       break;
587     }
588 
589   elf_elfheader (abfd)->e_machine = EM_MSP430;
590   elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
591   elf_elfheader (abfd)->e_flags |= val;
592 }
593 
594 /* Set the right machine number.  */
595 
596 static bfd_boolean
elf32_msp430_object_p(abfd)597 elf32_msp430_object_p (abfd)
598      bfd *abfd;
599 {
600   int e_set = bfd_mach_msp14;
601 
602   if (elf_elfheader (abfd)->e_machine == EM_MSP430
603       || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
604     {
605       int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
606 
607       switch (e_mach)
608 	{
609 	default:
610 	case E_MSP430_MACH_MSP430x11:
611 	  e_set = bfd_mach_msp11;
612 	  break;
613 
614 	case E_MSP430_MACH_MSP430x11x1:
615 	  e_set = bfd_mach_msp110;
616 	  break;
617 
618 	case E_MSP430_MACH_MSP430x12:
619 	  e_set = bfd_mach_msp12;
620 	  break;
621 
622 	case E_MSP430_MACH_MSP430x13:
623 	  e_set = bfd_mach_msp13;
624 	  break;
625 
626 	case E_MSP430_MACH_MSP430x14:
627 	  e_set = bfd_mach_msp14;
628 	  break;
629 
630 	case E_MSP430_MACH_MSP430x15:
631 	  e_set = bfd_mach_msp15;
632 	  break;
633 
634 	case E_MSP430_MACH_MSP430x16:
635 	  e_set = bfd_mach_msp16;
636 	  break;
637 
638 	case E_MSP430_MACH_MSP430x31:
639 	  e_set = bfd_mach_msp31;
640 	  break;
641 
642 	case E_MSP430_MACH_MSP430x32:
643 	  e_set = bfd_mach_msp32;
644 	  break;
645 
646 	case E_MSP430_MACH_MSP430x33:
647 	  e_set = bfd_mach_msp33;
648 	  break;
649 
650 	case E_MSP430_MACH_MSP430x41:
651 	  e_set = bfd_mach_msp41;
652 	  break;
653 
654 	case E_MSP430_MACH_MSP430x42:
655 	  e_set = bfd_mach_msp42;
656 	  break;
657 
658 	case E_MSP430_MACH_MSP430x43:
659 	  e_set = bfd_mach_msp43;
660 	  break;
661 
662 	case E_MSP430_MACH_MSP430x44:
663 	  e_set = bfd_mach_msp44;
664 	  break;
665 	}
666     }
667 
668   return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
669 }
670 
671 static void
elf32_msp430_post_process_headers(abfd,link_info)672 elf32_msp430_post_process_headers (abfd, link_info)
673      bfd *abfd;
674      struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
675 {
676   Elf_Internal_Ehdr *i_ehdrp;	/* ELF file header, internal form.  */
677 
678   i_ehdrp = elf_elfheader (abfd);
679 
680 #ifndef ELFOSABI_STANDALONE
681 #define ELFOSABI_STANDALONE	255
682 #endif
683 
684   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
685 }
686 
687 
688 #define ELF_ARCH		bfd_arch_msp430
689 #define ELF_MACHINE_CODE	EM_MSP430
690 #define ELF_MACHINE_ALT1	EM_MSP430_OLD
691 #define ELF_MAXPAGESIZE		1
692 
693 #define TARGET_LITTLE_SYM       bfd_elf32_msp430_vec
694 #define TARGET_LITTLE_NAME	"elf32-msp430"
695 
696 #define elf_info_to_howto	             msp430_info_to_howto_rela
697 #define elf_info_to_howto_rel	             NULL
698 #define elf_backend_relocate_section         elf32_msp430_relocate_section
699 #define elf_backend_gc_mark_hook             elf32_msp430_gc_mark_hook
700 #define elf_backend_gc_sweep_hook            elf32_msp430_gc_sweep_hook
701 #define elf_backend_check_relocs             elf32_msp430_check_relocs
702 #define elf_backend_can_gc_sections          1
703 #define elf_backend_final_write_processing   bfd_elf_msp430_final_write_processing
704 #define elf_backend_object_p		     elf32_msp430_object_p
705 #define elf_backend_post_process_headers     elf32_msp430_post_process_headers
706 
707 #include "elf32-target.h"
708