Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**** linker.c --- Front end to linking mode of TDF linker.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 **** Commentary:
36
 *
37
 * This file provides the front end to the linking mode of the TDF linker.
38
 *
39
 **** Change Log:
40
 * $Log: linker.c,v $
41
 * Revision 1.1.1.1  1998/01/17  15:57:16  release
42
 * First version to be checked into rolling release.
43
 *
44
 * Revision 1.3  1995/09/22  08:37:11  smf
45
 * Fixed problems with incomplete structures (to shut "tcc" up).
46
 *
47
 * Revision 1.2  1994/12/12  11:44:06  smf
48
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
49
 * OSSG C Coding Standards.
50
 *
51
 * Revision 1.1.1.1  1994/07/25  16:03:26  smf
52
 * Initial import of TDF linker 3.5 non shared files.
53
 *
54
**/
55
 
56
/****************************************************************************/
57
 
58
#include "linker.h"
59
#include "capsule.h"
60
#include "debug.h"
61
#include "error.h"
62
#include "file-name.h"
63
#include "gen-errors.h"
64
#include "library.h"
65
#include "shape-table.h"
66
#include "tdf.h"
67
#include "unit-table.h"
68
 
69
#include "solve-cycles.h"
70
 
71
/*--------------------------------------------------------------------------*/
72
 
73
typedef struct RenameClosureT {
74
    ShapeTableP			shapes;
75
    ShapeTableP			lib_shapes;
76
} RenameClosureT, *RenameClosureP;
77
 
78
/*--------------------------------------------------------------------------*/
79
 
80
static void
81
linker_rename_1 PROTO_N ((shape, names, gclosure))
82
		PROTO_T (NStringP         shape X
83
			 NameKeyPairListP names X
84
			 GenericP         gclosure)
85
{
86
    RenameClosureP        closure    = (RenameClosureP) gclosure;
87
    ShapeTableP           shapes     = closure->shapes;
88
    ShapeTableP           lib_shapes = closure->lib_shapes;
89
    ShapeEntryP           entry      = shape_table_add (shapes, shape);
90
    ShapeEntryP           lib_entry  = shape_table_add (lib_shapes, shape);
91
    NameTableP            table      = shape_entry_name_table (entry);
92
    NameTableP            lib_table  = shape_entry_name_table (lib_entry);
93
    NameKeyPairListEntryP name       = name_key_pair_list_head (names);
94
 
95
    for (; name; name = name_key_pair_list_entry_next (name)) {
96
	NameKeyP from = name_key_pair_list_entry_from (name);
97
	NameKeyP to   = name_key_pair_list_entry_to (name);
98
 
99
	debug_info_l_rename (shape, from, to);
100
	name_table_add_rename (table, from, to);
101
	name_table_add_rename (lib_table, from, to);
102
    }
103
    name_table_resolve_renames (table, shape, TRUE);
104
    name_table_resolve_renames (lib_table, shape, FALSE);
105
}
106
 
107
static void
108
linker_rename PROTO_N ((arg_data, shapes, lib_shapes))
109
	      PROTO_T (ArgDataP    arg_data X
110
		       ShapeTableP shapes X
111
		       ShapeTableP lib_shapes)
112
{
113
    RenameClosureT closure;
114
 
115
    closure.shapes     = shapes;
116
    closure.lib_shapes = lib_shapes;
117
    rename_control_iter (arg_data_get_renames (arg_data), linker_rename_1,
118
			 (GenericP) &closure);
119
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
120
	exit (EXIT_FAILURE);
121
	UNREACHED;
122
    }
123
}
124
 
125
static void
126
linker_read_capsules PROTO_N ((arg_data, units, shapes))
127
		     PROTO_T (ArgDataP    arg_data X
128
			      UnitTableP  units X
129
			      ShapeTableP shapes)
130
{
131
    unsigned  num_input_files = arg_data_get_num_files (arg_data);
132
    CStringP *input_files     = arg_data_get_files (arg_data);
133
    unsigned  i;
134
 
135
    for (i = 0; i < num_input_files; i ++) {
136
	CapsuleP capsule;
137
 
138
	if ((capsule = capsule_create_stream_input (input_files [i])) !=
139
	    NIL (CapsuleP)) {
140
	    capsule_read (capsule, units, shapes);
141
	    capsule_close (capsule);
142
	} else {
143
	    E_cannot_open_input_file (input_files [i]);
144
	}
145
    }
146
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
147
	exit (EXIT_FAILURE);
148
	UNREACHED;
149
    }
150
}
151
 
152
static void
153
linker_load_libraries PROTO_N ((arg_data, lib_shapes))
154
		      PROTO_T (ArgDataP    arg_data X
155
			       ShapeTableP lib_shapes)
156
{
157
    CStringP   *files     = arg_data_library_files (arg_data);
158
    CStringP   *paths     = arg_data_library_paths (arg_data);
159
    unsigned    num_files = arg_data_num_library_files (arg_data);
160
    unsigned    num_paths = arg_data_num_library_paths (arg_data);
161
    unsigned    i;
162
 
163
    for (i = 0; i < num_files; i ++) {
164
	LibraryP library = NIL (LibraryP);
165
 
166
	if (file_name_is_basename (files [i])) {
167
	    unsigned j;
168
 
169
	    for (j = 0; j < num_paths; j ++) {
170
		CStringP name = file_name_expand (paths [j], files [i], "tl");
171
 
172
		if ((library = library_create_stream_input (name)) !=
173
		    NIL (LibraryP)) {
174
		    goto found;
175
		} else {
176
		    DEALLOCATE (name);
177
		}
178
	    }
179
	    E_cannot_open_library_file (files [i]);
180
	} else {
181
	    if ((library = library_create_stream_input (files [i])) ==
182
		NIL (LibraryP)) {
183
		E_cannot_open_library_file (files [i]);
184
	    }
185
	}
186
      found:
187
	if (library) {
188
	    library_read (library, lib_shapes);
189
	    library_close (library);
190
	}
191
    }
192
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
193
	exit (EXIT_FAILURE);
194
	UNREACHED;
195
    }
196
}
197
 
198
static void
199
linker_suppress_1 PROTO_N ((shape, all, names, gclosure))
200
		  PROTO_T (NStringP     shape X
201
			   BoolT        all X
202
			   NameKeyListP names X
203
			   GenericP     gclosure)
204
{
205
    ShapeTableP lib_shapes = (ShapeTableP) gclosure;
206
    ShapeEntryP entry      = shape_table_get (lib_shapes, shape);
207
 
208
    if (entry) {
209
	NameTableP        table = shape_entry_name_table (entry);
210
	NameKeyListEntryP name  = name_key_list_head (names);
211
 
212
	if (all) {
213
	    name_table_iter (table, name_entry_suppress, (GenericP) shape);
214
	}
215
	for (; name; name = name_key_list_entry_next (name)) {
216
	    NameKeyP   key        = name_key_list_entry_key (name);
217
	    NameEntryP name_entry = name_table_get (table, key);
218
 
219
	    if (name_entry) {
220
		debug_info_l_suppress (shape, key);
221
		name_entry_set_lib_definition (name_entry, NIL (LibCapsuleP));
222
	    }
223
	}
224
    }
225
}
226
 
227
static void
228
linker_suppress PROTO_N ((arg_data, lib_shapes))
229
		PROTO_T (ArgDataP    arg_data X
230
			 ShapeTableP lib_shapes)
231
{
232
    if (arg_data_get_suppress_mult (arg_data)) {
233
	shape_table_iter (lib_shapes, shape_entry_lib_suppress_mult,
234
			  NIL (GenericP));
235
    }
236
    shape_control_iter (arg_data_get_suppresses (arg_data), linker_suppress_1,
237
			(GenericP) lib_shapes);
238
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
239
	exit (EXIT_FAILURE);
240
	UNREACHED;
241
    }
242
}
243
 
244
static void
245
linker_resolve_undefined PROTO_N ((units, shapes, lib_shapes))
246
			 PROTO_T (UnitTableP  units X
247
				  ShapeTableP shapes X
248
				  ShapeTableP lib_shapes)
249
{
250
    ShapeLibClosureT closure;
251
 
252
    closure.lib_shapes = lib_shapes;
253
    closure.units      = units;
254
    closure.shapes     = shapes;
255
    do {
256
	closure.did_define = FALSE;
257
	shape_table_iter (shapes, shape_entry_resolve_undefined,
258
			  (GenericP) &closure);
259
    } while (closure.did_define);
260
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
261
	exit (EXIT_FAILURE);
262
	UNREACHED;
263
    }
264
}
265
 
266
static void
267
linker_hide PROTO_N ((shape, all, names, gclosure))
268
	    PROTO_T (NStringP     shape X
269
		     BoolT        all X
270
		     NameKeyListP names X
271
		     GenericP     gclosure)
272
{
273
    ShapeTableP shapes = (ShapeTableP) gclosure;
274
    ShapeEntryP entry  = shape_table_get (shapes, shape);
275
 
276
    if (entry == NIL (ShapeEntryP)) {
277
	E_cannot_hide_shape (shape);
278
    } else {
279
	NameTableP        table = shape_entry_name_table (entry);
280
	NameKeyListEntryP name  = name_key_list_head (names);
281
 
282
	if (all) {
283
	    name_table_iter (table, name_entry_hide_defd, (GenericP) shape);
284
	}
285
	for (; name; name = name_key_list_entry_next (name)) {
286
	    NameKeyP   key        = name_key_list_entry_key (name);
287
	    NameEntryP name_entry = name_table_get (table, key);
288
 
289
	    if (name_entry == NIL (NameEntryP)) {
290
		E_cannot_hide (shape, key);
291
	    } else if (name_entry_get_use (name_entry) & U_DEFD) {
292
		debug_info_l_hide (shape, key);
293
		name_entry_hide (name_entry);
294
	    } else {
295
		E_cannot_hide_undefined (shape, key);
296
	    }
297
	}
298
    }
299
}
300
 
301
static void
302
linker_keep PROTO_N ((shape, all, names, gclosure))
303
	    PROTO_T (NStringP     shape X
304
		     BoolT        all X
305
		     NameKeyListP names X
306
		     GenericP     gclosure)
307
{
308
    ShapeTableP shapes = (ShapeTableP) gclosure;
309
    ShapeEntryP entry  = shape_table_get (shapes, shape);
310
 
311
    if (entry == NIL (ShapeEntryP)) {
312
	E_cannot_keep_shape (shape);
313
    } else {
314
	NameTableP        table = shape_entry_name_table (entry);
315
	NameKeyListEntryP name  = name_key_list_head (names);
316
 
317
	if (all) {
318
	    name_table_iter (table, name_entry_keep, (GenericP) shape);
319
	}
320
	for (; name; name = name_key_list_entry_next (name)) {
321
	    NameKeyP   key        = name_key_list_entry_key (name);
322
	    NameEntryP name_entry = name_table_get (table, key);
323
 
324
	    if (name_entry == NIL (NameEntryP)) {
325
		E_cannot_keep (shape, key);
326
	    } else {
327
		debug_info_l_keep (shape, key);
328
		name_entry_unhide (name_entry);
329
	    }
330
	}
331
    }
332
}
333
 
334
static void
335
linker_hide_and_keep PROTO_N ((arg_data, shapes))
336
		     PROTO_T (ArgDataP    arg_data X
337
			      ShapeTableP shapes)
338
{
339
    if (arg_data_get_all_hide_defd (arg_data)) {
340
	shape_table_iter (shapes, shape_entry_hide_all_defd, NIL (GenericP));
341
    }
342
    shape_control_iter (arg_data_get_hides (arg_data), linker_hide,
343
			(GenericP) shapes);
344
    shape_control_iter (arg_data_get_keeps (arg_data), linker_keep,
345
			(GenericP) shapes);
346
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
347
	exit (EXIT_FAILURE);
348
	UNREACHED;
349
    }
350
}
351
 
352
static void
353
linker_write_capsule PROTO_N ((arg_data, units, shapes))
354
		     PROTO_T (ArgDataP    arg_data X
355
			      UnitTableP  units X
356
			      ShapeTableP shapes)
357
{
358
    CStringP output_file = arg_data_get_output_file (arg_data);
359
    CapsuleP capsule;
360
 
361
    if ((capsule = capsule_create_stream_output (output_file)) !=
362
	NIL (CapsuleP)) {
363
	capsule_write (capsule, units, shapes);
364
	capsule_close (capsule);
365
    } else {
366
	E_cannot_open_output_file (output_file);
367
	UNREACHED;
368
    }
369
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
370
	exit (EXIT_FAILURE);
371
	UNREACHED;
372
    }
373
}
374
 
375
/*--------------------------------------------------------------------------*/
376
 
377
void
378
linker_main PROTO_N ((arg_data))
379
	    PROTO_T (ArgDataP arg_data)
380
{
381
    UnitTableP  units      = unit_table_create ();
382
    ShapeTableP shapes     = shape_table_create ();
383
    ShapeTableP lib_shapes = shape_table_create ();
384
 
385
    linker_rename (arg_data, shapes, lib_shapes);
386
    linker_read_capsules (arg_data, units, shapes);
387
    linker_load_libraries (arg_data, lib_shapes);
388
    linker_suppress (arg_data, lib_shapes);
389
    linker_resolve_undefined (units, shapes, lib_shapes);
390
    linker_hide_and_keep (arg_data, shapes);
391
    linker_write_capsule (arg_data, units, shapes);
392
}
393
 
394
/*
395
 * Local variables(smf):
396
 * eval: (include::add-path-entry "../os-interface" "../library" "../tdf")
397
 * eval: (include::add-path-entry "../generated")
398
 * End:
399
**/