Handle .space directive with non-constant operand:

* read.c (s_space): Rewrite to handle general expressions.  Generate rs_space
frags for non-constant values.
* write.c (cvt_frag_to_fill): Treat rs_align_code and rs_space like rs_align
and rs_org.  Verify that fr_offset is non-negative, and force frag type to
rs_fill only after assertion checks.
(relax_segment): Treat rs_align_code like rs_align.  Treat rs_space like rs_org
in the first switch; in the second, force the operand to a constant, and use it
for the growth size.
This commit is contained in:
Ken Raeburn 1994-12-31 00:08:40 +00:00
parent e12533e3e9
commit cd3b81bd4c
3 changed files with 83 additions and 22 deletions

View File

@ -9,6 +9,28 @@ Fri Dec 30 18:21:41 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
everything it includes. Delete those files from per-file
dependencies.
* as.h (relax_substateT): Now defined to be unsigned int.
(relax_stateT): Separate typedef from enum definition.
(enum _relax_state): Reordered for better punctuation. Added new
values rs_align_code and rs_space.
(lineno, struct lineno_struct): Unused, deleted.
* as.h: No longer include assert.h.
(as_assert): Declare.
(assert): New definition, calls as_assert longer needed.
(__PRETTY_FUNCTION__): Provide default for older versions of gcc.
* messages.c (as_assert): New function.
* gdbinit.in: Put a breakpoint there.
* read.c (s_space): Rewrite to handle general expressions.
Generate rs_space frags for non-constant values.
* write.c (cvt_frag_to_fill): Treat rs_align_code and rs_space
like rs_align and rs_org. Verify that fr_offset is non-negative,
and force frag type to rs_fill only after assertion checks.
(relax_segment): Treat rs_align_code like rs_align. Treat
rs_space like rs_org in the first switch; in the second, force the
operand to a constant, and use it for the growth size.
Wed Dec 28 20:57:37 1994 Jeff Law (law@snake.cs.utah.edu)
* config/tc-hppa.c (pa_subspace): For sections with the ZERO

View File

@ -1425,11 +1425,39 @@ void
s_space (mult)
int mult;
{
long temp_repeat;
register long temp_fill;
register char *p;
expressionS exp;
long temp_repeat, temp_fill;
char *p = 0;
/* Just like .fill, but temp_size = 1 */
expression (&exp);
if (exp.X_op == O_constant
/* for testing purposes */
&& 0)
{
long repeat;
repeat = exp.X_add_number;
if (mult)
repeat *= mult;
if (repeat <= 0)
{
as_warn (".space repeat count is %s, ignored",
repeat ? "negative" : "zero");
ignore_rest_of_line ();
return;
}
if (!need_pass_2)
p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
temp_repeat, (char *) 0);
}
else
{
if (!need_pass_2)
p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
make_expr_symbol (&exp), 0L, (char *) 0);
}
if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
{
temp_fill = get_absolute_expression ();
@ -1439,24 +1467,12 @@ s_space (mult)
input_line_pointer--; /* Backup over what was not a ','. */
temp_fill = 0;
}
if (mult)
if (p)
{
temp_repeat *= mult;
}
if (temp_repeat <= 0)
{
as_warn ("Repeat < 0, .space ignored");
ignore_rest_of_line ();
return;
}
if (!need_pass_2)
{
p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
temp_repeat, (char *) 0);
*p = temp_fill;
}
demand_empty_rest_of_line ();
} /* s_space() */
}
void
s_text (ignore)
@ -1969,7 +1985,7 @@ parse_bitfield_cons (exp, nbytes)
widths, positions, and masks which most
of our current object formats don't
support.
In the specific case where a symbol
*is* defined in this assembly, we
*could* build fixups and track it, but
@ -2481,7 +2497,7 @@ get_absolute_expression ()
if (exp.X_op != O_constant)
{
if (exp.X_op != O_absent)
as_bad ("bad absolute expression; zero assumed");
as_bad ("bad or irreducible absolute expression; zero assumed");
exp.X_add_number = 0;
}
return exp.X_add_number;

View File

@ -419,15 +419,18 @@ cvt_frag_to_fill (headers, fragP)
switch (fragP->fr_type)
{
case rs_align:
case rs_align_code:
case rs_org:
case rs_space:
#ifdef HANDLE_ALIGN
HANDLE_ALIGN (fragP);
#endif
fragP->fr_type = rs_fill;
know (fragP->fr_next != NULL);
fragP->fr_offset = (fragP->fr_next->fr_address
- fragP->fr_address
- fragP->fr_fix) / fragP->fr_var;
assert (fragP->fr_offset >= 0);
fragP->fr_type = rs_fill;
break;
case rs_fill:
@ -625,8 +628,8 @@ adjust_reloc_syms (abfd, sec, xxx)
md_estimate_size_before_relax in tc-mips.c uses this test
as well, so if you change this code you should look at that
code. */
if (symsec == &bfd_und_section
|| symsec == &bfd_abs_section
if (bfd_is_und_section (symsec)
|| bfd_is_abs_section (symsec)
|| bfd_is_com_section (symsec))
{
fixp->fx_addsy->sy_used_in_reloc = 1;
@ -1731,6 +1734,7 @@ relax_segment (segment_frag_root, segment)
break;
case rs_align:
case rs_align_code:
{
int offset = relax_align (address, (int) fragP->fr_offset);
if (offset % fragP->fr_var != 0)
@ -1744,6 +1748,7 @@ relax_segment (segment_frag_root, segment)
break;
case rs_org:
case rs_space:
/* Assume .org is nugatory. It will grow with 1st relax. */
break;
@ -1859,6 +1864,7 @@ relax_segment (segment_frag_root, segment)
} /* case rs_broken_word */
#endif
case rs_align:
case rs_align_code:
growth = (relax_align ((relax_addressT) (address
+ fragP->fr_fix),
(int) offset)
@ -1895,6 +1901,23 @@ relax_segment (segment_frag_root, segment)
growth -= stretch; /* This is an absolute growth factor */
break;
case rs_space:
if (symbolP)
{
growth = S_GET_VALUE (symbolP);
if (symbolP->sy_frag != &zero_address_frag)
as_bad (".space specifies non-absolute value");
fragP->fr_symbol = 0;
if (growth < 0)
{
as_warn (".space or .fill with negative value, ignored");
growth = 0;
}
}
else
growth = 0;
break;
case rs_machine_dependent:
#ifdef md_relax_frag
growth = md_relax_frag (fragP, stretch);