Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1998
33
 
34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
49
 
50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
53
 
54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
/**********************************************************************
62
$Author: pwe $
63
$Date: 1998/03/15 16:00:36 $
64
$Revision: 1.2 $
65
$Log: dw2_locdata.c,v $
66
 * Revision 1.2  1998/03/15  16:00:36  pwe
67
 * regtrack dwarf dagnostics added
68
 *
69
 * Revision 1.1  1998/03/11  11:03:46  pwe
70
 * DWARF optimisation info
71
 *
72
**********************************************************************/
73
 
74
#include "config.h"
75
#include "common_types.h"
76
#include "dg_types.h"
77
#include "dw2_config.h"
78
#include "dw2_basic.h"
79
#include "dw2_codes.h"
80
#include "dw2_iface.h"
81
#include "dw2_info.h"
82
#include "expmacs.h"
83
#include "tags.h"
84
#include "basicread.h"
85
#include "xalloc.h"
86
#include "externs.h"
87
#include "dg_aux.h"
88
#include "dw2_locdata.h"
89
 
90
 
6 7u83 91
/* Location list information is collected for each object, held via
92
   fields of the 'obtain_value' exp (which is a hold_tag). last is set if the
93
   object is master of a new location. bro is used to hold references to other
94
   objects that share this location (as a bro list).  no is label for shared
95
   location set.  pt holds other more temporary uses (via ll_item).
2 7u83 96
*/
97
 
98
 
99
 
100
#define	LOp_Non_Current 1
101
#define	LOp_Locked	2
102
#define	LOp_Const	3
103
#define	LOp_Shared	4
104
#define	LOp_Portion	5
105
 
106
 
6 7u83 107
typedef enum {
108
	LL_OPTLOCK = 1,
109
	LL_CONST,
110
	LL_RET,
111
	LL_REGSHARE,
112
	LL_MASTERSHARE
2 7u83 113
} loclist_key;
114
 
6 7u83 115
typedef struct rs_s {
116
	long		start;
117
	long		end;
118
	long		share;
119
	dg_name		nm;
120
	int		reg;
121
	struct rs_s	*next_share;
122
	struct rs_s	*next_loc;
123
} *regshare_item;
2 7u83 124
 
6 7u83 125
typedef struct rsl_s {
126
	dg_name		alloc;
127
	int		reg;
128
	regshare_item	items;
129
	struct rsl_s	*next;
130
} *regshare_list;
2 7u83 131
 
6 7u83 132
typedef struct ll_s {
133
	int		key:8;
134
	int		open:1;
135
	int		has_inner:1;
136
	union {
137
		dg_info		d;
138
		retrec		*r;
139
		regshare_item	l;
140
	} u;
141
	struct ll_s	*next;
142
	struct ll_s	*inner;
143
} *ll_item;
2 7u83 144
 
6 7u83 145
static ll_item *
146
ll_root(dg_name nm)
2 7u83 147
{
6 7u83 148
	exp x = nm->data.n_obj.obtain_val;
149
	exp * ref = & (pt(x));
150
	return(ll_item *)((void *)ref);
2 7u83 151
}
152
 
6 7u83 153
static ll_item
154
new_ll_item(loclist_key k, int o)
2 7u83 155
{
6 7u83 156
	ll_item ans = (ll_item)xmalloc(sizeof(struct ll_s));
157
	ans->key = k;
158
	ans->open = ans->has_inner = o;
159
	ans->next = (ll_item)0;
160
	ans->inner = (ll_item)0;
161
	return ans;
2 7u83 162
}
163
 
6 7u83 164
 
2 7u83 165
static regshare_list all_regshares = (regshare_list)0;
166
 
6 7u83 167
void *
168
dw_new_regshare(dg_name nm, int reg)
2 7u83 169
{
6 7u83 170
	regshare_list ans = (regshare_list)xmalloc(sizeof(struct rsl_s));
171
	ans->alloc = nm;
172
	ans->reg = reg;
173
	ans->items = (regshare_item)0;
174
	ans->next = all_regshares;
175
	all_regshares = ans;
176
	return (void *)ans;		/* actual type local to this file */
2 7u83 177
}
178
 
6 7u83 179
 
180
void
181
dw_add_regshare(void * w, dg_name nm, long start, long end)
2 7u83 182
{
6 7u83 183
	regshare_list holder = (regshare_list)w;
184
	regshare_item item = (regshare_item)xmalloc(sizeof(struct rs_s));
185
	item->start = start;
186
	item->end = end;
187
	item->share = 0;
188
	item->nm = nm;
189
	item->next_share = holder->items;
190
	item->next_loc = (regshare_item)0;
191
	holder->items = item;
192
	return;
2 7u83 193
}
194
 
195
 
6 7u83 196
obj_list *local_objects = (obj_list *)0;
2 7u83 197
 
6 7u83 198
static void
199
check_taggable(dg_name nm)
2 7u83 200
{
6 7u83 201
	if (!nm->mor || !nm->mor->this_tag) {
202
		IGNORE f_dg_tag_name(gen_tg_tag(), nm);
203
	}
204
	return;
2 7u83 205
}
206
 
207
 
6 7u83 208
void
209
set_locdata(obj_list this_obl)
2 7u83 210
{
6 7u83 211
	dg_name this_nm = this_obl.obj;
212
	while (this_nm) {
213
		if (this_nm->key == DGN_OBJECT) {
214
			exp x = this_nm->data.n_obj.obtain_val;
215
			exp id;
216
			if (x && (id = dw_has_location(son(x)), id)) {
217
				if (isglob(id)) {
218
					dg_name master =
219
					    brog(id)->dec_u.dec_val.diag_info;
220
					if (!master) {
221
						master = brog(id)->dec_u.dec_val.diag_info = this_nm;
222
					}
223
					if (master == this_nm) {
224
						setlast(x);
225
						no(x) = next_dwarf_label();
226
					} else {
227
						exp y = master->data.n_obj.obtain_val;
228
						setbro(x, bro(y));
229
						setbro(y,
230
						       (exp)((void *)this_nm));
231
						no(x) = no(y);
232
						check_taggable(master);
233
						check_taggable(this_nm);
234
					}
235
				} else {
236
					int found = 0;
237
					obj_list * obl = local_objects;
238
					while (obl && !found) {
239
						dg_name nm = obl->obj;
240
						while (nm) {
241
							if (nm->key == DGN_OBJECT) {
242
								exp y = nm->data.n_obj.obtain_val;
243
								if (y && last(y) && dw_has_location(son(y)) == id) {
244
									setbro(x, bro(y));
245
									setbro(y, (exp)((void *)this_nm));
246
									no(x) = no(y);
247
									check_taggable(nm);
248
									check_taggable(this_nm);
249
									found = 1;
250
									break;
251
								}
252
							}
253
							if (!obl->islist) {
254
								break;
255
							}
256
							nm = nm->next;
257
						}
258
						obl = obl->next;
259
					}
260
					if (!found) {
261
						setlast(x);
262
						no(x) = next_dwarf_label();
263
						dw_allocated(this_nm, id);
264
					}
265
				}
266
			} else {
267
				no(x) = 0;
268
			}
269
		}
270
		if (!this_obl.islist) {
271
			break;
272
		}
273
		this_nm = this_nm->next;
2 7u83 274
	}
6 7u83 275
}
276
 
277
 
278
void
279
close_locdata(obj_list this_obl)
280
{
281
	dg_name this_nm = this_obl.obj;
282
	while (this_nm) {
283
		if (this_nm->key == DGN_OBJECT) {
284
			exp x = this_nm->data.n_obj.obtain_val;
285
			if (x && last(x)) {
286
				dw_deallocated(this_nm);
287
			}
2 7u83 288
		}
6 7u83 289
		if (!this_obl.islist) {
290
			break;
291
		}
292
		this_nm = this_nm->next;
2 7u83 293
	}
294
}
295
 
296
 
6 7u83 297
dg_name
298
find_equiv_object(exp e, int isc)
2 7u83 299
{
6 7u83 300
	obj_list *obl = local_objects;
301
	while (obl) {
302
		dg_name nm = obl->obj;
303
		while (nm) {
304
			if (nm->key == DGN_OBJECT) {
305
				exp x = nm->data.n_obj.obtain_val;
306
				if (isc) {
307
					if (x && name(son(x)) == cont_tag &&
308
					    dw_loc_equivalence(e,
309
							       son(son(x)))) {
310
						return nm;
311
					}
312
				} else {
313
					if (x && dw_loc_equivalence(e,
314
								    son(x))) {
315
						return nm;
316
					}
317
				}
318
			}
319
			if (!obl->islist) {
320
				break;
321
			}
322
			nm = nm->next;
323
		}
324
		obl = obl->next;
325
	}
326
	return(dg_name)0;
2 7u83 327
}
328
 
329
 
6 7u83 330
static dg_name
331
find_simple_object(exp e)
2 7u83 332
{
6 7u83 333
	/* e is name_tag for required object */
334
	obj_list *obl = local_objects;
335
	while (obl) {
336
		dg_name nm = obl->obj;
337
		while (nm) {
338
			if (nm->key == DGN_OBJECT) {
339
				exp x = nm->data.n_obj.obtain_val;
340
				while (x && (name(x) == hold_tag ||
341
					     name(x) == cont_tag ||
342
					     name(x) == reff_tag)) {
343
					x = son(x);
344
				}
345
				if ((x) && name(x) == name_tag &&
346
				    son(x) == son(e) &&
347
				    (no(x) <= no(e)) &&
348
				    (no(x) + shape_size(sh(x))) >=
349
				    (no(e) + shape_size(sh(e)))) {
350
					return nm;
351
				}
352
			}
353
			if (!obl->islist) {
354
				break;
355
			}
356
			nm = nm->next;
357
		}
358
		obl = obl->next;
2 7u83 359
	}
6 7u83 360
	return(dg_name)0;
2 7u83 361
}
362
 
363
 
6 7u83 364
void
365
set_optim_objects(dg_info optim, int start)
366
{
367
	objset *obj = optim->data.i_optim.objs;
368
	while (obj) {
369
		dg_name nm = obj->tg->p.nam;
370
		if (start) {
371
			ll_item *l = ll_root(nm);
372
			while (*l) {
373
				if ((*l)->open) {
374
					l = & ((*l)->inner);
375
				} else {
376
					l = & ((*l)->next);
377
				}
378
			}
379
			*l = new_ll_item(LL_OPTLOCK, 1);
380
			(*l)->u.d = optim;
381
		} else {
382
			ll_item l = *ll_root(nm);
383
			while (l->key != LL_OPTLOCK || l->u.d != optim) {
384
				if ((l)->open) {
385
					l = l->inner;
386
				} else {
387
					l = l->next;
388
				}
389
			}
390
			l->open = 0;
391
		}
392
		obj = obj->next;
393
	}
394
	return;
2 7u83 395
}
396
 
397
 
6 7u83 398
void
399
set_remval_object(dg_info rmv)
2 7u83 400
{
6 7u83 401
	dg_name nm = find_simple_object(son(rmv->data.i_remval.var));
402
	if (nm) {
403
		ll_item *l = ll_root(nm);
404
		while (*l) {
405
			if ((*l)->open) {
406
				l = &((*l)->inner);
407
			} else {
408
				l = &((*l)->next);
409
			}
410
		}
411
		*l = new_ll_item(LL_CONST, 0);
412
		(*l)->u.d = rmv;
413
	}
414
	return;
2 7u83 415
}
416
 
417
 
6 7u83 418
void
419
set_obj_rets(retrec * rec)
2 7u83 420
{
6 7u83 421
	obj_list *obl = local_objects;
422
	while (obl) {
423
		dg_name nm = obl->obj;
424
		while (nm) {
425
			if (nm->key == DGN_OBJECT) {
426
				exp x = nm->data.n_obj.obtain_val;
427
				while (x && (name(x) == hold_tag ||
428
					     name(x) == cont_tag ||
429
					     name(x) == reff_tag)) {
430
					x = son(x);
431
				}
432
				if ((x) && name(x) == name_tag &&
433
				    !isdiscarded(x) &&
434
				    !isglob(son(x))) {
435
					ll_item *l = ll_root(nm);
436
					while (*l) {
437
						if ((*l)->open) {
438
							l = &((*l)->inner);
439
						} else {
440
							l = &((*l)->next);
441
						}
442
					}
443
					*l = new_ll_item(LL_RET, 0);
444
					(*l)->u.r = rec;
445
				}
446
			}
447
			if (!obl->islist) {
448
				break;
449
			}
450
			nm = nm->next;
451
		}
452
		obl = obl->next;
453
	}
454
	return;
2 7u83 455
}
456
 
457
 
6 7u83 458
static ll_item
459
find_ll_item(dg_name nm, loclist_key k, int force)
2 7u83 460
{
6 7u83 461
	ll_item *ll = ll_root(nm);
462
	ll_item l = *ll;
463
	while (l && l->key != k) {
464
		l = l->next;
2 7u83 465
	}
6 7u83 466
	if (!l && force) {
467
		l = new_ll_item(k, 0);
468
		l->u.l = (regshare_item)0;
469
		l->next = *ll;
470
		*ll = l;
471
	}
472
	return l;
2 7u83 473
}
474
 
475
 
6 7u83 476
static void
477
out_regshare_set(regshare_item it)
2 7u83 478
{
6 7u83 479
	regshare_item this = it;
480
	while (this) {
481
		dg_name nm = this->nm;
482
		if (nm) {
483
			regshare_item look = it;
484
			while (look->nm != nm) {
485
				/* avoid duplicates */
486
				look = look->next_share;
487
			}
488
			if (look == this) {
489
				dw_at_ext_address(nm->mor->this_tag);
490
			}
491
		}
492
		this = this->next_share;
493
	}
494
	return;
2 7u83 495
}
496
 
6 7u83 497
 
498
void
499
init_dw_locdata(void)
2 7u83 500
{
6 7u83 501
	all_regshares = (regshare_list)0;
502
	local_objects = (obj_list *)0;
503
	dw_all_deallocated();
504
	return;
2 7u83 505
}
506
 
507
 
6 7u83 508
void
509
complete_dw_locdata(void)
2 7u83 510
{
6 7u83 511
	regshare_list top_l = all_regshares;
512
	while (top_l) {
513
		dg_name master = top_l->alloc;
514
		int reg = top_l->reg;
515
		regshare_item regitem = top_l->items;
516
		dg_name nm;
517
		if (master) {
518
			while (regitem) {
519
				nm = master;
520
				do {
521
					if (regitem->nm == nm) {
522
						regitem->nm = (dg_name)0;
523
						break;
524
					}
525
					nm = (dg_name)((void *)bro(nm->data.n_obj.obtain_val));
526
				} while (nm);
527
				if (!nm) {
528
					/* regitem not in allocation shareset */
529
					ll_item l =
530
					    find_ll_item(master,
531
							 LL_MASTERSHARE, 1);
532
					if (!l->u.l) {
533
						/* start of extra share list
534
						 * for master */
535
						l->u.l = regitem;
536
					}
537
					regitem->share =
538
					    no(master->data.n_obj.obtain_val);
539
					regitem->reg = reg;
540
					l = find_ll_item(regitem->nm,
541
							 LL_REGSHARE, 1);
542
					regitem->next_loc = l->u.l;
543
					l->u.l = regitem;
544
					check_taggable(regitem->nm);
545
					check_taggable(master);
546
				}
547
				regitem = regitem->next_share;
548
			}
549
		} else {
550
			long share = 0;
551
			master = nm = (dg_name)0;
552
			while (regitem) {
553
				if (!master) {
554
					master = regitem->nm;
555
				}
556
				if (!nm) {
557
					nm = regitem->nm;
558
				}
559
				if (nm != master) {
560
					share = next_dwarf_label();
561
					break;
562
				}
563
				regitem = regitem->next_share;
564
			}
565
			regitem = top_l->items;
566
			while (regitem) {
567
				ll_item l = find_ll_item(regitem->nm,
568
							 LL_REGSHARE, 1);
569
				regitem->share = share;
570
				if (share) {
571
					check_taggable(regitem->nm);
572
				}
573
				regitem->reg = reg;
574
				regitem->next_loc = l->u.l;
575
				l->u.l = regitem;
576
				regitem = regitem->next_share;
577
			}
578
			if (share) {
579
				enter_section("debug_loc");
580
				out_dwf_label(share, 1);
581
				out_regshare_set(top_l->items);
582
				exit_section();
583
			}
584
		}
585
		top_l = top_l->next;
586
	}
587
	return;
2 7u83 588
}
589
 
6 7u83 590
 
591
static int
592
obj_decide(ll_item l)
2 7u83 593
{
6 7u83 594
	int ans = 0, x;
595
	while (l && ans < 2) {
596
		switch (l->key) {
597
		case LL_OPTLOCK:
598
		case LL_CONST:
599
		case LL_MASTERSHARE:
600
			return 2;
601
		case LL_RET:
602
			if (!ans) {
603
				ans = 1;
604
			}
605
			break;
606
		case LL_REGSHARE: {
607
			regshare_item rs = l->u.l;
608
			while (rs && ans<2) {
609
				if (rs->share) {
610
					ans = 2;
611
				} else if (!ans) {
612
					ans = 1;
613
				}
614
				rs = rs->next_loc;
615
			}
616
			break;
617
		}
618
		}
619
		if (l->has_inner && (x = obj_decide(l->inner), x > ans)) {
620
			ans = x;
621
		}
622
		l = l->next;
2 7u83 623
	}
6 7u83 624
	return ans;
2 7u83 625
}
626
 
627
 
6 7u83 628
int
629
decide_ll_type(exp x)
2 7u83 630
{
6 7u83 631
	/* 1 if need location list, 2 if extension list */
632
	ll_item l = (ll_item)((void *)(pt(x)));
633
	if ((last(x) && bro(x)) || (!last(x) && no(x))) {
634
		/* main location is shared */
635
		return 2;
636
	} else {
637
		return obj_decide(l);
2 7u83 638
	}
639
}
640
 
641
 
642
static long startlab;
643
static int ll_ok;
644
static exp obval;
645
 
6 7u83 646
static void
647
loclist_portion(ll_item l)
2 7u83 648
{
6 7u83 649
	while (l) {
650
		switch (l->key) {
651
		case LL_CONST:
652
			ll_ok = 0;
653
			break;
654
		case LL_RET: {
655
			long endlab = l->u.r->lab;
656
			if (ll_ok && endlab != startlab) {
657
				out_loc_range(startlab, endlab, 0);
658
				dw2_locate_exp(obval, 0, 1);
659
			}
660
			startlab = l->u.r->over;
661
			break;
662
		}
663
		case LL_REGSHARE: {
664
			regshare_item rs = l->u.l;
665
			while (rs) {
666
				out_loc_range(rs->start, rs->end, 1);
667
				out16();
668
				if (rs->reg < 32) {
669
					outn((long)1);
670
					outnl();
671
					out8();
672
					outn((long)(DW_OP_reg0 + rs->reg));
673
				} else {
674
					outn((long)(1 + uleb128_length((unsigned long)rs->reg)));
675
					outnl();
676
					out8();
677
					outn((long)DW_OP_regx);
678
					outs(", ");
679
					uleb128((unsigned long)rs->reg);
680
				}
681
				outnl();
682
				rs = rs->next_loc;
683
			}
684
		}
685
		default:
686
			break;
687
		}
688
		if (l->has_inner) {
689
			loclist_portion(l->inner);
690
		}
691
		l = l->next;
2 7u83 692
	}
6 7u83 693
	return;
2 7u83 694
}
695
 
6 7u83 696
 
697
void
698
out_obj_loclist(long l1, long l2, exp x)
2 7u83 699
{
6 7u83 700
	ll_item l = (ll_item)((void *)(pt(x)));
701
	startlab = l1;
702
	ll_ok = 1;
703
	obval = son(x);
704
	loclist_portion(l);
705
	if (ll_ok && l2 != startlab) {
706
		out_loc_range(startlab, l2, 0);
707
		dw2_locate_exp(obval, 0, 1);
708
	}
709
	return;
2 7u83 710
}
711
 
712
 
6 7u83 713
static void
714
extlist_portion(ll_item l)
2 7u83 715
{
6 7u83 716
	while (l) {
717
		switch (l->key) {
718
		case LL_CONST: {
719
			long here = l->u.d->data.i_remval.lo_pc;
720
			if (ll_ok && here != startlab) {
721
				out_loc_range(startlab, here, 0);
722
				dw_at_data(1, LOp_Const);
723
				dw_out_const(obval);
724
			}
725
			startlab = here;
726
			ll_ok = 1;
727
			obval = l->u.d->data.i_remval.val;
728
			break;
729
		}
730
		case LL_OPTLOCK:
731
			out_loc_range(l->u.d->data.i_optim.lo_pc,
732
				      l->u.d->data.i_optim.hi_pc, 0);
733
			dw_at_data(1, LOp_Locked);
734
			dw_at_data(1, l->u.d->data.i_optim.reason);
735
			break;
736
		case LL_REGSHARE: {
737
			regshare_item rs = l->u.l;
738
			while (rs) {
739
				if (rs->share) {
740
					out_loc_range(rs->start, rs->end, 1);
741
					dw_at_data(1, LOp_Shared);
742
					dw_at_address(rs->share);
743
				}
744
				rs = rs->next_loc;
745
			}
746
		}
747
		default:
748
			break;
749
		}
750
		if (l->has_inner) {
751
			loclist_portion(l->inner);
752
		}
753
		l = l->next;
2 7u83 754
	}
6 7u83 755
	return;
2 7u83 756
}
757
 
6 7u83 758
 
759
void
760
out_obj_extloclist(long l1, long l2, exp x)
2 7u83 761
{
6 7u83 762
	ll_item l = (ll_item)((void *)(pt(x)));
763
	if ((last(x) && bro(x)) || (!last(x) && no(x))) {
764
		/* main location is shared */
765
		out_loc_range(l1, l2, 0);
766
		dw_at_data(1, LOp_Shared);
767
		dw_at_address(no(x));
768
	}
769
	startlab = l1;
770
	ll_ok = 0;
771
	if (l) {
772
		extlist_portion(l);
773
	}
774
	if (ll_ok && l2 != startlab) {
775
		out_loc_range(startlab, l2, 0);
776
		dw_at_data(1, LOp_Const);
777
		dw_out_const(obval);
778
	}
779
	return;
2 7u83 780
}
781
 
6 7u83 782
 
783
void
784
out_obj_shared_set(dg_name dn)
2 7u83 785
{
6 7u83 786
	exp x = dn->data.n_obj.obtain_val;
787
	ll_item l = find_ll_item(dn, LL_MASTERSHARE, 0);
788
	if (last(x) && (bro(x) || l)) {
789
		out_dwf_label(no(x), 1);
790
		dw_at_ext_address(dn->mor->this_tag);
791
		while (bro(x)) {
792
			dg_name nm = (dg_name)((void *)bro(x));
793
			dw_at_ext_address(nm->mor->this_tag);
794
			x = nm->data.n_obj.obtain_val;
795
		}
796
		if (l) {
797
			out_regshare_set(l->u.l);
798
		}
799
		out32();
800
		outs("0");
801
		outnl_comment("share list end");
802
	}
803
	return;
2 7u83 804
}
805