File: objinfo_helper.c

package info (click to toggle)
ocaml 4.05.0-11
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 27,060 kB
  • sloc: ml: 199,255; ansic: 44,187; sh: 5,611; makefile: 4,958; lisp: 4,223; asm: 4,220; awk: 306; perl: 87; fortran: 21; cs: 9; sed: 9
file content (100 lines) | stat: -rw-r--r-- 2,869 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**************************************************************************/
/*                                                                        */
/*                                 OCaml                                  */
/*                                                                        */
/*         Mehdi Dogguy, PPS laboratory, University Paris Diderot         */
/*                                                                        */
/*   Copyright 2010 Mehdi Dogguy                                          */
/*                                                                        */
/*   All rights reserved.  This file is distributed under the terms of    */
/*   the GNU Lesser General Public License version 2.1, with the          */
/*   special exception on linking described in the file LICENSE.          */
/*                                                                        */
/**************************************************************************/

#include "../config/s.h"
#include <stdio.h>

#ifdef HAS_LIBBFD
#include <stdlib.h>
#include <string.h>

// PACKAGE: protect against binutils change
//   https://sourceware.org/bugzilla/show_bug.cgi?id=14243
#define PACKAGE "ocamlobjinfo"
#include <bfd.h>
#undef PACKAGE

#define plugin_header_sym (symbol_prefix "caml_plugin_header")

int main(int argc, char ** argv)
{
  bfd *fd;
  asection *sec;
  file_ptr offset;
  long st_size;
  asymbol ** symbol_table;
  long sym_count, i;

  if (argc != 2) {
    fprintf(stderr, "Usage: objinfo_helper <dynamic library>\n");
    return 2;
  }

  fd = bfd_openr(argv[1], "default");
  if (!fd) {
    fprintf(stderr, "Error opening file %s\n", argv[1]);
    return 2;
  }
  if (! bfd_check_format (fd, bfd_object)) {
    fprintf(stderr, "Error: wrong format\n");
    bfd_close(fd);
    return 2;
  }

  sec = bfd_get_section_by_name(fd, ".data");
  if (! sec) {
    fprintf(stderr, "Error: section .data not found\n");
    bfd_close(fd);
    return 2;
  }

  offset = sec->filepos;
  st_size = bfd_get_dynamic_symtab_upper_bound (fd);
  if (st_size <= 0) {
    fprintf(stderr, "Error: size of section .data unknown\n");
    bfd_close(fd);
    return 2;
  }

  symbol_table = malloc(st_size);
  if (! symbol_table) {
    fprintf(stderr, "Error: out of memory\n");
    bfd_close(fd);
    return 2;
  }

  sym_count = bfd_canonicalize_dynamic_symtab (fd, symbol_table);

  for (i = 0; i < sym_count; i++) {
    if (strcmp(symbol_table[i]->name, plugin_header_sym) == 0) {
      printf("%ld\n", (long) (offset + symbol_table[i]->value));
      bfd_close(fd);
      return 0;
    }
  }

  fprintf(stderr, "Error: missing symbol %s\n", plugin_header_sym);
  bfd_close(fd);
  return 2;
}

#else

int main(int argc, char ** argv)
{
  fprintf(stderr,"BFD library unavailable, cannot print info on .cmxs files\n");
  return 2;
}

#endif