summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog27
-rw-r--r--ld/emultempl/elf32.em1
-rw-r--r--ld/emultempl/mmo.em3
-rw-r--r--ld/emultempl/pe.em1
-rw-r--r--ld/ldexp.c7
-rw-r--r--ld/ldexp.h6
-rw-r--r--ld/ldgram.y2
-rw-r--r--ld/ldlang.c144
-rw-r--r--ld/ldlang.h3
-rw-r--r--ld/mri.c6
10 files changed, 115 insertions, 85 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 549abb2a83..88cb62176f 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,32 @@
2004-01-03 Alan Modra <amodra@bigpond.net.au>
+ * ldexp.c (align_n): Make static.
+ * ldexp.h (align_n): Delete declaration.
+ * ldlang.h (lang_enter_output_section_statement): Remove
+ block_value param.
+ * ldlang.c (lang_enter_output_section_statement): Likewise.
+ (TO_ADDR, TO_SIZE): Define.
+ (opb): New var.
+ (init_opb): New function.
+ (print_input_section): Call init_opb and use TO_ADDR.
+ (print_data_statement, print_reloc_statement): Likewise.
+ (print_padding_statement): Likewise.
+ (size_input_section): Use TO_SIZE and TO_ADDR, and global opb.
+ (lang_check_section_addresses): Likewise.
+ (lang_size_sections_1): Likewise.
+ (lang_do_assignments_1): Likewise.
+ (lang_set_startof): Likewise.
+ (lang_one_common): Likewise. Combine power_of_two and opb alignment.
+ (lang_process): Call init_opb.
+ (lang_abs_symbol_at_end_of): Use TO_ADDR and global opb.
+ (lang_enter_overlay_section): Adjust
+ lang_enter_output_section_statement call.
+ * ldgram.y: Likewise.
+ * mri.c (mri_draw_tree): Likewise.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Likewise.
+ * emultempl/mmo.em (mmo_place_orphan): Likewise.
+ * emultempl/pe.em (gld${EMULATION_NAME}_place_orphan): Likewise.
+
* ldfile.c (ldfile_set_output_arch): Add defarch param.
* ldfile.h (ldfile_set_output_arch): Ditto.
* emultempl/aix.em (gld${EMULATION_NAME}_before_parse): Use
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 9f68a8a211..45749e75d1 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1256,7 +1256,6 @@ gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s)
os_tail = lang_output_section_statement.tail;
os = lang_enter_output_section_statement (secname, address, 0,
- (bfd_vma) 0,
(etree_type *) NULL,
(etree_type *) NULL,
load_base);
diff --git a/ld/emultempl/mmo.em b/ld/emultempl/mmo.em
index 9e19af1711..38f1dbf78e 100644
--- a/ld/emultempl/mmo.em
+++ b/ld/emultempl/mmo.em
@@ -1,5 +1,5 @@
# This shell script emits a C file. -*- C -*-
-# Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
#
# This file is part of GLD, the Gnu Linker.
#
@@ -127,7 +127,6 @@ mmo_place_orphan (lang_input_statement_type *file, asection *s)
os = lang_enter_output_section_statement (bfd_get_section_name (s->owner,
s),
NULL, 0,
- (bfd_vma) 0,
(etree_type *) NULL,
(etree_type *) NULL,
(etree_type *) NULL);
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index ccf7a8e9f4..4f12d7f5bf 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -1647,7 +1647,6 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
}
os = lang_enter_output_section_statement (outsecname, address, 0,
- (bfd_vma) 0,
(etree_type *) NULL,
(etree_type *) NULL,
(etree_type *) NULL);
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 80d79cf193..2b973c3402 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1,6 +1,6 @@
/* This module handles expression trees.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003
+ 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
@@ -43,6 +43,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static etree_value_type exp_fold_tree_no_dot
(etree_type *, lang_output_section_statement_type *, lang_phase_type);
+static bfd_vma align_n
+ (bfd_vma, bfd_vma);
struct exp_data_seg exp_data_seg;
@@ -1099,7 +1101,8 @@ exp_get_abs_int (etree_type *tree,
return res.value;
}
-bfd_vma align_n (bfd_vma value, bfd_vma align)
+static bfd_vma
+align_n (bfd_vma value, bfd_vma align)
{
if (align <= 1)
return value;
diff --git a/ld/ldexp.h b/ld/ldexp.h
index c3cd5eda77..99e7073b2c 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -1,6 +1,6 @@
/* ldexp.h -
- Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@@ -138,7 +138,5 @@ fill_type *exp_get_fill
(etree_type *, fill_type *, char *, lang_phase_type);
bfd_vma exp_get_abs_int
(etree_type *, int, char *, lang_phase_type);
-bfd_vma align_n
- (bfd_vma, bfd_vma);
#endif
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 17717fbbbb..927114a8a1 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -841,7 +841,7 @@ section: NAME { ldlex_expression(); }
{
lang_enter_output_section_statement($1, $3,
sectype,
- 0, 0, $5, $4);
+ 0, $5, $4);
}
statement_list_opt
'}' { ldlex_popstate (); ldlex_expression (); }
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 6b201ecc73..55714c9766 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1,6 +1,6 @@
/* Linker command language support.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003
+ 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@@ -1799,6 +1799,30 @@ ldlang_open_output (lang_statement_union_type *statement)
}
}
+/* Convert between addresses in bytes and sizes in octets.
+ For currently supported targets, octets_per_byte is always a power
+ of two, so we can use shifts. */
+#define TO_ADDR(X) ((X) >> opb_shift)
+#define TO_SIZE(X) ((X) << opb_shift)
+
+/* Support the above. */
+static unsigned int opb_shift = 0;
+
+static void
+init_opb (void)
+{
+ unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
+ opb_shift = 0;
+ if (x > 1)
+ while ((x & 1) == 0)
+ {
+ x >>= 1;
+ ++opb_shift;
+ }
+ ASSERT (x == 1);
+}
+
/* Open all the input files. */
static void
@@ -2272,8 +2296,8 @@ print_input_section (lang_input_section_type *in)
{
asection *i = in->section;
bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
+
+ init_opb ();
if (size != 0)
{
print_space ();
@@ -2297,7 +2321,7 @@ print_input_section (lang_input_section_type *in)
}
minfo ("0x%V %W %B\n",
- i->output_section->vma + i->output_offset, size / opb,
+ i->output_section->vma + i->output_offset, TO_ADDR (size),
i->owner);
if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size)
@@ -2319,7 +2343,8 @@ print_input_section (lang_input_section_type *in)
bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
- print_dot = i->output_section->vma + i->output_offset + size / opb;
+ print_dot = (i->output_section->vma + i->output_offset
+ + TO_ADDR (size));
}
}
}
@@ -2342,9 +2367,8 @@ print_data_statement (lang_data_statement_type *data)
bfd_vma addr;
bfd_size_type size;
const char *name;
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
+ init_opb ();
for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
print_space ();
@@ -2388,8 +2412,7 @@ print_data_statement (lang_data_statement_type *data)
print_nl ();
- print_dot = addr + size / opb;
-
+ print_dot = addr + TO_ADDR (size);
}
/* Print an address statement. These are generated by options like
@@ -2411,9 +2434,8 @@ print_reloc_statement (lang_reloc_statement_type *reloc)
int i;
bfd_vma addr;
bfd_size_type size;
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
+ init_opb ();
for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
print_space ();
@@ -2434,7 +2456,7 @@ print_reloc_statement (lang_reloc_statement_type *reloc)
print_nl ();
- print_dot = addr + size / opb;
+ print_dot = addr + TO_ADDR (size);
}
static void
@@ -2442,9 +2464,8 @@ print_padding_statement (lang_padding_statement_type *s)
{
int len;
bfd_vma addr;
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
+ init_opb ();
minfo (" *fill*");
len = sizeof " *fill*" - 1;
@@ -2469,7 +2490,7 @@ print_padding_statement (lang_padding_statement_type *s)
print_nl ();
- print_dot = addr + s->size / opb;
+ print_dot = addr + TO_ADDR (s->size);
}
static void
@@ -2698,8 +2719,6 @@ size_input_section (lang_statement_union_type **this_ptr,
if (!is->ifile->just_syms_flag)
{
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
unsigned int alignment_needed;
asection *o;
@@ -2719,7 +2738,7 @@ size_input_section (lang_statement_union_type **this_ptr,
if (alignment_needed != 0)
{
- insert_pad (this_ptr, fill, alignment_needed * opb, o, dot);
+ insert_pad (this_ptr, fill, TO_SIZE (alignment_needed), o, dot);
dot += alignment_needed;
}
@@ -2729,10 +2748,10 @@ size_input_section (lang_statement_union_type **this_ptr,
/* Mark how big the output section must be to contain this now. */
if (i->_cooked_size != 0)
- dot += i->_cooked_size / opb;
+ dot += TO_ADDR (i->_cooked_size);
else
- dot += i->_raw_size / opb;
- o->_raw_size = (dot - o->vma) * opb;
+ dot += TO_ADDR (i->_raw_size);
+ o->_raw_size = TO_SIZE (dot - o->vma);
}
else
{
@@ -2755,7 +2774,6 @@ static void
lang_check_section_addresses (void)
{
asection *s;
- unsigned opb = bfd_octets_per_byte (output_bfd);
/* Scan all sections in the output list. */
for (s = output_bfd->sections; s != NULL; s = s->next)
@@ -2783,10 +2801,10 @@ lang_check_section_addresses (void)
/* We must check the sections' LMA addresses not their
VMA addresses because overlay sections can have
overlapping VMAs but they must have distinct LMAs. */
- s_start = bfd_section_lma (output_bfd, s);
+ s_start = bfd_section_lma (output_bfd, s);
os_start = bfd_section_lma (output_bfd, os);
- s_end = s_start + bfd_section_size (output_bfd, s) / opb - 1;
- os_end = os_start + bfd_section_size (output_bfd, os) / opb - 1;
+ s_end = s_start + TO_ADDR (bfd_section_size (output_bfd, s)) - 1;
+ os_end = os_start + TO_ADDR (bfd_section_size (output_bfd, os)) - 1;
/* Look for an overlap. */
if ((s_end < os_start) || (s_start > os_end))
@@ -2851,9 +2869,6 @@ lang_size_sections_1
bfd_boolean *relax,
bfd_boolean check_regions)
{
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
-
/* Size up the sections from their constituent parts. */
for (; s != NULL; s = s->header.next)
{
@@ -2990,9 +3005,10 @@ lang_size_sections_1
/* Put the section within the requested block size, or
align at the block boundary. */
- after = align_n (os->bfd_section->vma
- + os->bfd_section->_raw_size / opb,
- (bfd_vma) os->block_value);
+ after = ((os->bfd_section->vma
+ + TO_ADDR (os->bfd_section->_raw_size)
+ + os->block_value - 1)
+ & - (bfd_vma) os->block_value);
if (bfd_is_abs_section (os->bfd_section))
ASSERT (after == os->bfd_section->vma);
@@ -3001,10 +3017,10 @@ lang_size_sections_1
&& ! link_info.relocatable)
os->bfd_section->_raw_size = 0;
else
- os->bfd_section->_raw_size =
- (after - os->bfd_section->vma) * opb;
+ os->bfd_section->_raw_size
+ = TO_SIZE (after - os->bfd_section->vma);
- dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
+ dot = os->bfd_section->vma + TO_ADDR (os->bfd_section->_raw_size);
os->processed = TRUE;
if (os->update_dot_tree != 0)
@@ -3042,7 +3058,7 @@ lang_size_sections_1
/* Set load_base, which will be handled later. */
os->load_base = exp_intop (os->lma_region->current);
os->lma_region->current +=
- os->bfd_section->_raw_size / opb;
+ TO_ADDR (os->bfd_section->_raw_size);
if (check_regions)
os_region_check (os, os->lma_region, NULL,
os->bfd_section->lma);
@@ -3085,9 +3101,9 @@ lang_size_sections_1
size = BYTE_SIZE;
break;
}
- if (size < opb)
- size = opb;
- dot += size / opb;
+ if (size < TO_SIZE ((unsigned) 1))
+ size = TO_SIZE ((unsigned) 1);
+ dot += TO_ADDR (size);
output_section_statement->bfd_section->_raw_size += size;
/* The output section gets contents, and then we inspect for
any flags set in the input script which override any ALLOC. */
@@ -3109,7 +3125,7 @@ lang_size_sections_1
s->reloc_statement.output_section =
output_section_statement->bfd_section;
size = bfd_get_reloc_size (s->reloc_statement.howto);
- dot += size / opb;
+ dot += TO_ADDR (size);
output_section_statement->bfd_section->_raw_size += size;
}
break;
@@ -3184,7 +3200,7 @@ lang_size_sections_1
/* Insert a pad after this statement. We can't
put the pad before when relaxing, in case the
assignment references dot. */
- insert_pad (&s->header.next, fill, (newdot - dot) * opb,
+ insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot),
output_section_statement->bfd_section, dot);
/* Don't neuter the pad below when relaxing. */
@@ -3291,9 +3307,6 @@ lang_do_assignments_1
fill_type *fill,
bfd_vma dot)
{
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
-
for (; s != NULL; s = s->header.next)
{
switch (s->header.type)
@@ -3315,7 +3328,8 @@ lang_do_assignments_1
dot = os->bfd_section->vma;
(void) lang_do_assignments_1 (os->children.head, os,
os->fill, dot);
- dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
+ dot = (os->bfd_section->vma
+ + TO_ADDR (os->bfd_section->_raw_size));
}
if (os->load_base)
@@ -3377,9 +3391,9 @@ lang_do_assignments_1
size = BYTE_SIZE;
break;
}
- if (size < opb)
- size = opb;
- dot += size / opb;
+ if (size < TO_SIZE ((unsigned) 1))
+ size = TO_SIZE ((unsigned) 1);
+ dot += TO_ADDR (size);
}
break;
@@ -3394,7 +3408,7 @@ lang_do_assignments_1
if (!value.valid_p)
einfo (_("%F%P: invalid reloc statement\n"));
}
- dot += bfd_get_reloc_size (s->reloc_statement.howto) / opb;
+ dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto));
break;
case lang_input_section_enum:
@@ -3402,9 +3416,9 @@ lang_do_assignments_1
asection *in = s->input_section.section;
if (in->_cooked_size != 0)
- dot += in->_cooked_size / opb;
+ dot += TO_ADDR (in->_cooked_size);
else
- dot += in->_raw_size / opb;
+ dot += TO_ADDR (in->_raw_size);
}
break;
@@ -3424,7 +3438,7 @@ lang_do_assignments_1
break;
case lang_padding_statement_enum:
- dot += s->padding_statement.size / opb;
+ dot += TO_ADDR (s->padding_statement.size);
break;
case lang_group_statement_enum:
@@ -3447,8 +3461,7 @@ lang_do_assignments_1
void
lang_do_assignments (lang_statement_union_type *s,
- lang_output_section_statement_type
- *output_section_statement,
+ lang_output_section_statement_type *output_section_statement,
fill_type *fill,
bfd_vma dot)
{
@@ -3494,15 +3507,11 @@ lang_set_startof (void)
h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
if (h != NULL && h->type == bfd_link_hash_undefined)
{
- unsigned opb;
-
- opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
h->type = bfd_link_hash_defined;
if (s->_cooked_size != 0)
- h->u.def.value = s->_cooked_size / opb;
+ h->u.def.value = TO_ADDR (s->_cooked_size);
else
- h->u.def.value = s->_raw_size / opb;
+ h->u.def.value = TO_ADDR (s->_raw_size);
h->u.def.section = bfd_abs_section_ptr;
}
@@ -3696,8 +3705,6 @@ lang_one_common (struct bfd_link_hash_entry *h, void *info)
unsigned int power_of_two;
bfd_vma size;
asection *section;
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
if (h->type != bfd_link_hash_common)
return TRUE;
@@ -3711,9 +3718,9 @@ lang_one_common (struct bfd_link_hash_entry *h, void *info)
section = h->u.c.p->section;
- /* Increase the size of the section. */
- section->_cooked_size = align_n ((section->_cooked_size + opb - 1) / opb,
- (bfd_vma) 1 << power_of_two) * opb;
+ /* Increase the size of the section to align the common sym. */
+ section->_cooked_size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1;
+ section->_cooked_size &= (- (bfd_vma) 1 << (power_of_two + opb_shift));
/* Adjust the alignment if necessary. */
if (power_of_two > section->alignment_power)
@@ -3994,7 +4001,6 @@ lang_output_section_statement_type *
lang_enter_output_section_statement (const char *output_section_statement_name,
etree_type *address_exp,
enum section_type sectype,
- bfd_vma block_value,
etree_type *align,
etree_type *subalign,
etree_type *ebase)
@@ -4021,7 +4027,7 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
os->flags = SEC_NO_FLAGS;
else
os->flags = SEC_NEVER_LOAD;
- os->block_value = block_value ? block_value : 1;
+ os->block_value = 1;
stat_ptr = &os->children;
os->subsection_alignment =
@@ -4147,6 +4153,7 @@ lang_process (void)
/* Open the output file. */
lang_for_each_statement (ldlang_open_output);
+ init_opb ();
ldemul_create_output_section_statements ();
@@ -4582,8 +4589,7 @@ lang_abs_symbol_at_end_of (const char *secname, const char *name)
h->u.def.value = 0;
else
h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
- + bfd_section_size (output_bfd, sec) /
- bfd_octets_per_byte (output_bfd));
+ + TO_ADDR (bfd_section_size (output_bfd, sec)));
h->u.def.section = bfd_abs_section_ptr;
}
@@ -4832,7 +4838,7 @@ lang_enter_overlay_section (const char *name)
etree_type *size;
lang_enter_output_section_statement (name, overlay_vma, normal_section,
- 0, 0, overlay_subalign, 0);
+ 0, overlay_subalign, 0);
/* If this is the first section, then base the VMA of future
sections on this one. This will work correctly even if `.' is
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 29424bb689..87318b0501 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -1,6 +1,6 @@
/* ldlang.h - linker command language support
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003
+ 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@@ -403,7 +403,6 @@ extern lang_output_section_statement_type *lang_enter_output_section_statement
(const char *output_section_statement_name,
etree_type *address_exp,
enum section_type sectype,
- bfd_vma block_value,
etree_type *align,
etree_type *subalign,
etree_type *);
diff --git a/ld/mri.c b/ld/mri.c
index 41ba582466..f7edd8817f 100644
--- a/ld/mri.c
+++ b/ld/mri.c
@@ -1,6 +1,6 @@
/* mri.c -- handle MRI style linker scripts
- Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@@ -220,7 +220,7 @@ mri_draw_tree (void)
lang_enter_output_section_statement (p->name, base,
p->ok_to_load ? 0 : noload_section,
- 1, align, subalign, NULL);
+ align, subalign, NULL);
base = 0;
tmp = xmalloc (sizeof *tmp);
tmp->next = NULL;