Add ARM v5t, v5te and XScale support
[deliverable/binutils-gdb.git] / bfd / coffcode.h
index 25a90bb1e73a741fd0ad3281e7ce08ea2772cf6c..c5025fb52d1bd14a3917a3506e9b71a5a57401f4 100644 (file)
@@ -398,7 +398,11 @@ sec_to_styp_flags (sec_name, sec_flags)
     }
   else if (!strncmp (sec_name, ".stab", 5))
     {
+#ifdef COFF_ALIGN_IN_S_FLAGS
+      styp_flags = STYP_DSECT;
+#else
       styp_flags = STYP_INFO;
+#endif
     }
 #ifdef RS6000COFF_C
   else if (!strcmp (sec_name, _PAD))
@@ -436,6 +440,16 @@ sec_to_styp_flags (sec_name, sec_flags)
       styp_flags = STYP_BSS;
     }
 
+#ifdef STYP_CLINK
+  if (sec_flags & SEC_CLINK)
+    styp_flags |= STYP_CLINK;
+#endif
+
+#ifdef STYP_BLOCK
+  if (sec_flags & SEC_BLOCK)
+    styp_flags |= STYP_BLOCK;
+#endif
+
 #ifdef STYP_NOLOAD
   if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0)
     styp_flags |= STYP_NOLOAD;
@@ -533,6 +547,16 @@ styp_to_sec_flags (abfd, hdr, name, section)
   long styp_flags = internal_s->s_flags;
   flagword sec_flags = 0;
 
+#ifdef STYP_BLOCK
+  if (styp_flags & STYP_BLOCK)
+      sec_flags |= SEC_BLOCK;
+#endif  
+
+#ifdef STYP_CLINK
+  if (styp_flags & STYP_CLINK)
+      sec_flags |= SEC_CLINK;
+#endif  
+
 #ifdef STYP_NOLOAD
   if (styp_flags & STYP_NOLOAD)
     {
@@ -760,7 +784,7 @@ styp_to_sec_flags (abfd, hdr, name, section)
        {
          bfd_byte *esymstart, *esym, *esymend;
          int seen_state = 0;
-         char *target_name;
+         char *target_name = NULL;
 
          esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd);
          esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
@@ -1100,6 +1124,8 @@ dependent COFF routines:
 . boolean _bfd_coff_long_filenames;
 . boolean _bfd_coff_long_section_names;
 . unsigned int _bfd_coff_default_section_alignment_power;
+. boolean _bfd_coff_force_symnames_in_strings;
+. unsigned int _bfd_coff_debug_string_prefix_length;
 . void (*_bfd_coff_swap_filehdr_in) PARAMS ((
 .       bfd     *abfd,
 .       PTR     ext,
@@ -1297,6 +1323,12 @@ dependent COFF routines:
 .#define bfd_coff_symname_in_debug(abfd, sym)\
 .        ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym))
 .
+.#define bfd_coff_force_symnames_in_strings(abfd)\
+.      (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings)
+.
+.#define bfd_coff_debug_string_prefix_length(abfd)\
+.      (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length)
+.
 .#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\
 .        ((coff_backend_info (abfd)->_bfd_coff_print_aux)\
 .         (abfd, file, base, symbol, aux, indaux))
@@ -1434,8 +1466,8 @@ static const unsigned int coff_section_alignment_table_size =
 
 static boolean
 coff_new_section_hook (abfd, section)
-     bfd *abfd;
-     asection *section;
+     bfd * abfd;
+     asection * section;
 {
   combined_entry_type *native;
 
@@ -1500,10 +1532,17 @@ coff_set_alignment_hook (abfd, section, scnhdr)
       break;
 #endif
 #ifdef TIC80COFF
-  /* TI tools hijack bits 8-11 for the alignment */
+  /* TI tools puts the alignment power in bits 8-11 */
   i = (hdr->s_flags >> 8) & 0xF ;
+#endif
+#ifdef COFF_DECODE_ALIGNMENT
+  i = COFF_DECODE_ALIGNMENT(hdr->s_flags);
 #endif
   section->alignment_power = i;
+
+#ifdef coff_set_section_load_page
+  coff_set_section_load_page (section, hdr->s_page);
+#endif
 }
 
 #else /* ! COFF_ALIGN_IN_SECTION_HEADER */
@@ -1568,6 +1607,23 @@ coff_set_alignment_hook (abfd, section, scnhdr)
   pei_section_data (abfd, section)->pe_flags = hdr->s_flags;
 
   section->lma = hdr->s_vaddr;
+
+  /* check for extended relocs */
+  if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
+    {
+      struct external_reloc dst;
+      struct internal_reloc n;
+      int oldpos = bfd_tell (abfd);
+      bfd_seek (abfd, hdr->s_relptr, 0);
+      if (bfd_read ((PTR) & dst, 1, bfd_coff_relsz (abfd), abfd)
+         != bfd_coff_relsz (abfd))
+       return;
+      
+      coff_swap_reloc_in (abfd, &dst, &n);
+      bfd_seek (abfd, oldpos, 0);
+      section->reloc_count =
+       hdr->s_nreloc = n.r_vaddr;
+    }
 }
 #undef ALIGN_SET
 #undef ELIFALIGN_SET
@@ -1692,6 +1748,11 @@ coff_mkobject_hook (abfd, filehdr, aouthdr)
       struct xcoff_tdata *xcoff;
 
       xcoff = xcoff_data (abfd);
+# ifdef U803XTOCMAGIC
+      xcoff->xcoff64 = internal_f->f_magic == U803XTOCMAGIC;
+# else
+      xcoff->xcoff64 = 0;
+# endif
       xcoff->full_aouthdr = true;
       xcoff->toc = internal_a->o_toc;
       xcoff->sntoc = internal_a->o_sntoc;
@@ -1756,6 +1817,12 @@ coff_set_arch_mach_hook (abfd, filehdr)
       machine = 0;
       break;
 #endif
+#ifdef IA64MAGIC
+    case IA64MAGIC:
+      arch = bfd_arch_ia64;
+      machine = 0;
+      break;
+#endif
 #ifdef A29K_MAGIC_BIG
     case A29K_MAGIC_BIG:
     case A29K_MAGIC_LITTLE:
@@ -1864,9 +1931,13 @@ coff_set_arch_mach_hook (abfd, filehdr)
 #endif
 
 #ifdef RS6000COFF_C
+#ifdef XCOFF64
+    case U803XTOCMAGIC:
+#else
     case U802ROMAGIC:
     case U802WRMAGIC:
     case U802TOCMAGIC:
+#endif
       {
        int cputype;
 
@@ -1893,7 +1964,7 @@ coff_set_arch_mach_hook (abfd, filehdr)
                    free (buf);
                    return false;
                  }
-               coff_swap_sym_in (abfd, (PTR) buf, (PTR) &sym);
+               bfd_coff_swap_sym_in (abfd, (PTR) buf, (PTR) &sym);
                if (sym.n_sclass == C_FILE)
                  cputype = sym.n_type & 0xff;
                else
@@ -1912,28 +1983,33 @@ coff_set_arch_mach_hook (abfd, filehdr)
               (because that's how they were bootstrapped originally),
               but they are always PowerPC architecture.  */
            arch = bfd_arch_powerpc;
-           machine = 0;
+           machine = bfd_mach_ppc;
+#else
+#ifdef XCOFF64
+           arch = bfd_arch_powerpc;
+           machine = bfd_mach_ppc_620;
 #else
            arch = bfd_arch_rs6000;
-           machine = 6000;
+           machine = bfd_mach_rs6k;
+#endif
 #endif /* POWERMAC */
            break;
 
          case 1:
            arch = bfd_arch_powerpc;
-           machine = 601;
+           machine = bfd_mach_ppc_601;
            break;
          case 2: /* 64 bit PowerPC */
            arch = bfd_arch_powerpc;
-           machine = 620;
+           machine = bfd_mach_ppc_620;
            break;
          case 3:
            arch = bfd_arch_powerpc;
-           machine = 0;
+           machine = bfd_mach_ppc;
            break;
          case 4:
            arch = bfd_arch_rs6000;
-           machine = 6000;
+           machine = bfd_mach_rs6k;
            break;
          }
       }
@@ -2015,6 +2091,37 @@ coff_set_arch_mach_hook (abfd, filehdr)
       break;
 #endif
 
+#ifdef TICOFF0MAGIC
+#ifdef TICOFF_TARGET_ARCH
+      /* this TI COFF section should be used by all new TI COFF v0 targets */
+    case TICOFF0MAGIC:
+      arch = TICOFF_TARGET_ARCH;
+      break;
+#endif
+#endif
+
+#ifdef TICOFF1MAGIC
+      /* this TI COFF section should be used by all new TI COFF v1/2 targets */
+      /* TI COFF1 and COFF2 use the target_id field to specify which arch */
+    case TICOFF1MAGIC:
+    case TICOFF2MAGIC:
+      switch (internal_f->f_target_id)
+        {
+#ifdef TI_TARGET_ID
+        case TI_TARGET_ID:
+          arch = TICOFF_TARGET_ARCH;
+          break;
+#endif
+        default:
+          arch = bfd_arch_obscure;
+          (*_bfd_error_handler)
+            (_("Unrecognized TI COFF target id '0x%x'"), 
+             internal_f->f_target_id);
+          break;
+        }
+      break;
+#endif
+
 #ifdef TIC80_ARCH_MAGIC
     case TIC80_ARCH_MAGIC:
       arch = bfd_arch_tic80;
@@ -2057,6 +2164,10 @@ symname_in_debug_hook (abfd, sym)
 
 #ifdef RS6000COFF_C
 
+#ifdef XCOFF64
+#define FORCE_SYMNAMES_IN_STRINGS
+#endif
+
 /* Handle the csect auxent of a C_EXT or C_HIDEXT symbol.  */
 
 static boolean coff_pointerize_aux_hook
@@ -2242,6 +2353,22 @@ coff_write_relocs (abfd, first_undef)
 
       if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
        return false;
+
+#ifdef COFF_WITH_PE
+      if (s->reloc_count > 0xffff)
+       {
+         /* encode real count here as first reloc */
+         struct internal_reloc n;
+         memset ((PTR) & n, 0, sizeof (n));
+         /* add one to count *this* reloc (grr) */
+         n.r_vaddr = s->reloc_count + 1;
+         coff_swap_reloc_out (abfd, &n, &dst);
+         if (bfd_write ((PTR) & dst, 1, bfd_coff_relsz (abfd), abfd)
+             != bfd_coff_relsz (abfd))
+           return false;
+       }
+#endif
+
       for (i = 0; i < s->reloc_count; i++)
        {
          struct internal_reloc n;
@@ -2407,6 +2534,33 @@ coff_set_flags (abfd, magicp, flagsp)
       *magicp = TIC30MAGIC;
       return true;
 #endif
+
+#ifdef TICOFF_DEFAULT_MAGIC
+    case TICOFF_TARGET_ARCH:
+      /* if there's no indication of which version we want, use the default */
+      if (!abfd->xvec )
+        *magicp = TICOFF_DEFAULT_MAGIC;
+      else
+        {
+          /* we may want to output in a different COFF version */
+          switch (abfd->xvec->name[4])
+            {
+            case '0':
+              *magicp = TICOFF0MAGIC;
+              break;
+            case '1':
+              *magicp = TICOFF1MAGIC;
+              break;
+            case '2':
+              *magicp = TICOFF2MAGIC;
+              break;
+            default:
+              return false;
+            }
+        }
+      return true;
+#endif
+
 #ifdef TIC80_ARCH_MAGIC
     case bfd_arch_tic80:
       *magicp = TIC80_ARCH_MAGIC;
@@ -2442,7 +2596,10 @@ coff_set_flags (abfd, magicp, flagsp)
        case bfd_mach_arm_4:  * flagsp |= F_ARM_4;  break;
        case bfd_mach_arm_4T: * flagsp |= F_ARM_4T; break;
        case bfd_mach_arm_5:  * flagsp |= F_ARM_5;  break;
-       case bfd_mach_arm_5T: * flagsp |= F_ARM_5;  break; /* XXX - we do not have an F_ARM_5T */
+         /* FIXME: we do not have F_ARM vaues greater than F_ARM_5.  */
+       case bfd_mach_arm_5T: * flagsp |= F_ARM_5;  break;
+       case bfd_mach_arm_5TE: * flagsp |= F_ARM_5; break;
+       case bfd_mach_arm_XScale: * flagsp |= F_ARM_5; break;
        }
       return true;
 #endif
@@ -2468,6 +2625,12 @@ coff_set_flags (abfd, magicp, flagsp)
       return true;
       break;
 #endif
+#ifdef IA64MAGIC
+    case bfd_arch_ia64:
+      *magicp = IA64MAGIC;
+      return true;
+      break;
+#endif
 #ifdef MC68MAGIC
     case bfd_arch_m68k:
 #ifdef APOLLOM68KMAGIC
@@ -2566,12 +2729,19 @@ coff_set_flags (abfd, magicp, flagsp)
       break;
 #endif
 
-#ifdef U802TOCMAGIC
+#ifdef RS6000COFF_C
     case bfd_arch_rs6000:
 #ifndef PPCMAGIC
     case bfd_arch_powerpc:
 #endif
-      *magicp = U802TOCMAGIC;
+#ifdef XCOFF64
+      if (bfd_get_mach (abfd) == bfd_mach_ppc_620
+         && !strncmp (abfd->xvec->name,"aix", 3))
+       *magicp = U803XTOCMAGIC; 
+      else
+#else
+       *magicp = U802TOCMAGIC; 
+#endif
       return true;
       break;
 #endif
@@ -2582,9 +2752,15 @@ coff_set_flags (abfd, magicp, flagsp)
       return true;
 #endif
       
-    default:                   /* Unknown architecture */
-      /* return false;  -- fall through to "return false" below, to avoid
-       "statement never reached" errors on the one below. */
+#ifdef W65MAGIC
+    case bfd_arch_w65:
+      *magicp = W65MAGIC;
+      return true;
+#endif
+
+    default:                   /* Unknown architecture.  */
+      /* Fall through to "return false" below, to avoid
+        "statement never reached" errors on the one below.  */
       break;
     }
 
@@ -2641,7 +2817,7 @@ sort_by_secaddr (arg1, arg2)
 #ifndef I960
 #define ALIGN_SECTIONS_IN_FILE
 #endif
-#ifdef TIC80COFF
+#if defined(TIC80COFF) || defined(TICOFF)
 #undef ALIGN_SECTIONS_IN_FILE
 #endif
 
@@ -2679,8 +2855,8 @@ coff_compute_section_file_positions (abfd)
              size_t len;
 
              len = strlen (bfd_asymbol_name (*symp));
-             if (len > SYMNMLEN)
-               sz += len + 3;
+             if (len > SYMNMLEN || bfd_coff_force_symnames_in_strings (abfd))
+               sz += len + 1 + bfd_coff_debug_string_prefix_length (abfd);
            }
        }
       if (sz > 0)
@@ -3036,7 +3212,7 @@ coff_write_object_contents (abfd)
   file_ptr reloc_base;
   file_ptr lineno_base;
   file_ptr sym_base;
-  unsigned long reloc_size = 0;
+  unsigned long reloc_size = 0, reloc_count = 0;
   unsigned long lnno_size = 0;
   boolean long_section_names;
   asection *text_sec = NULL;
@@ -3067,7 +3243,16 @@ coff_write_object_contents (abfd)
 
   for (current = abfd->sections; current != NULL; current =
        current->next)
-    reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
+    {
+#ifdef COFF_WITH_PE
+      /* we store the actual reloc count in the first reloc's addr */
+      if (current->reloc_count > 0xffff)
+       reloc_count ++;
+#endif
+      reloc_count += current->reloc_count;
+    }
+
+  reloc_size = reloc_count * bfd_coff_relsz (abfd);
 
   lineno_base = reloc_base + reloc_size;
   sym_base = lineno_base + lnno_size;
@@ -3090,6 +3275,11 @@ coff_write_object_contents (abfd)
        {
          current->rel_filepos = reloc_base;
          reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
+#ifdef COFF_WITH_PE
+         /* extra reloc to hold real count */
+         if (current->reloc_count > 0xffff)
+           reloc_base += bfd_coff_relsz (abfd);
+#endif
        }
       else
        {
@@ -3164,6 +3354,9 @@ coff_write_object_contents (abfd)
       section.s_vaddr = current->vma;
       section.s_paddr = current->lma;
       section.s_size =  current->_raw_size;
+#ifdef coff_get_section_load_page
+      section.s_page = coff_get_section_load_page (current); 
+#endif
 
 #ifdef COFF_WITH_PE
       section.s_paddr = 0;
@@ -3206,12 +3399,14 @@ coff_write_object_contents (abfd)
        hasdebug = true;
 
 #ifdef RS6000COFF_C
+#ifndef XCOFF64
       /* Indicate the use of an XCOFF overflow section header.  */
       if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
        {
          section.s_nreloc = 0xffff;
          section.s_nlnno = 0xffff;
        }
+#endif
 #endif
 
       section.s_flags = sec_to_styp_flags (current->name, current->flags);
@@ -3233,10 +3428,13 @@ coff_write_object_contents (abfd)
       section.s_align = (current->alignment_power
                         ? 1 << current->alignment_power
                         : 0);
-#else
-#ifdef TIC80COFF
+#endif
+#ifdef TIC80COFF 
+      /* TI COFF puts the alignment power in bits 8-11 of the flags */
       section.s_flags |= (current->alignment_power & 0xF) << 8;
 #endif
+#ifdef COFF_ENCODE_ALIGNMENT
+      COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
 #endif
 
 #ifdef COFF_IMAGE_WITH_PE
@@ -3253,7 +3451,7 @@ coff_write_object_contents (abfd)
          SCNHDR buff;
          if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
              || bfd_write ((PTR) (&buff), 1, bfd_coff_scnhsz (abfd), abfd)
-                  != bfd_coff_scnhsz (abfd))
+             != bfd_coff_scnhsz (abfd))
            return false;
        }
 
@@ -3375,7 +3573,7 @@ coff_write_object_contents (abfd)
          scnhdr.s_flags = STYP_OVRFLO;
          if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
              || bfd_write ((PTR) &buff, 1, bfd_coff_scnhsz (abfd), abfd)
-                  != bfd_coff_scnhsz (abfd))
+             != bfd_coff_scnhsz (abfd))
            return false;
        }
     }
@@ -3426,6 +3624,11 @@ coff_write_object_contents (abfd)
     internal_f.f_flags |= F_AR32W;
 #endif
 
+#ifdef TI_TARGET_ID
+  /* target id is used in TI COFF v1 and later; COFF0 won't use this field,
+     but it doesn't hurt to set it internally */
+  internal_f.f_target_id = TI_TARGET_ID;
+#endif
 #ifdef TIC80_TARGET_ID
   internal_f.f_target_id = TIC80_TARGET_ID;
 #endif
@@ -3467,6 +3670,10 @@ coff_write_object_contents (abfd)
       internal_a.magic = NMAGIC; /* Assume separate i/d */
 #define __A_MAGIC_SET__
 #endif /* A29K */
+#ifdef TICOFF_AOUT_MAGIC
+    internal_a.magic = TICOFF_AOUT_MAGIC;
+#define __A_MAGIC_SET__
+#endif
 #ifdef TIC80COFF
     internal_a.magic = TIC80_ARCH_MAGIC;
 #define __A_MAGIC_SET__
@@ -3531,6 +3738,11 @@ coff_write_object_contents (abfd)
 #endif /* LYNXOS */
 #endif /* I386 */
 
+#if defined(IA64)
+#define __A_MAGIC_SET__
+    internal_a.magic = ZMAGIC;
+#endif /* IA64 */
+
 #if defined(SPARC)
 #define __A_MAGIC_SET__
 #if defined(LYNXOS)
@@ -3947,7 +4159,7 @@ coff_slurp_line_table (abfd, asect)
       while (counter < asect->lineno_count)
        {
          struct internal_lineno dst;
-         coff_swap_lineno_in (abfd, src, &dst);
+         bfd_coff_swap_lineno_in (abfd, src, &dst);
          cache_ptr->line_number = dst.l_lnno;
 
          if (cache_ptr->line_number == 0)
@@ -4200,7 +4412,8 @@ coff_slurp_symbol_table (abfd)
 #endif
            case C_REGPARM:     /* register parameter            */
            case C_REG: /* register variable             */
-#ifndef TIC80COFF
+              /* C_AUTOARG conflictes with TI COFF C_UEXT */
+#if !defined (TIC80COFF) && !defined (TICOFF)
 #ifdef C_AUTOARG
            case C_AUTOARG:     /* 960-specific storage class */
 #endif
@@ -4281,7 +4494,7 @@ coff_slurp_symbol_table (abfd)
 #endif
 
            case C_BLOCK:       /* ".bb" or ".eb"                */
-           case C_FCN:         /* ".bf" or ".ef" (or PE ".lf")  */
+           case C_FCN:         /* ".bf" or ".ef" (or PE ".lf")  */
            case C_EFCN:        /* physical end of function      */
 #if defined COFF_WITH_PE
              /* PE sets the symbol to a value relative to the start
@@ -4304,6 +4517,11 @@ coff_slurp_symbol_table (abfd)
 #endif
              break;
 
+           case C_STATLAB:     /* Static load time label */
+              dst->symbol.value = src->u.syment.n_value;
+              dst->symbol.flags = BSF_GLOBAL;
+              break;
+
            case C_NULL:
              /* PE DLLs sometimes have zeroed out symbols for some
                  reason.  Just ignore them without a warning.  */
@@ -4322,11 +4540,10 @@ coff_slurp_symbol_table (abfd)
              /* NT uses 0x67 for a weak symbol, not C_ALIAS.  */
            case C_ALIAS:       /* duplicate tag                 */
 #endif
-             /* New storage classes for TIc80 */
-#ifdef TIC80COFF
+             /* New storage classes for TI COFF */ 
+#if defined(TIC80COFF) || defined(TICOFF)
            case C_UEXT:        /* Tentative external definition */
 #endif
-           case C_STATLAB:     /* Static load time label */
            case C_EXTLAB:      /* External load time label */
            case C_HIDDEN:      /* ext symbol in dmert public lib */
            default:
@@ -4884,6 +5101,16 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table =
   false,
 #endif
   COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
+#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
+  true,
+#else
+  false,
+#endif
+#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
+  4,
+#else
+  2,
+#endif
   coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
   coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
   coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
This page took 0.037144 seconds and 4 git commands to generate.