1 /*****************************************************************************/
5 /* Module constructor/destructor support */
9 /* (C) 2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
52 /*****************************************************************************/
54 /*****************************************************************************/
58 /* Struct describing one condes type */
59 typedef struct ConDesDesc ConDesDesc;
61 Collection ExpList; /* List of exported symbols */
62 char* SegName; /* Name of segment the table is in */
63 char* Label; /* Name of table label */
64 char* CountSym; /* Name of symbol for entry count */
65 unsigned char Order; /* Table order (increasing/decreasing) */
68 /* Array for all types */
69 static ConDesDesc ConDes[CD_TYPE_COUNT] = {
70 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
71 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
72 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
73 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
74 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
75 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
76 { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
81 /*****************************************************************************/
82 /* Internally used function to create the condes tables */
83 /*****************************************************************************/
87 static int ConDesCompare (void* Data, const void* E1, const void* E2)
88 /* Compare function to sort the exports */
92 /* Data is actually a pointer to a ConDesDesc from the table, E1 and
93 * E2 are exports from the collection. Get the condes type and cast
94 * the void pointers to object pointers.
96 ConDesDesc* CD = ((ConDesDesc*) Data);
97 int Type = CD - ConDes;
98 const Export* Exp1 = (const Export*) E1;
99 const Export* Exp2 = (const Export*) E2;
101 /* Get the priorities of the two exports */
102 unsigned Prio1 = Exp1->ConDes[Type];
103 unsigned Prio2 = Exp2->ConDes[Type];
105 /* Compare the priorities for this condes type */
108 } else if (Prio1 > Prio2) {
111 /* Use the name in this case */
112 Cmp = strcmp (Exp1->Name, Exp2->Name);
115 /* Reverse the result for decreasing order */
116 if (CD->Order == cdIncreasing) {
125 static void ConDesCreateOne (ConDesDesc* CD)
126 /* Create one table if requested */
128 Segment* Seg; /* Segment for table */
129 Section* Sec; /* Section for table */
130 unsigned Count; /* Number of exports */
133 /* Check if this table has a segment and table label defined. If not,
134 * creation was not requested in the config file - ignore it.
136 if (CD->SegName == 0 || CD->Label == 0) {
140 /* Check if there is an import for the table label. If not, there is no
141 * reference to the table and we would just waste memory creating the
144 if (!IsUnresolved (CD->Label)) {
148 /* Sort the collection of exports according to priority */
149 CollSort (&CD->ExpList, ConDesCompare, CD);
151 /* Get the segment for the table, create it if needed */
152 Seg = GetSegment (CD->SegName, SEGTYPE_ABS, 0);
154 /* Create a new section for the table */
155 Sec = NewSection (Seg, 1, SEGTYPE_ABS);
157 /* Walk over the exports and create a fragment for each one. We will use
158 * the exported expression without copying it, since it's cheap and there
159 * is currently no place where it gets changed (hope this will not hunt
162 Count = CollCount (&CD->ExpList);
163 for (I = 0; I < Count; ++I) {
166 Export* E = CollAt (&CD->ExpList, I);
168 /* Create the fragment */
169 Fragment* F = NewFragment (FRAG_EXPR, 2, Sec);
171 /* Set the expression pointer */
175 /* Define the table start as an export, offset into section is zero
176 * (the section only contains the table).
178 CreateSegExport (CD->Label, Sec, 0);
180 /* If we have a CountSym name given AND if it is referenced, define it
181 * with the number of elements in the table.
184 CreateConstExport (CD->CountSym, Count);
190 /*****************************************************************************/
192 /*****************************************************************************/
196 void ConDesAddExport (struct Export* E)
197 /* Add the given export to the list of constructors/destructor */
201 /* Insert the export into all tables for which declarations exist */
202 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
203 unsigned Prio = E->ConDes[Type];
204 if (Prio != CD_PRIO_NONE) {
205 CollAppend (&ConDes[Type].ExpList, E);
212 void ConDesSetSegName (unsigned Type, const char* SegName)
213 /* Set the segment name where the table should go */
215 /* Check the parameters */
216 PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && SegName != 0);
218 /* Setting the segment name twice is bad */
219 CHECK (ConDes[Type].SegName == 0);
222 ConDes[Type].SegName = xstrdup (SegName);
227 void ConDesSetLabel (unsigned Type, const char* Name)
228 /* Set the label for the given ConDes type */
230 /* Check the parameters */
231 PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && Name != 0);
233 /* Setting the label twice is bad */
234 CHECK (ConDes[Type].Label == 0);
237 ConDes[Type].Label = xstrdup (Name);
242 void ConDesSetCountSym (unsigned Type, const char* Name)
243 /* Set the name for the given ConDes count symbol */
245 /* Check the parameters */
246 PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && Name != 0);
248 /* Setting the symbol twice is bad */
249 CHECK (ConDes[Type].CountSym == 0);
252 ConDes[Type].CountSym = xstrdup (Name);
257 void ConDesSetOrder (unsigned Type, ConDesOrder Order)
258 /* Set the sorting oder for the given ConDes table */
260 /* Check the parameters */
261 PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
264 ConDes[Type].Order = Order;
269 int ConDesHasSegName (unsigned Type)
270 /* Return true if a segment name is already defined for this ConDes type */
272 /* Check the parameters */
273 PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
275 return (ConDes[Type].SegName != 0);
280 int ConDesHasLabel (unsigned Type)
281 /* Return true if a label is already defined for this ConDes type */
283 /* Check the parameters */
284 PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
286 return (ConDes[Type].Label != 0);
291 void ConDesCreate (void)
292 /* Create the condes tables if requested */
296 /* Walk over the descriptor array and create a table for each entry */
297 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
298 ConDesCreateOne (ConDes + Type);
304 void ConDesDump (void)
305 /* Dump ConDes data to stdout for debugging */
308 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
309 Collection* ExpList = &ConDes[Type].ExpList;
310 printf ("CONDES(%u): %u symbols\n", Type, CollCount (ExpList));