From e5caa5e0caf09b4927fbe0520056c5eac9056fe5 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 3 Jan 2004 12:39:07 +0000 Subject: [PATCH] * 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. --- ld/ChangeLog | 27 ++++++++++ ld/emultempl/elf32.em | 1 - ld/emultempl/mmo.em | 3 +- ld/emultempl/pe.em | 1 - ld/ldexp.c | 7 ++- ld/ldexp.h | 6 +-- ld/ldgram.y | 2 +- ld/ldlang.c | 144 ++++++++++++++++++++++++++------------------------ ld/ldlang.h | 3 +- ld/mri.c | 6 +-- 10 files changed, 115 insertions(+), 85 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 549abb2..88cb621 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,32 @@ 2004-01-03 Alan Modra + * 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 9f68a8a..45749e7 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 9e19af1..38f1dbf 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 ccf7a8e..4f12d7f 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 80d79cf..2b973c3 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 . @@ -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 c3cd5ed..99e7073 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 17717fb..927114a 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 6b201ec..55714c9 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 29424bb..87318b0 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 41ba582..f7edd88 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; -- 2.7.4