summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rtl/rtl-unresolved.h
blob: beff6ff4c4de539c2e170b33160402fc9880692f (plain) (blame)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/* SPDX-License-Identifier: BSD-2-Clause */

/*
 *  COPYRIGHT (c) 2012, 2019 Chris Johns <chrisj@rtems.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * @file
 *
 * @ingroup rtems_rtl
 *
 * @brief RTEMS Run-Time Linker Object File Unresolved Relocations Table.
 *
 * The unresolved relocation table holds relocations in a loaded object file
 * which reference unresolved external symbols. The support is needed to allow
 * dependent object files to load. In the case of dependent object files one
 * will have unresolved externals until the dependent object file is also
 * loaded. There is no load order that resolves this.
 *
 * The unresolved relocation table is a single table used by all object files
 * with unresolved symbols. It made of blocks linked together where blocks are
 * allocated as requiered. The table is always maintained compacted. That is as
 * relocations are resolved and removed the table is compacted. The only
 * pointer in the table is the object file poniter. This is used to identify
 * which object the relocation belongs to. There are no linking or back
 * pointers in the unresolved relocations table. The table is scanned for each
 * object file's relocations. This is not fast but the table should be small
 * and if it happens to grow large you have other more pressing issues to
 * resolve in your application.
 *
 * The table holds two (2) types of records:
 *
 *  # Symbol name strings.
 *  # Relocations.
 *
 * The symbol name a relocation references is held in a specific symbol name
 * string record in the table the relocation record references. The record
 * counts the number of references and the string is removed from the table
 * when the reference count reaches 0. There can be many relocations
 * referencing the symbol. The strings are referenced by a single 16bit
 * unsigned integer which is the count of the string in the table.
 *
 * The section the relocation is for in the object is the section number. The
 * relocation data is series of machine word sized fields:
 *
 * # Offset in the section.
 * # Relocation info (format specific)
 * # Additional format specific data.
 */

#if !defined (_RTEMS_RTL_UNRESOLVED_H_)
#define _RTEMS_RTL_UNRESOLVED_H_

#include <rtems.h>
#include <rtems/chain.h>
#include "rtl-obj-fwd.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * Hack to work around machine size. This needs to be cleaned up
 * to better support 64bit targets.
 */
typedef uint32_t rtems_rtl_word;

/**
 * The types of records in the blocks.
 */
typedef enum rtems_rtl_unresolved_rtype
{
  rtems_rtl_unresolved_empty = 0,  /**< The records is empty. Must always be 0 */
  rtems_rtl_unresolved_symbol = 1, /**< The record is a symbol. */
  rtems_rtl_unresolved_reloc = 2,  /**< The record is a relocation record. */
  rtems_rtl_trampoline_reloc = 3   /**< The record is a trampoline relocation record. */
} rtems_rtl_unresolved_rtype;

/**
 * Unresolved external symbol flags.
 */
#define RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE (1 << 0) /**< Search the archive. */
#define RTEMS_RTL_UNRESOLV_SYM_HAS_ERROR      (1 << 1) /**< The symbol load
                                                        *   has an error. */

/**
 * Unresolved externals symbols. The symbols are reference counted and separate
 * from the relocation records because a number of records could reference the
 * same symbol.
 *
 * The name is extended in the allocator of the record in the unresolved data
 * block. The 10 is a minimum that is added to by joining more than one record.
 */
typedef struct rtems_rtl_unresolv_symbol
{
  uint16_t   refs;     /**< The number of references to this name. */
  uint16_t   flags;    /**< Flags to manage the symbol. */
  uint16_t   length;   /**< The length of this name. */
  const char name[];   /**< The symbol name. */
} rtems_rtl_unresolv_symbol;

/**
 * Unresolved externals symbols require the relocation records to be held
 * and referenced.
 */
typedef struct rtems_rtl_unresolv_reloc
{
  rtems_rtl_obj* obj;     /**< The relocation's object file. */
  uint16_t       flags;   /**< Format specific flags. */
  uint16_t       name;    /**< The symbol's name. */
  uint16_t       sect;    /**< The target section. */
  rtems_rtl_word rel[3];  /**< Relocation record. */
} rtems_rtl_unresolv_reloc;

/**
 * Trampolines require the relocation records to be held
 */
typedef struct rtems_rtl_tramp_reloc
{
  rtems_rtl_obj* obj;      /**< The relocation's object file. */
  uint16_t       flags;    /**< Format specific flags. */
  uint16_t       sect;     /**< The target section. */
  rtems_rtl_word symvalue; /**< The symbol's value. */
  rtems_rtl_word rel[3];   /**< Relocation record. */
} rtems_rtl_tramp_reloc;

/**
 * Unresolved externals records.
 */
typedef struct rtems_rtl_unresolv_rec
{
  rtems_rtl_unresolved_rtype type;
  union
  {
    rtems_rtl_unresolv_symbol name;   /**< The symbol, or */
    rtems_rtl_unresolv_reloc  reloc;  /**< The relocation record. */
    rtems_rtl_tramp_reloc     tramp;  /**< The trampoline relocation record. */
  } rec;
} rtems_rtl_unresolv_rec;

/**
 * Unresolved blocks.
 */
typedef struct rtems_rtl_unresolv_block
{
  rtems_chain_node       link;  /**< Blocks are chained. */
  uint32_t               recs;  /**< The number of records in the block. */
  rtems_rtl_unresolv_rec rec[]; /**< The records. More follow. */
} rtems_rtl_unresolv_block;

/**
 * Unresolved table holds the names and relocations.
 */
typedef struct rtems_rtl_unresolved
{
  uint32_t            marker;     /**< Block marker. */
  size_t              block_recs; /**< The records per blocks allocated. */
  rtems_chain_control blocks;     /**< List of blocks. */
} rtems_rtl_unresolved;

/**
 * The iterator function used to iterate over the unresolved table.
 *
 * @param rec The current iterator.
 * @param data The user data.
 * @retval true The iterator has finished.
 * @retval false The iterator has not finished. Keep iterating.
 */
typedef bool rtems_rtl_unresolved_iterator (rtems_rtl_unresolv_rec* rec,
                                            void*                   data);

/**
 * Open an unresolved relocation table.
 *
 * @param unresolv The unresolved table to open.
 * @param block_records The number of records per block allocated.
 * @retval true The table is open.
 * @retval false The unresolved relocation table could not created. The RTL
 *               error has the error.
 */
bool rtems_rtl_unresolved_table_open (rtems_rtl_unresolved* unresolved,
                                      size_t                block_records);

/**
 * Close the table and erase the blocks.
 *
 * @param unreolved Close the unresolved table.
 */
void rtems_rtl_unresolved_table_close (rtems_rtl_unresolved* unresolved);

/**
 * Iterate over the table of unresolved entries.
 */
bool rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_iterator iterator,
                                   void*                         data);

/**
 * Add a relocation to the list of unresolved relocations.
 *
 * @param unresolved The unresolved symbol table.
 * @param obj The object table the symbols are for.
 * @param flags Format specific flags.
 * @param name The symbol name the relocation references.
 * @param sect The target section number the relocation references.
 * @param rel The format specific relocation data.
 * @retval true The relocation has been added.
 * @retval false The relocation could not be added.
 */
bool rtems_rtl_unresolved_add (rtems_rtl_obj*        obj,
                               const uint16_t        flags,
                               const char*           name,
                               const uint16_t        sect,
                               const rtems_rtl_word* rel);

/**
 * Resolve the unresolved symbols.
 */
void rtems_rtl_unresolved_resolve (void);

/**
 * Remove a relocation from the list of unresolved relocations.
 *
 * @param unresolved The unresolved symbol table.
 * @param obj The object table the symbols are for.
 * @param esyms The exported symbol table.
 * @param size The size of the table in bytes.
 */
bool rtems_rtl_unresolved_remove (rtems_rtl_obj*        obj,
                                  const char*           name,
                                  const uint16_t        sect,
                                  const rtems_rtl_word* rel);

/**
 * Set all symbols to be archive searchable. This is done when the available
 * archives have been refreshed and there are new archives to search for.
 */
void rtems_rtl_unresolved_set_archive_search (void);

/**
 * Dump the RTL unresolved data.
 */
void rtems_rtl_unresolved_dump (void);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif