source: rtems-tools/linkers/rld-resolver.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: 4.7 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 (rld::files::object_list& dependents,
43             rld::files::cache&       cache,
44             rld::symbols::table&     base_symbols,
45             rld::symbols::table&     symbols,
46             rld::files::object&      object)
47    {
48      static int nesting = 0;
49
50      ++nesting;
51
52      /*
53       * Find each unresolved symbol in the symbol table pointing the
54       * unresolved symbol's object file to the file that resolves the
55       * symbol. Record each object file that is found and when all unresolved
56       * symbols in this object file have been found iterate over the found
57       * object files resolving them. The 'usr' is the unresolved symbol and
58       * 'es' is the exported symbol.
59       */
60
61      rld::symbols::table& unresolved = object.unresolved_symbols ();
62
63      if (rld::verbose () >= RLD_VERBOSE_INFO)
64        std::cout << "resolver:resolving: "
65                  << std::setw (nesting - 1) << ' '
66                  << object.name ().basename ()
67                  << ", unresolved: "
68                  << unresolved.size ()
69                  << ((*unresolved.begin ()).second.object () ? " (resolved)" : "")
70                  << std::endl;
71
72      rld::files::object_list objects;
73
74      for (rld::symbols::table::iterator ursi = unresolved.begin ();
75           (ursi != unresolved.end ()) && !(*ursi).second.object ();
76           ++ursi)
77      {
78        rld::symbols::symbol&         urs = (*ursi).second;
79        rld::symbols::table::iterator esi = base_symbols.find (urs.name ());
80        bool                          base = true;
81
82        if (esi == base_symbols.end ())
83        {
84          esi = symbols.find (urs.name ());
85          if (esi == symbols.end ())
86            throw rld::error ("symbol referenced in '" + object.name ().basename () +
87                              "' not found: " + urs.name (), "resolving");
88          base = false;
89        }
90
91        rld::symbols::symbol& es = (*esi).second;
92
93        if (rld::verbose () >= RLD_VERBOSE_INFO)
94        {
95          std::cout << "resolver:resolved : "
96                    << std::setw (nesting + 1) << ' '
97                    << urs.name ()
98                    << " -> ";
99          if (es.object())
100            std::cout << es.object()->name ().basename ();
101          else
102            std::cout << "null";
103          std::cout << std::endl;
104        }
105
106        if (!base)
107        {
108          urs.set_object (*es.object ());
109          objects.push_back (es.object ());
110        }
111
112        es.referenced ();
113      }
114
115      /*
116       * Recurse into any references object files. First remove any duplicate
117       * entries.
118       */
119      objects.unique ();
120
121      for (rld::files::object_list::iterator oli = objects.begin ();
122           oli != objects.end ();
123           ++oli)
124        resolve (dependents, cache, base_symbols, symbols, *(*oli));
125     
126      --nesting;
127
128      dependents.merge (objects);
129      dependents.unique ();
130    }
131
132    void
133    resolve (rld::files::object_list& dependents,
134             rld::files::cache&       cache,
135             rld::symbols::table&     base_symbols,
136             rld::symbols::table&     symbols,
137             rld::symbols::table&     undefined)
138    {
139      rld::files::object_list objects;
140      cache.get_objects (objects);
141       
142      for (rld::files::object_list::iterator oi = objects.begin ();
143           oi != objects.end ();
144           ++oi)
145      {
146        rld::files::object& object = *(*oi);
147        if (rld::verbose ())
148          std::cout << "resolver:resolving: top: "
149                    << object.name ().basename () << std::endl;
150        resolve (dependents, cache, base_symbols, symbols, object);
151      }
152    }
153  }
154
155}
Note: See TracBrowser for help on using the repository browser.