diff --git a/ld/ChangeLog b/ld/ChangeLog index d14446ba54..3065b4495e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,42 @@ +Mon Aug 5 16:26:14 1996 Ian Lance Taylor + + * ldlex.l: Recognize OVERLAY. + * ldgram.y: Add section_phdr field to %union. + (section): Handle phdr_opt result. Add OVERLAY case. + (opt_exp_without_type): New nonterminal. + (phdr_opt): Return list of phdrs. + (overlay_section): New nonterminal. + * ldlang.c: Include . + (lang_leave_output_section_statement): Add phdrs parameter. + Change all callers. + (lang_section_in_phdr): Remove. + (overlay_vma, overlay_lmn, overlay_max): New static variables. + (struct overlay_list): Define. + (overlay_list): New static variable. + (lang_enter_overlay, lang_enter_overlay_section): New functions. + (lang_leave_overlay_section, lang_leave_overlay): New functions. + * ldlang.h (lang_leave_output_section_statement): Update + declaration for new parameter. + (lang_section_in_phdr): Don't declare. + (lang_enter_overlay, lang_enter_overlay_section): Declare. + (lang_leave_overlay_section, lang_leave_overlay): Declare. + * ld.texinfo (Overlays): New node under SECTIONS, documenting + overlays. + + * ldlex.l: Recognize MAX and MIN. + * ldgram.y (MAX, MIN): New terminals. + (exp): Recognize MAX and MIN. + * ldexp.c (fold_binary): Handle MAX and MIN. + * ld.texinfo (Arithmetic Functions): Document MAX and MIN. + + * ld.texinfo (PHDRS): Use @cindex, not @kindex, for program header + index entries. + + * ldgram.y (SIZEOF, ADDR): Do not specify type. + + * ldcref.c (check_nocrossref): Skip symbols with no output + sections. + Fri Aug 2 14:57:49 1996 Ian Lance Taylor * ldgram.y (LOADADDR): New terminal. diff --git a/ld/ldlang.c b/ld/ldlang.c index 60f191f01d..3656a8a26f 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -14,8 +14,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" @@ -34,6 +35,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307 #include "ldfile.h" #include "fnmatch.h" +#include + /* FORWARDS */ static lang_statement_union_type *new_statement PARAMS ((enum statement_enum, size_t, @@ -3338,12 +3341,14 @@ lang_float (maybe) } void -lang_leave_output_section_statement (fill, memspec) +lang_leave_output_section_statement (fill, memspec, phdrs) bfd_vma fill; - CONST char *memspec; + const char *memspec; + struct lang_output_section_phdr_list *phdrs; { current_section->fill = fill; current_section->region = lang_memory_region_lookup (memspec); + current_section->phdrs = phdrs; stat_ptr = &statement_list; } @@ -3501,22 +3506,6 @@ lang_new_phdr (name, type, filehdr, phdrs, at, flags) *pp = n; } -/* Record that a section should be placed in a phdr. */ - -void -lang_section_in_phdr (name) - const char *name; -{ - struct lang_output_section_phdr_list *n; - - n = ((struct lang_output_section_phdr_list *) - stat_alloc (sizeof (struct lang_output_section_phdr_list))); - n->name = name; - n->used = false; - n->next = current_section->phdrs; - current_section->phdrs = n; -} - /* Record the program header information in the output BFD. FIXME: We should not be calling an ELF specific function here. */ @@ -3636,3 +3625,178 @@ lang_add_nocrossref (l) /* Set notice_all so that we get informed about all symbols. */ link_info.notice_all = true; } + +/* Overlay handling. We handle overlays with some static variables. */ + +/* The overlay virtual address. */ +static etree_type *overlay_vma; + +/* The overlay load address. */ +static etree_type *overlay_lma; + +/* An expression for the maximum section size seen so far. */ +static etree_type *overlay_max; + +/* A list of all the sections in this overlay. */ + +struct overlay_list +{ + struct overlay_list *next; + lang_output_section_statement_type *os; +}; + +static struct overlay_list *overlay_list; + +/* Start handling an overlay. */ + +void +lang_enter_overlay (vma_expr, lma_expr) + etree_type *vma_expr; + etree_type *lma_expr; +{ + /* The grammar should prevent nested overlays from occurring. */ + ASSERT (overlay_vma == NULL + && overlay_lma == NULL + && overlay_list == NULL + && overlay_max == NULL); + + overlay_vma = vma_expr; + overlay_lma = lma_expr; +} + +/* Start a section in an overlay. We handle this by calling + lang_enter_output_section_statement with the correct VMA and LMA. */ + +void +lang_enter_overlay_section (name) + const char *name; +{ + struct overlay_list *n; + etree_type *size; + + lang_enter_output_section_statement (name, overlay_vma, normal_section, + 0, 0, 0, overlay_lma); + + /* If this is the first section, then base the VMA and LMA of future + sections on this one. This will work correctly even if `.' is + used in the addresses. */ + if (overlay_list == NULL) + { + overlay_vma = exp_nameop (ADDR, name); + overlay_lma = exp_nameop (LOADADDR, name); + } + + /* Remember the section. */ + n = (struct overlay_list *) xmalloc (sizeof *n); + n->os = current_section; + n->next = overlay_list; + overlay_list = n; + + size = exp_nameop (SIZEOF, name); + + /* Adjust the LMA for the next section. */ + overlay_lma = exp_binop ('+', overlay_lma, size); + + /* Arrange to work out the maximum section end address. */ + if (overlay_max == NULL) + overlay_max = size; + else + overlay_max = exp_binop (MAX, overlay_max, size); +} + +/* Finish a section in an overlay. There isn't any special to do + here. */ + +void +lang_leave_overlay_section (fill, phdrs) + bfd_vma fill; + struct lang_output_section_phdr_list *phdrs; +{ + const char *name; + char *clean, *s2; + const char *s1; + char *buf; + + name = current_section->name; + + lang_leave_output_section_statement (fill, "*default*", phdrs); + + /* Define the magic symbols. */ + + clean = xmalloc (strlen (name) + 1); + s2 = clean; + for (s1 = name; *s1 != '\0'; s1++) + if (isalnum (*s1) || *s1 == '_') + *s2++ = *s1; + *s2 = '\0'; + + buf = xmalloc (strlen (clean) + sizeof "__load_start_"); + sprintf (buf, "__load_start_%s", clean); + lang_add_assignment (exp_assop ('=', buf, + exp_nameop (LOADADDR, name))); + + buf = xmalloc (strlen (clean) + sizeof "__load_stop_"); + sprintf (buf, "__load_stop_%s", clean); + lang_add_assignment (exp_assop ('=', buf, + exp_binop ('+', + exp_nameop (LOADADDR, name), + exp_nameop (SIZEOF, name)))); + + free (clean); +} + +/* Finish an overlay. If there are any overlay wide settings, this + looks through all the sections in the overlay and sets them. */ + +void +lang_leave_overlay (fill, memspec, phdrs) + bfd_vma fill; + const char *memspec; + struct lang_output_section_phdr_list *phdrs; +{ + lang_memory_region_type *region; + struct overlay_list *l; + struct lang_nocrossref *nocrossref; + + if (memspec == NULL) + region = NULL; + else + region = lang_memory_region_lookup (memspec); + + nocrossref = NULL; + + l = overlay_list; + while (l != NULL) + { + struct lang_nocrossref *nc; + struct overlay_list *next; + + if (fill != 0 && l->os->fill == 0) + l->os->fill = fill; + if (region != NULL && l->os->region == NULL) + l->os->region = region; + if (phdrs != NULL && l->os->phdrs == NULL) + l->os->phdrs = phdrs; + + nc = (struct lang_nocrossref *) xmalloc (sizeof *nc); + nc->name = l->os->name; + nc->next = nocrossref; + nocrossref = nc; + + next = l->next; + free (l); + l = next; + } + + if (nocrossref != NULL) + lang_add_nocrossref (nocrossref); + + /* Update . for the end of the overlay. */ + lang_add_assignment (exp_assop ('=', ".", + exp_binop ('+', overlay_vma, overlay_max))); + + overlay_vma = NULL; + overlay_lma = NULL; + overlay_list = NULL; + overlay_max = NULL; +}