Index: ldexp.c =================================================================== RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/ld/ldexp.c,v retrieving revision 1.1.1.3 diff -c -r1.1.1.3 ldexp.c *** ldexp.c 2001/08/14 02:59:08 1.1.1.3 --- ldexp.c 2002/11/19 17:30:37 *************** *** 460,465 **** --- 460,471 ---- os = lang_output_section_find (tree->name.name); check (os, tree->name.name, "SIZEOF"); result = new_abs (os->bfd_section->_raw_size / opb); + + /* If the output section has a size adjustment, apply it. */ + if (os->size_adj) + result = exp_fold_tree_no_dot + (exp_binop ('+', exp_intop (result.value), os->size_adj), + abs_output_section, allocation_done); } else result = invalid (); Index: ldlang.c =================================================================== RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/ld/ldlang.c,v retrieving revision 1.1.1.4 diff -c -r1.1.1.4 ldlang.c *** ldlang.c 2001/08/14 02:59:13 1.1.1.4 --- ldlang.c 2002/11/19 17:30:44 *************** *** 718,723 **** --- 718,724 ---- lookup->subsection_alignment = -1; lookup->section_alignment = -1; lookup->load_base = (union etree_union *) NULL; + lookup->size_adj = (union etree_union *) NULL; lookup->phdrs = NULL; lang_statement_append (&lang_output_section_statement, Index: ldlang.h =================================================================== RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/ld/ldlang.h,v retrieving revision 1.1.1.4 diff -c -r1.1.1.4 ldlang.h *** ldlang.h 2001/08/14 02:59:14 1.1.1.4 --- ldlang.h 2002/11/19 17:30:45 *************** *** 131,136 **** --- 131,137 ---- int section_alignment; /* alignment of start of section */ union etree_union *load_base; + union etree_union *size_adj; struct lang_output_section_phdr_list *phdrs; } lang_output_section_statement_type; Index: emultempl/elf32.em =================================================================== RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/ld/emultempl/elf32.em,v retrieving revision 1.3 diff -c -r1.3 elf32.em *** emultempl/elf32.em 2002/11/01 16:07:37 1.3 --- emultempl/elf32.em 2002/11/19 17:30:48 *************** *** 1005,1010 **** --- 1005,1011 ---- lang_statement_list_type *old; lang_statement_list_type add; etree_type *address; + etree_type *load_base; const char *secname; const char *outsecname; const char *ps = NULL; *************** *** 1133,1143 **** else address = NULL; os = lang_enter_output_section_statement (outsecname, address, 0, (bfd_vma) 0, (etree_type *) NULL, (etree_type *) NULL, ! (etree_type *) NULL); wild_doit (&os->children, s, os, file); --- 1134,1153 ---- else address = NULL; + /* If the output section we're sorting with has an AT expression, + then we need to copy that AT expression, adjusting it for the + size of the previous section. */ + if (place != NULL && place->os->load_base != NULL) + load_base = exp_binop ('+', place->os->load_base, + exp_nameop (SIZEOF, place->os->name)); + else + load_base = NULL; + os = lang_enter_output_section_statement (outsecname, address, 0, (bfd_vma) 0, (etree_type *) NULL, (etree_type *) NULL, ! load_base); wild_doit (&os->children, s, os, file); *************** *** 1158,1163 **** --- 1168,1185 ---- sprintf (symname, "__stop_%s", outsecname); lang_add_assignment (exp_assop ('=', symname, exp_nameop (NAME, "."))); + } + + if (load_base != NULL) + { + /* By sorting the orphan after place->os, we effectively changed + the size of that section. Adjust the size of the section to + reflect the additional output. */ + if (place->os->size_adj == NULL) + place->os->size_adj = exp_nameop (SIZEOF, os->name); + else + place->os->size_adj = exp_binop ('+', place->os->size_adj, + exp_nameop (SIZEOF, os->name)); } /* Restore the global list pointer. */