X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=as%2Flink%2Fz80%2Flkarea.c;h=7292d9541e0289141b8b5abe745e2bcd5ac4578a;hb=22ec133e94d056a395025c302b6c331c8cd04658;hp=95e5a8aca30342737811bd3a0a0e60a261837160;hpb=b7fec7bdb767e95165097f43e52cf1cbc4ee6017;p=fw%2Fsdcc diff --git a/as/link/z80/lkarea.c b/as/link/z80/lkarea.c index 95e5a8ac..7292d954 100644 --- a/as/link/z80/lkarea.c +++ b/as/link/z80/lkarea.c @@ -1,89 +1,96 @@ -/* lkarea.c */ +/* lkarea.c -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ + Copyright (C) 1989-1995 Alan R. Baldwin + 721 Berkeley St., Kent, Ohio 44240 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +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 this program. If not, see . */ #include #include #include "aslink.h" -/*)Module lkarea.c +/*)Module lkarea.c * - * The module lkarea.c contains the functions which - * create and link together all area definitions read - * from the .rel file(s). + * The module lkarea.c contains the functions which + * create and link together all area definitions read + * from the .rel file(s). * - * lkarea.c contains the following functions: - * VOID lnkarea() - * VOID lnksect() - * VOID lkparea() - * VOID newarea() + * lkarea.c contains the following functions: + * VOID lnkarea() + * VOID lnksect() + * VOID lkparea() + * VOID newarea() * - * lkarea.c contains no global variables. + * lkarea.c contains no global variables. */ -/*)Function VOID newarea() - * - * The function newarea() creates and/or modifies area - * and areax structures for each A directive read from - * the .rel file(s). The function lkparea() is called - * to find the area structure associated with this name. - * If the area does not yet exist then a new area - * structure is created and linked to any existing - * linked area structures. The area flags are copied - * into the area flag variable. For each occurence of - * an A directive an areax structure is created and - * linked to the areax structures associated with this - * area. The size of this area section is placed into - * the areax structure. The flag value for all subsequent - * area definitions for the same area are compared and - * flagged as an error if they are not identical. - * The areax structure created for every occurence of - * an A directive is loaded with a pointer to the base - * area structure and a pointer to the associated - * head structure. And finally, a pointer to this - * areax structure is loaded into the list of areax - * structures in the head structure. Refer to lkdata.c - * for details of the structures and their linkage. - * - * local variables: - * areax **halp pointer to an array of pointers - * int i counter, loop variable, value - * char id[] id string - * int narea number of areas in this head structure - * areax * taxp pointer to an areax structure - * to areax structures - * - * global variables: - * area *ap Pointer to the current - * area structure - * areax *axp Pointer to the current - * areax structure - * head *hp Pointer to the current - * head structure - * int lkerr error flag - * - * functions called: - * Addr_T eval() lkeval.c - * VOID exit() c_library - * int fprintf() c_library - * VOID getid() lklex.c - * VOID lkparea() lkarea.c - * VOID skip() lklex.c - * - * side effects: - * The area and areax structures are created and - * linked with the appropriate head structures. - * Failure to allocate area or areax structure - * space will terminate the linker. Other internal - * errors most likely caused by corrupted .rel - * files will also terminate the linker. +/*)Function VOID newarea() + * + * The function newarea() creates and/or modifies area + * and areax structures for each A directive read from + * the .rel file(s). The function lkparea() is called + * to find the area structure associated with this name. + * If the area does not yet exist then a new area + * structure is created and linked to any existing + * linked area structures. The area flags are copied + * into the area flag variable. For each occurence of + * an A directive an areax structure is created and + * linked to the areax structures associated with this + * area. The size of this area section is placed into + * the areax structure. The flag value for all subsequent + * area definitions for the same area are compared and + * flagged as an error if they are not identical. + * The areax structure created for every occurence of + * an A directive is loaded with a pointer to the base + * area structure and a pointer to the associated + * head structure. And finally, a pointer to this + * areax structure is loaded into the list of areax + * structures in the head structure. Refer to lkdata.c + * for details of the structures and their linkage. + * + * local variables: + * areax **halp pointer to an array of pointers + * int i counter, loop variable, value + * char id[] id string + * int narea number of areas in this head structure + * areax * taxp pointer to an areax structure + * to areax structures + * + * global variables: + * area *ap Pointer to the current + * area structure + * areax *axp Pointer to the current + * areax structure + * head *hp Pointer to the current + * head structure + * int lkerr error flag + * + * functions called: + * Addr_T eval() lkeval.c + * VOID exit() c_library + * int fprintf() c_library + * VOID getid() lklex.c + * VOID lkparea() lkarea.c + * VOID skip() lklex.c + * + * side effects: + * The area and areax structures are created and + * linked with the appropriate head structures. + * Failure to allocate area or areax structure + * space will terminate the linker. Other internal + * errors most likely caused by corrupted .rel + * files will also terminate the linker. */ /* @@ -99,210 +106,210 @@ VOID newarea() { - register int i, narea; - struct areax *taxp; - struct areax **halp; - char id[NCPS]; + register int i, narea; + struct areax *taxp; + struct areax **halp; + char id[NCPS]; - /* - * Create Area entry - */ - getid(id, -1); - lkparea(id); - /* - * Evaluate area size - */ - skip(-1); - axp->a_size = eval(); - /* - * Evaluate flags - */ - skip(-1); - i = 0; - taxp = ap->a_axp; - while (taxp->a_axp) { - ++i; - taxp = taxp->a_axp; - } - if (i == 0) { - ap->a_flag = eval(); - } else { - i = eval(); - if (i && (ap->a_flag != i)) { - fprintf(stderr, "Conflicting flags in area %.8s\n", id); - lkerr++; - } - } - /* - * Place pointer in header area list - */ - if (headp == NULL) { - fprintf(stderr, "No header defined\n"); - lkexit(1); - } - narea = hp->h_narea; - halp = hp->a_list; - for (i=0; i < narea ;++i) { - if (halp[i] == NULL) { - halp[i] = taxp; - return; - } - } - fprintf(stderr, "Header area list overflow\n"); - lkexit(1); + /* + * Create Area entry + */ + getid(id, -1); + lkparea(id); + /* + * Evaluate area size + */ + skip(-1); + axp->a_size = eval(); + /* + * Evaluate flags + */ + skip(-1); + i = 0; + taxp = ap->a_axp; + while (taxp->a_axp) { + ++i; + taxp = taxp->a_axp; + } + if (i == 0) { + ap->a_flag = eval(); + } else { + i = eval(); + if (i && (ap->a_flag != i)) { + fprintf(stderr, "Conflicting flags in area %.8s\n", id); + lkerr++; + } + } + /* + * Place pointer in header area list + */ + if (headp == NULL) { + fprintf(stderr, "No header defined\n"); + lkexit(1); + } + narea = hp->h_narea; + halp = hp->a_list; + for (i=0; i < narea ;++i) { + if (halp[i] == NULL) { + halp[i] = taxp; + return; + } + } + fprintf(stderr, "Header area list overflow\n"); + lkexit(1); } -/*)Function VOID lkparea(id) - * - * char * id pointer to the area name string - * - * The function lkparea() searches the linked area structures - * for a name match. If the name is not found then an area - * structure is created. An areax structure is created and - * appended to the areax structures linked to the area structure. - * The associated base area and head structure pointers are - * loaded into the areax structure. - * - * local variables: - * area * tap pointer to an area structure - * areax * taxp pointer to an areax structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * areax *axp Pointer to the current - * areax structure - * - * functions called: - * VOID * new() lksym() - * char * strcpy() c_library - * int symeq() lksym.c - * - * side effects: - * Area and/or areax structures are created. - * Failure to allocate space for created structures - * will terminate the linker. +/*)Function VOID lkparea(id) + * + * char * id pointer to the area name string + * + * The function lkparea() searches the linked area structures + * for a name match. If the name is not found then an area + * structure is created. An areax structure is created and + * appended to the areax structures linked to the area structure. + * The associated base area and head structure pointers are + * loaded into the areax structure. + * + * local variables: + * area * tap pointer to an area structure + * areax * taxp pointer to an areax structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * areax *axp Pointer to the current + * areax structure + * + * functions called: + * VOID * new() lksym() + * char * strcpy() c_library + * int symeq() lksym.c + * + * side effects: + * Area and/or areax structures are created. + * Failure to allocate space for created structures + * will terminate the linker. */ VOID lkparea(char *id) { - register struct area *tap; - register struct areax *taxp; + register struct area *tap; + register struct areax *taxp; - ap = areap; - axp = (struct areax *) new (sizeof(struct areax)); - while (ap) { - if (symeq(id, ap->a_id)) { - taxp = ap->a_axp; - while (taxp->a_axp) - taxp = taxp->a_axp; - taxp->a_axp = axp; - axp->a_bap = ap; - axp->a_bhp = hp; - return; - } - ap = ap->a_ap; - } - ap = (struct area *) new (sizeof(struct area)); - if (areap == NULL) { - areap = ap; - } else { - tap = areap; - while (tap->a_ap) - tap = tap->a_ap; - tap->a_ap = ap; - } - ap->a_axp = axp; - axp->a_bap = ap; - axp->a_bhp = hp; - strncpy(ap->a_id, id, NCPS); + ap = areap; + axp = (struct areax *) new (sizeof(struct areax)); + while (ap) { + if (symeq(id, ap->a_id)) { + taxp = ap->a_axp; + while (taxp->a_axp) + taxp = taxp->a_axp; + taxp->a_axp = axp; + axp->a_bap = ap; + axp->a_bhp = hp; + return; + } + ap = ap->a_ap; + } + ap = (struct area *) new (sizeof(struct area)); + if (areap == NULL) { + areap = ap; + } else { + tap = areap; + while (tap->a_ap) + tap = tap->a_ap; + tap->a_ap = ap; + } + ap->a_axp = axp; + axp->a_bap = ap; + axp->a_bhp = hp; + strncpy(ap->a_id, id, NCPS); ap->a_addr = 0; } -/*)Function VOID lnkarea() - * - * The function lnkarea() resolves all area addresses. - * The function evaluates each area structure (and all - * the associated areax structures) in sequence. The - * linking process supports four (4) possible area types: - * - * ABS/OVR - All sections (each individual areax - * section) starts at the identical base - * area address overlaying all other - * areax sections for this area. The - * size of the area is largest of the area - * sections. - * - * ABS/CON - All sections (each individual areax - * section) are concatenated with the - * first section starting at the base - * area address. The size of the area - * is the sum of the section sizes. - * - * NOTE: Multiple absolute (ABS) areas are - * never concatenated with each other, - * thus absolute area A and absolute area - * B will overlay each other if they begin - * at the same location (the default is - * always address 0 for absolute areas). - * - * REL/OVR - All sections (each individual areax - * section) starts at the identical base - * area address overlaying all other - * areax sections for this area. The - * size of the area is largest of the area - * sections. - * - * REL/CON - All sections (each individual areax - * section) are concatenated with the - * first section starting at the base - * area address. The size of the area - * is the sum of the section sizes. - * - * NOTE: Relocatable (REL) areas are always concatenated - * with each other, thus relocatable area B - * (defined after area A) will follow - * relocatable area A independent of the - * starting address of area A. Within a - * specific area each areax section may be - * overlayed or concatenated with other - * areax sections. - * - * - * If a base address for an area is specified then the - * area will start at that address. Any relocatable - * areas defined subsequently will be concatenated to the - * previous relocatable area if it does not have a base - * address specified. - * - * The names s_ and l_ are created to - * define the starting address and length of each area. - * - * local variables: - * Addr_T rloc ;current relocation address - * char temp[] ;temporary string - * struct symbol *sp ;symbol structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * - * functions called: - * int fprintf() c_library - * VOID lnksect() lkarea.c - * symbol *lkpsym() lksym.c - * char * strncpy() c_library - * int symeq() lksym.c - * - * side effects: - * All area and areax addresses and sizes are - * determined and saved in their respective - * structures. +/*)Function VOID lnkarea() + * + * The function lnkarea() resolves all area addresses. + * The function evaluates each area structure (and all + * the associated areax structures) in sequence. The + * linking process supports four (4) possible area types: + * + * ABS/OVR - All sections (each individual areax + * section) starts at the identical base + * area address overlaying all other + * areax sections for this area. The + * size of the area is largest of the area + * sections. + * + * ABS/CON - All sections (each individual areax + * section) are concatenated with the + * first section starting at the base + * area address. The size of the area + * is the sum of the section sizes. + * + * NOTE: Multiple absolute (ABS) areas are + * never concatenated with each other, + * thus absolute area A and absolute area + * B will overlay each other if they begin + * at the same location (the default is + * always address 0 for absolute areas). + * + * REL/OVR - All sections (each individual areax + * section) starts at the identical base + * area address overlaying all other + * areax sections for this area. The + * size of the area is largest of the area + * sections. + * + * REL/CON - All sections (each individual areax + * section) are concatenated with the + * first section starting at the base + * area address. The size of the area + * is the sum of the section sizes. + * + * NOTE: Relocatable (REL) areas are always concatenated + * with each other, thus relocatable area B + * (defined after area A) will follow + * relocatable area A independent of the + * starting address of area A. Within a + * specific area each areax section may be + * overlayed or concatenated with other + * areax sections. + * + * + * If a base address for an area is specified then the + * area will start at that address. Any relocatable + * areas defined subsequently will be concatenated to the + * previous relocatable area if it does not have a base + * address specified. + * + * The names s_ and l_ are created to + * define the starting address and length of each area. + * + * local variables: + * Addr_T rloc ;current relocation address + * char temp[] ;temporary string + * struct symbol *sp ;symbol structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * + * functions called: + * int fprintf() c_library + * VOID lnksect() lkarea.c + * symbol *lkpsym() lksym.c + * char * strncpy() c_library + * int symeq() lksym.c + * + * side effects: + * All area and areax addresses and sizes are + * determined and saved in their respective + * structures. */ //unsigned long codemap[2048]; @@ -316,8 +323,8 @@ lnkarea() { register Addr_T rloc = 0; // Addr_T gs_size = 0; - char temp[NCPS]; - struct sym *sp; + char temp[NCPS]; + struct sym *sp; #if 0 struct area *abs_ap = NULL; struct area *gs0_ap = NULL; @@ -370,50 +377,50 @@ lnkarea() if (gs0_ap) gs0_ap->a_size = gs_size; #endif - ap = areap; + ap = areap; while (ap) { if (ap->a_flag & A_ABS) { - /* - * Absolute sections - */ - lnksect(ap); - } else { - /* - * Relocatable sections - */ - if (ap->a_addr == 0) - ap->a_addr = rloc; + /* + * Absolute sections + */ + lnksect(ap); + } else { + /* + * Relocatable sections + */ + if (ap->a_addr == 0) + ap->a_addr = rloc; // rloc = lnksect(ap); - lnksect(ap); - rloc = ap->a_addr + ap->a_size; - } + lnksect(ap); + rloc = ap->a_addr + ap->a_size; + } - /* - * Create symbols called: - * s_ the start address of the area - * l_ the length of the area - */ + /* + * Create symbols called: + * s_ the start address of the area + * l_ the length of the area + */ if (! symeq(ap->a_id, _abs_)) { - strncpy(temp+2,ap->a_id,NCPS-2); - *(temp+1) = '_'; + strncpy(temp+2,ap->a_id,NCPS-2); + *(temp+1) = '_'; - *temp = 's'; - sp = lkpsym(temp, 1); - sp->s_addr = ap->a_addr; - sp->s_axp = NULL; - sp->s_type |= S_DEF; + *temp = 's'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_addr; + sp->s_axp = NULL; + sp->s_type |= S_DEF; - *temp = 'l'; - sp = lkpsym(temp, 1); - sp->s_addr = ap->a_size; - sp->s_axp = NULL; - sp->s_type |= S_DEF; - } - ap = ap->a_ap; - } + *temp = 'l'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_size; + sp->s_axp = NULL; + sp->s_type |= S_DEF; + } + ap = ap->a_ap; + } } #if 0 static @@ -495,57 +502,57 @@ Addr_T allocate_space(Addr_T start, Addr_T size, char* id, unsigned long *map) return start; } #endif -/*)Function VOID lnksect() +/*)Function VOID lnksect() * - * area * tap pointer to an area structure + * area * tap pointer to an area structure * - * The function lnksect() is the function called by - * lnkarea() to resolve the areax addresses. Refer - * to the function lnkarea() for more detail. Pageing - * boundary and length errors will be reported by this - * function. + * The function lnksect() is the function called by + * lnkarea() to resolve the areax addresses. Refer + * to the function lnkarea() for more detail. Pageing + * boundary and length errors will be reported by this + * function. * - * local variables: - * Addr_T size size of area - * Addr_T addr address of area - * areax * taxp pointer to an areax structure + * local variables: + * Addr_T size size of area + * Addr_T addr address of area + * areax * taxp pointer to an areax structure * - * global variables: - * int lkerr error flag + * global variables: + * int lkerr error flag * - * functions called: - * none + * functions called: + * none * - * side effects: - * All area and areax addresses and sizes area determined - * and linked into the structures. + * side effects: + * All area and areax addresses and sizes area determined + * and linked into the structures. */ VOID lnksect(register struct area *tap) //Addr_T lnksect(register struct area *tap) { - register Addr_T size, addr; - register struct areax *taxp; + register Addr_T size, addr; + register struct areax *taxp; - size = 0; - addr = tap->a_addr; - if ((tap->a_flag&A_PAG) && (addr & 0xFF)) { - fprintf(stderr, - "\n?ASlink-Warning-Paged Area %.8s Boundary Error\n", tap->a_id); - lkerr++; - } + size = 0; + addr = tap->a_addr; + if ((tap->a_flag&A_PAG) && (addr & 0xFF)) { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %.8s Boundary Error\n", tap->a_id); + lkerr++; + } - taxp = tap->a_axp; + taxp = tap->a_axp; if (tap->a_flag & A_OVR) { - /* - * Overlayed sections - */ - while (taxp) { - taxp->a_addr = addr; - if (taxp->a_size > size) - size = taxp->a_size; - taxp = taxp->a_axp; - } + /* + * Overlayed sections + */ + while (taxp) { + taxp->a_addr = addr; + if (taxp->a_size > size) + size = taxp->a_size; + taxp = taxp->a_axp; + } } #if 0 else if (tap->a_flag & A_ABS) @@ -564,15 +571,15 @@ VOID lnksect(register struct area *tap) #endif else { - /* - * Concatenated sections - */ + /* + * Concatenated sections + */ /* if (tap->a_size) { addr = find_empty_space(addr, tap->a_size, codemap); } */ - while (taxp) { + while (taxp) { /* //find next unused address now if (taxp->a_size) @@ -581,19 +588,19 @@ VOID lnksect(register struct area *tap) allocate_space(addr, taxp->a_size, tap->a_id, codemap); } */ - taxp->a_addr = addr; - addr += taxp->a_size; - size += taxp->a_size; - taxp = taxp->a_axp; - } - } - tap->a_size = size; + taxp->a_addr = addr; + addr += taxp->a_size; + size += taxp->a_size; + taxp = taxp->a_axp; + } + } + tap->a_size = size; if ((tap->a_flag & A_PAG) && (size > 256)) { - fprintf(stderr, - "\n?ASlink-Warning-Paged Area %.8s Length Error\n", tap->a_id); - lkerr++; - } + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %.8s Length Error\n", tap->a_id); + lkerr++; + } // return addr; }