OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [lto-plugin/] [lto-symtab.c] - Blame information for rev 767

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 743 jeremybenn
/* Program to read the IL symbol table.
2
   Copyright (C) 2008 Free Software Foundation, Inc.
3
   Contributed by Rafael Avila de Espindola (espindola@google.com).
4
 
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 3 of the License, or
8
(at your option) any later version.
9
 
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
18
 
19
#include <fcntl.h>
20
#include <assert.h>
21
#include <dlfcn.h>
22
#include <stdio.h>
23
#include <inttypes.h>
24
#include <stdlib.h>
25
#include <string.h>
26
 
27
#include "plugin-api.h"
28
#include "../gcc/lto/common.h"
29
 
30
/* The presence of gelf.h is checked by the toplevel configure script.  */
31
# include <gelf.h>
32
 
33
static ld_plugin_claim_file_handler claim_file_handler;
34
static ld_plugin_all_symbols_read_handler all_symbols_read_handler;
35
static ld_plugin_cleanup_handler cleanup_handler;
36
static void *plugin_handle;
37
 
38
struct file_handle {
39
  unsigned nsyms;
40
  struct ld_plugin_symbol *syms;
41
};
42
 
43
static struct file_handle **all_file_handles = NULL;
44
static unsigned int num_file_handles;
45
 
46
/* Write NSYMS symbols from file HANDLE in SYMS. */
47
 
48
static enum ld_plugin_status
49
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
50
{
51
  unsigned i;
52
  struct file_handle *h = (struct file_handle *) handle;
53
  assert (h->nsyms == nsyms);
54
 
55
  for (i = 0; i < nsyms; i++)
56
    syms[i] = h->syms[i];
57
 
58
  return LDPS_OK;
59
}
60
 
61
/* Register HANDLER as the callback for notifying the plugin that all symbols
62
   have been read. */
63
 
64
static enum ld_plugin_status
65
register_all_symbols_read (ld_plugin_all_symbols_read_handler handler)
66
{
67
  all_symbols_read_handler = handler;
68
  return LDPS_OK;
69
}
70
 
71
/* Register HANDLER as the callback for claiming a file. */
72
 
73
static enum ld_plugin_status
74
register_claim_file(ld_plugin_claim_file_handler handler)
75
{
76
  claim_file_handler = handler;
77
  return LDPS_OK;
78
}
79
 
80
/* Register HANDLER as the callback to removing temporary files. */
81
 
82
static enum ld_plugin_status
83
register_cleanup (ld_plugin_cleanup_handler handler)
84
{
85
  cleanup_handler = handler;
86
  return LDPS_OK;
87
}
88
 
89
/* For a file identified by HANDLE, add NSYMS symbols from SYMS. */
90
 
91
static enum ld_plugin_status
92
add_symbols (void *handle, int nsyms,
93
             const struct ld_plugin_symbol *syms)
94
{
95
  int i;
96
  struct file_handle *h = (struct file_handle *) handle;
97
  h->nsyms = nsyms;
98
  h->syms = calloc (nsyms, sizeof (struct ld_plugin_symbol));
99
  assert (h->syms);
100
 
101
  for (i = 0; i < nsyms; i++)
102
    {
103
      h->syms[i] = syms[i];
104
      h->syms[i].name = strdup (h->syms[i].name);
105
      if (h->syms[i].version)
106
        h->syms[i].version = strdup (h->syms[i].version);
107
      if (h->syms[i].comdat_key)
108
        h->syms[i].comdat_key = strdup (h->syms[i].comdat_key);
109
    }
110
 
111
  return LDPS_OK;
112
}
113
 
114
struct ld_plugin_tv tv[] = {
115
  {LDPT_REGISTER_CLAIM_FILE_HOOK,
116
   {.tv_register_claim_file = register_claim_file}
117
  },
118
  {LDPT_ADD_SYMBOLS,
119
   {.tv_add_symbols = add_symbols}
120
  },
121
 
122
  {LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
123
   {.tv_register_all_symbols_read = register_all_symbols_read}
124
  },
125
  {LDPT_GET_SYMBOLS,
126
   {.tv_get_symbols = get_symbols}
127
  },
128
  {LDPT_REGISTER_CLEANUP_HOOK,
129
   {.tv_register_cleanup = register_cleanup}
130
  },
131
  {0, {0}}
132
};
133
 
134
/* Load a plugin from a file named NAME. */
135
 
136
static void
137
load_plugin (const char *name)
138
{
139
  ld_plugin_onload onload;
140
  plugin_handle = dlopen (name, RTLD_LAZY);
141
 
142
  assert (plugin_handle != NULL);
143
  onload = dlsym (plugin_handle, "onload");
144
  assert (onload);
145
  onload (tv);
146
  assert (claim_file_handler);
147
}
148
 
149
/* Send object to the plugin. The file (archive or object) name is NAME.
150
   FD is an open file descriptor. The object data starts at OFFSET and is
151
   FILESIZE bytes long. */
152
 
153
static void
154
register_object (const char *name, int fd, off_t offset, off_t filesize)
155
{
156
  int claimed;
157
  struct ld_plugin_input_file file;
158
  void *handle;
159
 
160
  num_file_handles++;
161
  all_file_handles = realloc (all_file_handles, num_file_handles
162
                              * sizeof (struct file_handle *));
163
  assert (all_file_handles);
164
 
165
  all_file_handles[num_file_handles - 1] = calloc (1,
166
                                                   sizeof (struct file_handle));
167
  handle = all_file_handles[num_file_handles - 1];
168
  assert (handle);
169
 
170
  file.name = (char *) name;
171
  file.fd = fd;
172
  file.offset = offset;
173
  file.filesize = filesize;
174
 
175
  file.handle = handle;
176
 
177
  claim_file_handler (&file, &claimed);
178
}
179
 
180
/* Send file named NAME to the plugin. */
181
 
182
static void
183
register_file (const char *name)
184
{
185
 int fd = open (name, O_RDONLY);
186
 Elf *elf;
187
 
188
 assert (fd >= 0);
189
 
190
 elf = elf_begin (fd, ELF_C_READ, NULL);
191
 assert (elf);
192
 
193
 Elf_Kind kind = elf_kind (elf);
194
 
195
 assert (kind == ELF_K_ELF || kind == ELF_K_AR);
196
 
197
 if (kind == ELF_K_AR)
198
   {
199
     Elf *member = elf_begin (fd, ELF_C_READ, elf);
200
     while (member)
201
       {
202
         Elf_Arhdr *h = elf_getarhdr (member);
203
         assert (h);
204
 
205
         if (h->ar_name[0] != '/')
206
           {
207
             off_t offset = elf_getbase (member);
208
             register_object (name, fd, offset, h->ar_size);
209
           }
210
 
211
         Elf_Cmd cmd = elf_next (member);
212
         elf_end (member);
213
         member = elf_begin (fd, cmd, elf);
214
       }
215
   }
216
 else /* Single File */
217
   register_object (name, fd, 0, 0);
218
 
219
 elf_end (elf);
220
}
221
 
222
/* Fake symbol resolution for testing. */
223
 
224
static void
225
resolve (void)
226
{
227
  unsigned j;
228
  for (j = 0; j < num_file_handles; j++)
229
    {
230
      struct file_handle *handle = all_file_handles[j];
231
      unsigned int nsyms = handle->nsyms;
232
      struct ld_plugin_symbol *syms = handle->syms;
233
      unsigned i;
234
      for (i = 0; i < nsyms; i++)
235
        {
236
          switch (syms[i].def)
237
            {
238
            case LDPK_DEF:
239
            case LDPK_WEAKDEF:
240
            case LDPK_COMMON:
241
              syms[i].resolution =  LDPR_PREVAILING_DEF;
242
              break;
243
            case LDPK_UNDEF:
244
            case LDPK_WEAKUNDEF:
245
              syms[i].resolution =  LDPR_RESOLVED_IR;
246
              break;
247
            }
248
        }
249
    }
250
}
251
 
252
/* Print all symbol information. */
253
 
254
static void
255
print (void)
256
{
257
  unsigned j;
258
  for (j = 0; j < num_file_handles; j++)
259
    {
260
      struct file_handle *handle = all_file_handles[j];
261
      unsigned int nsyms = handle->nsyms;
262
      struct ld_plugin_symbol *syms = handle->syms;
263
      unsigned i;
264
      for (i = 0; i < nsyms; i++)
265
        {
266
          printf("name: %s; ", syms[i].name);
267
          if (syms[i].version)
268
             printf("version: %s;", syms[i].version);
269
          else
270
            printf("not versioned; ");
271
          printf("kind: %s; ", lto_kind_str[syms[i].def]);
272
          printf("visibility: %s; ", lto_visibility_str[syms[i].visibility]);
273
          printf("size: %" PRId64 "; ", syms[i].size);
274
          if (syms[i].comdat_key)
275
            printf("comdat_key: %s; ", syms[i].comdat_key);
276
          else
277
            printf("no comdat_key; ");
278
          printf ("resolution: %s\n", lto_resolution_str[syms[i].resolution]);
279
        }
280
    }
281
}
282
 
283
/* Unload the plugin. */
284
 
285
static void
286
unload_plugin (void)
287
{
288
  unsigned err = dlclose (plugin_handle);
289
  assert (err == 0);
290
  claim_file_handler = 0;
291
  all_symbols_read_handler = 0;
292
}
293
 
294
/* Free all memory allocated by us that hasn't been freed yet. */
295
 
296
static void
297
free_all (void)
298
{
299
  unsigned j;
300
  for (j = 0; j < num_file_handles; j++)
301
    {
302
      struct file_handle *handle = all_file_handles[j];
303
      unsigned int nsyms = handle->nsyms;
304
      struct ld_plugin_symbol *syms = handle->syms;
305
      unsigned i;
306
      for (i = 0; i < nsyms; i++)
307
        {
308
          free (syms[i].name);
309
          syms[i].name = 0;
310
          if (syms[i].version)
311
            {
312
              free (syms[i].version);
313
              syms[i].version = 0;
314
            }
315
          if (syms[i].comdat_key)
316
            {
317
              free (syms[i].comdat_key);
318
              syms[i].comdat_key = 0;
319
            }
320
        }
321
      free (syms);
322
      handle->syms = NULL;
323
      handle->nsyms = 0;
324
      free (all_file_handles[j]);
325
      all_file_handles[j] = NULL;
326
    }
327
 
328
  free (all_file_handles);
329
  all_file_handles = NULL;
330
  num_file_handles = 0;
331
}
332
 
333
int
334
main(int argc, char *argv[])
335
{
336
  const char *plugin;
337
  unsigned int i;
338
  assert (argc >= 3);
339
  plugin = argv[1];
340
 
341
  load_plugin (plugin);
342
 
343
  for (i = 2; i < argc; i++)
344
    register_file (argv[i]);
345
 
346
  resolve ();
347
 
348
  print ();
349
 
350
  all_symbols_read_handler ();
351
 
352
  free_all ();
353
 
354
  cleanup_handler ();
355
 
356
  unload_plugin ();
357
 
358
  return 0;
359
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.