/* coff object file format with bfd
- Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc.
This file is part of GAS.
9,
10,
C_UNDEF_SECTION, /* SEG_UNKNOWN */
- C_UNDEF_SECTION, /* SEG_ABSENT */
- C_UNDEF_SECTION, /* SEG_PASS1 */
C_UNDEF_SECTION, /* SEG_GOOF */
- C_UNDEF_SECTION, /* SEG_BIG */
- C_UNDEF_SECTION, /* SEG_DIFFERENCE */
+ C_UNDEF_SECTION, /* SEG_EXPR */
C_DEBUG_SECTION, /* SEG_DEBUG */
C_NTV_SECTION, /* SEG_NTV */
C_PTV_SECTION, /* SEG_PTV */
static void EXFUN( obj_coff_ident,(void));
static void EXFUN (obj_coff_endef, (void));
static void EXFUN (obj_coff_line, (void));
-static void EXFUN (obj_coff_ln, (void));
+static void EXFUN (obj_coff_ln, (int));
static void EXFUN (obj_coff_scl, (void));
static void EXFUN (obj_coff_size, (void));
static void EXFUN (obj_coff_tag, (void));
{"endef", obj_coff_endef, 0},
{"line", obj_coff_line, 0},
{"ln", obj_coff_ln, 0},
+ {"appline", obj_coff_ln, 1},
{"scl", obj_coff_scl, 0},
{"size", obj_coff_size, 0},
{"tag", obj_coff_tag, 0},
{"ident", obj_coff_ident, 0},
{"ABORT", s_abort, 0},
{"lcomm", obj_coff_lcomm, 0},
+#ifdef TC_M88K
+ /* The m88k uses sdef instead of def. */
+ {"sdef", obj_coff_def, 0},
+#endif
{NULL} /* end sentinel */
}; /* obj_pseudo_table */
intr.r_vaddr =
base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
+#ifdef TC_M88K
intr.r_offset = fix_ptr->fx_offset;
-
+#else
intr.r_offset = 0;
+#endif
/* Turn the segment of the symbol into an offset. */
if (symbol_ptr)
}
know (s->s_paddr == paddr);
- s->s_flags = STYP_REG;
if (strcmp (s->s_name, ".text") == 0)
s->s_flags |= STYP_TEXT;
else if (strcmp (s->s_name, ".data") == 0)
}
fill_size = frag->fr_var;
- if (fill_size)
+ if (fill_size && frag->fr_offset > 0)
{
unsigned int count;
unsigned int off = frag->fr_fix;
{
unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
unsigned int i;
+ valueT val;
/* Turn any symbols with register attributes into abs symbols */
if (S_GET_SEGMENT (symbolP) == SEG_REGISTER)
}
/* At the same time, relocate all symbols to their output value */
- S_SET_VALUE (symbolP,
- segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
- + S_GET_VALUE (symbolP));
+ val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
+ + S_GET_VALUE (symbolP));
+
+ S_SET_VALUE (symbolP, val);
+
+ symbolP->sy_symbol.ost_entry.n_value = val;
where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
where);
}
-
-
void
obj_symbol_new_hook (symbolP)
symbolS *symbolP;
*/
static void
-obj_coff_ln ()
+obj_coff_ln (appline)
+ int appline;
{
int l;
- if (def_symbol_in_progress != NULL)
+ if (! appline && def_symbol_in_progress != NULL)
{
as_warn (".ln pseudo-op inside .def/.endef: ignored.");
demand_empty_rest_of_line ();
if (listing)
{
- listing_source_line (l + line_base - 1);
+ if (! appline)
+ l += line_base - 1;
+ listing_source_line (l);
}
}
def_symbol_in_progress->sy_name_offset = ~0;
def_symbol_in_progress->sy_number = ~0;
def_symbol_in_progress->sy_frag = &zero_address_frag;
+ S_SET_VALUE (def_symbol_in_progress, 0);
if (S_IS_STRING (def_symbol_in_progress))
{
break;
} /* switch on storage class */
- /* Now that we have built a debug symbol, try to find if
- we should merge with an existing symbol or not. If a
- symbol is C_EFCN or SEG_ABSOLUTE or untagged
- SEG_DEBUG it never merges. We also don't merge
- labels, which are in a different namespace, nor
- symbols which have not yet been defined since they
- are typically unique, nor do we merge tags with
- non-tags. */
-
- /* Two cases for functions. Either debug followed
- by definition or definition followed by debug.
- For definition first, we will merge the debug
- symbol into the definition. For debug first, the
- lineno entry MUST point to the definition
- function or else it will point off into space
- when crawl_symbols() merges the debug
- symbol into the real symbol. Therefor, let's
- presume the debug symbol is a real function
- reference. */
-
- /* FIXME-SOON If for some reason the definition
- label/symbol is never seen, this will probably
- leave an undefined symbol at link time. */
+ /* Now that we have built a debug symbol, try to find if we should
+ merge with an existing symbol or not. If a symbol is C_EFCN or
+ SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. We also
+ don't merge labels, which are in a different namespace, nor
+ symbols which have not yet been defined since they are typically
+ unique, nor do we merge tags with non-tags. */
+
+ /* Two cases for functions. Either debug followed by definition or
+ definition followed by debug. For definition first, we will
+ merge the debug symbol into the definition. For debug first, the
+ lineno entry MUST point to the definition function or else it
+ will point off into space when crawl_symbols() merges the debug
+ symbol into the real symbol. Therefor, let's presume the debug
+ symbol is a real function reference. */
+
+ /* FIXME-SOON If for some reason the definition label/symbol is
+ never seen, this will probably leave an undefined symbol at link
+ time. */
if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
|| S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
|| (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
&& !SF_GET_TAG (def_symbol_in_progress))
|| S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE
- || def_symbol_in_progress->sy_forward != NULL
+ || def_symbol_in_progress->sy_value.X_op != O_constant
|| (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
|| (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
{
-
- symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
-
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+ &symbol_lastP);
}
else
{
- /* This symbol already exists, merge the
- newly created symbol into the old one.
- This is not mandatory. The linker can
- handle duplicate symbols correctly. But I
- guess that it save a *lot* of space if
- the assembly file defines a lot of
- symbols. [loic] */
+ /* This symbol already exists, merge the newly created symbol
+ into the This is not mandatory. The linker can handle
+ duplicate symbols correctly. But I guess that it save a *lot*
+ of space if the assembly file defines a lot of
+ symbols. [loic] */
- /* The debug entry (def_symbol_in_progress)
- is merged into the previous definition. */
+ /* The debug entry (def_symbol_in_progress) is merged into the
+ previous definition. */
c_symbol_merge (def_symbol_in_progress, symbolP);
/* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
if (SF_GET_FUNCTION (def_symbol_in_progress)
|| SF_GET_TAG (def_symbol_in_progress))
{
- /* For functions, and tags, the symbol *must* be where the debug symbol
- appears. Move the existing symbol to the current place. */
+ /* For functions, and tags, the symbol *must* be where the
+ debug symbol appears. Move the existing symbol to the
+ current place. */
/* If it already is at the end of the symbol list, do nothing */
if (def_symbol_in_progress != symbol_lastP)
{
- symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
- symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+ symbol_remove (def_symbol_in_progress, &symbol_rootP,
+ &symbol_lastP);
+ symbol_append (def_symbol_in_progress, symbol_lastP,
+ &symbol_rootP, &symbol_lastP);
} /* if not already in place */
} /* if function */
} /* normal or mergable */
&& symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
{
tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
- } /* If symbol is a {structure,union} tag, associate symbol to its name. */
+ }
if (SF_GET_FUNCTION (def_symbol_in_progress))
{
function_lineoff
= c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
-
-
SF_SET_PROCESS (def_symbol_in_progress);
if (symbolP == NULL)
{
- /* That is, if this is the first
- time we've seen the function... */
+ /* That is, if this is the first time we've seen the
+ function... */
symbol_table_insert (def_symbol_in_progress);
} /* definition follows debug */
} /* Create the line number entry pointing to the function being defined */
def_symbol_in_progress = NULL;
demand_empty_rest_of_line ();
return;
-} /* obj_coff_endef() */
+}
static void
DEFUN_VOID (obj_coff_dim)
if (def_symbol_in_progress == NULL)
{
- obj_coff_ln ();
+ obj_coff_ln (0);
return;
} /* if it looks like a stabs style line */
}
else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
{
- def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
-
- /* If the segment is undefined when the forward
- reference is solved, then copy the segment id
- from the forward symbol. */
+ def_symbol_in_progress->sy_value.X_op = O_symbol;
+ def_symbol_in_progress->sy_value.X_add_symbol =
+ symbol_find_or_make (symbol_name);
+ def_symbol_in_progress->sy_value.X_op_symbol = NULL;
+ def_symbol_in_progress->sy_value.X_add_number = 0;
+
+ /* If the segment is undefined when the forward reference is
+ resolved, then copy the segment id from the forward
+ symbol. */
SF_SET_GET_SEGMENT (def_symbol_in_progress);
/* FIXME: gcc can generate address expressions
/* L* and C_EFCN symbols never merge. */
if (!SF_GET_LOCAL (symbolP)
&& S_GET_STORAGE_CLASS (symbolP) != C_LABEL
+ && symbolP->sy_value.X_op == O_constant
&& (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
&& real_symbolP != symbolP)
{
S_SET_SEGMENT (symbolP, SEG_E0);
} /* push data into text */
- S_SET_VALUE (symbolP,
- S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+ resolve_symbol_value (symbolP);
if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
{
/* Initialize the stack used to keep track of the matching .bb .be */
block_stack = stack_init (512, sizeof (symbolS *));
- /* JF deal with forward references first... */
- for (symbolP = symbol_rootP;
- symbolP;
- symbolP = symbol_next (symbolP))
- {
-
- if (symbolP->sy_forward)
- {
- S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
- + S_GET_VALUE (symbolP->sy_forward)
- + symbolP->sy_forward->sy_frag->fr_address));
-
- if (SF_GET_GET_SEGMENT (symbolP))
- {
- S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
- } /* forward segment also */
-
- symbolP->sy_forward = 0;
- } /* if it has a forward reference */
- } /* walk the symbol chain */
-
/* The symbol list should be ordered according to the following sequence
* order :
symbolS *symbolP;
/* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
- md_number_to_chars (where, string_byte_count, sizeof (string_byte_count));
- where += sizeof (string_byte_count);
+ md_number_to_chars (where, string_byte_count, 4);
+ where += 4;
for (symbolP = symbol_rootP;
symbolP;
symbolP = symbol_next (symbolP))
{
subseg_new (i, exp);
return;
-
}
}
/* No section, add one */
strncpy (segment_info[i].scnhdr.s_name, name, 8);
+ segment_info[i].scnhdr.s_flags = STYP_REG;
subseg_new (i, exp);
}
static void
obj_coff_data ()
{
- change_to_section (".data", 5, get_absolute_expression ());
+ if (flagseen['R'])
+ change_to_section (".text", 5, get_absolute_expression () + 1000);
+ else
+ change_to_section (".data", 5, get_absolute_expression ());
}
static void
if (pcrel)
{
+#ifndef TC_M88K
+ /* This adjustment is not correct on the m88k, for which the
+ linker does all the computation. */
add_number -= md_pcrel_from (fixP);
+#endif
if (add_symbolP == 0)
{
fixP->fx_addsy = &abs_symbol;
if (!fixP->fx_bit_fixP)
{
+#ifndef TC_M88K
+ /* The m88k uses the offset field of the reloc to get around
+ this problem. */
if ((size == 1 &&
(add_number & ~0xFF) && ((add_number & ~0xFF) != (-1 & ~0xFF))) ||
(size == 2 &&
as_bad ("Value of %d too large for field of %d bytes at 0x%x",
add_number, size, fragP->fr_address + where);
} /* generic error checking */
+#endif
#ifdef WARN_SIGNED_OVERFLOW_WORD
/* Warn if a .word value is too large when treated as
a signed number. We already know it is not too