From cd3b81bd4cda2f9e04cca02ea6539be322a46986 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 31 Dec 1994 00:08:40 +0000 Subject: [PATCH] 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. --- gas/ChangeLog | 22 +++++++++++++++++++++ gas/read.c | 54 +++++++++++++++++++++++++++++++++------------------ gas/write.c | 29 ++++++++++++++++++++++++--- 3 files changed, 83 insertions(+), 22 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index a704239254..80a4a12a5b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -9,6 +9,28 @@ Fri Dec 30 18:21:41 1994 Ken Raeburn 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 diff --git a/gas/read.c b/gas/read.c index 3bedd149e7..2b20177d3f 100644 --- a/gas/read.c +++ b/gas/read.c @@ -1425,38 +1425,54 @@ 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 */ - if (get_absolute_expression_and_terminator (&temp_repeat) == ',') + expression (&exp); + if (exp.X_op == O_constant + /* for testing purposes */ + && 0) { - temp_fill = get_absolute_expression (); + 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 { - input_line_pointer--; /* Backup over what was not a ','. */ - temp_fill = 0; + if (!need_pass_2) + p = frag_var (rs_space, 1, 1, (relax_substateT) 0, + make_expr_symbol (&exp), 0L, (char *) 0); } - if (mult) + if (get_absolute_expression_and_terminator (&temp_repeat) == ',') { - temp_repeat *= mult; + temp_fill = get_absolute_expression (); } - if (temp_repeat <= 0) + else { - as_warn ("Repeat < 0, .space ignored"); - ignore_rest_of_line (); - return; + input_line_pointer--; /* Backup over what was not a ','. */ + temp_fill = 0; } - if (!need_pass_2) + if (p) { - 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; diff --git a/gas/write.c b/gas/write.c index b362670255..7cdf2c2008 100644 --- a/gas/write.c +++ b/gas/write.c @@ -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); -- 2.34.1