File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039
0040 #include <errno.h>
0041 #include <inttypes.h>
0042 #include <stdlib.h>
0043 #include <stdio.h>
0044 #include <string.h>
0045
0046 #include <rtems/libio_.h>
0047
0048 #include <rtems/rtl/rtl.h>
0049 #include "rtl-chain-iterator.h"
0050 #include <rtems/rtl/rtl-obj.h>
0051 #include "rtl-error.h"
0052 #include "rtl-find-file.h"
0053 #include "rtl-string.h"
0054 #include <rtems/rtl/rtl-trace.h>
0055
0056 #define RTEMS_RTL_ELF_LOADER 1
0057 #define RTEMS_RTL_RAP_LOADER 1
0058
0059 #if RTEMS_RTL_RAP_LOADER
0060 #include "rtl-rap.h"
0061 #define RTEMS_RTL_RAP_LOADER_COUNT 1
0062 #else
0063 #define RTEMS_RTL_RAP_LOADER_COUNT 0
0064 #endif
0065
0066 #if RTEMS_RTL_ELF_LOADER
0067 #include "rtl-elf.h"
0068 #define RTEMS_RTL_ELF_LOADER_COUNT 1
0069 #else
0070 #define RTEMS_RTL_ELF_LOADER_COUNT 0
0071 #endif
0072
0073
0074
0075
0076 #define RTEMS_RTL_LOADERS (RTEMS_RTL_ELF_LOADER_COUNT + RTEMS_RTL_RAP_LOADER_COUNT)
0077 static const rtems_rtl_loader_table loaders[RTEMS_RTL_LOADERS] =
0078 {
0079 #if RTEMS_RTL_RAP_LOADER
0080 { .check = rtems_rtl_rap_file_check,
0081 .load = rtems_rtl_rap_file_load,
0082 .unload = rtems_rtl_rap_file_unload,
0083 .signature = rtems_rtl_rap_file_sig },
0084 #endif
0085 #if RTEMS_RTL_ELF_LOADER
0086 { .check = rtems_rtl_elf_file_check,
0087 .load = rtems_rtl_elf_file_load,
0088 .unload = rtems_rtl_elf_file_unload,
0089 .signature = rtems_rtl_elf_file_sig },
0090 #endif
0091 };
0092
0093 rtems_rtl_obj*
0094 rtems_rtl_obj_alloc (void)
0095 {
0096 rtems_rtl_obj* obj = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
0097 sizeof (rtems_rtl_obj),
0098 true);
0099 if (obj)
0100 {
0101
0102
0103
0104 rtems_chain_initialize_empty (&obj->sections);
0105 rtems_chain_initialize_empty (&obj->dependents);
0106
0107
0108
0109 obj->format = -1;
0110 }
0111 return obj;
0112 }
0113
0114 static void
0115 rtems_rtl_obj_free_names (rtems_rtl_obj* obj)
0116 {
0117 if (rtems_rtl_obj_oname_valid (obj))
0118 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->oname);
0119 if (rtems_rtl_obj_aname_valid (obj))
0120 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->aname);
0121 if (rtems_rtl_obj_fname_valid (obj))
0122 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->fname);
0123 }
0124
0125 bool
0126 rtems_rtl_obj_free (rtems_rtl_obj* obj)
0127 {
0128 if (obj->users > 0 || ((obj->flags & RTEMS_RTL_OBJ_LOCKED) != 0))
0129 {
0130 rtems_rtl_set_error (EINVAL, "cannot free obj still in use");
0131 return false;
0132 }
0133 if (!rtems_chain_is_node_off_chain (&obj->link))
0134 rtems_chain_extract (&obj->link);
0135 rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
0136 &obj->data_base, &obj->bss_base);
0137 rtems_rtl_obj_erase_sections (obj);
0138 rtems_rtl_obj_erase_dependents (obj);
0139 rtems_rtl_symbol_obj_erase (obj);
0140 rtems_rtl_obj_free_names (obj);
0141 if (obj->sec_num != NULL)
0142 free (obj->sec_num);
0143 if (obj->linkmap != NULL)
0144 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->linkmap);
0145 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj);
0146 return true;
0147 }
0148
0149 typedef struct rtems_rtl_obj_unresolved_data
0150 {
0151 bool has_unresolved;
0152 } rtems_rtl_obj_unresolved_data;
0153
0154 static bool
0155 rtems_rtl_obj_unresolved_dependent (rtems_rtl_obj* obj,
0156 rtems_rtl_obj* dependent,
0157 void* data)
0158 {
0159 rtems_rtl_obj_unresolved_data* ud;
0160 ud = (rtems_rtl_obj_unresolved_data*) data;
0161 if ((dependent->flags & RTEMS_RTL_OBJ_DEP_VISITED) == 0)
0162 {
0163 dependent->flags |= RTEMS_RTL_OBJ_DEP_VISITED;
0164 if ((dependent->flags & RTEMS_RTL_OBJ_UNRESOLVED) != 0)
0165 ud->has_unresolved = true;
0166 else
0167 {
0168 rtems_rtl_obj_iterate_dependents (dependent,
0169 rtems_rtl_obj_unresolved_dependent,
0170 ud);
0171 }
0172 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0173 printf ("rtl: obj: unresolved: dep: %s is %s\n",
0174 dependent->oname, ud->has_unresolved ? "unresolved" : "resolved");
0175 }
0176 return ud->has_unresolved;
0177 }
0178
0179 static bool
0180 rtems_rtl_obj_unresolved_object (rtems_chain_node* node, void* data)
0181 {
0182 rtems_rtl_obj* obj = (rtems_rtl_obj*) node;
0183 rtems_rtl_obj_unresolved_data* ud;
0184 ud = (rtems_rtl_obj_unresolved_data*) data;
0185 ud->has_unresolved = (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED) != 0;
0186 return !ud->has_unresolved;
0187 }
0188
0189 bool
0190 rtems_rtl_obj_unresolved (rtems_rtl_obj* obj)
0191 {
0192 rtems_rtl_obj_unresolved_data ud = {
0193 .has_unresolved = (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED) != 0
0194 };
0195 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0196 printf ("rtl: obj: unresolved: dep: %s is %s\n",
0197 obj->oname, ud.has_unresolved ? "unresolved" : "resolved");
0198 if (!ud.has_unresolved)
0199 {
0200 if ((obj->flags & RTEMS_RTL_OBJ_BASE) != 0)
0201 {
0202 rtems_rtl_data* rtl = rtems_rtl_data_unprotected ();
0203 rtems_rtl_chain_iterate (&rtl->objects,
0204 rtems_rtl_obj_unresolved_object,
0205 &ud);
0206 }
0207 else
0208 {
0209 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_DEP_VISITED, 0);
0210 obj->flags |= RTEMS_RTL_OBJ_DEP_VISITED;
0211 rtems_rtl_obj_iterate_dependents (obj,
0212 rtems_rtl_obj_unresolved_dependent,
0213 &ud);
0214 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_DEP_VISITED, 0);
0215 }
0216 }
0217 return ud.has_unresolved;
0218 }
0219
0220 bool
0221 rtems_rtl_parse_name (const char* name,
0222 const char** aname,
0223 const char** oname,
0224 off_t* ooffset)
0225 {
0226 const char* laname = NULL;
0227 const char* loname = NULL;
0228 const char* colon;
0229 const char* end;
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 end = name + strlen (name);
0240 colon = strrchr (name, ':');
0241 if (colon == NULL || colon < strrchr(name, '/'))
0242 colon = end;
0243
0244 loname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, colon - name + 1, true);
0245 if (!loname)
0246 {
0247 rtems_rtl_set_error (ENOMEM, "no memory for object file name");
0248 return false;
0249 }
0250
0251 memcpy ((void*) loname, name, colon - name);
0252
0253
0254
0255
0256 if (colon != end)
0257 {
0258 const char* at;
0259
0260
0261
0262
0263
0264 laname = loname;
0265 ++colon;
0266
0267
0268
0269
0270
0271 at = strchr (colon, '@');
0272
0273 if (at == NULL)
0274 at = end;
0275
0276
0277 loname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, at - colon + 1, true);
0278 if (!loname)
0279 {
0280 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) laname);
0281 rtems_rtl_set_error (ENOMEM, "no memory for object file name");
0282 return false;
0283 }
0284
0285 memcpy ((void*) loname, colon, at - colon);
0286
0287 if (at != end)
0288 {
0289
0290
0291
0292
0293
0294 *ooffset = strtoul (at + 1, 0, 0);
0295 }
0296 }
0297
0298 *oname = loname;
0299 *aname = laname;
0300 return true;
0301 }
0302
0303 static bool
0304 rtems_rtl_obj_parse_name (rtems_rtl_obj* obj, const char* name)
0305 {
0306 return rtems_rtl_parse_name (name, &(obj->aname), &(obj->oname), &(obj->ooffset));
0307 }
0308
0309
0310
0311
0312 typedef struct
0313 {
0314 uint32_t mask;
0315 size_t size;
0316 } rtems_rtl_obj_sect_summer_data;
0317
0318 static bool
0319 rtems_rtl_obj_sect_summer (rtems_chain_node* node, void* data)
0320 {
0321 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0322 if ((sect->flags & RTEMS_RTL_OBJ_SECT_ARCH_ALLOC) == 0)
0323 {
0324 rtems_rtl_obj_sect_summer_data* summer = data;
0325 if ((sect->flags & summer->mask) == summer->mask)
0326 summer->size =
0327 rtems_rtl_obj_align (summer->size, sect->alignment) + sect->size;
0328 }
0329 return true;
0330 }
0331
0332 static size_t
0333 rtems_rtl_obj_section_size (const rtems_rtl_obj* obj, uint32_t mask)
0334 {
0335 rtems_rtl_obj_sect_summer_data summer;
0336 summer.mask = mask;
0337 summer.size = 0;
0338 rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
0339 rtems_rtl_obj_sect_summer,
0340 &summer);
0341 return summer.size;
0342 }
0343
0344
0345
0346
0347
0348 typedef struct
0349 {
0350 uint32_t mask;
0351 uint32_t alignment;
0352 } rtems_rtl_obj_sect_aligner_data;
0353
0354
0355
0356
0357 static bool
0358 rtems_rtl_obj_sect_aligner (rtems_chain_node* node, void* data)
0359 {
0360 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0361 rtems_rtl_obj_sect_aligner_data* aligner = data;
0362 if ((sect->flags & aligner->mask) == aligner->mask)
0363 {
0364 aligner->alignment = sect->alignment;
0365 return false;
0366 }
0367 return true;
0368 }
0369
0370 static size_t
0371 rtems_rtl_obj_section_alignment (const rtems_rtl_obj* obj, uint32_t mask)
0372 {
0373 rtems_rtl_obj_sect_aligner_data aligner;
0374 aligner.mask = mask;
0375 aligner.alignment = 0;
0376 rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
0377 rtems_rtl_obj_sect_aligner,
0378 &aligner);
0379 return aligner.alignment;
0380 }
0381
0382 static bool
0383 rtems_rtl_obj_section_handler (uint32_t mask,
0384 rtems_rtl_obj* obj,
0385 int fd,
0386 rtems_rtl_obj_sect_handler handler,
0387 void* data)
0388 {
0389 rtems_chain_node* node = rtems_chain_first (&obj->sections);
0390 while (!rtems_chain_is_tail (&obj->sections, node))
0391 {
0392 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0393 if ((sect->flags & mask) != 0)
0394 {
0395 if (!handler (obj, fd, sect, data))
0396 return false;
0397 }
0398 node = rtems_chain_next (node);
0399 }
0400 return true;
0401 }
0402
0403 bool
0404 rtems_rtl_obj_find_file (rtems_rtl_obj* obj, const char* name)
0405 {
0406 const char* pname;
0407 rtems_rtl_data* rtl;
0408
0409
0410
0411
0412
0413
0414
0415 if (!rtems_rtl_obj_parse_name (obj, name))
0416 return false;
0417
0418
0419
0420
0421
0422
0423
0424 if (rtems_rtl_obj_aname_valid (obj))
0425 pname = rtems_rtl_obj_aname (obj);
0426 else
0427 pname = rtems_rtl_obj_oname (obj);
0428
0429 rtl = rtems_rtl_lock ();
0430
0431 if (!rtems_rtl_find_file (pname, rtl->paths, &obj->fname, &obj->fsize))
0432 {
0433 rtems_rtl_set_error (ENOENT, "file not found");
0434 rtems_rtl_unlock ();
0435 return false;
0436 }
0437
0438 rtems_rtl_unlock ();
0439
0440 return true;
0441 }
0442
0443 bool
0444 rtems_rtl_obj_add_section (rtems_rtl_obj* obj,
0445 int section,
0446 const char* name,
0447 size_t size,
0448 off_t offset,
0449 uint32_t alignment,
0450 int link,
0451 int info,
0452 uint32_t flags)
0453 {
0454 if (size > 0)
0455 {
0456 rtems_rtl_obj_sect* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
0457 sizeof (rtems_rtl_obj_sect),
0458 true);
0459 if (!sect)
0460 {
0461 rtems_rtl_set_error (ENOMEM, "adding allocated section");
0462 return false;
0463 }
0464 sect->section = section;
0465 sect->name = rtems_rtl_strdup (name);
0466 sect->size = size;
0467 sect->offset = offset;
0468 sect->alignment = alignment;
0469 sect->link = link;
0470 sect->info = info;
0471 sect->flags = flags;
0472 sect->base = NULL;
0473 rtems_chain_append (&obj->sections, §->node);
0474
0475 if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
0476 printf ("rtl: sect: add: %-2d: %s (%zu) 0x%08" PRIu32 "\n",
0477 section, name, size, flags);
0478 }
0479 return true;
0480 }
0481
0482 void
0483 rtems_rtl_obj_erase_sections (rtems_rtl_obj* obj)
0484 {
0485 rtems_chain_node* node = rtems_chain_first (&obj->sections);
0486 while (!rtems_chain_is_tail (&obj->sections, node))
0487 {
0488 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0489 rtems_chain_node* next_node = rtems_chain_next (node);
0490 rtems_chain_extract (node);
0491 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) sect->name);
0492 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, sect);
0493 node = next_node;
0494 }
0495 }
0496
0497
0498
0499
0500 typedef struct
0501 {
0502 rtems_rtl_obj_sect* sect;
0503 const char* name;
0504 int index;
0505 uint32_t mask;
0506 unsigned int flags;
0507 } rtems_rtl_obj_sect_finder;
0508
0509 static bool
0510 rtems_rtl_obj_sect_match_name (rtems_chain_node* node, void* data)
0511 {
0512 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0513 rtems_rtl_obj_sect_finder* match = data;
0514 if (strcmp (sect->name, match->name) == 0)
0515 {
0516 match->sect = sect;
0517 return false;
0518 }
0519 return true;
0520 }
0521
0522 rtems_rtl_obj_sect*
0523 rtems_rtl_obj_find_section (const rtems_rtl_obj* obj,
0524 const char* name)
0525 {
0526 rtems_rtl_obj_sect_finder match;
0527 match.sect = NULL;
0528 match.name = name;
0529 match.mask = 0;
0530 match.flags = 0;
0531 rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
0532 rtems_rtl_obj_sect_match_name,
0533 &match);
0534 return match.sect;
0535 }
0536
0537 static bool
0538 rtems_rtl_obj_sect_match_index (rtems_chain_node* node, void* data)
0539 {
0540 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0541 rtems_rtl_obj_sect_finder* match = data;
0542 if (sect->section == match->index)
0543 {
0544 match->sect = sect;
0545 return false;
0546 }
0547 return true;
0548 }
0549
0550 rtems_rtl_obj_sect*
0551 rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj* obj,
0552 int index)
0553 {
0554 rtems_rtl_obj_sect_finder match;
0555 match.sect = NULL;
0556 match.index = index;
0557 match.mask = 0;
0558 match.flags = 0;
0559 rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
0560 rtems_rtl_obj_sect_match_index,
0561 &match);
0562 return match.sect;
0563 }
0564
0565 static bool
0566 rtems_rtl_obj_sect_match_mask (rtems_chain_node* node, void* data)
0567 {
0568 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0569 rtems_rtl_obj_sect_finder* match = data;
0570 if (match->flags == 0)
0571 {
0572 if (match->index < 0 || sect->section == match->index)
0573 match->flags = 1;
0574 if (match->index >= 0)
0575 return true;
0576 }
0577 if ((sect->flags & match->mask) != 0)
0578 {
0579 match->sect = sect;
0580 return false;
0581 }
0582 return true;
0583 }
0584
0585 rtems_rtl_obj_sect*
0586 rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
0587 int index,
0588 uint32_t mask)
0589 {
0590 rtems_rtl_obj_sect_finder match;
0591 match.sect = NULL;
0592 match.index = index;
0593 match.mask = mask;
0594 match.flags = 0;
0595 rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
0596 rtems_rtl_obj_sect_match_mask,
0597 &match);
0598 return match.sect;
0599 }
0600
0601 bool
0602 rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
0603 {
0604 rtems_rtl_obj_depends* depends;
0605 size_t size;
0606
0607 size = sizeof (rtems_rtl_obj_depends) + sizeof (rtems_rtl_obj*) * dependents;
0608
0609 depends = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
0610 size,
0611 true);
0612 if (depends == NULL)
0613 {
0614 rtems_rtl_set_error (ENOMEM, "no memory for the dependency");
0615 }
0616 else
0617 {
0618 depends->dependents = dependents;
0619 rtems_chain_append (&obj->dependents, &depends->node);
0620 }
0621
0622 return depends != NULL;
0623 }
0624
0625 void
0626 rtems_rtl_obj_erase_dependents (rtems_rtl_obj* obj)
0627 {
0628 rtems_chain_node* node = rtems_chain_first (&obj->dependents);
0629 while (!rtems_chain_is_tail (&obj->dependents, node))
0630 {
0631 rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
0632 rtems_chain_node* next_node = rtems_chain_next (node);
0633 rtems_chain_extract (node);
0634 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, depends);
0635 node = next_node;
0636 }
0637 }
0638
0639 bool
0640 rtems_rtl_obj_add_dependent (rtems_rtl_obj* obj, rtems_rtl_obj* dependent)
0641 {
0642 rtems_rtl_obj** free_slot;
0643 rtems_chain_node* node;
0644
0645 if (obj == dependent || dependent == rtems_rtl_baseimage ())
0646 return false;
0647
0648 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DEPENDENCY))
0649 printf ("rtl: depend: add: %s -> %s\n", obj->oname, dependent->oname);
0650
0651 free_slot = NULL;
0652
0653 node = rtems_chain_first (&obj->dependents);
0654 while (!rtems_chain_is_tail (&obj->dependents, node))
0655 {
0656 rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
0657 size_t d;
0658 for (d = 0; d < depends->dependents; ++d)
0659 {
0660 if (free_slot == NULL && depends->depends[d] == NULL)
0661 free_slot = &(depends->depends[d]);
0662 if (depends->depends[d] == dependent)
0663 return false;
0664 }
0665 node = rtems_chain_next (node);
0666 }
0667
0668 if (free_slot == NULL)
0669 {
0670 if (rtems_rtl_obj_alloc_dependents (obj,
0671 RTEMS_RTL_DEPENDENCY_BLOCK_SIZE))
0672 {
0673 rtems_rtl_obj_depends* depends;
0674 node = rtems_chain_last (&obj->dependents);
0675 depends = (rtems_rtl_obj_depends*) node;
0676 free_slot = &(depends->depends[0]);
0677 if (*free_slot != NULL)
0678 {
0679 rtems_rtl_set_error (EINVAL, "new dependency node not empty");
0680 free_slot = NULL;
0681 }
0682 }
0683 }
0684
0685 if (free_slot != NULL)
0686 *free_slot = dependent;
0687
0688 return free_slot != NULL;
0689 }
0690
0691
0692 bool
0693 rtems_rtl_obj_remove_dependencies (rtems_rtl_obj* obj)
0694 {
0695
0696
0697
0698 if (obj->refs == 0)
0699 {
0700
0701
0702
0703
0704
0705 rtems_chain_node* node = rtems_chain_first (&obj->dependents);
0706 while (!rtems_chain_is_tail (&obj->dependents, node))
0707 {
0708 rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
0709 size_t d;
0710 for (d = 0; d < depends->dependents; ++d)
0711 {
0712 if (depends->depends[d] != NULL)
0713 {
0714 rtems_rtl_obj_dec_reference (depends->depends[d]);
0715 depends->depends[d] = NULL;
0716 }
0717 }
0718 node = rtems_chain_next (node);
0719 }
0720 return true;
0721 }
0722 return false;
0723 }
0724
0725 bool
0726 rtems_rtl_obj_iterate_dependents (rtems_rtl_obj* obj,
0727 rtems_rtl_obj_depends_iterator iterator,
0728 void* data)
0729 {
0730 rtems_chain_node* node = rtems_chain_first (&obj->dependents);
0731 while (!rtems_chain_is_tail (&obj->dependents, node))
0732 {
0733 rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
0734 size_t d;
0735 for (d = 0; d < depends->dependents; ++d)
0736 {
0737 if (depends->depends[d])
0738 {
0739 if (iterator (obj, depends->depends[d], data))
0740 return true;
0741 }
0742 }
0743 node = rtems_chain_next (node);
0744 }
0745 return false;
0746 }
0747
0748 size_t
0749 rtems_rtl_obj_text_size (const rtems_rtl_obj* obj)
0750 {
0751 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_TEXT;
0752 return rtems_rtl_obj_section_size (obj, flags);
0753 }
0754
0755 uint32_t
0756 rtems_rtl_obj_text_alignment (const rtems_rtl_obj* obj)
0757 {
0758 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_TEXT;
0759 return rtems_rtl_obj_section_alignment (obj, flags);
0760 }
0761
0762 size_t
0763 rtems_rtl_obj_const_size (const rtems_rtl_obj* obj)
0764 {
0765 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_CONST;
0766 return rtems_rtl_obj_section_size (obj, flags);
0767 }
0768
0769 uint32_t
0770 rtems_rtl_obj_const_alignment (const rtems_rtl_obj* obj)
0771 {
0772 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_CONST;
0773 return rtems_rtl_obj_section_alignment (obj, flags);
0774 }
0775
0776 uint32_t
0777 rtems_rtl_obj_eh_alignment (const rtems_rtl_obj* obj)
0778 {
0779 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_EH;
0780 return rtems_rtl_obj_section_alignment (obj, flags);
0781 }
0782
0783 size_t
0784 rtems_rtl_obj_eh_size (const rtems_rtl_obj* obj)
0785 {
0786 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_EH;
0787 return rtems_rtl_obj_section_size (obj, flags);
0788 }
0789
0790 size_t
0791 rtems_rtl_obj_data_size (const rtems_rtl_obj* obj)
0792 {
0793 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_DATA;
0794 return rtems_rtl_obj_section_size (obj, flags);
0795 }
0796
0797 uint32_t
0798 rtems_rtl_obj_data_alignment (const rtems_rtl_obj* obj)
0799 {
0800 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_DATA;
0801 return rtems_rtl_obj_section_alignment (obj, flags);
0802 }
0803
0804 size_t
0805 rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj)
0806 {
0807 return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
0808 }
0809
0810 size_t
0811 rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj)
0812 {
0813 return obj->tramp_slots * obj->tramp_slot_size;
0814 }
0815
0816 uint32_t
0817 rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj)
0818 {
0819 return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_BSS);
0820 }
0821
0822 bool
0823 rtems_rtl_obj_relocate (rtems_rtl_obj* obj,
0824 int fd,
0825 rtems_rtl_obj_sect_handler handler,
0826 void* data)
0827 {
0828 const uint32_t flags = (RTEMS_RTL_OBJ_SECT_LOAD |
0829 RTEMS_RTL_OBJ_SECT_REL |
0830 RTEMS_RTL_OBJ_SECT_RELA);
0831 bool r = rtems_rtl_obj_section_handler (flags, obj, fd, handler, data);
0832 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_RELOC_TAG, 0);
0833 return r;
0834 }
0835
0836
0837
0838
0839 typedef struct
0840 {
0841 uint32_t mask;
0842 void *start_va;
0843 void *end_va;
0844 size_t cache_line_size;
0845 } rtems_rtl_obj_sect_sync_ctx;
0846
0847 static bool
0848 rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
0849 {
0850 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0851 rtems_rtl_obj_sect_sync_ctx* sync_ctx = data;
0852 uintptr_t old_end;
0853 uintptr_t new_start;
0854
0855 if ((sect->flags & sync_ctx->mask) == 0 || sect->size == 0)
0856 return true;
0857
0858 if (sync_ctx->end_va == sync_ctx->start_va)
0859 {
0860 sync_ctx->start_va = sect->base;
0861 }
0862 else
0863 {
0864 old_end = (uintptr_t) sync_ctx->end_va & ~(sync_ctx->cache_line_size - 1);
0865 new_start = (uintptr_t) sect->base & ~(sync_ctx->cache_line_size - 1);
0866 if ((sect->base < sync_ctx->start_va) ||
0867 (new_start - old_end > sync_ctx->cache_line_size))
0868 {
0869 rtems_cache_instruction_sync_after_code_change(sync_ctx->start_va,
0870 sync_ctx->end_va - sync_ctx->start_va + 1);
0871 sync_ctx->start_va = sect->base;
0872 }
0873 }
0874
0875 sync_ctx->end_va = sect->base + sect->size;
0876
0877 return true;
0878 }
0879
0880 void
0881 rtems_rtl_obj_synchronize_cache (rtems_rtl_obj* obj)
0882 {
0883 rtems_rtl_obj_sect_sync_ctx sync_ctx;
0884
0885 if (rtems_cache_get_instruction_line_size() == 0)
0886 return;
0887
0888 sync_ctx.cache_line_size = rtems_cache_get_maximal_line_size();
0889
0890 sync_ctx.mask = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST |
0891 RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_BSS |
0892 RTEMS_RTL_OBJ_SECT_EH | RTEMS_RTL_OBJ_SECT_EXEC;
0893
0894 sync_ctx.start_va = 0;
0895 sync_ctx.end_va = sync_ctx.start_va;
0896 rtems_rtl_chain_iterate (&obj->sections,
0897 rtems_rtl_obj_sect_sync_handler,
0898 &sync_ctx);
0899
0900 if (sync_ctx.end_va != sync_ctx.start_va)
0901 {
0902 size_t size = sync_ctx.end_va - sync_ctx.start_va;
0903 rtems_cache_instruction_sync_after_code_change(sync_ctx.start_va,
0904 size);
0905 }
0906
0907 if (obj->tramp_base != NULL)
0908 {
0909 rtems_cache_instruction_sync_after_code_change(obj->tramp_base,
0910 obj->tramp_size);
0911 }
0912 }
0913
0914 bool
0915 rtems_rtl_obj_load_symbols (rtems_rtl_obj* obj,
0916 int fd,
0917 rtems_rtl_obj_sect_handler handler,
0918 void* data)
0919 {
0920 uint32_t mask = RTEMS_RTL_OBJ_SECT_SYM;
0921 bool ok;
0922 ok = rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
0923 if (ok)
0924 rtems_rtl_symbol_obj_sort (obj);
0925 return ok;
0926 }
0927
0928 static int
0929 rtems_rtl_obj_sections_linked_to_order (rtems_rtl_obj* obj,
0930 int section,
0931 uint32_t visited_mask)
0932 {
0933 rtems_chain_control* sections = &obj->sections;
0934 rtems_chain_node* node = rtems_chain_first (sections);
0935
0936
0937
0938
0939 while (!rtems_chain_is_tail (sections, node))
0940 {
0941 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0942 if (sect->section == section)
0943 {
0944 const uint32_t mask = sect->flags & RTEMS_RTL_OBJ_SECT_TYPES;
0945 int order = 0;
0946 if (sect->link != 0)
0947 {
0948
0949
0950
0951
0952 if ((sect->flags & visited_mask) != 0)
0953 {
0954 rtems_rtl_set_error (errno, "section link loop");
0955 return -1;
0956 }
0957 return rtems_rtl_obj_sections_linked_to_order (obj,
0958 sect->link,
0959 visited_mask | mask);
0960 }
0961 node = rtems_chain_first (sections);
0962 while (!rtems_chain_is_tail (sections, node))
0963 {
0964 sect = (rtems_rtl_obj_sect*) node;
0965 if ((sect->flags & mask) == mask)
0966 {
0967 if (sect->section == section)
0968 return order;
0969 ++order;
0970 }
0971 node = rtems_chain_next (node);
0972 }
0973 }
0974 node = rtems_chain_next (node);
0975 }
0976 rtems_rtl_set_error (errno, "section link not found");
0977 return -1;
0978 }
0979
0980 static void
0981 rtems_rtl_obj_sections_link_order (uint32_t mask, rtems_rtl_obj* obj)
0982 {
0983 rtems_chain_control* sections = &obj->sections;
0984 rtems_chain_node* node = rtems_chain_first (sections);
0985 int order = 0;
0986 while (!rtems_chain_is_tail (sections, node))
0987 {
0988 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
0989 if ((sect->flags & mask) == mask)
0990 {
0991
0992
0993
0994
0995 if (sect->link == 0)
0996 sect->load_order = order++;
0997 else
0998 {
0999 sect->load_order =
1000 rtems_rtl_obj_sections_linked_to_order (obj,
1001 sect->link,
1002 mask);
1003 }
1004 }
1005 node = rtems_chain_next (node);
1006 }
1007 }
1008
1009 static void
1010 rtems_rtl_obj_sections_locate (uint32_t mask,
1011 rtems_rtl_alloc_tag tag,
1012 rtems_rtl_obj* obj,
1013 uint8_t* base)
1014 {
1015 rtems_chain_control* sections = &obj->sections;
1016 rtems_chain_node* node = rtems_chain_first (sections);
1017 size_t base_offset = 0;
1018 int order = 0;
1019
1020 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
1021 printf ("rtl: locating section: mask:%08" PRIx32 " base:%p\n", mask, base);
1022
1023 while (!rtems_chain_is_tail (sections, node))
1024 {
1025 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
1026
1027 if ((sect->size != 0) && ((sect->flags & mask) == mask))
1028 {
1029 if (sect->load_order == order)
1030 {
1031 if ((sect->flags & RTEMS_RTL_OBJ_SECT_ARCH_ALLOC) == 0)
1032 {
1033 base_offset = rtems_rtl_obj_align (base_offset, sect->alignment);
1034 sect->base = base + base_offset;
1035 base_offset += sect->size;
1036 }
1037
1038 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
1039 printf ("rtl: locating:%2d: %s -> %p (s:%zi f:%04" PRIx32
1040 " a:%" PRIu32 " l:%02d)\n",
1041 order, sect->name, sect->base, sect->size,
1042 sect->flags, sect->alignment, sect->link);
1043
1044 ++order;
1045
1046 node = rtems_chain_first (sections);
1047 continue;
1048 }
1049 }
1050
1051 node = rtems_chain_next (node);
1052 }
1053 }
1054
1055 static void
1056 rtems_rtl_obj_set_sizes (rtems_rtl_obj* obj)
1057 {
1058 size_t text_size;
1059 size_t tramp_size;
1060 size_t const_size;
1061 size_t eh_size;
1062 size_t data_size;
1063 size_t bss_size;
1064
1065
1066
1067
1068
1069 text_size = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_text_alignment (obj);
1070 tramp_size = rtems_rtl_obj_tramp_size (obj);
1071 if (tramp_size != 0)
1072 tramp_size += rtems_rtl_obj_tramp_alignment (obj);
1073 const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_const_alignment (obj);
1074 eh_size = rtems_rtl_obj_eh_size (obj) + rtems_rtl_obj_eh_alignment (obj);
1075 data_size = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_data_alignment (obj);
1076 bss_size = rtems_rtl_obj_bss_size (obj) + rtems_rtl_obj_bss_alignment (obj);
1077
1078
1079
1080
1081 obj->text_size = text_size + tramp_size;
1082 obj->tramp_size = tramp_size;
1083 obj->const_size = const_size;
1084 obj->data_size = data_size;
1085 obj->eh_size = eh_size;
1086 obj->bss_size = bss_size;
1087
1088 obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
1089 }
1090
1091 static void
1092 rtems_rtl_obj_print_sizes (rtems_rtl_obj* obj, const char* label)
1093 {
1094 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
1095 {
1096 printf ("rtl: %s sect: text - b:%p s:%zi a:%" PRIu32 "\n",
1097 label, obj->text_base, obj->text_size, rtems_rtl_obj_text_alignment (obj));
1098 printf ("rtl: %s sect: tramp - b:%p s:%zi a:%" PRIu32 "\n",
1099 label, obj->tramp_base, obj->tramp_size, rtems_rtl_obj_tramp_alignment (obj));
1100 printf ("rtl: %s sect: const - b:%p s:%zi a:%" PRIu32 "\n",
1101 label, obj->const_base, obj->const_size, rtems_rtl_obj_const_alignment (obj));
1102 printf ("rtl: %s sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
1103 label, obj->eh_base, obj->eh_size, rtems_rtl_obj_eh_alignment (obj));
1104 printf ("rtl: %s sect: data - b:%p s:%zi a:%" PRIu32 "\n",
1105 label, obj->data_base, obj->data_size, rtems_rtl_obj_data_alignment (obj));
1106 printf ("rtl: %s sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
1107 label, obj->bss_base, obj->bss_size, rtems_rtl_obj_bss_alignment (obj));
1108 }
1109 }
1110
1111 static void
1112 rtems_rtl_obj_locate (rtems_rtl_obj* obj)
1113 {
1114
1115
1116
1117
1118 rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_TEXT,
1119 rtems_rtl_alloc_text_tag (),
1120 obj, obj->text_base);
1121 rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_CONST,
1122 rtems_rtl_alloc_const_tag (),
1123 obj, obj->const_base);
1124 rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_EH,
1125 rtems_rtl_alloc_eh_tag (),
1126 obj, obj->eh_base);
1127 rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_DATA,
1128 rtems_rtl_alloc_data_tag (),
1129 obj, obj->data_base);
1130 rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
1131 rtems_rtl_alloc_bss_tag (),
1132 obj, obj->bss_base);
1133 }
1134
1135 bool
1136 rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
1137 int fd,
1138 rtems_rtl_obj_sect_handler handler,
1139 void* data)
1140 {
1141 rtems_rtl_obj_set_sizes (obj);
1142
1143
1144
1145
1146 if (handler != NULL)
1147 {
1148 if (!rtems_rtl_obj_section_handler (RTEMS_RTL_OBJ_SECT_TYPES,
1149 obj,
1150 fd,
1151 handler,
1152 data))
1153 {
1154 obj->exec_size = 0;
1155 return false;
1156 }
1157 }
1158
1159
1160
1161
1162
1163 if (!rtems_rtl_alloc_module_new (&obj->text_base, obj->text_size,
1164 &obj->const_base, obj->const_size,
1165 &obj->eh_base, obj->eh_size,
1166 &obj->data_base, obj->data_size,
1167 &obj->bss_base, obj->bss_size))
1168 {
1169 obj->exec_size = 0;
1170 rtems_rtl_set_error (ENOMEM, "no memory to load obj");
1171 return false;
1172 }
1173
1174
1175
1176
1177 if (obj->tramp_size != 0)
1178 {
1179 obj->tramp_base = obj->tramp_brk =
1180 obj->text_base + obj->text_size - obj->tramp_size;
1181 }
1182
1183 rtems_rtl_obj_print_sizes (obj, "alloc");
1184
1185
1186
1187
1188 rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_TEXT, obj);
1189 rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_CONST, obj);
1190 rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_EH, obj);
1191 rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_DATA, obj);
1192 rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_BSS, obj);
1193
1194
1195
1196
1197 rtems_rtl_obj_locate (obj);
1198
1199 return true;
1200 }
1201
1202 bool
1203 rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj)
1204 {
1205 rtems_rtl_obj_set_sizes (obj);
1206
1207
1208
1209
1210 if (!rtems_rtl_alloc_module_resize (&obj->text_base, obj->text_size,
1211 &obj->const_base, obj->const_size,
1212 &obj->eh_base, obj->eh_size,
1213 &obj->data_base, obj->data_size,
1214 &obj->bss_base, obj->bss_size))
1215 {
1216 rtems_rtl_obj_free (obj);
1217 obj->exec_size = 0;
1218 rtems_rtl_set_error (ENOMEM, "no memory resize obj");
1219 return false;
1220 }
1221
1222
1223
1224
1225 if (obj->tramp_size != 0)
1226 {
1227 obj->tramp_base = obj->tramp_brk =
1228 obj->text_base + obj->text_size - obj->tramp_size;
1229 }
1230
1231 rtems_rtl_obj_print_sizes (obj, "resize");
1232
1233
1234
1235
1236 rtems_rtl_obj_locate (obj);
1237
1238 return true;
1239 }
1240
1241 static bool
1242 rtems_rtl_obj_sections_loader (uint32_t mask,
1243 rtems_rtl_alloc_tag tag,
1244 rtems_rtl_obj* obj,
1245 int fd,
1246 uint8_t* base,
1247 rtems_rtl_obj_sect_handler handler,
1248 void* data)
1249 {
1250 rtems_chain_control* sections = &obj->sections;
1251 rtems_chain_node* node = rtems_chain_first (sections);
1252 int order = 0;
1253
1254 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
1255 printf ("rtl: loading section: mask:%08" PRIx32 " base:%p\n", mask, base);
1256
1257 rtems_rtl_alloc_wr_enable (tag, base);
1258
1259 while (!rtems_chain_is_tail (sections, node))
1260 {
1261 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
1262
1263 if ((sect->size != 0) && ((sect->flags & mask) == mask))
1264 {
1265 if (sect->load_order == order)
1266 {
1267 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
1268 printf ("rtl: loading:%2d: %s -> %p (s:%zi f:%04" PRIx32
1269 " a:%" PRIu32 " l:%02d)\n",
1270 order, sect->name, sect->base, sect->size,
1271 sect->flags, sect->alignment, sect->link);
1272
1273 if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
1274 {
1275 if (!handler (obj, fd, sect, data))
1276 {
1277 sect->base = 0;
1278 rtems_rtl_alloc_wr_disable (tag, base);
1279 return false;
1280 }
1281 }
1282 else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
1283 {
1284 memset (sect->base, 0, sect->size);
1285 }
1286 else
1287 {
1288
1289
1290
1291 sect->base = 0;
1292 }
1293
1294 ++order;
1295
1296 node = rtems_chain_first (sections);
1297 continue;
1298 }
1299 }
1300
1301 node = rtems_chain_next (node);
1302 }
1303
1304 rtems_rtl_alloc_wr_disable (tag, base);
1305
1306 return true;
1307 }
1308
1309 bool
1310 rtems_rtl_obj_load_sections (rtems_rtl_obj* obj,
1311 int fd,
1312 rtems_rtl_obj_sect_handler handler,
1313 void* data)
1314 {
1315
1316
1317
1318
1319
1320 if (!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_TEXT,
1321 rtems_rtl_alloc_text_tag (),
1322 obj, fd, obj->text_base, handler, data) ||
1323 !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST,
1324 rtems_rtl_alloc_const_tag (),
1325 obj, fd, obj->const_base, handler, data) ||
1326 !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_EH,
1327 rtems_rtl_alloc_eh_tag (),
1328 obj, fd, obj->eh_base, handler, data) ||
1329 !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA,
1330 rtems_rtl_alloc_data_tag (),
1331 obj, fd, obj->data_base, handler, data) ||
1332 !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS,
1333 rtems_rtl_alloc_bss_tag (),
1334 obj, fd, obj->bss_base, handler, data))
1335 {
1336 rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
1337 &obj->data_base, &obj->bss_base);
1338 obj->exec_size = 0;
1339 return false;
1340 }
1341
1342 return true;
1343 }
1344
1345 static void
1346 rtems_rtl_obj_run_cdtors (rtems_rtl_obj* obj, uint32_t mask)
1347 {
1348 rtems_chain_node* node = rtems_chain_first (&obj->sections);
1349 while (!rtems_chain_is_tail (&obj->sections, node))
1350 {
1351 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
1352 if ((sect->flags & mask) == mask)
1353 {
1354 rtems_rtl_cdtor* handler;
1355 size_t handlers = sect->size / sizeof (rtems_rtl_cdtor);
1356 int c;
1357 for (c = 0, handler = sect->base; c < handlers; ++c)
1358 if (*handler)
1359 (*handler) ();
1360 }
1361 node = rtems_chain_next (node);
1362 }
1363 }
1364
1365 static bool
1366 rtems_rtl_obj_cdtors_to_run (rtems_rtl_obj* obj, uint32_t mask)
1367 {
1368 rtems_chain_node* node = rtems_chain_first (&obj->sections);
1369 while (!rtems_chain_is_tail (&obj->sections, node))
1370 {
1371 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
1372 if ((sect->flags & mask) == mask)
1373 return true;
1374 node = rtems_chain_next (node);
1375 }
1376 return false;
1377 }
1378
1379 bool
1380 rtems_rtl_obj_ctors_to_run (rtems_rtl_obj* obj)
1381 {
1382 return rtems_rtl_obj_cdtors_to_run (obj, RTEMS_RTL_OBJ_SECT_CTOR);
1383 }
1384
1385 void
1386 rtems_rtl_obj_run_ctors (rtems_rtl_obj* obj)
1387 {
1388 rtems_rtl_obj_run_cdtors (obj, RTEMS_RTL_OBJ_SECT_CTOR);
1389 }
1390
1391 bool
1392 rtems_rtl_obj_dtors_to_run (rtems_rtl_obj* obj)
1393 {
1394 return rtems_rtl_obj_cdtors_to_run (obj, RTEMS_RTL_OBJ_SECT_DTOR);
1395 }
1396
1397 void
1398 rtems_rtl_obj_run_dtors (rtems_rtl_obj* obj)
1399 {
1400 rtems_rtl_obj_run_cdtors (obj, RTEMS_RTL_OBJ_SECT_DTOR);
1401 }
1402
1403 static bool
1404 rtems_rtl_obj_file_load (rtems_rtl_obj* obj, int fd)
1405 {
1406 int l;
1407
1408 for (l = 0; l < (sizeof (loaders) / sizeof (rtems_rtl_loader_table)); ++l)
1409 {
1410 if (loaders[l].check (obj, fd))
1411 {
1412 obj->format = l;
1413 return loaders[l].load (obj, fd);
1414 }
1415 }
1416
1417 rtems_rtl_set_error (ENOENT, "no format loader found");
1418 return false;
1419 }
1420
1421 static void
1422 rtems_rtl_obj_set_error (int num, const char* text)
1423 {
1424 rtems_rtl_set_error (num, text);
1425 }
1426
1427 size_t
1428 rtems_rtl_obj_get_reference (rtems_rtl_obj* obj)
1429 {
1430 return obj->refs;
1431 }
1432
1433 void
1434 rtems_rtl_obj_inc_reference (rtems_rtl_obj* obj)
1435 {
1436 ++obj->refs;
1437 }
1438
1439 void
1440 rtems_rtl_obj_dec_reference (rtems_rtl_obj* obj)
1441 {
1442 if (obj->refs)
1443 --obj->refs;
1444 }
1445
1446 bool
1447 rtems_rtl_obj_orphaned (rtems_rtl_obj* obj)
1448 {
1449 return ((obj->flags & RTEMS_RTL_OBJ_LOCKED) == 0 &&
1450 obj->users == 0 &&
1451 rtems_rtl_obj_get_reference (obj) == 0);
1452 }
1453
1454 bool
1455 rtems_rtl_obj_load (rtems_rtl_obj* obj)
1456 {
1457 int fd;
1458
1459 if (!rtems_rtl_obj_fname_valid (obj))
1460 {
1461 rtems_rtl_set_error (ENOMEM, "invalid object file name path");
1462 return false;
1463 }
1464
1465 fd = open (rtems_rtl_obj_fname (obj), O_RDONLY);
1466 if (fd < 0)
1467 {
1468 rtems_rtl_set_error (errno, "opening for object file");
1469 return false;
1470 }
1471
1472
1473
1474
1475
1476 if (rtems_rtl_obj_aname_valid (obj))
1477 {
1478 off_t enames = 0;
1479 if (!rtems_rtl_obj_archive_find_obj (fd,
1480 obj->fsize,
1481 &obj->oname,
1482 &obj->ooffset,
1483 &obj->fsize,
1484 &enames,
1485 rtems_rtl_obj_set_error))
1486 {
1487 close (fd);
1488 return false;
1489 }
1490 }
1491
1492
1493
1494
1495 if (!rtems_rtl_obj_file_load (obj, fd))
1496 {
1497 close (fd);
1498 return false;
1499 }
1500
1501
1502
1503
1504 if (!_rtld_linkmap_add (obj))
1505 {
1506 close (fd);
1507 return false;
1508 }
1509
1510 close (fd);
1511
1512 return true;
1513 }
1514
1515 bool
1516 rtems_rtl_obj_unload (rtems_rtl_obj* obj)
1517 {
1518 bool ok = false;
1519 if (obj->format >= 0 && obj->format < RTEMS_RTL_LOADERS)
1520 {
1521 _rtld_linkmap_delete(obj);
1522 ok = loaders[obj->format].unload (obj);
1523 }
1524 else
1525 {
1526 rtems_rtl_set_error (EINVAL, "invalid object loader format");
1527 }
1528 return ok;
1529 }