02c1912c8ccd185d03c3377c3c74dd15d2f53cb5
[fw/sdcc] / as / link / lkrel.c
1 /* lkrel.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  *
11  * With contributions for the
12  * object libraries from
13  * Ken Hornstein
14  * kenh@cmf.nrl.navy.mil
15  *
16  */
17
18 #include <string.h>
19 #include <assert.h>
20
21 #include "getline.h"
22 #include "aslink.h"
23 #include "lkrel.h"
24
25 int
26 is_rel (FILE * libfp)
27 {
28   int c;
29   long pos = ftell (libfp);
30   int ret = 0;
31
32   /* [XDQ][HL] */
33   if (((c = getc (libfp)) == 'X' || c == 'D' || c == 'Q') && ((c = getc (libfp)) == 'H' || c == 'L'))
34     {
35       switch (getc (libfp))
36         {
37         case '\r':
38           if (getc (libfp) == '\n')
39             ret = 1;
40           break;
41
42         case '\n':
43           ret = 1;
44         }
45     }
46   else if (c == ';')
47     {
48       char buf[6];
49
50       if (fread (buf, 1, sizeof (buf), libfp) == sizeof (buf) && memcmp (buf, "!FILE ", 6) == 0)
51         ret = 1;
52     }
53   fseek (libfp, pos, SEEK_SET);
54   return ret;
55 }
56
57 /* Load a .rel file embedded in a sdcclib file */
58 int
59 load_rel (FILE * libfp, long size)
60 {
61   if (is_rel (libfp))
62     {
63       char str[NINPUT];
64       long end;
65
66       if (size >= 0)
67         end = ftell (libfp) + size;
68       else
69         end = -1;
70
71       while ((end < 0 || ftell (libfp) < end) && getline (str, sizeof (str), libfp) != NULL)
72         {
73           if (0 == strcmp (str, "</REL>"))
74             return 1;
75
76           ip = str;
77           link_main ();
78         }
79
80       return 1;
81     }
82   else
83     return 0;
84 }
85
86 int
87 enum_symbols (FILE * fp, long size, int (*func) (const char *symvoid, void *param), void *param)
88 {
89   char buf[NINPUT];
90   long end = (size >= 0) ? ftell (fp) + size : -1;
91
92   assert (func != NULL);
93
94   /*
95    * Read in the object file.  Look for lines that
96    * begin with "S" and end with "D".  These are
97    * symbol table definitions.  If we find one, see
98    * if it is our symbol.  Make sure we only read in
99    * our object file and don't go into the next one.
100    */
101
102   while ((end <= 0 || ftell (fp) < end) && getline (buf, sizeof (buf), fp) != NULL)
103     {
104       char symname[NINPUT];
105       char c;
106
107       /*
108        * When a 'T line' is found terminate file scan.
109        * All 'S line's preceed 'T line's in .REL files.
110        */
111       if (buf[0] == 'T')
112         break;
113
114       /*
115        * Skip everything that's not a symbol record.
116        */
117       if (buf[0] != 'S')
118         continue;
119
120       sscanf (buf, "S %s %c", symname, &c);
121
122       /* If it's an actual symbol, record it */
123       if (c == 'D')
124         {
125           if ((*func) (symname, param))
126             return 1;
127         }
128     }
129
130   return 0;
131 }