source: rtems-tools/linkers/rld-resolver.cpp @ fe19d06

4.104.11
Last change on this file since fe19d06 was 1976825, checked in by Chris Johns <chrisj@…>, on Nov 18, 2012 at 11:36:34 PM

Resolve the ld and user undefines.

  • Property mode set to 100644
File size: 5.5 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.
22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <iomanip>
30#include <iostream>
31
32#include <sys/stat.h>
33
34#include <rld.h>
35#include <rld.h>
36
37namespace rld
38{
39  namespace resolver
40  {
41    static void
42    resolve_symbols (rld::files::object_list& dependents,
43                     rld::files::cache&       cache,
44                     rld::symbols::table&     base_symbols,
45                     rld::symbols::table&     symbols,
46                     rld::symbols::table&     unresolved,
47                     const std::string&       name)
48    {
49      static int nesting = 0;
50
51      ++nesting;
52
53      /*
54       * Find each unresolved symbol in the symbol table pointing the
55       * unresolved symbol's object file to the file that resolves the
56       * symbol. Record each object file that is found and when all unresolved
57       * symbols in this object file have been found iterate over the found
58       * object files resolving them. The 'urs' is the unresolved symbol and
59       * 'es' is the exported symbol.
60       */
61
62      if (rld::verbose () >= RLD_VERBOSE_INFO)
63        std::cout << "resolver:resolving: "
64                  << std::setw (nesting - 1) << ' '
65                  << name
66                  << ", unresolved: "
67                  << unresolved.size ()
68                  << std::endl;
69
70      rld::files::object_list objects;
71
72      for (rld::symbols::table::iterator ursi = unresolved.begin ();
73           (ursi != unresolved.end ()) && !((*ursi).second)->object ();
74           ++ursi)
75      {
76        rld::symbols::symbol&         urs = *((*ursi).second);
77        rld::symbols::table::iterator esi = base_symbols.find (urs.name ());
78        bool                          base = true;
79
80        if (rld::verbose () >= RLD_VERBOSE_INFO)
81        {
82          std::cout << "resolver:resolve  : "
83                    << std::setw (nesting + 1) << ' '
84                    << urs.name () << std::endl;
85        }
86
87        if (esi == base_symbols.end ())
88        {
89          esi = symbols.find (urs.name ());
90          if (esi == symbols.end ())
91            throw rld::error ("symbol referenced in '" + name +
92                              "' not found: " + urs.name (), "resolving");
93          base = false;
94        }
95
96        rld::symbols::symbol& es = *((*esi).second);
97
98        if (rld::verbose () >= RLD_VERBOSE_INFO)
99        {
100          std::cout << "resolver:resolved : "
101                    << std::setw (nesting + 1) << ' '
102                    << urs.name ()
103                    << " -> ";
104          if (es.object())
105            std::cout << es.object()->name ().basename ();
106          else
107            std::cout << "null";
108          std::cout << std::endl;
109        }
110
111        if (!base)
112        {
113          urs.set_object (*es.object ());
114          objects.push_back (es.object ());
115        }
116
117        es.referenced ();
118      }
119
120      /*
121       * Recurse into any references object files. First remove any duplicate
122       * entries.
123       */
124      objects.unique ();
125
126      for (rld::files::object_list::iterator oli = objects.begin ();
127           oli != objects.end ();
128           ++oli)
129      {
130        rld::files::object& object = *(*oli);
131        if (rld::verbose () >= RLD_VERBOSE_INFO)
132          std::cout << "resolver:resolving:    : "
133                    << object.name ().basename () << std::endl;
134        resolve_symbols (dependents, cache, base_symbols, symbols,
135                         object.unresolved_symbols (),
136                         object.name ().basename ());
137      }
138
139      --nesting;
140
141      dependents.merge (objects);
142      dependents.unique ();
143    }
144
145    void
146    resolve (rld::files::object_list& dependents,
147             rld::files::cache&       cache,
148             rld::symbols::table&     base_symbols,
149             rld::symbols::table&     symbols,
150             rld::symbols::table&     undefined)
151    {
152      rld::files::object_list objects;
153      cache.get_objects (objects);
154
155      /*
156       * First resolve any undefined symbols that are forced by the linker or
157       * the user.
158       */
159      resolver::resolve_symbols (dependents, cache, base_symbols, symbols,
160                                 undefined, "undefines");
161
162      /*
163       * Resolve the symbols in the object files.
164       */
165      for (rld::files::object_list::iterator oi = objects.begin ();
166           oi != objects.end ();
167           ++oi)
168      {
169        rld::files::object& object = *(*oi);
170        if (rld::verbose () >= RLD_VERBOSE_INFO)
171          std::cout << "resolver:resolving: top: "
172                    << object.name ().basename () << std::endl;
173        resolver::resolve_symbols (dependents, cache, base_symbols, symbols,
174                                   object.unresolved_symbols (),
175                                   object.name ().basename ());
176      }
177    }
178  }
179
180}
Note: See TracBrowser for help on using the repository browser.