source: rtems-tools/linkers/rld-symbols.cpp @ ec24a37

4.104.115
Last change on this file since ec24a37 was ec24a37, checked in by Chris Johns <chrisj@…>, on 05/06/12 at 22:47:11

Add to git.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/**
17 * @file
18 *
19 * @ingroup rtems-ld
20 *
21 * @brief RTEMS Linker symbols manages the symbols from all the object files.
22 *
23 */
24
25#include <string.h>
26
27#include <iomanip>
28
29#include <rld.h>
30
31#include <libiberty/demangle.h>
32
33namespace rld
34{
35  namespace symbols
36  {
37    /**
38     * Get the demangled name.
39     */
40    static void
41    denamgle_name (std::string& name, std::string& demangled)
42    {
43      char* demangled_name = ::cplus_demangle (name.c_str (),
44                                               DMGL_ANSI | DMGL_PARAMS);
45      if (demangled_name)
46      {
47        demangled = demangled_name;
48        ::free (demangled_name);
49      }
50    }
51
52    symbol::symbol ()
53      : object_ (0),
54        references_ (0)
55    {
56      memset (&esym_, 0, sizeof (esym_));
57    }
58
59    symbol::symbol (const std::string&  name,
60                    rld::files::object& object,
61                    const elf::elf_sym& esym)
62      : name_ (name),
63        object_ (&object),
64        esym_ (esym),
65        references_ (0)
66    {
67      if (!object_)
68        throw rld_error_at ("object pointer is 0");
69      if (name_.empty ())
70        throw rld_error_at ("name is empty in " + object.name ().full ());
71      if (is_cplusplus ())
72        denamgle_name (name_, demangled_);
73    }
74
75    symbol::symbol (const std::string& name, const elf::elf_sym& esym)
76      : name_ (name),
77        object_ (0),
78        esym_ (esym),
79        references_ (0)
80    {
81      if (name_.empty ())
82        throw rld_error_at ("name is empty");
83      if (is_cplusplus ())
84        denamgle_name (name_, demangled_);
85    }
86
87    symbol::symbol (const std::string&  name,
88                    const elf::elf_addr value)
89      : name_ (name),
90        object_ (0),
91        references_ (0)
92    {
93      memset (&esym_, 0, sizeof (esym_));
94      esym_.st_value = value;
95    }
96
97    symbol::symbol (const char*         name,
98                    const elf::elf_addr value)
99      : name_ (name),
100        object_ (0),
101        references_ (0)
102    {
103      memset (&esym_, 0, sizeof (esym_));
104      esym_.st_value = value;
105    }
106
107    const std::string&
108    symbol::name () const
109    {
110      return name_;
111    }
112
113    const std::string&
114    symbol::demangled () const
115    {
116      return demangled_;
117    }
118
119    bool
120    symbol::is_cplusplus () const
121    {
122      return (name_[0] == '_') && (name_[1] == 'Z');
123    }
124
125    rld::files::object*
126    symbol::object () const
127    {
128      return object_;
129    }
130   
131    void
132    symbol::set_object (rld::files::object& obj)
133    {
134      object_ = &obj;
135    }
136
137    const elf::elf_sym&
138    symbol::esym () const
139    {
140      return esym_;
141    }
142
143    void
144    symbol::referenced ()
145    {
146      ++references_;
147      if (object_)
148        object_->symbol_referenced ();
149    }
150
151    bool
152    symbol::operator< (const symbol& rhs) const
153    {
154      return name_ < rhs.name_;
155    }
156
157    void
158    symbol::output (std::ostream& out) const
159    {
160      const elf::elf_sym& es = esym ();
161
162      std::string binding;
163      int binding_val = GELF_ST_BIND (es.st_info);
164      switch (binding_val)
165      {
166        case STB_LOCAL:
167          binding = "STB_LOCAL ";
168          break;
169        case STB_GLOBAL:
170          binding = "STB_GLOBAL";
171          break;
172        case STB_WEAK:
173          binding = "STB_WEAK  ";
174          break;
175        default:
176          if ((binding_val >= STB_LOPROC) && (binding_val <= STB_HIPROC))
177            binding = "STB_LOPROC(" + rld::to_string (binding_val) + ")";
178          else
179            binding = "STB_INVALID("  + rld::to_string (binding_val) + ")";
180          break;
181      }
182
183      std::string type;
184      int type_val = GELF_ST_TYPE (es.st_info);
185      switch (type_val)
186      {
187        case STT_NOTYPE:
188          type = "STT_NOTYPE ";
189          break;
190        case STT_OBJECT:
191          type = "STT_OBJECT ";
192          break;
193        case STT_FUNC:
194          type = "STT_FUNC   ";
195          break;
196        case STT_SECTION:
197          type = "STT_SECTION";
198          break;
199        case STT_FILE:
200          type = "STT_FILE   ";
201          break;
202        default:
203          if ((type_val >= STT_LOPROC) && (type_val <= STT_HIPROC))
204            type = "STT_LOPROC(" + rld::to_string (type_val) + ")";
205          else
206            type = "STT_INVALID("  + rld::to_string (type_val) + ")";
207          break;
208      }
209
210      out << binding
211          << ' ' << type
212          << " 0x" << std::setw (8) << std::setfill ('0') << std::hex
213          << es.st_value
214          << std::dec << std::setfill (' ')
215          << ' ' << std::setw (7)  << es.st_size
216          << ' ';
217     
218      if (is_cplusplus ())
219        out << demangled ();
220      else
221        out << name ();
222
223      if (object ())
224        out << "   (" << object ()->name ().basename () << ')';
225    }
226
227    size_t
228    referenced (list& symbols)
229    {
230      size_t used = 0;
231      for (rld::symbols::list::iterator sli = symbols.begin ();
232           sli != symbols.end ();
233           ++sli)
234      {
235        rld::symbols::symbol& sym = *(*sli);
236        if (sym.references ())
237          ++used;
238      }
239
240      return used;
241    }
242
243    void
244    output (std::ostream& out, const table& symbols)
245    {
246      std::cout << " No.  Scope      Type        Address    Size    Name" << std::endl;
247      int index = 0;
248      for (table::const_iterator si = symbols.begin ();
249           si != symbols.end ();
250           ++si)
251      {
252        const symbol& sym = (*si).second;
253        out << std::setw (5) << index << ' ' << sym << std::endl;
254        ++index;
255      }
256    }
257
258  }
259}
Note: See TracBrowser for help on using the repository browser.