ld expression section
Changes the result of ld expressions that were previously plain numbers to be an absolute address, in the same circumstances where numbers are treated as absolute addresses. * ld.texinfo (Expression Section): Update result of arithmetic expressions. * ldexp.c (arith_result_section): New function. (fold_binary): Use it.
This commit is contained in:
parent
9ad39107ca
commit
94b41882b0
3 changed files with 39 additions and 22 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2016-10-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* ld.texinfo (Expression Section): Update result of arithmetic
|
||||||
|
expressions.
|
||||||
|
* ldexp.c (arith_result_section): New function.
|
||||||
|
(fold_binary): Use it.
|
||||||
|
|
||||||
2016-10-04 Alan Modra <amodra@gmail.com>
|
2016-10-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* ldexp.c (exp_value_fold): New function.
|
* ldexp.c (exp_value_fold): New function.
|
||||||
|
|
|
@ -6032,7 +6032,9 @@ The result of comparisons, @samp{&&} and @samp{||} is also a number.
|
||||||
@item
|
@item
|
||||||
The result of other binary arithmetic and logical operations on two
|
The result of other binary arithmetic and logical operations on two
|
||||||
relative addresses in the same section or two absolute addresses
|
relative addresses in the same section or two absolute addresses
|
||||||
(after above conversions) is also a number.
|
(after above conversions) is also a number when
|
||||||
|
@code{LD_FEATURE ("SANE_EXPR")} or inside an output section definition
|
||||||
|
but an absolute address otherwise.
|
||||||
@item
|
@item
|
||||||
The result of other operations on relative addresses or one
|
The result of other operations on relative addresses or one
|
||||||
relative address and a number, is a relative address in the same
|
relative address and a number, is a relative address in the same
|
||||||
|
|
50
ld/ldexp.c
50
ld/ldexp.c
|
@ -417,6 +417,32 @@ fold_unary (etree_type *tree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Arithmetic operators, bitwise AND, bitwise OR and XOR keep the
|
||||||
|
section of one of their operands only when the other operand is a
|
||||||
|
plain number. Losing the section when operating on two symbols,
|
||||||
|
ie. a result of a plain number, is required for subtraction and
|
||||||
|
XOR. It's justifiable for the other operations on the grounds that
|
||||||
|
adding, multiplying etc. two section relative values does not
|
||||||
|
really make sense unless they are just treated as numbers.
|
||||||
|
The same argument could be made for many expressions involving one
|
||||||
|
symbol and a number. For example, "1 << x" and "100 / x" probably
|
||||||
|
should not be given the section of x. The trouble is that if we
|
||||||
|
fuss about such things the rules become complex and it is onerous
|
||||||
|
to document ld expression evaluation. */
|
||||||
|
static void
|
||||||
|
arith_result_section (const etree_value_type *lhs)
|
||||||
|
{
|
||||||
|
if (expld.result.section == lhs->section)
|
||||||
|
{
|
||||||
|
if (expld.section == bfd_abs_section_ptr
|
||||||
|
&& !config.sane_expr)
|
||||||
|
/* Duplicate the insanity in exp_fold_tree_1 case etree_value. */
|
||||||
|
expld.result.section = bfd_abs_section_ptr;
|
||||||
|
else
|
||||||
|
expld.result.section = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fold_binary (etree_type *tree)
|
fold_binary (etree_type *tree)
|
||||||
{
|
{
|
||||||
|
@ -483,26 +509,10 @@ fold_binary (etree_type *tree)
|
||||||
|
|
||||||
switch (tree->type.node_code)
|
switch (tree->type.node_code)
|
||||||
{
|
{
|
||||||
/* Arithmetic operators, bitwise AND, bitwise OR and XOR
|
|
||||||
keep the section of one of their operands only when the
|
|
||||||
other operand is a plain number. Losing the section when
|
|
||||||
operating on two symbols, ie. a result of a plain number,
|
|
||||||
is required for subtraction and XOR. It's justifiable
|
|
||||||
for the other operations on the grounds that adding,
|
|
||||||
multiplying etc. two section relative values does not
|
|
||||||
really make sense unless they are just treated as
|
|
||||||
numbers.
|
|
||||||
The same argument could be made for many expressions
|
|
||||||
involving one symbol and a number. For example,
|
|
||||||
"1 << x" and "100 / x" probably should not be given the
|
|
||||||
section of x. The trouble is that if we fuss about such
|
|
||||||
things the rules become complex and it is onerous to
|
|
||||||
document ld expression evaluation. */
|
|
||||||
#define BOP(x, y) \
|
#define BOP(x, y) \
|
||||||
case x: \
|
case x: \
|
||||||
expld.result.value = lhs.value y expld.result.value; \
|
expld.result.value = lhs.value y expld.result.value; \
|
||||||
if (expld.result.section == lhs.section) \
|
arith_result_section (&lhs); \
|
||||||
expld.result.section = NULL; \
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Comparison operators, logical AND, and logical OR always
|
/* Comparison operators, logical AND, and logical OR always
|
||||||
|
@ -536,8 +546,7 @@ fold_binary (etree_type *tree)
|
||||||
% (bfd_signed_vma) expld.result.value);
|
% (bfd_signed_vma) expld.result.value);
|
||||||
else if (expld.phase != lang_mark_phase_enum)
|
else if (expld.phase != lang_mark_phase_enum)
|
||||||
einfo (_("%F%S %% by zero\n"), tree->binary.rhs);
|
einfo (_("%F%S %% by zero\n"), tree->binary.rhs);
|
||||||
if (expld.result.section == lhs.section)
|
arith_result_section (&lhs);
|
||||||
expld.result.section = NULL;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '/':
|
case '/':
|
||||||
|
@ -546,8 +555,7 @@ fold_binary (etree_type *tree)
|
||||||
/ (bfd_signed_vma) expld.result.value);
|
/ (bfd_signed_vma) expld.result.value);
|
||||||
else if (expld.phase != lang_mark_phase_enum)
|
else if (expld.phase != lang_mark_phase_enum)
|
||||||
einfo (_("%F%S / by zero\n"), tree->binary.rhs);
|
einfo (_("%F%S / by zero\n"), tree->binary.rhs);
|
||||||
if (expld.result.section == lhs.section)
|
arith_result_section (&lhs);
|
||||||
expld.result.section = NULL;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAX_K:
|
case MAX_K:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue