gbdk-releases/sdcc/as/mcs51/lkdata.c
2015-01-10 16:25:09 +01:00

481 lines
14 KiB
C

/* lkdata.c */
/*
* (C) Copyright 1989-1995
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*
* 28-Oct-97 JLH:
* - change s_id from [NCPS] to pointer (comment)
* 31-Oct-97 JLH:
* - add jflag and jfp for NoICE output
*/
#include <stdio.h>
#include <string.h>
#include "aslink.h"
/*)Module lkdata.c
*
* The module lkdata contains the global variables
* and structures used in the linker aslink.
*/
/*
* Definitions for all Global Variables
*/
char *_abs_ = { ". .ABS." };
int lkerr; /* Linker error flag
*/
char *ip; /* Pointer into the REL file text line in ib[]
*/
char ib[NINPUT]; /* REL file text line
*/
char *rp; /* pointer into the LST file
* text line in rb[]
*/
char rb[NINPUT]; /* LST file text line being
* address relocated
*/
int dflag; /* Debug information output flag
*/
int oflag; /* Output file type flag
*/
int mflag; /* Map output flag
*/
int aflag; /* Overlapping area warning flag
*/
int jflag; /* NoICE output flag
*/
int xflag; /* Map file radix type flag
*/
int pflag; /* print linker command file flag
*/
int uflag; /* Listing relocation flag
*/
int rflag; /* Extended linear address record flag.
*/
int radix; /* current number conversion radix:
* 2 (binary), 8 (octal), 10 (decimal),
* 16 (hexadecimal)
*/
int line; /* current line number
*/
int page; /* current page number
*/
int lop; /* current line number on page
*/
int pass; /* linker pass number
*/
int rtcnt; /* count of elements in the
* rtval[] and rtflg[] arrays
*/
Addr_T rtval[NTXT]; /* data associated with relocation
*/
int rtflg[NTXT]; /* indicates if rtval[] value is
* to be sent to the output file.
* (always set in this linker)
*/
int hilo; /* REL file byte ordering
*/
int gline; /* LST file relocation active
* for current line
*/
int gcntr; /* LST file relocation active
* counter
*/
Addr_T iram_size; /* internal ram size
*/
/*
* The structure lfile contains a pointer to a
* file specification string, the file type, and
* a link to the next lfile structure.
*
* struct lfile
* {
* struct lfile *f_flp; lfile link
* int f_type; File type
* char *f_idp; Pointer to file spec
* };
*/
struct lfile *filep; /* The pointers (lfile *) filep,
* (lfile *) cfp, and (FILE *) sfp
* are used in conjunction with
* the routine getline() to read
* asmlnk commands from
* (1) the standard input or
* (2) or a command file
* and to read the REL files
* sequentially as defined by the
* asmlnk input commands.
*
* The pointer *filep points to the
* beginning of a linked list of
* lfile structures.
*/
struct lfile *cfp; /* The pointer *cfp points to the
* current lfile structure
*/
struct lfile *startp;/* asmlnk startup file structure
*/
struct lfile *linkp; /* pointer to first lfile structure
* containing an input REL file
* specification
*/
struct lfile *lfp; /* pointer to current lfile structure
* being processed by parse()
*/
FILE *ofp; /* Output file handle
* for word formats
*/
FILE *mfp; /* Map output file handle
*/
FILE *jfp; /* NoICE output file handle
*/
FILE *rfp; /* File handle for output
* address relocated ASxxxx
* listing file
*/
FILE *sfp; /* The file handle sfp points to the
* currently open file
*/
FILE *tfp; /* File handle for input
* ASxxxx listing file
*/
FILE *dfp = NULL ; /*
* File handle for debug
* information output file
*/
/*
* The structures of head, area, areax, and sym are created
* as the REL files are read during the first pass of the
* linker. The struct head is created upon encountering a
* H directive in the REL file. The structure contains a
* link to a link file structure (struct lfile) which describes
* the file containing the H directive, the number of data/code
* areas contained in this header segment, the number of
* symbols referenced/defined in this header segment, a pointer
* to an array of pointers to areax structures (struct areax)
* created as each A directive is read, and a pointer to an
* array of pointers to symbol structures (struct sym) for
* all referenced/defined symbols. As H directives are read
* from the REL files a linked list of head structures is
* created by placing a link to the new head structure
* in the previous head structure.
*
* struct head
* {
* struct head *h_hp; Header link
* struct lfile *h_lfile; Associated file
* int h_narea; # of areas
* struct areax **a_list; Area list
* int h_nglob; # of global symbols
* struct sym **s_list; Global symbol list
* char m_id[NCPS]; Module name
* };
*/
struct head *headp; /* The pointer to the first
* head structure of a linked list
*/
struct head *hp; /* Pointer to the current
* head structure
*/
/*
* A structure area is created for each 'unique' data/code
* area definition found as the REL files are read. The
* struct area contains the name of the area, a flag byte
* which contains the area attributes (REL/CON/OVR/ABS),
* an area subtype (not used in this assembler), and the
* area base address and total size which will be filled
* in at the end of the first pass through the REL files.
* As A directives are read from the REL files a linked
* list of unique area structures is created by placing a
* link to the new area structure in the previous area structure.
*
* struct area
* {
* struct area *a_ap; Area link
* struct areax *a_axp; Area extension link
* Addr_T a_addr; Beginning address of area
* Addr_T a_size; Total size of the area
* char a_type; Area subtype
* char a_flag; Flag byte
* char a_id[NCPS]; Name
* };
*/
struct area *areap; /* The pointer to the first
* area structure of a linked list
*/
struct area *ap; /* Pointer to the current
* area structure
*/
/*
* An areax structure is created for every A directive found
* while reading the REL files. The struct areax contains a
* link to the 'unique' area structure referenced by the A
* directive and to the head structure this area segment is
* a part of. The size of this area segment as read from the
* A directive is placed in the areax structure. The beginning
* address of this segment will be filled in at the end of the
* first pass through the REL files. As A directives are read
* from the REL files a linked list of areax structures is
* created for each unique area. The final areax linked
* list has at its head the 'unique' area structure linked
* to the linked areax structures (one areax structure for
* each A directive for this area).
*
* struct areax
* {
* struct areax *a_axp; Area extension link
* struct area *a_bap; Base area link
* struct head *a_bhp; Base header link
* Addr_T a_addr; Beginning address of section
* Addr_T a_size; Size of the area in section
* };
*/
struct areax *axp; /* Pointer to the current
* areax structure
*/
/*
* A sym structure is created for every unique symbol
* referenced/defined while reading the REL files. The
* struct sym contains the symbol's name, a flag value
* (not used in this linker), a symbol type denoting
* referenced/defined, and an address which is loaded
* with the relative address within the area in which
* the symbol was defined. The sym structure also
* contains a link to the area where the symbol was defined.
* The sym structures are linked into linked lists using
* the symbol link element.
*
* struct sym
* {
* struct sym *s_sp; Symbol link
* struct areax *s_axp; Symbol area link
* char s_type; Symbol subtype
* char s_flag; Flag byte
* Addr_T s_addr; Address
* char *s_id; Name (JLH)
* };
*/
struct sym *symhash[NHASH]; /* array of pointers to NHASH
* linked symbol lists
*/
/*
* The struct base contains a pointer to a
* base definition string and a link to the next
* base structure.
*
* struct base
* {
* struct base *b_base; Base link
* char *b_strp; String pointer
* };
*/
struct base *basep; /* The pointer to the first
* base structure
*/
struct base *bsp; /* Pointer to the current
* base structure
*/
/*
* The struct globl contains a pointer to a
* global definition string and a link to the next
* global structure.
*
* struct globl
* {
* struct globl *g_globl; Global link
* char *g_strp; String pointer
* };
*/
struct globl *globlp;/* The pointer to the first
* globl structure
*/
struct globl *gsp; /* Pointer to the current
* globl structure
*/
/*
* A structure sdp is created for each 'unique' paged
* area definition found as the REL files are read.
* As P directives are read from the REL files a linked
* list of unique sdp structures is created by placing a
* link to the new sdp structure in the previous area structure.
*
* struct sdp
* {
* struct area *s_area; Paged Area link
* struct areax *s_areax; Paged Area Extension Link
* Addr_T s_addr; Page address offset
* };
*/
struct sdp sdp; /* Base Page Structure */
/*
* The structure rerr is loaded with the information
* required to report an error during the linking
* process. The structure contains an index value
* which selects the areax structure from the header
* areax structure list, a mode value which selects
* symbol or area relocation, the base address in the
* area section, an area/symbol list index value, and
* an area/symbol offset value.
*
* struct rerr
* {
* int aindex; Linking area
* int mode; Relocation mode
* Addr_T rtbase; Base address in section
* int rindex; Area/Symbol reloaction index
* Addr_T rval; Area/Symbol offset value
* };
*/
struct rerr rerr; /* Structure containing the
* linker error information
*/
/*
* The structure lbpath is created for each library
* path specification input by the -k option. The
* lbpath structures are linked into a list using
* the next link element.
*
* struct lbpath {
* struct lbpath *next;
* char *path;
* };
*/
struct lbpath *lbphead; /* pointer to the first
* library path structure
*/
/*
* The structure lbname is created for all combinations of the
* library path specifications (input by the -k option) and the
* library file specifications (input by the -l option) that
* lead to an existing file. The element path points to
* the path string, element libfil points to the library
* file string, and the element libspc is the concatenation
* of the valid path and libfil strings.
*
* The lbpath structures are linked into a list
* using the next link element.
*
* Each library file contains a list of object files
* that are contained in the particular library. e.g.:
*
* \iolib\termio
* \inilib\termio
*
* Only one specification per line is allowed.
*
* struct lbname {
* struct lbname *next;
* char *path;
* char *libfil;
* char *libspc;
* };
*/
struct lbname *lbnhead; /* pointer to the first
* library name structure
*/
/*
* The function fndsym() searches through all combinations of the
* library path specifications (input by the -k option) and the
* library file specifications (input by the -l option) that
* lead to an existing file for a symbol definition.
*
* The structure lbfile is created for the first library
* object file which contains the definition for the
* specified undefined symbol.
*
* The element libspc points to the library file path specification
* and element relfil points to the object file specification string.
* The element filspc is the complete path/file specification for
* the library file to be imported into the linker. The
* file specicifation may be formed in one of two ways:
*
* (1) If the library file contained an absolute
* path/file specification then this becomes filspc.
* (i.e. C:\...)
*
* (2) If the library file contains a relative path/file
* specification then the concatenation of the path
* and this file specification becomes filspc.
* (i.e. \...)
*
* The lbpath structures are linked into a list
* using the next link element.
*
* struct lbfile {
* struct lbfile *next;
* char *libspc;
* char *relfil;
* char *filspc;
* };
*/
struct lbfile *lbfhead; /* pointer to the first
* library file structure
*/
/*
* array of character types, one per
* ASCII character
*/
char ctype[128] = {
/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL,
/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC,
/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP,
/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8,
/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC,
/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER,
/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER,
/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER,
/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC
};
/*
* an array of characters which
* perform the case translation function
*/
#if CASE_SENSITIVE
#else
char ccase[128] = {
/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177'
};
#endif