mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-27 17:37:36 +08:00
* ldexp.c (fold_binary): Set result section for arithmetic and
logical operations to NULL when both operands are in same section. * ld.texinfo (Expression Section): Describe this.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2011-01-21 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* ldexp.c (fold_binary): Set result section for arithmetic and
|
||||||
|
logical operations to NULL when both operands are in same section.
|
||||||
|
* ld.texinfo (Expression Section): Describe this.
|
||||||
|
|
||||||
2011-01-14 Alan Modra <amodra@gmail.com>
|
2011-01-14 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* ldmain.c (main): Flush stdout before and stderr after printing
|
* ldmain.c (main): Flush stdout before and stderr after printing
|
||||||
|
@ -5567,8 +5567,13 @@ An operation involving only numbers results in a number.
|
|||||||
@item
|
@item
|
||||||
The result of comparisons, @samp{&&} and @samp{||} is also a number.
|
The result of comparisons, @samp{&&} and @samp{||} is also a number.
|
||||||
@item
|
@item
|
||||||
The result of other operations on relative addresses (after above
|
The result of other binary arithmetic and logical operations on two
|
||||||
conversions) is a relative address in the same section as the operand(s).
|
relative addresses in the same section or two absolute addresess
|
||||||
|
(after above conversions) is also a number.
|
||||||
|
@item
|
||||||
|
The result of other operations on relative addresses or one
|
||||||
|
relative address and a number, is a relative address in the same
|
||||||
|
section as the relative operand(s).
|
||||||
@item
|
@item
|
||||||
The result of other operations on absolute addresses (after above
|
The result of other operations on absolute addresses (after above
|
||||||
conversions) is an absolute address.
|
conversions) is an absolute address.
|
||||||
|
65
ld/ldexp.c
65
ld/ldexp.c
@ -335,36 +335,47 @@ fold_binary (etree_type *tree)
|
|||||||
{
|
{
|
||||||
make_abs ();
|
make_abs ();
|
||||||
lhs.value += lhs.section->vma;
|
lhs.value += lhs.section->vma;
|
||||||
|
lhs.section = bfd_abs_section_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the rhs is just a number, keep the lhs section. */
|
/* If the rhs is just a number, keep the lhs section. */
|
||||||
else if (expld.result.section == NULL)
|
else if (expld.result.section == NULL)
|
||||||
expld.result.section = lhs.section;
|
{
|
||||||
|
expld.result.section = lhs.section;
|
||||||
|
/* Make this NULL so that we know one of the operands
|
||||||
|
was just a number, for later tests. */
|
||||||
|
lhs.section = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* At this point we know that both operands have the same
|
||||||
|
section, or at least one of them is a plain number. */
|
||||||
|
|
||||||
switch (tree->type.node_code)
|
switch (tree->type.node_code)
|
||||||
{
|
{
|
||||||
case '%':
|
/* Arithmetic operators, bitwise AND, bitwise OR and XOR
|
||||||
if (expld.result.value != 0)
|
keep the section of one of their operands only when the
|
||||||
expld.result.value = ((bfd_signed_vma) lhs.value
|
other operand is a plain number. Losing the section when
|
||||||
% (bfd_signed_vma) expld.result.value);
|
operating on two symbols, ie. a result of a plain number,
|
||||||
else if (expld.phase != lang_mark_phase_enum)
|
is required for subtraction and XOR. It's justifiable
|
||||||
einfo (_("%F%S %% by zero\n"));
|
for the other operations on the grounds that adding,
|
||||||
break;
|
multiplying etc. two section relative values does not
|
||||||
|
really make sense unless they are just treated as
|
||||||
case '/':
|
numbers.
|
||||||
if (expld.result.value != 0)
|
The same argument could be made for many expressions
|
||||||
expld.result.value = ((bfd_signed_vma) lhs.value
|
involving one symbol and a number. For example,
|
||||||
/ (bfd_signed_vma) expld.result.value);
|
"1 << x" and "100 / x" probably should not be given the
|
||||||
else if (expld.phase != lang_mark_phase_enum)
|
section of x. The trouble is that if we fuss about such
|
||||||
einfo (_("%F%S / by zero\n"));
|
things the rules become complex and it is onerous to
|
||||||
break;
|
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) \
|
||||||
|
expld.result.section = NULL; \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Comparison operators, logical AND, and logical OR always
|
||||||
|
return a plain number. */
|
||||||
#define BOPN(x, y) \
|
#define BOPN(x, y) \
|
||||||
case x: \
|
case x: \
|
||||||
expld.result.value = lhs.value y expld.result.value; \
|
expld.result.value = lhs.value y expld.result.value; \
|
||||||
@ -388,6 +399,26 @@ fold_binary (etree_type *tree)
|
|||||||
BOPN (ANDAND, &&);
|
BOPN (ANDAND, &&);
|
||||||
BOPN (OROR, ||);
|
BOPN (OROR, ||);
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
if (expld.result.value != 0)
|
||||||
|
expld.result.value = ((bfd_signed_vma) lhs.value
|
||||||
|
% (bfd_signed_vma) expld.result.value);
|
||||||
|
else if (expld.phase != lang_mark_phase_enum)
|
||||||
|
einfo (_("%F%S %% by zero\n"));
|
||||||
|
if (expld.result.section == lhs.section)
|
||||||
|
expld.result.section = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
if (expld.result.value != 0)
|
||||||
|
expld.result.value = ((bfd_signed_vma) lhs.value
|
||||||
|
/ (bfd_signed_vma) expld.result.value);
|
||||||
|
else if (expld.phase != lang_mark_phase_enum)
|
||||||
|
einfo (_("%F%S / by zero\n"));
|
||||||
|
if (expld.result.section == lhs.section)
|
||||||
|
expld.result.section = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
case MAX_K:
|
case MAX_K:
|
||||||
if (lhs.value > expld.result.value)
|
if (lhs.value > expld.result.value)
|
||||||
expld.result.value = lhs.value;
|
expld.result.value = lhs.value;
|
||||||
|
Reference in New Issue
Block a user