Subversion Repositories Kolibri OS

Rev

Rev 5199 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5199 Rev 6324
1
/* ldcref.c -- output a cross reference table
1
/* ldcref.c -- output a cross reference table
2
   Copyright 1996-2013 Free Software Foundation, Inc.
2
   Copyright (C) 1996-2015 Free Software Foundation, Inc.
3
   Written by Ian Lance Taylor 
3
   Written by Ian Lance Taylor 
4
 
4
 
5
   This file is part of the GNU Binutils.
5
   This file is part of the GNU Binutils.
6
 
6
 
7
   This program is free software; you can redistribute it and/or modify
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
10
   (at your option) any later version.
11
 
11
 
12
   This program is distributed in the hope that it will be useful,
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
15
   GNU General Public License for more details.
16
 
16
 
17
   You should have received a copy of the GNU General Public License
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
20
   MA 02110-1301, USA.  */
21
 
21
 
22
 
22
 
23
/* This file holds routines that manage the cross reference table.
23
/* This file holds routines that manage the cross reference table.
24
   The table is used to generate cross reference reports.  It is also
24
   The table is used to generate cross reference reports.  It is also
25
   used to implement the NOCROSSREFS command in the linker script.  */
25
   used to implement the NOCROSSREFS command in the linker script.  */
26
 
26
 
27
#include "sysdep.h"
27
#include "sysdep.h"
28
#include "bfd.h"
28
#include "bfd.h"
29
#include "bfdlink.h"
29
#include "bfdlink.h"
30
#include "libiberty.h"
30
#include "libiberty.h"
31
#include "demangle.h"
31
#include "demangle.h"
32
#include "objalloc.h"
32
#include "objalloc.h"
33
 
33
 
34
#include "ld.h"
34
#include "ld.h"
35
#include "ldmain.h"
35
#include "ldmain.h"
36
#include "ldmisc.h"
36
#include "ldmisc.h"
37
#include "ldexp.h"
37
#include "ldexp.h"
38
#include "ldlang.h"
38
#include "ldlang.h"
39
 
39
 
40
/* We keep an instance of this structure for each reference to a
40
/* We keep an instance of this structure for each reference to a
41
   symbol from a given object.  */
41
   symbol from a given object.  */
42
 
42
 
-
 
43
struct cref_ref
43
struct cref_ref {
44
{
44
  /* The next reference.  */
45
  /* The next reference.  */
45
  struct cref_ref *next;
46
  struct cref_ref *next;
46
  /* The object.  */
47
  /* The object.  */
47
  bfd *abfd;
48
  bfd *abfd;
48
  /* True if the symbol is defined.  */
49
  /* True if the symbol is defined.  */
49
  unsigned int def : 1;
50
  unsigned int def : 1;
50
  /* True if the symbol is common.  */
51
  /* True if the symbol is common.  */
51
  unsigned int common : 1;
52
  unsigned int common : 1;
52
  /* True if the symbol is undefined.  */
53
  /* True if the symbol is undefined.  */
53
  unsigned int undef : 1;
54
  unsigned int undef : 1;
54
};
55
};
55
 
56
 
56
/* We keep a hash table of symbols.  Each entry looks like this.  */
57
/* We keep a hash table of symbols.  Each entry looks like this.  */
57
 
58
 
-
 
59
struct cref_hash_entry
58
struct cref_hash_entry {
60
{
59
  struct bfd_hash_entry root;
61
  struct bfd_hash_entry root;
60
  /* The demangled name.  */
62
  /* The demangled name.  */
61
  const char *demangled;
63
  const char *demangled;
62
  /* References to and definitions of this symbol.  */
64
  /* References to and definitions of this symbol.  */
63
  struct cref_ref *refs;
65
  struct cref_ref *refs;
64
};
66
};
65
 
67
 
66
/* This is what the hash table looks like.  */
68
/* This is what the hash table looks like.  */
67
 
69
 
-
 
70
struct cref_hash_table
68
struct cref_hash_table {
71
{
69
  struct bfd_hash_table root;
72
  struct bfd_hash_table root;
70
};
73
};
71
 
74
 
72
/* Forward declarations.  */
75
/* Forward declarations.  */
73
 
76
 
74
static void output_one_cref (FILE *, struct cref_hash_entry *);
77
static void output_one_cref (FILE *, struct cref_hash_entry *);
75
static void check_local_sym_xref (lang_input_statement_type *);
78
static void check_local_sym_xref (lang_input_statement_type *);
76
static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
79
static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
77
static void check_refs (const char *, bfd_boolean, asection *, bfd *,
80
static void check_refs (const char *, bfd_boolean, asection *, bfd *,
78
			struct lang_nocrossrefs *);
81
			struct lang_nocrossrefs *);
79
static void check_reloc_refs (bfd *, asection *, void *);
82
static void check_reloc_refs (bfd *, asection *, void *);
80
 
83
 
81
/* Look up an entry in the cref hash table.  */
84
/* Look up an entry in the cref hash table.  */
82
 
85
 
83
#define cref_hash_lookup(table, string, create, copy)		\
86
#define cref_hash_lookup(table, string, create, copy)		\
84
  ((struct cref_hash_entry *)					\
87
  ((struct cref_hash_entry *)					\
85
   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
88
   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
86
 
89
 
87
/* Traverse the cref hash table.  */
90
/* Traverse the cref hash table.  */
88
 
91
 
89
#define cref_hash_traverse(table, func, info)				\
92
#define cref_hash_traverse(table, func, info)				\
90
  (bfd_hash_traverse							\
93
  (bfd_hash_traverse							\
91
   (&(table)->root,							\
94
   (&(table)->root,							\
92
    (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func),		\
95
    (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func),		\
93
    (info)))
96
    (info)))
94
 
97
 
95
/* The cref hash table.  */
98
/* The cref hash table.  */
96
 
99
 
97
static struct cref_hash_table cref_table;
100
static struct cref_hash_table cref_table;
98
 
101
 
99
/* Whether the cref hash table has been initialized.  */
102
/* Whether the cref hash table has been initialized.  */
100
 
103
 
101
static bfd_boolean cref_initialized;
104
static bfd_boolean cref_initialized;
102
 
105
 
103
/* The number of symbols seen so far.  */
106
/* The number of symbols seen so far.  */
104
 
107
 
105
static size_t cref_symcount;
108
static size_t cref_symcount;
106
 
109
 
107
/* Used to take a snapshot of the cref hash table when starting to
110
/* Used to take a snapshot of the cref hash table when starting to
108
   add syms from an as-needed library.  */
111
   add syms from an as-needed library.  */
109
static struct bfd_hash_entry **old_table;
112
static struct bfd_hash_entry **old_table;
110
static unsigned int old_size;
113
static unsigned int old_size;
111
static unsigned int old_count;
114
static unsigned int old_count;
112
static void *old_tab;
115
static void * old_tab;
113
static void *alloc_mark;
116
static void * alloc_mark;
114
static size_t tabsize, entsize, refsize;
117
static size_t tabsize, entsize, refsize;
115
static size_t old_symcount;
118
static size_t old_symcount;
116
 
119
 
117
/* Create an entry in a cref hash table.  */
120
/* Create an entry in a cref hash table.  */
118
 
121
 
119
static struct bfd_hash_entry *
122
static struct bfd_hash_entry *
120
cref_hash_newfunc (struct bfd_hash_entry *entry,
123
cref_hash_newfunc (struct bfd_hash_entry *entry,
121
		   struct bfd_hash_table *table,
124
		   struct bfd_hash_table *table,
122
		   const char *string)
125
		   const char *string)
123
{
126
{
124
  struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
127
  struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
125
 
128
 
126
  /* Allocate the structure if it has not already been allocated by a
129
  /* Allocate the structure if it has not already been allocated by a
127
     subclass.  */
130
     subclass.  */
128
  if (ret == NULL)
131
  if (ret == NULL)
129
    ret = ((struct cref_hash_entry *)
132
    ret = ((struct cref_hash_entry *)
130
	   bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
133
	   bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
131
  if (ret == NULL)
134
  if (ret == NULL)
132
    return NULL;
135
    return NULL;
133
 
136
 
134
  /* Call the allocation method of the superclass.  */
137
  /* Call the allocation method of the superclass.  */
135
  ret = ((struct cref_hash_entry *)
138
  ret = ((struct cref_hash_entry *)
136
	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
139
	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
137
  if (ret != NULL)
140
  if (ret != NULL)
138
    {
141
    {
139
      /* Set local fields.  */
142
      /* Set local fields.  */
140
      ret->demangled = NULL;
143
      ret->demangled = NULL;
141
      ret->refs = NULL;
144
      ret->refs = NULL;
142
 
145
 
143
      /* Keep a count of the number of entries created in the hash
146
      /* Keep a count of the number of entries created in the hash
144
	 table.  */
147
	 table.  */
145
      ++cref_symcount;
148
      ++cref_symcount;
146
    }
149
    }
147
 
150
 
148
  return &ret->root;
151
  return &ret->root;
149
}
152
}
150
 
153
 
151
/* Add a symbol to the cref hash table.  This is called for every
154
/* Add a symbol to the cref hash table.  This is called for every
152
   global symbol that is seen during the link.  */
155
   global symbol that is seen during the link.  */
153
 
156
 
154
void
157
void
155
add_cref (const char *name,
158
add_cref (const char *name,
156
	  bfd *abfd,
159
	  bfd *abfd,
157
	  asection *section,
160
	  asection *section,
158
	  bfd_vma value ATTRIBUTE_UNUSED)
161
	  bfd_vma value ATTRIBUTE_UNUSED)
159
{
162
{
160
  struct cref_hash_entry *h;
163
  struct cref_hash_entry *h;
161
  struct cref_ref *r;
164
  struct cref_ref *r;
162
 
165
 
163
  if (! cref_initialized)
166
  if (! cref_initialized)
164
    {
167
    {
165
      if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
168
      if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
166
				sizeof (struct cref_hash_entry)))
169
				sizeof (struct cref_hash_entry)))
167
	einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
170
	einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
168
      cref_initialized = TRUE;
171
      cref_initialized = TRUE;
169
    }
172
    }
170
 
173
 
171
  h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
174
  h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
172
  if (h == NULL)
175
  if (h == NULL)
173
    einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
176
    einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
174
 
177
 
175
  for (r = h->refs; r != NULL; r = r->next)
178
  for (r = h->refs; r != NULL; r = r->next)
176
    if (r->abfd == abfd)
179
    if (r->abfd == abfd)
177
      break;
180
      break;
178
 
181
 
179
  if (r == NULL)
182
  if (r == NULL)
180
    {
183
    {
181
      r = (struct cref_ref *) bfd_hash_allocate (&cref_table.root, sizeof *r);
184
      r = (struct cref_ref *) bfd_hash_allocate (&cref_table.root, sizeof *r);
182
      if (r == NULL)
185
      if (r == NULL)
183
	einfo (_("%X%P: cref alloc failed: %E\n"));
186
	einfo (_("%X%P: cref alloc failed: %E\n"));
184
      r->next = h->refs;
187
      r->next = h->refs;
185
      h->refs = r;
188
      h->refs = r;
186
      r->abfd = abfd;
189
      r->abfd = abfd;
187
      r->def = FALSE;
190
      r->def = FALSE;
188
      r->common = FALSE;
191
      r->common = FALSE;
189
      r->undef = FALSE;
192
      r->undef = FALSE;
190
    }
193
    }
191
 
194
 
192
  if (bfd_is_und_section (section))
195
  if (bfd_is_und_section (section))
193
    r->undef = TRUE;
196
    r->undef = TRUE;
194
  else if (bfd_is_com_section (section))
197
  else if (bfd_is_com_section (section))
195
    r->common = TRUE;
198
    r->common = TRUE;
196
  else
199
  else
197
    r->def = TRUE;
200
    r->def = TRUE;
198
}
201
}
199
 
202
 
200
/* Called before loading an as-needed library to take a snapshot of
203
/* Called before loading an as-needed library to take a snapshot of
201
   the cref hash table, and after we have loaded or found that the
204
   the cref hash table, and after we have loaded or found that the
202
   library was not needed.  */
205
   library was not needed.  */
203
 
206
 
204
bfd_boolean
207
bfd_boolean
205
handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
208
handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
206
		      enum notice_asneeded_action act)
209
		      enum notice_asneeded_action act)
207
{
210
{
208
  unsigned int i;
211
  unsigned int i;
209
 
212
 
210
  if (!cref_initialized)
213
  if (!cref_initialized)
211
    return TRUE;
214
    return TRUE;
212
 
215
 
213
  if (act == notice_as_needed)
216
  if (act == notice_as_needed)
214
    {
217
    {
215
      char *old_ent, *old_ref;
218
      char *old_ent, *old_ref;
216
 
219
 
217
      for (i = 0; i < cref_table.root.size; i++)
220
      for (i = 0; i < cref_table.root.size; i++)
218
	{
221
	{
219
	  struct bfd_hash_entry *p;
222
	  struct bfd_hash_entry *p;
220
	  struct cref_hash_entry *c;
223
	  struct cref_hash_entry *c;
221
	  struct cref_ref *r;
224
	  struct cref_ref *r;
222
 
225
 
223
	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
226
	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
224
	    {
227
	    {
225
	      entsize += cref_table.root.entsize;
228
	      entsize += cref_table.root.entsize;
226
	      c = (struct cref_hash_entry *) p;
229
	      c = (struct cref_hash_entry *) p;
227
	      for (r = c->refs; r != NULL; r = r->next)
230
	      for (r = c->refs; r != NULL; r = r->next)
228
		refsize += sizeof (struct cref_ref);
231
		refsize += sizeof (struct cref_ref);
229
	    }
232
	    }
230
	}
233
	}
231
 
234
 
232
      tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
235
      tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
233
      old_tab = xmalloc (tabsize + entsize + refsize);
236
      old_tab = xmalloc (tabsize + entsize + refsize);
234
 
237
 
235
      alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
238
      alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
236
      if (alloc_mark == NULL)
239
      if (alloc_mark == NULL)
237
	return FALSE;
240
	return FALSE;
238
 
241
 
239
      memcpy (old_tab, cref_table.root.table, tabsize);
242
      memcpy (old_tab, cref_table.root.table, tabsize);
240
      old_ent = (char *) old_tab + tabsize;
243
      old_ent = (char *) old_tab + tabsize;
241
      old_ref = (char *) old_ent + entsize;
244
      old_ref = (char *) old_ent + entsize;
242
      old_table = cref_table.root.table;
245
      old_table = cref_table.root.table;
243
      old_size = cref_table.root.size;
246
      old_size = cref_table.root.size;
244
      old_count = cref_table.root.count;
247
      old_count = cref_table.root.count;
245
      old_symcount = cref_symcount;
248
      old_symcount = cref_symcount;
246
 
249
 
247
      for (i = 0; i < cref_table.root.size; i++)
250
      for (i = 0; i < cref_table.root.size; i++)
248
	{
251
	{
249
	  struct bfd_hash_entry *p;
252
	  struct bfd_hash_entry *p;
250
	  struct cref_hash_entry *c;
253
	  struct cref_hash_entry *c;
251
	  struct cref_ref *r;
254
	  struct cref_ref *r;
252
 
255
 
253
	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
256
	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
254
	    {
257
	    {
255
	      memcpy (old_ent, p, cref_table.root.entsize);
258
	      memcpy (old_ent, p, cref_table.root.entsize);
256
	      old_ent = (char *) old_ent + cref_table.root.entsize;
259
	      old_ent = (char *) old_ent + cref_table.root.entsize;
257
	      c = (struct cref_hash_entry *) p;
260
	      c = (struct cref_hash_entry *) p;
258
	      for (r = c->refs; r != NULL; r = r->next)
261
	      for (r = c->refs; r != NULL; r = r->next)
259
		{
262
		{
260
		  memcpy (old_ref, r, sizeof (struct cref_ref));
263
		  memcpy (old_ref, r, sizeof (struct cref_ref));
261
		  old_ref = (char *) old_ref + sizeof (struct cref_ref);
264
		  old_ref = (char *) old_ref + sizeof (struct cref_ref);
262
		}
265
		}
263
	    }
266
	    }
264
	}
267
	}
265
      return TRUE;
268
      return TRUE;
266
    }
269
    }
267
 
270
 
268
  if (act == notice_not_needed)
271
  if (act == notice_not_needed)
269
    {
272
    {
270
      char *old_ent, *old_ref;
273
      char *old_ent, *old_ref;
271
 
274
 
272
      if (old_tab == NULL)
275
      if (old_tab == NULL)
273
	{
276
	{
274
	  /* The only way old_tab can be NULL is if the cref hash table
277
	  /* The only way old_tab can be NULL is if the cref hash table
275
	     had not been initialised when notice_as_needed.  */
278
	     had not been initialised when notice_as_needed.  */
276
	  bfd_hash_table_free (&cref_table.root);
279
	  bfd_hash_table_free (&cref_table.root);
277
	  cref_initialized = FALSE;
280
	  cref_initialized = FALSE;
278
	  return TRUE;
281
	  return TRUE;
279
	}
282
	}
280
 
283
 
281
      old_ent = (char *) old_tab + tabsize;
284
      old_ent = (char *) old_tab + tabsize;
282
      old_ref = (char *) old_ent + entsize;
285
      old_ref = (char *) old_ent + entsize;
283
      cref_table.root.table = old_table;
286
      cref_table.root.table = old_table;
284
      cref_table.root.size = old_size;
287
      cref_table.root.size = old_size;
285
      cref_table.root.count = old_count;
288
      cref_table.root.count = old_count;
286
      memcpy (cref_table.root.table, old_tab, tabsize);
289
      memcpy (cref_table.root.table, old_tab, tabsize);
287
      cref_symcount = old_symcount;
290
      cref_symcount = old_symcount;
288
 
291
 
289
      for (i = 0; i < cref_table.root.size; i++)
292
      for (i = 0; i < cref_table.root.size; i++)
290
	{
293
	{
291
	  struct bfd_hash_entry *p;
294
	  struct bfd_hash_entry *p;
292
	  struct cref_hash_entry *c;
295
	  struct cref_hash_entry *c;
293
	  struct cref_ref *r;
296
	  struct cref_ref *r;
294
 
297
 
295
	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
298
	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
296
	    {
299
	    {
297
	      memcpy (p, old_ent, cref_table.root.entsize);
300
	      memcpy (p, old_ent, cref_table.root.entsize);
298
	      old_ent = (char *) old_ent + cref_table.root.entsize;
301
	      old_ent = (char *) old_ent + cref_table.root.entsize;
299
	      c = (struct cref_hash_entry *) p;
302
	      c = (struct cref_hash_entry *) p;
300
	      for (r = c->refs; r != NULL; r = r->next)
303
	      for (r = c->refs; r != NULL; r = r->next)
301
		{
304
		{
302
		  memcpy (r, old_ref, sizeof (struct cref_ref));
305
		  memcpy (r, old_ref, sizeof (struct cref_ref));
303
		  old_ref = (char *) old_ref + sizeof (struct cref_ref);
306
		  old_ref = (char *) old_ref + sizeof (struct cref_ref);
304
		}
307
		}
305
	    }
308
	    }
306
	}
309
	}
307
 
310
 
308
      objalloc_free_block ((struct objalloc *) cref_table.root.memory,
311
      objalloc_free_block ((struct objalloc *) cref_table.root.memory,
309
			   alloc_mark);
312
			   alloc_mark);
310
    }
313
    }
311
  else if (act != notice_needed)
314
  else if (act != notice_needed)
312
    return FALSE;
315
    return FALSE;
313
 
316
 
314
  free (old_tab);
317
  free (old_tab);
315
  old_tab = NULL;
318
  old_tab = NULL;
316
  return TRUE;
319
  return TRUE;
317
}
320
}
318
 
321
 
319
/* Copy the addresses of the hash table entries into an array.  This
322
/* Copy the addresses of the hash table entries into an array.  This
320
   is called via cref_hash_traverse.  We also fill in the demangled
323
   is called via cref_hash_traverse.  We also fill in the demangled
321
   name.  */
324
   name.  */
322
 
325
 
323
static bfd_boolean
326
static bfd_boolean
324
cref_fill_array (struct cref_hash_entry *h, void *data)
327
cref_fill_array (struct cref_hash_entry *h, void *data)
325
{
328
{
326
  struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;
329
  struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;
327
 
330
 
328
  ASSERT (h->demangled == NULL);
331
  ASSERT (h->demangled == NULL);
329
  h->demangled = bfd_demangle (link_info.output_bfd, h->root.string,
332
  h->demangled = bfd_demangle (link_info.output_bfd, h->root.string,
330
			       DMGL_ANSI | DMGL_PARAMS);
333
			       DMGL_ANSI | DMGL_PARAMS);
331
  if (h->demangled == NULL)
334
  if (h->demangled == NULL)
332
    h->demangled = h->root.string;
335
    h->demangled = h->root.string;
333
 
336
 
334
  **pph = h;
337
  **pph = h;
335
 
338
 
336
  ++*pph;
339
  ++*pph;
337
 
340
 
338
  return TRUE;
341
  return TRUE;
339
}
342
}
340
 
343
 
341
/* Sort an array of cref hash table entries by name.  */
344
/* Sort an array of cref hash table entries by name.  */
342
 
345
 
343
static int
346
static int
344
cref_sort_array (const void *a1, const void *a2)
347
cref_sort_array (const void *a1, const void *a2)
345
{
348
{
346
  const struct cref_hash_entry * const *p1 =
349
  const struct cref_hash_entry * const *p1 =
347
      (const struct cref_hash_entry * const *) a1;
350
      (const struct cref_hash_entry * const *) a1;
348
  const struct cref_hash_entry * const *p2 =
351
  const struct cref_hash_entry * const *p2 =
349
      (const struct cref_hash_entry * const *) a2;
352
      (const struct cref_hash_entry * const *) a2;
-
 
353
 
350
 
354
  if (demangling)
-
 
355
  return strcmp ((*p1)->demangled, (*p2)->demangled);
-
 
356
  else
351
  return strcmp ((*p1)->demangled, (*p2)->demangled);
357
    return strcmp ((*p1)->root.string, (*p2)->root.string);
352
}
358
}
353
 
359
 
354
/* Write out the cref table.  */
360
/* Write out the cref table.  */
355
 
361
 
356
#define FILECOL (50)
362
#define FILECOL (50)
357
 
363
 
358
void
364
void
359
output_cref (FILE *fp)
365
output_cref (FILE *fp)
360
{
366
{
361
  int len;
367
  int len;
362
  struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
368
  struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
363
  const char *msg;
369
  const char *msg;
364
 
370
 
365
  fprintf (fp, _("\nCross Reference Table\n\n"));
371
  fprintf (fp, _("\nCross Reference Table\n\n"));
366
  msg = _("Symbol");
372
  msg = _("Symbol");
367
  fprintf (fp, "%s", msg);
373
  fprintf (fp, "%s", msg);
368
  len = strlen (msg);
374
  len = strlen (msg);
369
  while (len < FILECOL)
375
  while (len < FILECOL)
370
    {
376
    {
371
      putc (' ', fp);
377
      putc (' ', fp);
372
      ++len;
378
      ++len;
373
    }
379
    }
374
  fprintf (fp, _("File\n"));
380
  fprintf (fp, _("File\n"));
375
 
381
 
376
  if (! cref_initialized)
382
  if (! cref_initialized)
377
    {
383
    {
378
      fprintf (fp, _("No symbols\n"));
384
      fprintf (fp, _("No symbols\n"));
379
      return;
385
      return;
380
    }
386
    }
381
 
387
 
382
  csyms = (struct cref_hash_entry **) xmalloc (cref_symcount * sizeof (*csyms));
388
  csyms = (struct cref_hash_entry **) xmalloc (cref_symcount * sizeof (*csyms));
383
 
389
 
384
  csym_fill = csyms;
390
  csym_fill = csyms;
385
  cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
391
  cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
386
  ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
392
  ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
387
 
393
 
388
  qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
394
  qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
389
 
395
 
390
  csym_end = csyms + cref_symcount;
396
  csym_end = csyms + cref_symcount;
391
  for (csym = csyms; csym < csym_end; csym++)
397
  for (csym = csyms; csym < csym_end; csym++)
392
    output_one_cref (fp, *csym);
398
    output_one_cref (fp, *csym);
393
}
399
}
394
 
400
 
395
/* Output one entry in the cross reference table.  */
401
/* Output one entry in the cross reference table.  */
396
 
402
 
397
static void
403
static void
398
output_one_cref (FILE *fp, struct cref_hash_entry *h)
404
output_one_cref (FILE *fp, struct cref_hash_entry *h)
399
{
405
{
400
  int len;
406
  int len;
401
  struct bfd_link_hash_entry *hl;
407
  struct bfd_link_hash_entry *hl;
402
  struct cref_ref *r;
408
  struct cref_ref *r;
403
 
409
 
404
  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
410
  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
405
			     FALSE, TRUE);
411
			     FALSE, TRUE);
406
  if (hl == NULL)
412
  if (hl == NULL)
407
    einfo ("%P: symbol `%T' missing from main hash table\n",
413
    einfo ("%P: symbol `%T' missing from main hash table\n",
408
	   h->root.string);
414
	   h->root.string);
409
  else
415
  else
410
    {
416
    {
411
      /* If this symbol is defined in a dynamic object but never
417
      /* If this symbol is defined in a dynamic object but never
412
	 referenced by a normal object, then don't print it.  */
418
	 referenced by a normal object, then don't print it.  */
413
      if (hl->type == bfd_link_hash_defined)
419
      if (hl->type == bfd_link_hash_defined)
414
	{
420
	{
415
	  if (hl->u.def.section->output_section == NULL)
421
	  if (hl->u.def.section->output_section == NULL)
416
	    return;
422
	    return;
417
	  if (hl->u.def.section->owner != NULL
423
	  if (hl->u.def.section->owner != NULL
418
	      && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
424
	      && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
419
	    {
425
	    {
420
	      for (r = h->refs; r != NULL; r = r->next)
426
	      for (r = h->refs; r != NULL; r = r->next)
421
		if ((r->abfd->flags & DYNAMIC) == 0)
427
		if ((r->abfd->flags & DYNAMIC) == 0)
422
		  break;
428
		  break;
423
	      if (r == NULL)
429
	      if (r == NULL)
424
		return;
430
		return;
425
	    }
431
	    }
426
	}
432
	}
427
    }
433
    }
-
 
434
 
-
 
435
  if (demangling)
428
 
436
    {
429
  fprintf (fp, "%s ", h->demangled);
437
  fprintf (fp, "%s ", h->demangled);
-
 
438
  len = strlen (h->demangled) + 1;
-
 
439
    }
-
 
440
  else
-
 
441
    {
-
 
442
      fprintf (fp, "%s ", h->root.string);
-
 
443
      len = strlen (h->root.string) + 1;
430
  len = strlen (h->demangled) + 1;
444
    }
431
 
445
 
432
  for (r = h->refs; r != NULL; r = r->next)
446
  for (r = h->refs; r != NULL; r = r->next)
433
    {
447
    {
434
      if (r->def)
448
      if (r->def)
435
	{
449
	{
436
	  while (len < FILECOL)
450
	  while (len < FILECOL)
437
	    {
451
	    {
438
	      putc (' ', fp);
452
	      putc (' ', fp);
439
	      ++len;
453
	      ++len;
440
	    }
454
	    }
441
	  lfinfo (fp, "%B\n", r->abfd);
455
	  lfinfo (fp, "%B\n", r->abfd);
442
	  len = 0;
456
	  len = 0;
443
	}
457
	}
444
    }
458
    }
445
 
459
 
446
  for (r = h->refs; r != NULL; r = r->next)
460
  for (r = h->refs; r != NULL; r = r->next)
447
    {
461
    {
448
      if (r->common)
462
      if (r->common)
449
	{
463
	{
450
	  while (len < FILECOL)
464
	  while (len < FILECOL)
451
	    {
465
	    {
452
	      putc (' ', fp);
466
	      putc (' ', fp);
453
	      ++len;
467
	      ++len;
454
	    }
468
	    }
455
	  lfinfo (fp, "%B\n", r->abfd);
469
	  lfinfo (fp, "%B\n", r->abfd);
456
	  len = 0;
470
	  len = 0;
457
	}
471
	}
458
    }
472
    }
459
 
473
 
460
  for (r = h->refs; r != NULL; r = r->next)
474
  for (r = h->refs; r != NULL; r = r->next)
461
    {
475
    {
462
      if (! r->def && ! r->common)
476
      if (! r->def && ! r->common)
463
	{
477
	{
464
	  while (len < FILECOL)
478
	  while (len < FILECOL)
465
	    {
479
	    {
466
	      putc (' ', fp);
480
	      putc (' ', fp);
467
	      ++len;
481
	      ++len;
468
	    }
482
	    }
469
	  lfinfo (fp, "%B\n", r->abfd);
483
	  lfinfo (fp, "%B\n", r->abfd);
470
	  len = 0;
484
	  len = 0;
471
	}
485
	}
472
    }
486
    }
473
 
487
 
474
  ASSERT (len == 0);
488
  ASSERT (len == 0);
475
}
489
}
476
 
490
 
477
/* Check for prohibited cross references.  */
491
/* Check for prohibited cross references.  */
478
 
492
 
479
void
493
void
480
check_nocrossrefs (void)
494
check_nocrossrefs (void)
481
{
495
{
482
  if (! cref_initialized)
496
  if (! cref_initialized)
483
    return;
497
    return;
484
 
498
 
485
  cref_hash_traverse (&cref_table, check_nocrossref, NULL);
499
  cref_hash_traverse (&cref_table, check_nocrossref, NULL);
486
 
500
 
487
  lang_for_each_file (check_local_sym_xref);
501
  lang_for_each_file (check_local_sym_xref);
488
}
502
}
489
 
503
 
490
/* Check for prohibited cross references to local and section symbols.  */
504
/* Check for prohibited cross references to local and section symbols.  */
491
 
505
 
492
static void
506
static void
493
check_local_sym_xref (lang_input_statement_type *statement)
507
check_local_sym_xref (lang_input_statement_type *statement)
494
{
508
{
495
  bfd *abfd;
509
  bfd *abfd;
496
  asymbol **syms;
510
  asymbol **syms;
497
 
511
 
498
  abfd = statement->the_bfd;
512
  abfd = statement->the_bfd;
499
  if (abfd == NULL)
513
  if (abfd == NULL)
500
    return;
514
    return;
501
 
515
 
502
  if (!bfd_generic_link_read_symbols (abfd))
516
  if (!bfd_generic_link_read_symbols (abfd))
503
    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
517
    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
504
 
518
 
505
  for (syms = bfd_get_outsymbols (abfd); *syms; ++syms)
519
  for (syms = bfd_get_outsymbols (abfd); *syms; ++syms)
506
    {
520
    {
507
      asymbol *sym = *syms;
521
      asymbol *sym = *syms;
508
      if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
522
      if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
509
	continue;
523
	continue;
510
      if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
524
      if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
511
	  && sym->section->output_section != NULL)
525
	  && sym->section->output_section != NULL)
512
	{
526
	{
513
	  const char *outsecname, *symname;
527
	  const char *outsecname, *symname;
514
	  struct lang_nocrossrefs *ncrs;
528
	  struct lang_nocrossrefs *ncrs;
515
	  struct lang_nocrossref *ncr;
529
	  struct lang_nocrossref *ncr;
516
 
530
 
517
	  outsecname = sym->section->output_section->name;
531
	  outsecname = sym->section->output_section->name;
518
	  symname = NULL;
532
	  symname = NULL;
519
	  if ((sym->flags & BSF_SECTION_SYM) == 0)
533
	  if ((sym->flags & BSF_SECTION_SYM) == 0)
520
	    symname = sym->name;
534
	    symname = sym->name;
521
	  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
535
	  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
522
	    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
536
	    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
523
	      if (strcmp (ncr->name, outsecname) == 0)
537
	      if (strcmp (ncr->name, outsecname) == 0)
524
		check_refs (symname, FALSE, sym->section, abfd, ncrs);
538
		check_refs (symname, FALSE, sym->section, abfd, ncrs);
525
	}
539
	}
526
    }
540
    }
527
}
541
}
528
 
542
 
529
/* Check one symbol to see if it is a prohibited cross reference.  */
543
/* Check one symbol to see if it is a prohibited cross reference.  */
530
 
544
 
531
static bfd_boolean
545
static bfd_boolean
532
check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
546
check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
533
{
547
{
534
  struct bfd_link_hash_entry *hl;
548
  struct bfd_link_hash_entry *hl;
535
  asection *defsec;
549
  asection *defsec;
536
  const char *defsecname;
550
  const char *defsecname;
537
  struct lang_nocrossrefs *ncrs;
551
  struct lang_nocrossrefs *ncrs;
538
  struct lang_nocrossref *ncr;
552
  struct lang_nocrossref *ncr;
539
  struct cref_ref *ref;
553
  struct cref_ref *ref;
540
 
554
 
541
  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
555
  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
542
			     FALSE, TRUE);
556
			     FALSE, TRUE);
543
  if (hl == NULL)
557
  if (hl == NULL)
544
    {
558
    {
545
      einfo (_("%P: symbol `%T' missing from main hash table\n"),
559
      einfo (_("%P: symbol `%T' missing from main hash table\n"),
546
	     h->root.string);
560
	     h->root.string);
547
      return TRUE;
561
      return TRUE;
548
    }
562
    }
549
 
563
 
550
  if (hl->type != bfd_link_hash_defined
564
  if (hl->type != bfd_link_hash_defined
551
      && hl->type != bfd_link_hash_defweak)
565
      && hl->type != bfd_link_hash_defweak)
552
    return TRUE;
566
    return TRUE;
553
 
567
 
554
  defsec = hl->u.def.section->output_section;
568
  defsec = hl->u.def.section->output_section;
555
  if (defsec == NULL)
569
  if (defsec == NULL)
556
    return TRUE;
570
    return TRUE;
557
  defsecname = bfd_get_section_name (defsec->owner, defsec);
571
  defsecname = bfd_get_section_name (defsec->owner, defsec);
558
 
572
 
559
  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
573
  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
560
    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
574
    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
561
      if (strcmp (ncr->name, defsecname) == 0)
575
      if (strcmp (ncr->name, defsecname) == 0)
562
	for (ref = h->refs; ref != NULL; ref = ref->next)
576
	for (ref = h->refs; ref != NULL; ref = ref->next)
563
	  check_refs (hl->root.string, TRUE, hl->u.def.section,
577
	  check_refs (hl->root.string, TRUE, hl->u.def.section,
564
		      ref->abfd, ncrs);
578
		      ref->abfd, ncrs);
565
 
579
 
566
  return TRUE;
580
  return TRUE;
567
}
581
}
568
 
582
 
569
/* The struct is used to pass information from check_refs to
583
/* The struct is used to pass information from check_refs to
570
   check_reloc_refs through bfd_map_over_sections.  */
584
   check_reloc_refs through bfd_map_over_sections.  */
571
 
585
 
572
struct check_refs_info {
586
struct check_refs_info {
573
  const char *sym_name;
587
  const char *sym_name;
574
  asection *defsec;
588
  asection *defsec;
575
  struct lang_nocrossrefs *ncrs;
589
  struct lang_nocrossrefs *ncrs;
576
  asymbol **asymbols;
590
  asymbol **asymbols;
577
  bfd_boolean global;
591
  bfd_boolean global;
578
};
592
};
579
 
593
 
580
/* This function is called for each symbol defined in a section which
594
/* This function is called for each symbol defined in a section which
581
   prohibits cross references.  We need to look through all references
595
   prohibits cross references.  We need to look through all references
582
   to this symbol, and ensure that the references are not from
596
   to this symbol, and ensure that the references are not from
583
   prohibited sections.  */
597
   prohibited sections.  */
584
 
598
 
585
static void
599
static void
586
check_refs (const char *name,
600
check_refs (const char *name,
587
	    bfd_boolean global,
601
	    bfd_boolean global,
588
	    asection *sec,
602
	    asection *sec,
589
	    bfd *abfd,
603
	    bfd *abfd,
590
	    struct lang_nocrossrefs *ncrs)
604
	    struct lang_nocrossrefs *ncrs)
591
{
605
{
592
  struct check_refs_info info;
606
  struct check_refs_info info;
593
 
607
 
594
  /* We need to look through the relocations for this BFD, to see
608
  /* We need to look through the relocations for this BFD, to see
595
     if any of the relocations which refer to this symbol are from
609
     if any of the relocations which refer to this symbol are from
596
     a prohibited section.  Note that we need to do this even for
610
     a prohibited section.  Note that we need to do this even for
597
     the BFD in which the symbol is defined, since even a single
611
     the BFD in which the symbol is defined, since even a single
598
     BFD might contain a prohibited cross reference.  */
612
     BFD might contain a prohibited cross reference.  */
599
 
613
 
600
  if (!bfd_generic_link_read_symbols (abfd))
614
  if (!bfd_generic_link_read_symbols (abfd))
601
    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
615
    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
602
 
616
 
603
  info.sym_name = name;
617
  info.sym_name = name;
604
  info.global = global;
618
  info.global = global;
605
  info.defsec = sec;
619
  info.defsec = sec;
606
  info.ncrs = ncrs;
620
  info.ncrs = ncrs;
607
  info.asymbols = bfd_get_outsymbols (abfd);
621
  info.asymbols = bfd_get_outsymbols (abfd);
608
  bfd_map_over_sections (abfd, check_reloc_refs, &info);
622
  bfd_map_over_sections (abfd, check_reloc_refs, &info);
609
}
623
}
610
 
624
 
611
/* This is called via bfd_map_over_sections.  INFO->SYM_NAME is a symbol
625
/* This is called via bfd_map_over_sections.  INFO->SYM_NAME is a symbol
612
   defined in INFO->DEFSECNAME.  If this section maps into any of the
626
   defined in INFO->DEFSECNAME.  If this section maps into any of the
613
   sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
627
   sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
614
   look through the relocations.  If any of the relocations are to
628
   look through the relocations.  If any of the relocations are to
615
   INFO->SYM_NAME, then we report a prohibited cross reference error.  */
629
   INFO->SYM_NAME, then we report a prohibited cross reference error.  */
616
 
630
 
617
static void
631
static void
618
check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
632
check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
619
{
633
{
620
  struct check_refs_info *info = (struct check_refs_info *) iarg;
634
  struct check_refs_info *info = (struct check_refs_info *) iarg;
621
  asection *outsec;
635
  asection *outsec;
622
  const char *outsecname;
636
  const char *outsecname;
623
  asection *outdefsec;
637
  asection *outdefsec;
624
  const char *outdefsecname;
638
  const char *outdefsecname;
625
  struct lang_nocrossref *ncr;
639
  struct lang_nocrossref *ncr;
626
  const char *symname;
640
  const char *symname;
627
  bfd_boolean global;
641
  bfd_boolean global;
628
  long relsize;
642
  long relsize;
629
  arelent **relpp;
643
  arelent **relpp;
630
  long relcount;
644
  long relcount;
631
  arelent **p, **pend;
645
  arelent **p, **pend;
632
 
646
 
633
  outsec = sec->output_section;
647
  outsec = sec->output_section;
634
  outsecname = bfd_get_section_name (outsec->owner, outsec);
648
  outsecname = bfd_get_section_name (outsec->owner, outsec);
635
 
649
 
636
  outdefsec = info->defsec->output_section;
650
  outdefsec = info->defsec->output_section;
637
  outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
651
  outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
638
 
652
 
639
  /* The section where the symbol is defined is permitted.  */
653
  /* The section where the symbol is defined is permitted.  */
640
  if (strcmp (outsecname, outdefsecname) == 0)
654
  if (strcmp (outsecname, outdefsecname) == 0)
641
    return;
655
    return;
642
 
656
 
643
  for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
657
  for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
644
    if (strcmp (outsecname, ncr->name) == 0)
658
    if (strcmp (outsecname, ncr->name) == 0)
645
      break;
659
      break;
646
 
660
 
647
  if (ncr == NULL)
661
  if (ncr == NULL)
648
    return;
662
    return;
649
 
663
 
650
  /* This section is one for which cross references are prohibited.
664
  /* This section is one for which cross references are prohibited.
651
     Look through the relocations, and see if any of them are to
665
     Look through the relocations, and see if any of them are to
652
     INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
666
     INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
653
     against the section symbol.  If INFO->GLOBAL is TRUE, the
667
     against the section symbol.  If INFO->GLOBAL is TRUE, the
654
     definition is global, check for relocations against the global
668
     definition is global, check for relocations against the global
655
     symbols.  Otherwise check for relocations against the local and
669
     symbols.  Otherwise check for relocations against the local and
656
     section symbols.  */
670
     section symbols.  */
657
 
671
 
658
  symname = info->sym_name;
672
  symname = info->sym_name;
659
  global = info->global;
673
  global = info->global;
660
 
674
 
661
  relsize = bfd_get_reloc_upper_bound (abfd, sec);
675
  relsize = bfd_get_reloc_upper_bound (abfd, sec);
662
  if (relsize < 0)
676
  if (relsize < 0)
663
    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
677
    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
664
  if (relsize == 0)
678
  if (relsize == 0)
665
    return;
679
    return;
666
 
680
 
667
  relpp = (arelent **) xmalloc (relsize);
681
  relpp = (arelent **) xmalloc (relsize);
668
  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
682
  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
669
  if (relcount < 0)
683
  if (relcount < 0)
670
    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
684
    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
671
 
685
 
672
  p = relpp;
686
  p = relpp;
673
  pend = p + relcount;
687
  pend = p + relcount;
674
  for (; p < pend && *p != NULL; p++)
688
  for (; p < pend && *p != NULL; p++)
675
    {
689
    {
676
      arelent *q = *p;
690
      arelent *q = *p;
677
 
691
 
678
      if (q->sym_ptr_ptr != NULL
692
      if (q->sym_ptr_ptr != NULL
679
	  && *q->sym_ptr_ptr != NULL
693
	  && *q->sym_ptr_ptr != NULL
680
	  && ((global
694
	  && ((global
681
	       && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
695
	       && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
682
		   || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
696
		   || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
683
		   || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
697
		   || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
684
						   | BSF_WEAK)) != 0))
698
						   | BSF_WEAK)) != 0))
685
	      || (!global
699
	      || (!global
686
		  && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
700
		  && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
687
						  | BSF_SECTION_SYM)) != 0
701
						  | BSF_SECTION_SYM)) != 0
688
		  && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))
702
		  && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))
689
	  && (symname != NULL
703
	  && (symname != NULL
690
	      ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
704
	      ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
691
	      : ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0))
705
	      : ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0))
692
	{
706
	{
693
	  /* We found a reloc for the symbol.  The symbol is defined
707
	  /* We found a reloc for the symbol.  The symbol is defined
694
	     in OUTSECNAME.  This reloc is from a section which is
708
	     in OUTSECNAME.  This reloc is from a section which is
695
	     mapped into a section from which references to OUTSECNAME
709
	     mapped into a section from which references to OUTSECNAME
696
	     are prohibited.  We must report an error.  */
710
	     are prohibited.  We must report an error.  */
697
	  einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
711
	  einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
698
		 abfd, sec, q->address, outsecname,
712
		 abfd, sec, q->address, outsecname,
699
		 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
713
		 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
700
	}
714
	}
701
    }
715
    }
702
 
716
 
703
  free (relpp);
717
  free (relpp);
704
}
718
}