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