aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-04-16 20:53:55 +0000
committerIan Lance Taylor <ian@airs.com>1996-04-16 20:53:55 +0000
commite3e69b1328d20373043c170bb3aa4148d6c82a30 (patch)
tree4008520d20939991bfcdcd28e6d0094eb1a35719 /ld/ldexp.c
parentf32fb3fd1fb24d8d72ba1abe43ec8cfd0cf4a89d (diff)
downloadgdb-e3e69b1328d20373043c170bb3aa4148d6c82a30.zip
gdb-e3e69b1328d20373043c170bb3aa4148d6c82a30.tar.gz
gdb-e3e69b1328d20373043c170bb3aa4148d6c82a30.tar.bz2
* ldexp.c (fold_binary): Correct handling of subtraction with
absolute values. (fold_name): Permit symbols in lang_allocating_phase_enum.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c70
1 files changed, 33 insertions, 37 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 6426e63..ae457e5 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
This module is in charge of working out the contents of expressions.
@@ -161,7 +161,7 @@ etree_type *
exp_intop (value)
bfd_vma value;
{
- etree_type *new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->value)));
+ etree_type *new = (etree_type *) stat_alloc(sizeof(new->value));
new->type.node_code = INT;
new->value.value = value;
new->type.node_class = etree_value;
@@ -238,8 +238,9 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
value from a relative value is meaningful, and is an
exception. */
if (current_section != abs_output_section
- && (result.section == abs_output_section
- || other.section == abs_output_section)
+ && (other.section == abs_output_section
+ || (result.section == abs_output_section
+ && tree->type.node_code == '+'))
&& (tree->type.node_code == '+'
|| tree->type.node_code == '-'))
{
@@ -247,7 +248,7 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
/* If there is only one absolute term, make sure it is the
second one. */
- if (result.section == abs_output_section)
+ if (other.section != abs_output_section)
{
hold = result;
result = other;
@@ -345,10 +346,12 @@ fold_name (tree, current_section, allocation_done, dot)
{
struct bfd_link_hash_entry *h;
- h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
- false, false, true);
+ h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
+ tree->name.name,
+ false, false, true);
result.value = (h != (struct bfd_link_hash_entry *) NULL
&& (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_common));
result.section = 0;
result.valid = true;
@@ -367,13 +370,17 @@ fold_name (tree, current_section, allocation_done, dot)
{
struct bfd_link_hash_entry *h;
- h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
- false, false, true);
- if (h != NULL && h->type == bfd_link_hash_defined)
+ h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
+ tree->name.name,
+ false, false, true);
+ if (h != NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
{
if (bfd_is_abs_section (h->u.def.section))
result = new_abs (h->u.def.value);
- else if (allocation_done == lang_final_phase_enum)
+ else if (allocation_done == lang_final_phase_enum
+ || allocation_done == lang_allocating_phase_enum)
{
lang_output_section_statement_type *os;
@@ -472,28 +479,15 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
}
break;
case ABSOLUTE:
- if (allocation_done != lang_first_phase_enum)
- {
- if (current_section
- == (lang_output_section_statement_type*)NULL)
+ if (allocation_done != lang_first_phase_enum && result.valid)
{
- /* Outside a section, so it's all ok */
-
- }
- else {
- /* Inside a section, subtract the base of the section,
- so when it's added again (in an assignment), everything comes out fine
- */
+ result.value += result.section->bfd_section->vma;
result.section = abs_output_section;
- result.value -= current_section->bfd_section->vma;
- result.valid = true;
}
- }
else
- {
- result.valid = false;
- }
-
+ {
+ result.valid = false;
+ }
break;
case '~':
make_abs(&result);
@@ -546,7 +540,9 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
/* Assignment to dot can only be done during allocation */
if (tree->type.node_class == etree_provide)
einfo ("%F%S can not PROVIDE assignment to location counter\n");
- if (allocation_done == lang_allocating_phase_enum) {
+ if (allocation_done == lang_allocating_phase_enum
+ || (allocation_done == lang_final_phase_enum
+ && current_section == abs_output_section)) {
result = exp_fold_tree(tree->assign.src,
current_section,
lang_allocating_phase_enum, dot, dotp);
@@ -561,7 +557,7 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
else {
bfd_vma nextdot =result.value +
current_section->bfd_section->vma;
- if (nextdot < dot) {
+ if (nextdot < dot && current_section != abs_output_section) {
einfo("%F%S cannot move location counter backwards (from %V to %V)\n", dot, nextdot);
}
else {
@@ -651,7 +647,7 @@ exp_binop (code, lhs, rhs)
{
return exp_intop(r.value);
}
- new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->binary)));
+ new = (etree_type *) stat_alloc (sizeof (new->binary));
memcpy((char *)new, (char *)&value, sizeof(new->binary));
return new;
}
@@ -675,7 +671,7 @@ exp_trinop (code, cond, lhs, rhs)
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->trinary)));
+ new = (etree_type *) stat_alloc (sizeof (new->trinary));
memcpy((char *)new,(char *) &value, sizeof(new->trinary));
return new;
}
@@ -697,7 +693,7 @@ exp_unop (code, child)
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->unary)));
+ new = (etree_type *) stat_alloc (sizeof (new->unary));
memcpy((char *)new, (char *)&value, sizeof(new->unary));
return new;
}
@@ -721,7 +717,7 @@ exp_nameop (code, name)
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->name)));
+ new = (etree_type *) stat_alloc (sizeof (new->name));
memcpy((char *)new, (char *)&value, sizeof(new->name));
return new;
@@ -750,7 +746,7 @@ exp_assop (code, dst, src)
return exp_intop(result);
}
#endif
- new = (etree_type*)stat_alloc((bfd_size_type)(sizeof(new->assign)));
+ new = (etree_type*) stat_alloc (sizeof (new->assign));
memcpy((char *)new, (char *)&value, sizeof(new->assign));
return new;
}
@@ -887,7 +883,7 @@ exp_get_value_int (tree,def,name, allocation_done)
}
-int
+bfd_vma
exp_get_abs_int (tree, def, name, allocation_done)
etree_type *tree;
int def;