bfd/
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index cdc915b6213dcd884288b807c0f25455c6d9599f..df3a35b39fbe13b76f8519e614fe29e9668c61e3 100644 (file)
@@ -305,6 +305,7 @@ static int allow_naked_reg = 0;
    leave, push, and pop instructions so that gcc has the same stack
    frame as in 32 bit mode.  */
 static char stackop_size = '\0';
+static void handle_large_common (int small ATTRIBUTE_UNUSED);
 
 /* Non-zero to optimize code alignment.  */
 int optimize_align_code = 1;
@@ -467,6 +468,9 @@ const pseudo_typeS md_pseudo_table[] =
   {"att_syntax", set_intel_syntax, 0},
   {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
   {"loc", dwarf2_directive_loc, 0},
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+  {"largecomm", handle_large_common, 0},
+#endif
 #ifdef TE_PE
   {"secrel32", pe_directive_secrel, 0},
 #endif
@@ -1021,7 +1025,7 @@ md_begin ()
   }
 
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
-  if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+  if (IS_ELF)
     {
       record_alignment (text_section, 2);
       record_alignment (data_section, 2);
@@ -1291,7 +1295,7 @@ tc_i386_fix_adjustable (fixP)
      fixS *fixP ATTRIBUTE_UNUSED;
 {
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
-  if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+  if (!IS_ELF)
     return 1;
 
   /* Don't adjust pc-relative references to merge sections in 64-bit
@@ -3741,7 +3745,9 @@ output_imm (insn_start_frag, insn_start_off)
     }
 }
 \f
-#ifndef LEX_AT
+#if (!defined (OBJ_ELF) && !defined (OBJ_MAYBE_ELF)) || defined (LEX_AT)
+# define lex_got(reloc, adjust, types) NULL
+#else
 /* Parse operands of the form
    <symbol>@GOTOFF+<nnn>
    and similar .plt or .got references.
@@ -3779,6 +3785,9 @@ lex_got (enum bfd_reloc_code_real *reloc,
   char *cp;
   unsigned int j;
 
+  if (!IS_ELF)
+    return NULL;
+
   for (cp = input_line_pointer; *cp != '@'; cp++)
     if (is_end_of_line[(unsigned char) *cp])
       return NULL;
@@ -3944,9 +3953,7 @@ i386_immediate (imm_start)
      char *imm_start;
 {
   char *save_input_line_pointer;
-#ifndef LEX_AT
   char *gotfree_input_line;
-#endif
   segT exp_seg = 0;
   expressionS *exp;
   unsigned int types = ~0U;
@@ -3966,11 +3973,9 @@ i386_immediate (imm_start)
   save_input_line_pointer = input_line_pointer;
   input_line_pointer = imm_start;
 
-#ifndef LEX_AT
   gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types);
   if (gotfree_input_line)
     input_line_pointer = gotfree_input_line;
-#endif
 
   exp_seg = expression (exp);
 
@@ -3979,10 +3984,8 @@ i386_immediate (imm_start)
     as_bad (_("junk `%s' after expression"), input_line_pointer);
 
   input_line_pointer = save_input_line_pointer;
-#ifndef LEX_AT
   if (gotfree_input_line)
     free (gotfree_input_line);
-#endif
 
   if (exp->X_op == O_absent || exp->X_op == O_big)
     {
@@ -4089,9 +4092,7 @@ i386_displacement (disp_start, disp_end)
   expressionS *exp;
   segT exp_seg = 0;
   char *save_input_line_pointer;
-#ifndef LEX_AT
   char *gotfree_input_line;
-#endif
   int bigdisp = Disp32;
   unsigned int types = Disp;
 
@@ -4155,11 +4156,9 @@ i386_displacement (disp_start, disp_end)
       *displacement_string_end = '0';
     }
 #endif
-#ifndef LEX_AT
   gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types);
   if (gotfree_input_line)
     input_line_pointer = gotfree_input_line;
-#endif
 
   exp_seg = expression (exp);
 
@@ -4171,10 +4170,8 @@ i386_displacement (disp_start, disp_end)
 #endif
   RESTORE_END_STRING (disp_end);
   input_line_pointer = save_input_line_pointer;
-#ifndef LEX_AT
   if (gotfree_input_line)
     free (gotfree_input_line);
-#endif
 
   /* We do this to make sure that the section symbol is in
      the symbol table.  We will ultimately change the relocation
@@ -4657,7 +4654,7 @@ md_estimate_size_before_relax (fragP, segment)
      shared library.  */
   if (S_GET_SEGMENT (fragP->fr_symbol) != segment
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
-      || (OUTPUT_FLAVOR == bfd_target_elf_flavour
+      || (IS_ELF
          && (S_IS_EXTERNAL (fragP->fr_symbol)
              || S_IS_WEAK (fragP->fr_symbol)))
 #endif
@@ -4944,7 +4941,7 @@ md_apply_fix (fixP, valP, seg)
         subtract the current location (for partial_inplace, PC relative
         relocations); see more below.  */
 #ifndef OBJ_AOUT
-      if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+      if (IS_ELF
 #ifdef TE_PE
          || OUTPUT_FLAVOR == bfd_target_coff_flavour
 #endif
@@ -4952,7 +4949,7 @@ md_apply_fix (fixP, valP, seg)
        value += fixP->fx_where + fixP->fx_frag->fr_address;
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
-      if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+      if (IS_ELF)
        {
          segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy);
 
@@ -4984,8 +4981,7 @@ md_apply_fix (fixP, valP, seg)
   /* Fix a few things - the dynamic linker expects certain values here,
      and we must not disappoint it.  */
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
-  if (OUTPUT_FLAVOR == bfd_target_elf_flavour
-      && fixP->fx_addsy)
+  if (IS_ELF && fixP->fx_addsy)
     switch (fixP->fx_r_type)
       {
       case BFD_RELOC_386_PLT32:
@@ -5328,8 +5324,7 @@ i386_target_format ()
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
 void i386_elf_emit_arch_note ()
 {
-  if (OUTPUT_FLAVOR == bfd_target_elf_flavour
-      && cpu_arch_name != NULL)
+  if (IS_ELF && cpu_arch_name != NULL)
     {
       char *p;
       asection *seg = now_seg;
@@ -6999,3 +6994,71 @@ tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
   emit_expr (&expr, size);
 }
 #endif
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+/* For ELF on x86-64, add support for SHF_X86_64_LARGE.  */
+
+int
+x86_64_section_letter (int letter, char **ptr_msg)
+{
+  if (flag_code == CODE_64BIT)
+    {
+      if (letter == 'l')
+       return SHF_X86_64_LARGE;
+
+      *ptr_msg = _("Bad .section directive: want a,l,w,x,M,S,G,T in string");
+     }
+  else
+   *ptr_msg = _("Bad .section directive: want a,w,x,M,S,G,T in string");
+  return -1;
+}
+
+int
+x86_64_section_word (char *str, size_t len)
+{
+  if (len == 5 && flag_code == CODE_64BIT && strncmp (str, "large", 5) == 0)
+    return SHF_X86_64_LARGE;
+
+  return -1;
+}
+
+static void
+handle_large_common (int small ATTRIBUTE_UNUSED)
+{
+  if (flag_code != CODE_64BIT)
+    {
+      s_comm_internal (0, elf_common_parse);
+      as_warn (_(".largecomm supported only in 64bit mode, producing .comm"));
+    }
+  else
+    {
+      static segT lbss_section;
+      asection *saved_com_section_ptr = elf_com_section_ptr;
+      asection *saved_bss_section = bss_section;
+
+      if (lbss_section == NULL)
+       {
+         flagword applicable;
+         segT seg = now_seg;
+         subsegT subseg = now_subseg;
+
+         /* The .lbss section is for local .largecomm symbols.  */
+         lbss_section = subseg_new (".lbss", 0);
+         applicable = bfd_applicable_section_flags (stdoutput);
+         bfd_set_section_flags (stdoutput, lbss_section,
+                                applicable & SEC_ALLOC);
+         seg_info (lbss_section)->bss = 1;
+
+         subseg_set (seg, subseg);
+       }
+
+      elf_com_section_ptr = &_bfd_elf_large_com_section;
+      bss_section = lbss_section;
+
+      s_comm_internal (0, elf_common_parse);
+
+      elf_com_section_ptr = saved_com_section_ptr;
+      bss_section = saved_bss_section;
+    }
+}
+#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
This page took 0.030109 seconds and 4 git commands to generate.