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;
{"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
}
#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);
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
}
}
\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.
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;
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;
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);
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)
{
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;
*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);
#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
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
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
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);
/* 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:
#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;
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 */