mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-22 07:53:36 +08:00
binutils/
* NEWS: Mention change in linker script expression evaluation. ld/ * ld.texinfo (Expression Section): Detail expression evaluation. (Builtin Functions <ADDR>): Correct. (Builtin Functions <LOADADDR>): Don't mention LOADADDR normally the same as ADDR. (Builtin Functions <SEGMENT_START>): Typo fix. * ldexp.c (new_number): New function. (make_abs, exp_get_abs_int): Cope with NULL expld.result.section. (fold_unary <'~', '!', '-'>): Don't make_abs. (fold_binary): Simplify result section logic. Return NULL section for logical ops. (fold_binary <SEGMENT_START>): Use new_rel_from_abs to set value to a consistent result. (fold_name <SIZEOF_HEADERS>): Return new_number, not new_abs. (fold_name <DEFINED, SIZEOF, ALIGNOF, LENGTH, CONSTANT>): Likewise. (fold_name <NAME>): No need to handle absolute symbols differently from relative ones. (fold_name <ORIGIN>): Don't return valid result when lang_first_phase_enum. Return new_rel_from_abs, not new_abs. (exp_fold_tree_1 <etree_value>): Return new_number, not new_rel. (exp_fold_tree_1): Ajust for NULL expld.result.section. When assigning a plain number to dot, assume the value is relative to expld.section. Make terms not in an output section, absolute. * ldlang.c (print_assignment): Fix style nit. (lang_size_sections_1): Cope with NULL expld.result.section. (lang_do_assignments_1): Likewise. ld/testsuite/ * ld-scripts/memory.t: Remove ORIGIN fudge.
This commit is contained in:
parent
56f75c03fc
commit
7542af2ae8
@ -1,3 +1,7 @@
|
||||
2010-08-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* NEWS: Mention change in linker script expression evaluation.
|
||||
|
||||
2010-08-13 Dan Rosenberg <dan.j.rosenberg@gmail.com>
|
||||
|
||||
PR binutils/11889
|
||||
|
@ -1,5 +1,8 @@
|
||||
-*- text -*-
|
||||
|
||||
* Linker script expression evaluation is somewhat more sane. This may
|
||||
break scripts that depend on quirks of the old expression evaluation.
|
||||
|
||||
* Add support for the TMS320C6000 (TI C6X) processor family.
|
||||
|
||||
* Readelf can now display ARM unwind tables (.ARM.exidx / .ARM.extab) using
|
||||
|
28
ld/ChangeLog
28
ld/ChangeLog
@ -1,3 +1,31 @@
|
||||
2010-08-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ld.texinfo (Expression Section): Detail expression evaluation.
|
||||
(Builtin Functions <ADDR>): Correct.
|
||||
(Builtin Functions <LOADADDR>): Don't mention LOADADDR normally
|
||||
the same as ADDR.
|
||||
(Builtin Functions <SEGMENT_START>): Typo fix.
|
||||
* ldexp.c (new_number): New function.
|
||||
(make_abs, exp_get_abs_int): Cope with NULL expld.result.section.
|
||||
(fold_unary <'~', '!', '-'>): Don't make_abs.
|
||||
(fold_binary): Simplify result section logic. Return NULL section
|
||||
for logical ops.
|
||||
(fold_binary <SEGMENT_START>): Use new_rel_from_abs to set value to
|
||||
a consistent result.
|
||||
(fold_name <SIZEOF_HEADERS>): Return new_number, not new_abs.
|
||||
(fold_name <DEFINED, SIZEOF, ALIGNOF, LENGTH, CONSTANT>): Likewise.
|
||||
(fold_name <NAME>): No need to handle absolute symbols differently
|
||||
from relative ones.
|
||||
(fold_name <ORIGIN>): Don't return valid result when
|
||||
lang_first_phase_enum. Return new_rel_from_abs, not new_abs.
|
||||
(exp_fold_tree_1 <etree_value>): Return new_number, not new_rel.
|
||||
(exp_fold_tree_1): Ajust for NULL expld.result.section. When assigning
|
||||
a plain number to dot, assume the value is relative to expld.section.
|
||||
Make terms not in an output section, absolute.
|
||||
* ldlang.c (print_assignment): Fix style nit.
|
||||
(lang_size_sections_1): Cope with NULL expld.result.section.
|
||||
(lang_do_assignments_1): Likewise.
|
||||
|
||||
2010-08-12 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ldexp.c (new_rel): Remove "str". Update all call sites.
|
||||
|
104
ld/ld.texinfo
104
ld/ld.texinfo
@ -5447,23 +5447,82 @@ address}.
|
||||
@cindex absolute and relocatable symbols
|
||||
@cindex relocatable and absolute symbols
|
||||
@cindex symbols, relocatable and absolute
|
||||
When the linker evaluates an expression, the result is either absolute
|
||||
or relative to some section. A relative expression is expressed as a
|
||||
fixed offset from the base of a section.
|
||||
Addresses and symbols may be section relative, or absolute. A section
|
||||
relative symbol is relocatable. If you request relocatable output
|
||||
using the @samp{-r} option, a further link operation may change the
|
||||
value of a section relative symbol. On the other hand, an absolute
|
||||
symbol will retain the same value throughout any further link
|
||||
operations.
|
||||
|
||||
The position of the expression within the linker script determines
|
||||
whether it is absolute or relative. An expression which appears within
|
||||
an output section definition is relative to the base of the output
|
||||
section. An expression which appears elsewhere will be absolute.
|
||||
Some terms in linker expressions are addresses. This is true of all
|
||||
symbols and for builtin functions that return an address, such as
|
||||
@code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and @code{SEGMENT_START}.
|
||||
Other terms are simply numbers, or are builtin functions that return a
|
||||
non-address value, such as @code{LENGTH}.
|
||||
|
||||
A symbol set to a relative expression will be relocatable if you request
|
||||
relocatable output using the @samp{-r} option. That means that a
|
||||
further link operation may change the value of the symbol. The symbol's
|
||||
section will be the section of the relative expression.
|
||||
When the linker evaluates an expression, the result depends on where
|
||||
the expression is located in a linker script. Expressions appearing
|
||||
outside an output section definitions are evaluated with all terms
|
||||
first being converted to absolute addresses before applying operators,
|
||||
and evaluate to an absolute address result. Expressions appearing
|
||||
inside an output section definition are evaluated with more complex
|
||||
rules, but the aim is to treat terms as relative addresses and produce
|
||||
a relative address result. In particular, an assignment of a number
|
||||
to a symbol results in a symbol relative to the output section with an
|
||||
offset given by the number. So, in the following simple example,
|
||||
|
||||
A symbol set to an absolute expression will retain the same value
|
||||
through any further link operation. The symbol will be absolute, and
|
||||
will not have any particular associated section.
|
||||
@smallexample
|
||||
@group
|
||||
SECTIONS
|
||||
@{
|
||||
. = 0x100;
|
||||
__executable_start = 0x100;
|
||||
.data :
|
||||
@{
|
||||
. = 0x10;
|
||||
__data_start = 0x10;
|
||||
*(.data)
|
||||
@}
|
||||
@dots{}
|
||||
@}
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
both @code{.} and @code{__executable_start} are set to the absolute
|
||||
address 0x100 in the first two assignments, then both @code{.} and
|
||||
@code{__data_start} are set to 0x10 relative to the @code{.data}
|
||||
section in the second two assignments.
|
||||
|
||||
For expressions appearing inside an output section definition
|
||||
involving numbers, relative addresses and absolute addresses, ld
|
||||
follows these rules to evaluate terms:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Unary operations on a relative address, and binary operations on two
|
||||
relative addresses in the same section or between one relative address
|
||||
and a number, apply the operator to the offset part of the address(es).
|
||||
@item
|
||||
Unary operations on an absolute address, and binary operations on one
|
||||
or more absolute addresses or on two relative addresses not in the
|
||||
same section, first convert any non-absolute term to an absolute
|
||||
address before applying the operator.
|
||||
@end itemize
|
||||
|
||||
The result section of each sub-expression is as follows:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
An operation involving only numbers results in a number.
|
||||
@item
|
||||
The result of comparisons, @samp{&&} and @samp{||} is also a number.
|
||||
@item
|
||||
The result of other operations on relative addresses (after above
|
||||
conversions) is a relative address in the same section as the operand(s).
|
||||
@item
|
||||
The result of other operations on absolute addresses (after above
|
||||
conversions) is an absolute address.
|
||||
@end itemize
|
||||
|
||||
You can use the builtin function @code{ABSOLUTE} to force an expression
|
||||
to be absolute when it would otherwise be relative. For example, to
|
||||
@ -5479,6 +5538,9 @@ SECTIONS
|
||||
If @samp{ABSOLUTE} were not used, @samp{_edata} would be relative to the
|
||||
@samp{.data} section.
|
||||
|
||||
Using @code{LOADADDR} also forces an expression absolute, since this
|
||||
particular builtin function returns an absolute address.
|
||||
|
||||
@node Builtin Functions
|
||||
@subsection Builtin Functions
|
||||
@cindex functions in expressions
|
||||
@ -5497,10 +5559,12 @@ normally section relative. @xref{Expression Section}.
|
||||
@item ADDR(@var{section})
|
||||
@kindex ADDR(@var{section})
|
||||
@cindex section address in expression
|
||||
Return the absolute address (the VMA) of the named @var{section}. Your
|
||||
Return the address (VMA) of the named @var{section}. Your
|
||||
script must previously have defined the location of that section. In
|
||||
the following example, @code{symbol_1} and @code{symbol_2} are assigned
|
||||
identical values:
|
||||
the following example, @code{start_of_output_1}, @code{symbol_1} and
|
||||
@code{symbol_2} are assigned equivalent values, except that
|
||||
@code{symbol_1} will be relative to the @code{.output1} section while
|
||||
the other two will be absolute:
|
||||
@smallexample
|
||||
@group
|
||||
SECTIONS @{ @dots{}
|
||||
@ -5664,9 +5728,7 @@ Return the length of the memory region named @var{memory}.
|
||||
@item LOADADDR(@var{section})
|
||||
@kindex LOADADDR(@var{section})
|
||||
@cindex section load address in expression
|
||||
Return the absolute LMA of the named @var{section}. This is normally
|
||||
the same as @code{ADDR}, but it may be different if the @code{AT}
|
||||
attribute is used in the output section definition (@pxref{Output
|
||||
Return the absolute LMA of the named @var{section}. (@pxref{Output
|
||||
Section LMA}).
|
||||
|
||||
@kindex MAX
|
||||
@ -5696,7 +5758,7 @@ value has been given for this segment (with a command-line @samp{-T}
|
||||
option) that value will be returned; otherwise the value will be
|
||||
@var{default}. At present, the @samp{-T} command-line option can only
|
||||
be used to set the base address for the ``text'', ``data'', and
|
||||
``bss'' sections, but you use @code{SEGMENT_START} with any segment
|
||||
``bss'' sections, but you can use @code{SEGMENT_START} with any segment
|
||||
name.
|
||||
|
||||
@item SIZEOF(@var{section})
|
||||
|
177
ld/ldexp.c
177
ld/ldexp.c
@ -138,7 +138,8 @@ exp_print_token (token_code_type code, int infix_p)
|
||||
static void
|
||||
make_abs (void)
|
||||
{
|
||||
expld.result.value += expld.result.section->vma;
|
||||
if (expld.result.section != NULL)
|
||||
expld.result.value += expld.result.section->vma;
|
||||
expld.result.section = bfd_abs_section_ptr;
|
||||
}
|
||||
|
||||
@ -189,6 +190,15 @@ exp_relop (asection *section, bfd_vma value)
|
||||
return new_e;
|
||||
}
|
||||
|
||||
static void
|
||||
new_number (bfd_vma value)
|
||||
{
|
||||
expld.result.valid_p = TRUE;
|
||||
expld.result.value = value;
|
||||
expld.result.str = NULL;
|
||||
expld.result.section = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
new_rel (bfd_vma value, asection *section)
|
||||
{
|
||||
@ -227,17 +237,14 @@ fold_unary (etree_type *tree)
|
||||
break;
|
||||
|
||||
case '~':
|
||||
make_abs ();
|
||||
expld.result.value = ~expld.result.value;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
make_abs ();
|
||||
expld.result.value = !expld.result.value;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
make_abs ();
|
||||
expld.result.value = -expld.result.value;
|
||||
break;
|
||||
|
||||
@ -293,6 +300,7 @@ fold_binary (etree_type *tree)
|
||||
{
|
||||
const char *segment_name;
|
||||
segment_type *seg;
|
||||
|
||||
/* Check to see if the user has overridden the default
|
||||
value. */
|
||||
segment_name = tree->binary.rhs->name.name;
|
||||
@ -305,9 +313,7 @@ fold_binary (etree_type *tree)
|
||||
einfo (_("%P: warning: address of `%s' isn't multiple of maximum page size\n"),
|
||||
segment_name);
|
||||
seg->used = TRUE;
|
||||
expld.result.value = seg->value;
|
||||
expld.result.str = NULL;
|
||||
expld.result.section = expld.section;
|
||||
new_rel_from_abs (seg->value);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@ -319,32 +325,20 @@ fold_binary (etree_type *tree)
|
||||
|
||||
if (expld.result.valid_p)
|
||||
{
|
||||
/* If the values are from different sections, or this is an
|
||||
absolute expression, make both the source arguments
|
||||
absolute. However, adding or subtracting an absolute
|
||||
value from a relative value is meaningful, and is an
|
||||
exception. */
|
||||
if (expld.section != bfd_abs_section_ptr
|
||||
&& lhs.section == bfd_abs_section_ptr
|
||||
&& tree->type.node_code == '+')
|
||||
if (lhs.section != expld.result.section)
|
||||
{
|
||||
/* Keep the section of the rhs term. */
|
||||
expld.result.value = lhs.value + expld.result.value;
|
||||
return;
|
||||
}
|
||||
else if (expld.section != bfd_abs_section_ptr
|
||||
&& expld.result.section == bfd_abs_section_ptr
|
||||
&& (tree->type.node_code == '+'
|
||||
|| tree->type.node_code == '-'))
|
||||
{
|
||||
/* Keep the section of the lhs term. */
|
||||
expld.result.section = lhs.section;
|
||||
}
|
||||
else if (expld.result.section != lhs.section
|
||||
|| expld.section == bfd_abs_section_ptr)
|
||||
{
|
||||
make_abs ();
|
||||
lhs.value += lhs.section->vma;
|
||||
/* If the values are from different sections, and neither is
|
||||
just a number, make both the source arguments absolute. */
|
||||
if (expld.result.section != NULL
|
||||
&& lhs.section != NULL)
|
||||
{
|
||||
make_abs ();
|
||||
lhs.value += lhs.section->vma;
|
||||
}
|
||||
|
||||
/* If the rhs is just a number, keep the lhs section. */
|
||||
else if (expld.result.section == NULL)
|
||||
expld.result.section = lhs.section;
|
||||
}
|
||||
|
||||
switch (tree->type.node_code)
|
||||
@ -366,26 +360,32 @@ fold_binary (etree_type *tree)
|
||||
break;
|
||||
|
||||
#define BOP(x, y) \
|
||||
case x: \
|
||||
expld.result.value = lhs.value y expld.result.value; \
|
||||
break;
|
||||
case x: \
|
||||
expld.result.value = lhs.value y expld.result.value; \
|
||||
break;
|
||||
|
||||
#define BOPN(x, y) \
|
||||
case x: \
|
||||
expld.result.value = lhs.value y expld.result.value; \
|
||||
expld.result.section = NULL; \
|
||||
break;
|
||||
|
||||
BOP ('+', +);
|
||||
BOP ('*', *);
|
||||
BOP ('-', -);
|
||||
BOP (LSHIFT, <<);
|
||||
BOP (RSHIFT, >>);
|
||||
BOP (EQ, ==);
|
||||
BOP (NE, !=);
|
||||
BOP ('<', <);
|
||||
BOP ('>', >);
|
||||
BOP (LE, <=);
|
||||
BOP (GE, >=);
|
||||
BOP ('&', &);
|
||||
BOP ('^', ^);
|
||||
BOP ('|', |);
|
||||
BOP (ANDAND, &&);
|
||||
BOP (OROR, ||);
|
||||
BOPN (EQ, ==);
|
||||
BOPN (NE, !=);
|
||||
BOPN ('<', <);
|
||||
BOPN ('>', >);
|
||||
BOPN (LE, <=);
|
||||
BOPN (GE, >=);
|
||||
BOPN (ANDAND, &&);
|
||||
BOPN (OROR, ||);
|
||||
|
||||
case MAX_K:
|
||||
if (lhs.value > expld.result.value)
|
||||
@ -499,7 +499,7 @@ fold_name (etree_type *tree)
|
||||
The bfd function may cache incorrect data. */
|
||||
if (expld.phase != lang_mark_phase_enum)
|
||||
hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
|
||||
new_abs (hdr_size);
|
||||
new_number (hdr_size);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -516,14 +516,12 @@ fold_name (etree_type *tree)
|
||||
&link_info,
|
||||
tree->name.name,
|
||||
FALSE, FALSE, TRUE);
|
||||
expld.result.value = (h != NULL
|
||||
&& (h->type == bfd_link_hash_defined
|
||||
|| h->type == bfd_link_hash_defweak
|
||||
|| h->type == bfd_link_hash_common)
|
||||
&& (def_iteration == lang_statement_iteration
|
||||
|| def_iteration == -1));
|
||||
expld.result.section = expld.section;
|
||||
expld.result.valid_p = TRUE;
|
||||
new_number (h != NULL
|
||||
&& (h->type == bfd_link_hash_defined
|
||||
|| h->type == bfd_link_hash_defweak
|
||||
|| h->type == bfd_link_hash_common)
|
||||
&& (def_iteration == lang_statement_iteration
|
||||
|| def_iteration == -1));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -545,24 +543,19 @@ fold_name (etree_type *tree)
|
||||
else if (h->type == bfd_link_hash_defined
|
||||
|| h->type == bfd_link_hash_defweak)
|
||||
{
|
||||
if (bfd_is_abs_section (h->u.def.section))
|
||||
new_abs (h->u.def.value);
|
||||
else
|
||||
{
|
||||
asection *output_section;
|
||||
asection *output_section;
|
||||
|
||||
output_section = h->u.def.section->output_section;
|
||||
if (output_section == NULL)
|
||||
{
|
||||
if (expld.phase != lang_mark_phase_enum)
|
||||
einfo (_("%X%S: unresolvable symbol `%s'"
|
||||
" referenced in expression\n"),
|
||||
tree->name.name);
|
||||
}
|
||||
else
|
||||
new_rel (h->u.def.value + h->u.def.section->output_offset,
|
||||
output_section);
|
||||
output_section = h->u.def.section->output_section;
|
||||
if (output_section == NULL)
|
||||
{
|
||||
if (expld.phase != lang_mark_phase_enum)
|
||||
einfo (_("%X%S: unresolvable symbol `%s'"
|
||||
" referenced in expression\n"),
|
||||
tree->name.name);
|
||||
}
|
||||
else
|
||||
new_rel (h->u.def.value + h->u.def.section->output_offset,
|
||||
output_section);
|
||||
}
|
||||
else if (expld.phase == lang_final_phase_enum
|
||||
|| expld.assigning_to_dot)
|
||||
@ -633,7 +626,7 @@ fold_name (etree_type *tree)
|
||||
if (expld.phase == lang_final_phase_enum)
|
||||
einfo (_("%F%S: undefined section `%s' referenced in expression\n"),
|
||||
tree->name.name);
|
||||
new_abs (0);
|
||||
new_number (0);
|
||||
}
|
||||
else if (os->processed_vma)
|
||||
{
|
||||
@ -645,7 +638,7 @@ fold_name (etree_type *tree)
|
||||
else
|
||||
val = (bfd_vma)1 << os->bfd_section->alignment_power;
|
||||
|
||||
new_abs (val);
|
||||
new_number (val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -656,7 +649,7 @@ fold_name (etree_type *tree)
|
||||
|
||||
mem = lang_memory_region_lookup (tree->name.name, FALSE);
|
||||
if (mem != NULL)
|
||||
new_abs (mem->length);
|
||||
new_number (mem->length);
|
||||
else
|
||||
einfo (_("%F%S: undefined MEMORY region `%s'"
|
||||
" referenced in expression\n"), tree->name.name);
|
||||
@ -664,23 +657,24 @@ fold_name (etree_type *tree)
|
||||
break;
|
||||
|
||||
case ORIGIN:
|
||||
{
|
||||
lang_memory_region_type *mem;
|
||||
if (expld.phase != lang_first_phase_enum)
|
||||
{
|
||||
lang_memory_region_type *mem;
|
||||
|
||||
mem = lang_memory_region_lookup (tree->name.name, FALSE);
|
||||
if (mem != NULL)
|
||||
new_abs (mem->origin);
|
||||
else
|
||||
einfo (_("%F%S: undefined MEMORY region `%s'"
|
||||
" referenced in expression\n"), tree->name.name);
|
||||
}
|
||||
mem = lang_memory_region_lookup (tree->name.name, FALSE);
|
||||
if (mem != NULL)
|
||||
new_rel_from_abs (mem->origin);
|
||||
else
|
||||
einfo (_("%F%S: undefined MEMORY region `%s'"
|
||||
" referenced in expression\n"), tree->name.name);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONSTANT:
|
||||
if (strcmp (tree->name.name, "MAXPAGESIZE") == 0)
|
||||
new_abs (config.maxpagesize);
|
||||
new_number (config.maxpagesize);
|
||||
else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0)
|
||||
new_abs (config.commonpagesize);
|
||||
new_number (config.commonpagesize);
|
||||
else
|
||||
einfo (_("%F%S: unknown constant `%s' referenced in expression\n"),
|
||||
tree->name.name);
|
||||
@ -704,7 +698,7 @@ exp_fold_tree_1 (etree_type *tree)
|
||||
switch (tree->type.node_class)
|
||||
{
|
||||
case etree_value:
|
||||
new_rel (tree->value.value, expld.section);
|
||||
new_number (tree->value.value);
|
||||
expld.result.str = tree->value.str;
|
||||
break;
|
||||
|
||||
@ -767,7 +761,11 @@ exp_fold_tree_1 (etree_type *tree)
|
||||
{
|
||||
bfd_vma nextdot;
|
||||
|
||||
nextdot = expld.result.value + expld.result.section->vma;
|
||||
nextdot = expld.result.value;
|
||||
if (expld.result.section != NULL)
|
||||
nextdot += expld.result.section->vma;
|
||||
else
|
||||
nextdot += expld.section->vma;
|
||||
if (nextdot < expld.dot
|
||||
&& expld.section != bfd_abs_section_ptr)
|
||||
einfo (_("%F%S cannot move location counter backwards"
|
||||
@ -818,6 +816,8 @@ exp_fold_tree_1 (etree_type *tree)
|
||||
lang_update_definedness (tree->assign.dst, h);
|
||||
h->type = bfd_link_hash_defined;
|
||||
h->u.def.value = expld.result.value;
|
||||
if (expld.result.section == NULL)
|
||||
expld.result.section = expld.section;
|
||||
h->u.def.section = expld.result.section;
|
||||
if (tree->type.node_class == etree_provide)
|
||||
tree->type.node_class = etree_provided;
|
||||
@ -856,6 +856,12 @@ exp_fold_tree_1 (etree_type *tree)
|
||||
memset (&expld.result, 0, sizeof (expld.result));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Any value not inside an output section statement is an
|
||||
absolute value. */
|
||||
if (expld.result.valid_p
|
||||
&& expld.section == bfd_abs_section_ptr)
|
||||
make_abs ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1186,7 +1192,8 @@ exp_get_abs_int (etree_type *tree, int def, char *name)
|
||||
|
||||
if (expld.result.valid_p)
|
||||
{
|
||||
expld.result.value += expld.result.section->vma;
|
||||
if (expld.result.section != NULL)
|
||||
expld.result.value += expld.result.section->vma;
|
||||
return expld.result.value;
|
||||
}
|
||||
else if (name != NULL && expld.phase != lang_mark_phase_enum)
|
||||
|
17
ld/ldlang.c
17
ld/ldlang.c
@ -3916,7 +3916,7 @@ print_assignment (lang_assignment_statement_type *assignment,
|
||||
{
|
||||
value = expld.result.value;
|
||||
|
||||
if (expld.result.section)
|
||||
if (expld.result.section != NULL)
|
||||
value += expld.result.section->vma;
|
||||
|
||||
minfo ("0x%V", value);
|
||||
@ -3933,7 +3933,7 @@ print_assignment (lang_assignment_statement_type *assignment,
|
||||
{
|
||||
value = h->u.def.value;
|
||||
|
||||
if (expld.result.section)
|
||||
if (expld.result.section != NULL)
|
||||
value += expld.result.section->vma;
|
||||
|
||||
minfo ("[0x%V]", value);
|
||||
@ -4718,7 +4718,11 @@ lang_size_sections_1
|
||||
exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot);
|
||||
|
||||
if (expld.result.valid_p)
|
||||
dot = expld.result.value + expld.result.section->vma;
|
||||
{
|
||||
dot = expld.result.value;
|
||||
if (expld.result.section != NULL)
|
||||
dot += expld.result.section->vma;
|
||||
}
|
||||
else if (expld.phase != lang_mark_phase_enum)
|
||||
einfo (_("%F%S: non constant or forward reference"
|
||||
" address expression for section %s\n"),
|
||||
@ -5397,8 +5401,11 @@ lang_do_assignments_1 (lang_statement_union_type *s,
|
||||
case lang_data_statement_enum:
|
||||
exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
|
||||
if (expld.result.valid_p)
|
||||
s->data_statement.value = (expld.result.value
|
||||
+ expld.result.section->vma);
|
||||
{
|
||||
s->data_statement.value = expld.result.value;
|
||||
if (expld.result.section != NULL)
|
||||
s->data_statement.value += expld.result.section->vma;
|
||||
}
|
||||
else
|
||||
einfo (_("%F%P: invalid data statement\n"));
|
||||
{
|
||||
|
@ -1,3 +1,7 @@
|
||||
2010-08-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ld-scripts/memory.t: Remove ORIGIN fudge.
|
||||
|
||||
2010-08-13 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/11913
|
||||
|
@ -15,19 +15,7 @@ SECTIONS
|
||||
. = 0;
|
||||
.text :
|
||||
{
|
||||
/* The value returned by the ORIGIN operator is a constant.
|
||||
However it is being assigned to a symbol declared within
|
||||
a section. Therefore the symbol is section-relative and
|
||||
its value will include the offset of that section from
|
||||
the start of memory. ie the declaration:
|
||||
text_start = ORIGIN (TEXTMEM);
|
||||
here will result in text_start having a value of 0x200.
|
||||
Hence we need to subtract the absolute value of the
|
||||
location counter at this point in order to give text_start
|
||||
a value that is truely absolute, and which coincidentally
|
||||
will allow the tests in script.exp to work. */
|
||||
|
||||
text_start = ORIGIN(TEXTMEM) - ABSOLUTE (.);
|
||||
text_start = ORIGIN (TEXTMEM);
|
||||
*(.text)
|
||||
*(.pr)
|
||||
text_end = .;
|
||||
|
Loading…
Reference in New Issue
Block a user