Home | History | Annotate | Download | only in bfd
      1 /* Renesas / SuperH specific support for Symbian 32-bit ELF files
      2    Copyright (C) 2004-2016 Free Software Foundation, Inc.
      3    Contributed by Red Hat
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 
     23 /* Stop elf32-sh.c from defining any target vectors.  */
     24 #define SH_TARGET_ALREADY_DEFINED
     25 #define sh_find_elf_flags           sh_symbian_find_elf_flags
     26 #define sh_elf_get_flags_from_mach  sh_symbian_elf_get_flags_from_mach
     27 #include "elf32-sh.c"
     28 
     29 
     30 //#define SYMBIAN_DEBUG 1
     31 #define SYMBIAN_DEBUG 0
     32 
     33 #define DIRECTIVE_HEADER	"#<SYMEDIT>#\n"
     34 #define DIRECTIVE_IMPORT	"IMPORT "
     35 #define DIRECTIVE_EXPORT	"EXPORT "
     36 #define DIRECTIVE_AS		"AS "
     37 
     38 /* Macro to advance 's' until either it reaches 'e' or the
     39    character pointed to by 's' is equal to 'c'.  If 'e' is
     40    reached and SYMBIAN_DEBUG is enabled then the error message 'm'
     41    is displayed.  */
     42 #define SKIP_UNTIL(s,e,c,m)					\
     43   do								\
     44     {								\
     45       while (s < e && *s != c)					\
     46 	++ s;							\
     47       if (s >= e)						\
     48 	{							\
     49           if (SYMBIAN_DEBUG)					\
     50 	    fprintf (stderr, "Corrupt directive: %s\n", m);	\
     51 	  result = FALSE;					\
     52 	}							\
     53     }								\
     54   while (0);							\
     55   if (!result)							\
     56      break;
     57 
     58 /* Like SKIP_UNTIL except there are two terminator characters
     59    c1 and c2.  */
     60 #define SKIP_UNTIL2(s,e,c1,c2,m)				\
     61   do								\
     62     {								\
     63       while (s < e && *s != c1 && *s != c2)			\
     64 	++ s;							\
     65       if (s >= e)						\
     66 	{							\
     67           if (SYMBIAN_DEBUG)					\
     68 	    fprintf (stderr, "Corrupt directive: %s\n", m);	\
     69 	  result = FALSE;					\
     70 	}							\
     71     }								\
     72   while (0);							\
     73   if (!result)							\
     74      break;
     75 
     76 /* Macro to advance 's' until either it reaches 'e' or the
     77    character pointed to by 's' is not equal to 'c'.  If 'e'
     78    is reached and SYMBIAN_DEBUG is enabled then the error message
     79    'm' is displayed.  */
     80 #define SKIP_WHILE(s,e,c,m)					\
     81   do								\
     82     {								\
     83       while (s < e && *s == c)					\
     84 	++ s;							\
     85       if (s >= e)						\
     86 	{							\
     87           if (SYMBIAN_DEBUG)					\
     88 	    fprintf (stderr, "Corrupt directive: %s\n", m);	\
     89 	  result = FALSE;					\
     90 	}							\
     91     }								\
     92   while (0);							\
     93   if (!result)							\
     94      break;
     95 
     96 
     97 typedef struct symbol_rename
     98 {
     99   struct symbol_rename *       next;
    100   char *                       current_name;
    101   char *                       new_name;
    102   struct elf_link_hash_entry * current_hash;
    103   unsigned long                new_symndx;
    104 }
    105 symbol_rename;
    106 
    107 static symbol_rename * rename_list = NULL;
    108 
    109 /* Accumulate a list of symbols to be renamed.  */
    110 
    111 static bfd_boolean
    112 sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd,
    113 		      char * current_name, char * new_name)
    114 {
    115   struct elf_link_hash_entry * new_hash;
    116   symbol_rename * node;
    117 
    118   if (SYMBIAN_DEBUG)
    119     fprintf (stderr, "IMPORT '%s' AS '%s'\n", current_name, new_name);
    120 
    121   for (node = rename_list; node; node = node->next)
    122     if (strcmp (node->current_name, current_name) == 0)
    123       {
    124 	if (strcmp (node->new_name, new_name) == 0)
    125 	  /* Already added to rename list.  */
    126 	  return TRUE;
    127 
    128 	bfd_set_error (bfd_error_invalid_operation);
    129 	_bfd_error_handler (_("%B: IMPORT AS directive for %s conceals previous IMPORT AS"),
    130 			    abfd, current_name);
    131 	return FALSE;
    132       }
    133 
    134   if ((node = bfd_malloc (sizeof * node)) == NULL)
    135     {
    136       if (SYMBIAN_DEBUG)
    137 	fprintf (stderr, "IMPORT AS: No mem for new rename node\n");
    138       return FALSE;
    139     }
    140 
    141   if ((node->current_name = bfd_malloc (strlen (current_name) + 1)) == NULL)
    142     {
    143       if (SYMBIAN_DEBUG)
    144 	fprintf (stderr, "IMPORT AS: No mem for current name field in rename node\n");
    145       free (node);
    146       return FALSE;
    147     }
    148   else
    149     strcpy (node->current_name, current_name);
    150 
    151   if ((node->new_name = bfd_malloc (strlen (new_name) + 1)) == NULL)
    152     {
    153       if (SYMBIAN_DEBUG)
    154 	fprintf (stderr, "IMPORT AS: No mem for new name field in rename node\n");
    155       free (node->current_name);
    156       free (node);
    157       return FALSE;
    158     }
    159   else
    160     strcpy (node->new_name, new_name);
    161 
    162   node->next = rename_list;
    163   node->current_hash = NULL;
    164   node->new_symndx = 0;
    165   rename_list = node;
    166 
    167   new_hash = elf_link_hash_lookup (elf_hash_table (info), node->new_name, TRUE, FALSE, TRUE);
    168   bfd_elf_link_record_dynamic_symbol (info, new_hash);
    169   if (new_hash->root.type == bfd_link_hash_new)
    170     new_hash->root.type = bfd_link_hash_undefined;
    171 
    172   return TRUE;
    173 }
    174 
    175 
    176 static bfd_boolean
    177 sh_symbian_import (bfd * abfd ATTRIBUTE_UNUSED, char * name)
    178 {
    179   if (SYMBIAN_DEBUG)
    180     fprintf (stderr, "IMPORT '%s'\n", name);
    181 
    182   /* XXX: Generate an import somehow ?  */
    183 
    184   return TRUE;
    185 }
    186 
    187 static bfd_boolean
    188 sh_symbian_export (bfd * abfd ATTRIBUTE_UNUSED, char * name)
    189 {
    190   if (SYMBIAN_DEBUG)
    191     fprintf (stderr, "EXPORT '%s'\n", name);
    192 
    193   /* XXX: Generate an export somehow ?  */
    194 
    195   return TRUE;
    196 }
    197 
    198 /* Process any magic embedded commands in the .directive. section.
    199    Returns TRUE upon sucecss, but if it fails it sets bfd_error and
    200    returns FALSE.  */
    201 
    202 static bfd_boolean
    203 sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd,
    204 				      asection * sec, bfd_byte * contents)
    205 {
    206   char *s;
    207   char *e;
    208   bfd_boolean result = TRUE;
    209   bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
    210 
    211   for (s = (char *) contents, e = s + sz; s < e;)
    212     {
    213       char * directive = s;
    214 
    215       switch (*s)
    216 	{
    217 	  /* I want to use "case DIRECTIVE_HEADER [0]:" here but gcc won't let me :-(  */
    218 	case '#':
    219 	  if (strcmp (s, DIRECTIVE_HEADER))
    220 	    result = FALSE;
    221 	  else
    222 	    /* Just ignore the header.
    223 	       XXX: Strictly speaking we ought to check that the header
    224 	       is present and that it is the first thing in the file.  */
    225 	    s += strlen (DIRECTIVE_HEADER) + 1;
    226 	  break;
    227 
    228 	case 'I':
    229 	  if (! CONST_STRNEQ (s, DIRECTIVE_IMPORT))
    230 	    result = FALSE;
    231 	  else
    232 	    {
    233 	      char * new_name;
    234 	      char * new_name_end;
    235 	      char   name_end_char;
    236 
    237 	      /* Skip the IMPORT directive.  */
    238 	      s += strlen (DIRECTIVE_IMPORT);
    239 
    240 	      new_name = s;
    241 	      /* Find the end of the new name.  */
    242 	      while (s < e && *s != ' ' && *s != '\n')
    243 		++ s;
    244 	      if (s >= e)
    245 		{
    246 		  /* We have reached the end of the .directive section
    247 		     without encountering a string terminator.  This is
    248 		     allowed for IMPORT directives.  */
    249 		  new_name_end   = e - 1;
    250 		  name_end_char  = * new_name_end;
    251 		  * new_name_end = 0;
    252 		  result = sh_symbian_import (abfd, new_name);
    253 		  * new_name_end = name_end_char;
    254 		  break;
    255 		}
    256 
    257 	      /* Remember where the name ends.  */
    258 	      new_name_end = s;
    259 	      /* Skip any whitespace before the 'AS'.  */
    260 	      SKIP_WHILE (s, e, ' ', "IMPORT: Name just followed by spaces");
    261 	      /* Terminate the new name.  (Do this after skiping...)  */
    262 	      name_end_char = * new_name_end;
    263 	      * new_name_end = 0;
    264 
    265 	      /* Check to see if 'AS '... is present.  If so we have an
    266 		 IMPORT AS directive, otherwise we have an IMPORT directive.  */
    267 	      if (! CONST_STRNEQ (s, DIRECTIVE_AS))
    268 		{
    269 		  /* Skip the new-line at the end of the name.  */
    270 		  if (SYMBIAN_DEBUG && name_end_char != '\n')
    271 		    fprintf (stderr, "IMPORT: No newline at end of directive\n");
    272 		  else
    273 		    s ++;
    274 
    275 		  result = sh_symbian_import (abfd, new_name);
    276 
    277 		  /* Skip past the NUL character.  */
    278 		  if (* s ++ != 0)
    279 		    {
    280 		      if (SYMBIAN_DEBUG)
    281 			fprintf (stderr, "IMPORT: No NUL at end of directive\n");
    282 		    }
    283 		}
    284 	      else
    285 		{
    286 		  char * current_name;
    287 		  char * current_name_end;
    288 		  char   current_name_end_char;
    289 
    290 		  /* Skip the 'AS '.  */
    291 		  s += strlen (DIRECTIVE_AS);
    292 		  /* Skip any white space after the 'AS '.  */
    293 		  SKIP_WHILE (s, e, ' ', "IMPORT AS: Nothing after AS");
    294 		  current_name = s;
    295 		  /* Find the end of the current name.  */
    296 		  SKIP_UNTIL2 (s, e, ' ', '\n', "IMPORT AS: No newline at the end of the current name");
    297 		  /* Skip (backwards) over spaces at the end of the current name.  */
    298 		  current_name_end = s;
    299 		  current_name_end_char = * current_name_end;
    300 
    301 		  SKIP_WHILE (s, e, ' ', "IMPORT AS: Current name just followed by spaces");
    302 		  /* Skip past the newline character.  */
    303 		  if (* s ++ != '\n')
    304 		    if (SYMBIAN_DEBUG)
    305 		      fprintf (stderr, "IMPORT AS: No newline at end of directive\n");
    306 
    307 		  /* Terminate the current name after having performed the skips.  */
    308 		  * current_name_end = 0;
    309 
    310 		  result = sh_symbian_import_as (info, abfd, current_name, new_name);
    311 
    312 		  /* The next character should be a NUL.  */
    313 		  if (* s != 0)
    314 		    {
    315 		      if (SYMBIAN_DEBUG)
    316 			fprintf (stderr, "IMPORT AS: Junk at end of directive\n");
    317 		      result = FALSE;
    318 		    }
    319 		  s ++;
    320 
    321 		  * current_name_end = current_name_end_char;
    322 		}
    323 
    324 	      /* Restore the characters we overwrote, since
    325 		 the .directive section will be emitted.  */
    326 	      * new_name_end = name_end_char;
    327 	    }
    328 	  break;
    329 
    330 	case 'E':
    331 	  if (! CONST_STRNEQ (s, DIRECTIVE_EXPORT))
    332 	    result = FALSE;
    333 	  else
    334 	    {
    335 	      char * name;
    336 	      char * name_end;
    337 	      char   name_end_char;
    338 
    339 	      /* Skip the directive.  */
    340 	      s += strlen (DIRECTIVE_EXPORT);
    341 	      name = s;
    342 	      /* Find the end of the name to be exported.  */
    343 	      SKIP_UNTIL (s, e, '\n', "EXPORT: no newline at end of directive");
    344 	      /* Skip (backwards) over spaces at end of exported name.  */
    345 	      for (name_end = s; name_end[-1] == ' '; name_end --)
    346 		;
    347 	      /* name_end now points at the first character after the
    348 		 end of the exported name, so we can termiante it  */
    349 	      name_end_char = * name_end;
    350 	      * name_end = 0;
    351 	      /* Skip passed the newline character.  */
    352 	      s ++;
    353 
    354 	      result = sh_symbian_export (abfd, name);
    355 
    356 	      /* The next character should be a NUL.  */
    357 	      if (* s != 0)
    358 		{
    359 		  if (SYMBIAN_DEBUG)
    360 		    fprintf (stderr, "EXPORT: Junk at end of directive\n");
    361 		  result = FALSE;
    362 		}
    363 	      s++;
    364 
    365 	      /* Restore the character we deleted.  */
    366 	      * name_end = name_end_char;
    367 	    }
    368 	  break;
    369 
    370 	default:
    371 	  result = FALSE;
    372 	  break;
    373 	}
    374 
    375       if (! result)
    376 	{
    377 	  if (SYMBIAN_DEBUG)
    378 	    fprintf (stderr, "offset into .directive section: %ld\n",
    379 		     (long) (directive - (char *) contents));
    380 
    381 	  bfd_set_error (bfd_error_invalid_operation);
    382 	  _bfd_error_handler (_("%B: Unrecognised .directive command: %s"),
    383 			      abfd, directive);
    384 	  break;
    385 	}
    386     }
    387 
    388   return result;
    389 }
    390 
    391 
    392 /* Scan a bfd for a .directive section, and if found process it.
    393    Returns TRUE upon success, FALSE otherwise.  */
    394 
    395 static bfd_boolean
    396 sh_symbian_process_directives (bfd *abfd, struct bfd_link_info *info)
    397 {
    398   bfd_boolean result = FALSE;
    399   bfd_byte *  contents;
    400   asection *  sec = bfd_get_section_by_name (abfd, ".directive");
    401   bfd_size_type sz;
    402 
    403   if (!sec)
    404     return TRUE;
    405 
    406   sz = sec->rawsize ? sec->rawsize : sec->size;
    407   contents = bfd_malloc (sz);
    408 
    409   if (!contents)
    410     bfd_set_error (bfd_error_no_memory);
    411   else
    412     {
    413       if (bfd_get_section_contents (abfd, sec, contents, 0, sz))
    414 	result = sh_symbian_process_embedded_commands (info, abfd, sec, contents);
    415       free (contents);
    416     }
    417 
    418   return result;
    419 }
    420 
    421 /* Intercept the normal sh_relocate_section() function
    422    and magle the relocs to allow for symbol renaming.  */
    423 
    424 static bfd_boolean
    425 sh_symbian_relocate_section (bfd *                  output_bfd,
    426 			     struct bfd_link_info * info,
    427 			     bfd *                  input_bfd,
    428 			     asection *             input_section,
    429 			     bfd_byte *             contents,
    430 			     Elf_Internal_Rela *    relocs,
    431 			     Elf_Internal_Sym *     local_syms,
    432 			     asection **            local_sections)
    433 {
    434   /* When performing a final link we implement the IMPORT AS directives.  */
    435   if (!bfd_link_relocatable (info))
    436     {
    437       Elf_Internal_Rela *            rel;
    438       Elf_Internal_Rela *            relend;
    439       Elf_Internal_Shdr *            symtab_hdr;
    440       struct elf_link_hash_entry **  sym_hashes;
    441       struct elf_link_hash_entry **  sym_hashes_end;
    442       struct elf_link_hash_table *   hash_table;
    443       symbol_rename *                ptr;
    444       bfd_size_type                  num_global_syms;
    445       unsigned long		     num_local_syms;
    446 
    447       BFD_ASSERT (! elf_bad_symtab (input_bfd));
    448 
    449       symtab_hdr       = & elf_tdata (input_bfd)->symtab_hdr;
    450       hash_table       = elf_hash_table (info);
    451       num_local_syms   = symtab_hdr->sh_info;
    452       num_global_syms  = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
    453       num_global_syms -= num_local_syms;
    454       sym_hashes       = elf_sym_hashes (input_bfd);
    455       sym_hashes_end   = sym_hashes + num_global_syms;
    456 
    457       /* First scan the rename table, caching the hash entry and the new index.  */
    458       for (ptr = rename_list; ptr; ptr = ptr->next)
    459 	{
    460 	  struct elf_link_hash_entry *   new_hash;
    461 	  struct elf_link_hash_entry **  h;
    462 
    463 	  ptr->current_hash = elf_link_hash_lookup (hash_table, ptr->current_name, FALSE, FALSE, TRUE);
    464 
    465 	  if (ptr->current_hash == NULL)
    466 	    {
    467 	      if (SYMBIAN_DEBUG)
    468 		fprintf (stderr, "IMPORT AS: current symbol '%s' does not exist\n", ptr->current_name);
    469 	      continue;
    470 	    }
    471 
    472 	  new_hash = elf_link_hash_lookup (hash_table, ptr->new_name,
    473 					   FALSE, FALSE, TRUE);
    474 	  /* If we could not find the symbol then it is a new, undefined symbol.
    475 	     Symbian want this behaviour - ie they want to be able to rename the
    476 	     reference in a reloc from one undefined symbol to another, new and
    477 	     undefined symbol.  So we create that symbol here.  */
    478 	  if (new_hash == NULL)
    479 	    {
    480 	      struct bfd_link_hash_entry *bh = NULL;
    481 	      bfd_boolean collect = get_elf_backend_data (input_bfd)->collect;
    482 	      if (_bfd_generic_link_add_one_symbol (info, input_bfd,
    483 						    ptr->new_name, BSF_GLOBAL,
    484 						    bfd_und_section_ptr, 0,
    485 						    NULL, FALSE, collect,
    486 						    &bh))
    487 		{
    488 		  new_hash = (struct elf_link_hash_entry *) bh;
    489 		  new_hash->type = STT_FUNC;
    490 		  new_hash->non_elf = 0;
    491 
    492 		  if (SYMBIAN_DEBUG)
    493 		    fprintf (stderr, "Created new symbol %s\n", ptr->new_name);
    494 		}
    495 	    }
    496 
    497 	  if (new_hash == NULL)
    498 	    {
    499 	      _bfd_error_handler (_("%B: Failed to add renamed symbol %s"),
    500 				  input_bfd, ptr->new_name);
    501 	      continue;
    502 	    }
    503 
    504 	  /* Convert the new_hash value into a index into the table of symbol hashes.  */
    505 	  for (h = sym_hashes; h < sym_hashes_end; h ++)
    506 	    {
    507 	      if (* h == new_hash)
    508 		{
    509 		  ptr->new_symndx = h - sym_hashes + num_local_syms;
    510 		  if (SYMBIAN_DEBUG)
    511 		    fprintf (stderr, "Converted new hash to index of %ld\n", ptr->new_symndx);
    512 		  break;
    513 		}
    514 	    }
    515 	  /* If the new symbol is not in the hash table then it must be
    516 	     because it is one of the newly created undefined symbols
    517 	     manufactured above.  So we extend the sym has table here to
    518 	     include this extra symbol.  */
    519 	  if (h == sym_hashes_end)
    520 	    {
    521 	      struct elf_link_hash_entry **  new_sym_hashes;
    522 
    523 	      /* This is not very efficient, but it works.  */
    524 	      ++ num_global_syms;
    525 	      new_sym_hashes = bfd_alloc (input_bfd, num_global_syms * sizeof * sym_hashes);
    526 	      if (new_sym_hashes == NULL)
    527 		{
    528 		  if (SYMBIAN_DEBUG)
    529 		    fprintf (stderr, "Out of memory extending hash table\n");
    530 		  continue;
    531 		}
    532 	      memcpy (new_sym_hashes, sym_hashes, (num_global_syms - 1) * sizeof * sym_hashes);
    533 	      new_sym_hashes[num_global_syms - 1] = new_hash;
    534 	      elf_sym_hashes (input_bfd) = sym_hashes = new_sym_hashes;
    535 	      sym_hashes_end = sym_hashes + num_global_syms;
    536 	      symtab_hdr->sh_size  = (num_global_syms + num_local_syms) * sizeof (Elf32_External_Sym);
    537 
    538 	      ptr->new_symndx = num_global_syms - 1 + num_local_syms;
    539 
    540 	      if (SYMBIAN_DEBUG)
    541 		fprintf (stderr, "Extended symbol hash table to insert new symbol as index %ld\n",
    542 			 ptr->new_symndx);
    543 	    }
    544 	}
    545 
    546       /* Walk the reloc list looking for references to renamed symbols.
    547 	 When we find one, we alter the index in the reloc to point to the new symbol.  */
    548       for (rel = relocs, relend = relocs + input_section->reloc_count;
    549 	   rel < relend;
    550 	   rel ++)
    551 	{
    552 	  int                          r_type;
    553 	  unsigned long                r_symndx;
    554 	  struct elf_link_hash_entry * h;
    555 
    556 	  r_symndx = ELF32_R_SYM (rel->r_info);
    557 	  r_type = ELF32_R_TYPE (rel->r_info);
    558 
    559 	  /* Ignore unused relocs.  */
    560 	  if ((r_type >= (int) R_SH_GNU_VTINHERIT
    561 	       && r_type <= (int) R_SH_LABEL)
    562 	      || r_type == (int) R_SH_NONE
    563 	      || r_type < 0
    564 	      || r_type >= R_SH_max)
    565 	    continue;
    566 
    567 	  /* Ignore relocs against local symbols.  */
    568 	  if (r_symndx < num_local_syms)
    569 	    continue;
    570 
    571 	  BFD_ASSERT (r_symndx < (num_global_syms + num_local_syms));
    572 	  h = sym_hashes[r_symndx - num_local_syms];
    573 	  BFD_ASSERT (h != NULL);
    574 
    575 	  while (   h->root.type == bfd_link_hash_indirect
    576 		 || h->root.type == bfd_link_hash_warning)
    577 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    578 
    579 	  /* If the symbol is defined there is no need to rename it.
    580 	     XXX - is this true ?  */
    581 	  if (   h->root.type == bfd_link_hash_defined
    582 	      || h->root.type == bfd_link_hash_defweak
    583 	      || h->root.type == bfd_link_hash_undefweak)
    584 	    continue;
    585 
    586 	  for (ptr = rename_list; ptr; ptr = ptr->next)
    587 	    if (h == ptr->current_hash)
    588 	      {
    589 		BFD_ASSERT (ptr->new_symndx);
    590 		if (SYMBIAN_DEBUG)
    591 		  fprintf (stderr, "convert reloc %lx from using index %ld to using index %ld\n",
    592 			   (unsigned long) rel->r_info,
    593 			   (long) ELF32_R_SYM (rel->r_info), ptr->new_symndx);
    594 		rel->r_info = ELF32_R_INFO (ptr->new_symndx, r_type);
    595 		break;
    596 	      }
    597 	}
    598     }
    599 
    600   return sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
    601 				  contents, relocs, local_syms, local_sections);
    602 }
    603 
    604 #define TARGET_LITTLE_SYM	sh_elf32_symbian_le_vec
    605 #define TARGET_LITTLE_NAME      "elf32-shl-symbian"
    606 
    607 #undef  elf_backend_relocate_section
    608 #define elf_backend_relocate_section	sh_symbian_relocate_section
    609 #undef  elf_backend_check_directives
    610 #define elf_backend_check_directives    sh_symbian_process_directives
    611 
    612 #include "elf32-target.h"
    613