mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
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
@ -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>
|
||||
|
||||
* ldexp.c (exp_value_fold): New function.
|
||||
|
@ -6032,7 +6032,9 @@ The result of comparisons, @samp{&&} and @samp{||} is also a number.
|
||||
@item
|
||||
The result of other binary arithmetic and logical operations on two
|
||||
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
|
||||
The result of other operations on relative addresses or one
|
||||
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
|
||||
fold_binary (etree_type *tree)
|
||||
{
|
||||
@ -483,26 +509,10 @@ fold_binary (etree_type *tree)
|
||||
|
||||
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) \
|
||||
case x: \
|
||||
expld.result.value = lhs.value y expld.result.value; \
|
||||
if (expld.result.section == lhs.section) \
|
||||
expld.result.section = NULL; \
|
||||
arith_result_section (&lhs); \
|
||||
break;
|
||||
|
||||
/* Comparison operators, logical AND, and logical OR always
|
||||
@ -536,8 +546,7 @@ fold_binary (etree_type *tree)
|
||||
% (bfd_signed_vma) expld.result.value);
|
||||
else if (expld.phase != lang_mark_phase_enum)
|
||||
einfo (_("%F%S %% by zero\n"), tree->binary.rhs);
|
||||
if (expld.result.section == lhs.section)
|
||||
expld.result.section = NULL;
|
||||
arith_result_section (&lhs);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
@ -546,8 +555,7 @@ fold_binary (etree_type *tree)
|
||||
/ (bfd_signed_vma) expld.result.value);
|
||||
else if (expld.phase != lang_mark_phase_enum)
|
||||
einfo (_("%F%S / by zero\n"), tree->binary.rhs);
|
||||
if (expld.result.section == lhs.section)
|
||||
expld.result.section = NULL;
|
||||
arith_result_section (&lhs);
|
||||
break;
|
||||
|
||||
case MAX_K:
|
||||
|
Loading…
Reference in New Issue
Block a user