/* coff object file format
- Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS.
#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
#endif
+/* This is used to hold the symbol built by a sequence of pseudo-ops
+ from .def and .endef. */
+static symbolS *def_symbol_in_progress;
+
+typedef struct
+ {
+ unsigned long chunk_size;
+ unsigned long element_size;
+ unsigned long size;
+ char *data;
+ unsigned long pointer;
+ }
+stack;
+
+static stack *stack_init PARAMS ((unsigned long, unsigned long));
+static char *stack_push PARAMS ((stack *, char *));
+static char *stack_pop PARAMS ((stack *));
+static void tag_init PARAMS ((void));
+static void tag_insert PARAMS ((const char *, symbolS *));
+static symbolS *tag_find PARAMS ((char *));
+static symbolS *tag_find_or_make PARAMS ((char *));
static void obj_coff_bss PARAMS ((int));
+static void obj_coff_weak PARAMS ((int));
const char *s_get_name PARAMS ((symbolS * s));
static void obj_coff_ln PARAMS ((int));
static void obj_coff_def PARAMS ((int));
#ifdef BFD_ASSEMBLER
static void obj_coff_loc PARAMS((int));
#endif
-
-/* This is used to hold the symbol built by a sequence of pseudo-ops
- from .def and .endef. */
-static symbolS *def_symbol_in_progress;
\f
/* stack stuff */
-typedef struct
- {
- unsigned long chunk_size;
- unsigned long element_size;
- unsigned long size;
- char *data;
- unsigned long pointer;
- }
-stack;
static stack *
stack_init (chunk_size, element_size)
*input_line_pointer = c;
SKIP_WHITESPACE ();
-#ifdef BFD_ASSEMBLER
+#if defined BFD_ASSEMBLER || defined S_SET_WEAK
S_SET_WEAK (symbolP);
#endif
#ifdef BFD_ASSEMBLER
+static segT fetch_coff_debug_section PARAMS ((void));
static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
+static int S_GET_DATA_TYPE PARAMS ((symbolS *));
+void c_symbol_merge PARAMS ((symbolS *, symbolS *));
+static void add_lineno PARAMS ((fragS *, addressT, int));
#define GET_FILENAME_STRING(X) \
-((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
+((char*) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
/* @@ Ick. */
static segT
{
abort ();
}
+
+#ifndef OBJ_XCOFF
+ /* The native aix assembler accepts negative line number */
+
if (num <= 0)
{
/* Zero is used as an end marker in the file. */
as_warn (_("Line numbers must be positive integers\n"));
num = 1;
}
+#endif /* OBJ_XCOFF */
new_line->next = line_nos;
new_line->frag = frag;
new_line->l.line_number = num;
}
l = get_absolute_expression ();
- if (!appline)
- {
- add_lineno (frag_now, frag_now_fix (), l);
- }
- if (appline)
+ /* If there is no lineno symbol, treat a .ln
+ directive as if it were a .appline directive. */
+ if (appline || current_lineno_sym == NULL)
new_logical_line ((char *) NULL, l - 1);
+ else
+ add_lineno (frag_now, frag_now_fix (), l);
#ifndef NO_LISTING
{
if (!SF_GET_DEBUG (symp))
{
- symbolS *real;
+ symbolS * real;
+
if (!SF_GET_LOCAL (symp)
&& !SF_GET_STATICS (symp)
&& S_GET_STORAGE_CLASS (symp) != C_LABEL
&& symbol_constant_p(symp)
&& (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
+ && S_GET_STORAGE_CLASS (real) == C_NULL
&& real != symp)
{
c_symbol_merge (symp, real);
*punt = 1;
return;
}
+
if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
{
assert (S_GET_VALUE (symp) == 0);
else
S_SET_STORAGE_CLASS (symp, C_STAT);
}
+
if (SF_GET_PROCESS (symp))
{
if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
else
{
symbolS *begin;
+
begin = *(symbolS **) stack_pop (block_stack);
if (begin == 0)
as_warn (_("mismatched .eb"));
next_set_end = begin;
}
}
+
if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
{
union internal_auxent *auxp;
+
coff_last_function = symp;
if (S_GET_NUMBER_AUXILIARY (symp) < 1)
S_SET_NUMBER_AUXILIARY (symp, 1);
memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
}
+
if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
{
if (coff_last_function == 0)
coff_last_function = 0;
}
}
+
if (S_IS_EXTERNAL (symp))
S_SET_STORAGE_CLASS (symp, C_EXT);
else if (SF_GET_LOCAL (symp))
set_end = next_set_end;
}
+#ifndef OBJ_XCOFF
if (! *punt
&& S_GET_STORAGE_CLASS (symp) == C_FCN
&& strcmp (S_GET_NAME (symp), ".bf") == 0)
SA_SET_SYM_ENDNDX (coff_last_bf, symp);
coff_last_bf = symp;
}
-
+#endif
if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
{
int i;
switch (*input_line_pointer)
{
case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
- case 'n': flags &=~ SEC_LOAD; break;
+ case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
case 'w': flags &=~ SEC_READONLY; break;
case 'x': flags |= SEC_CODE | SEC_LOAD; break;
/* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
sections so adjust_reloc_syms in write.c will correctly handle
relocs which refer to non-local symbols in these sections. */
- if (strncmp (name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1) == 0)
+ if (strncmp (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1) == 0)
flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
#endif
{
/* This section's attributes have already been set. Warn if the
attributes don't match. */
- flagword matchflags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
- | SEC_DATA | SEC_SHARED;
+ flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+ | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD);
if ((flags ^ oldflags) & matchflags)
as_warn (_("Ignoring changed section attributes for %s"), name);
}
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
- printf(_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
+ printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
(unsigned long) symbolP,
S_GET_NAME(symbolP),
(long) S_GET_DATA_TYPE(symbolP),
break;
#endif
case rs_space:
- assert (frag->fr_symbol == 0);
case rs_fill:
case rs_org:
size += frag->fr_fix;
break;
case rs_align:
case rs_align_code:
+ case rs_align_test:
{
addressT off;
/* Turn the segment of the symbol into an offset. */
if (symbol_ptr)
{
- resolve_symbol_value (symbol_ptr, 1);
+ resolve_symbol_value (symbol_ptr);
if (! symbol_ptr->sy_resolved)
{
char *file;
#endif
/* Write out the reloc table */
- bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,
- abfd);
+ bfd_bwrite ((PTR) external_reloc_vec,
+ (bfd_size_type) external_reloc_size, abfd);
free (external_reloc_vec);
/* Fill in section header info. */
if (s->s_name[0])
{
fragS *frag = segment_info[i].frchainP->frch_root;
- char *buffer;
+ char *buffer = NULL;
if (s->s_size == 0)
s->s_scnptr = 0;
break;
case rs_space:
- assert (frag->fr_symbol == 0);
case rs_fill:
case rs_align:
case rs_align_code:
+ case rs_align_test:
case rs_org:
if (frag->fr_fix)
{
{
if (s->s_scnptr != 0)
{
- bfd_write (buffer, s->s_size, 1, abfd);
+ bfd_bwrite (buffer, s->s_size, abfd);
*file_cursor += s->s_size;
}
free (buffer);
unsigned long string_size = 4;
#endif
- bfd_seek (abfd, 0, 0);
+ bfd_seek (abfd, (file_ptr) 0, 0);
#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
- bfd_write (buffer, i, 1, abfd);
- bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, abfd);
+ bfd_bwrite (buffer, (bfd_size_type) i, abfd);
+ bfd_bwrite (buffero, (bfd_size_type) H_GET_SIZEOF_OPTIONAL_HEADER (h), abfd);
for (i = SEG_E0; i < SEG_LAST; i++)
{
buffer);
if (size == 0)
as_bad (_("bfd_coff_swap_scnhdr_out failed"));
- bfd_write (buffer, size, 1, abfd);
+ bfd_bwrite (buffer, (bfd_size_type) size, abfd);
}
}
}
S_SET_SEGMENT (symbolP, SEG_E0);
} /* push data into text */
- resolve_symbol_value (symbolP, 1);
+ resolve_symbol_value (symbolP);
if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
{
line_ptr != (struct lineno_list *) NULL;
line_ptr = line_ptr->next)
{
-
if (line_ptr->line.l_lnno == 0)
{
- /* Turn a pointer to a symbol into the symbols' index */
- line_ptr->line.l_addr.l_symndx =
- ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
+ /* Turn a pointer to a symbol into the symbols' index,
+ provided that it has been initialised. */
+ if (line_ptr->line.l_addr.l_symndx)
+ line_ptr->line.l_addr.l_symndx =
+ ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
}
else
{
s->scnhdr.s_lnnoptr = *file_cursor;
- bfd_write (buffer, 1, s->scnhdr.s_nlnno * LINESZ, abfd);
+ bfd_bwrite (buffer, (bfd_size_type) s->scnhdr.s_nlnno * LINESZ, abfd);
free (buffer);
*file_cursor += s->scnhdr.s_nlnno * LINESZ;
md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
alignment_done);
#endif
- frag_align (SUB_SEGMENT_ALIGN (now_seg),
- subseg_text_p (now_seg) ? NOP_OPCODE : 0,
- 0);
+ if (subseg_text_p (now_seg))
+ frag_align_code (SUB_SEGMENT_ALIGN (now_seg), 0);
+ else
+ frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
+
#ifdef md_do_align
alignment_done:
#endif
+
frag_wane (frag_now);
frag_now->fr_fix = 0;
know (frag_now->fr_next == NULL);
relax_segment (segment_info[i].frchainP->frch_root, i);
}
+ /* Relaxation has completed. Freeze all syms. */
+ finalize_syms = 1;
+
H_SET_NUMBER_OF_SECTIONS (&headers, 0);
/* Find out how big the sections are, and set the addresses. */
w_symbols (abfd, buffer1, symbol_rootP);
if (string_byte_count > 0)
w_strings (buffer1 + symtable_size);
- bfd_write (buffer1, 1, symtable_size + string_byte_count, abfd);
+ bfd_bwrite (buffer1, (bfd_size_type) symtable_size + string_byte_count,
+ abfd);
free (buffer1);
}
}
*p = 0;
- symbolP = symbol_find_or_make(name);
+ symbolP = symbol_find_or_make (name);
- if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN &&
- S_GET_VALUE(symbolP) == 0)
+ if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN &&
+ S_GET_VALUE (symbolP) == 0)
{
if (! need_pass_2)
{
(offsetT) temp, (char *) 0);
*p = 0;
subseg_set (current_seg, current_subseg); /* restore current seg */
- S_SET_SEGMENT(symbolP, SEG_E2);
- S_SET_STORAGE_CLASS(symbolP, C_STAT);
+ S_SET_SEGMENT (symbolP, SEG_E2);
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
}
}
else
- as_bad(_("Symbol %s already defined"), name);
+ as_bad (_("Symbol %s already defined"), name);
- demand_empty_rest_of_line();
+ demand_empty_rest_of_line ();
#endif
}
{
case rs_align:
case rs_align_code:
+ case rs_align_test:
case rs_org:
#ifdef HANDLE_ALIGN
HANDLE_ALIGN (frags);
/* Make sure the symbols have been resolved; this may not have
happened if these are expression symbols. */
if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
- resolve_symbol_value (add_symbolP, 1);
+ resolve_symbol_value (add_symbolP);
if (add_symbolP != NULL)
{
}
if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
- resolve_symbol_value (sub_symbolP, 1);
+ resolve_symbol_value (sub_symbolP);
if (add_symbolP != NULL
&& add_symbolP->sy_mri_common)
#endif
} /* if pcrel */
-#ifdef MD_APPLY_FIX3
- md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type);
-#else
- md_apply_fix (fixP, add_number);
-#endif
+ md_apply_fix3 (fixP, (valueT *) & add_number, this_segment_type);
if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
{