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
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <errno.h>
0043 #include <fcntl.h>
0044 #include <inttypes.h>
0045 #include <stdlib.h>
0046 #include <string.h>
0047 #include <stdio.h>
0048 #include <unistd.h>
0049
0050 #include <rtems/rtl/rtl.h>
0051 #include "rtl-elf.h"
0052 #include "rtl-error.h"
0053 #include <rtems/rtl/rtl-obj-comp.h>
0054 #include "rtl-rap.h"
0055 #include <rtems/rtl/rtl-trace.h>
0056 #include <rtems/rtl/rtl-unresolved.h>
0057
0058
0059
0060
0061 #define REL_R_OFFSET (0)
0062 #define REL_R_INFO (1)
0063 #define REL_R_ADDEND (2)
0064
0065
0066
0067
0068 static rtems_rtl_loader_format rap_sig =
0069 {
0070 .label = "RAP",
0071 .flags = RTEMS_RTL_FMT_COMP
0072 };
0073
0074
0075
0076
0077 typedef struct rtems_rtl_rap_sectdef
0078 {
0079 const char* name;
0080 const uint32_t flags;
0081 } rtems_rtl_rap_sectdef;
0082
0083
0084
0085
0086 #define RTEMS_RTL_RAP_TEXT_SEC (0)
0087 #define RTEMS_RTL_RAP_CONST_SEC (1)
0088 #define RTEMS_RTL_RAP_CTOR_SEC (2)
0089 #define RTEMS_RTL_RAP_DTOR_SEC (3)
0090 #define RTEMS_RTL_RAP_DATA_SEC (4)
0091 #define RTEMS_RTL_RAP_BSS_SEC (5)
0092 #define RTEMS_RTL_RAP_SECS (6)
0093
0094
0095
0096
0097 static const rtems_rtl_rap_sectdef rap_sections[RTEMS_RTL_RAP_SECS] =
0098 {
0099 { ".text", RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_LOAD },
0100 { ".const", RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD },
0101 { ".ctor", RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_CTOR },
0102 { ".dtor", RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_DTOR },
0103 { ".data", RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_LOAD },
0104 { ".bss", RTEMS_RTL_OBJ_SECT_BSS | RTEMS_RTL_OBJ_SECT_ZERO }
0105 };
0106
0107
0108
0109
0110 typedef struct rtems_rtl_rap_section
0111 {
0112 uint32_t size;
0113 uint32_t alignment;
0114 } rtems_rtl_rap_section;
0115
0116
0117
0118
0119 typedef struct rtems_rtl_rap
0120 {
0121 rtems_rtl_obj_cache* file;
0122 rtems_rtl_obj_comp* decomp;
0123 uint32_t length;
0124 uint32_t version;
0125 uint32_t compression;
0126 uint32_t checksum;
0127 uint32_t machinetype;
0128 uint32_t datatype;
0129 uint32_t class;
0130 uint32_t init;
0131 uint32_t fini;
0132 rtems_rtl_rap_section secs[RTEMS_RTL_RAP_SECS];
0133 uint32_t symtab_size;
0134 char* strtab;
0135 uint32_t strtab_size;
0136 uint32_t relocs_size;
0137 uint32_t symbols;
0138 uint32_t strtable_size;
0139 uint32_t rpathlen;
0140 char* strtable;
0141 } rtems_rtl_rap;
0142
0143
0144
0145
0146 static bool
0147 rtems_rtl_rap_machine_check (uint32_t machinetype)
0148 {
0149
0150
0151
0152 switch (machinetype)
0153 {
0154 ELFDEFNNAME (MACHDEP_ID_CASES)
0155 default:
0156 return false;
0157 }
0158 return true;
0159 }
0160
0161
0162
0163
0164 static bool
0165 rtems_rtl_rap_datatype_check (uint32_t datatype)
0166 {
0167
0168
0169
0170 if (datatype != ELFDEFNNAME (MACHDEP_ENDIANNESS))
0171 return false;
0172 return true;
0173 }
0174
0175
0176
0177
0178 static bool
0179 rtems_rtl_rap_class_check (uint32_t class)
0180 {
0181
0182
0183
0184 switch (class)
0185 {
0186 case ELFCLASS32:
0187 if (ARCH_ELFSIZE == 32)
0188 return true;
0189 break;
0190 case ELFCLASS64:
0191 if (ARCH_ELFSIZE == 64)
0192 return true;
0193 break;
0194 default:
0195 break;
0196 }
0197 return false;
0198 }
0199
0200 static uint32_t
0201 rtems_rtl_rap_get_uint32 (const uint8_t* buffer)
0202 {
0203 uint32_t value = 0;
0204 int b;
0205 for (b = 0; b < sizeof (uint32_t); ++b)
0206 {
0207 value <<= 8;
0208 value |= buffer[b];
0209 }
0210 return value;
0211 }
0212
0213 static bool
0214 rtems_rtl_rap_read_uint32 (rtems_rtl_obj_comp* comp, uint32_t* value)
0215 {
0216 uint8_t buffer[sizeof (uint32_t)];
0217
0218 if (!rtems_rtl_obj_comp_read (comp, buffer, sizeof (uint32_t)))
0219 return false;
0220
0221 *value = rtems_rtl_rap_get_uint32 (buffer);
0222
0223 return true;
0224 }
0225
0226 static bool
0227 rtems_rtl_rap_loader (rtems_rtl_obj* obj,
0228 int fd,
0229 rtems_rtl_obj_sect* sect,
0230 void* data)
0231 {
0232 rtems_rtl_rap* rap = (rtems_rtl_rap*) data;
0233
0234 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0235 printf ("rtl: rap: input %s=%" PRIu32 "\n",
0236 sect->name, rtems_rtl_obj_comp_input (rap->decomp));
0237
0238 return rtems_rtl_obj_comp_read (rap->decomp, sect->base, sect->size);
0239 }
0240
0241 static bool
0242 rtems_rtl_rap_relocate (rtems_rtl_rap* rap, rtems_rtl_obj* obj)
0243 {
0244 #define SYMNAME_BUFFER_SIZE (1024)
0245 char* symname_buffer = NULL;
0246 int section;
0247
0248 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0249 printf ("rtl: relocation\n");
0250
0251 symname_buffer = malloc (SYMNAME_BUFFER_SIZE);
0252 if (!symname_buffer)
0253 {
0254 rtems_rtl_set_error (ENOMEM, "no memory for local symbol name buffer");
0255 return false;
0256 }
0257
0258 for (section = 0; section < RTEMS_RTL_RAP_SECS; ++section)
0259 {
0260 rtems_rtl_obj_sect* targetsect;
0261 uint32_t header = 0;
0262 int relocs;
0263 bool is_rela;
0264 int r;
0265
0266 targetsect = rtems_rtl_obj_find_section (obj, rap_sections[section].name);
0267
0268 if (!targetsect)
0269 continue;
0270
0271 if (!rtems_rtl_rap_read_uint32 (rap->decomp, &header))
0272 {
0273 free (symname_buffer);
0274 return false;
0275 }
0276
0277
0278
0279
0280
0281
0282 is_rela = (header & (1 << 31)) != 0 ? true : false;
0283 relocs = header & ~(1 << 31);
0284
0285 if (relocs && rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0286 printf ("rtl: relocation: %s: header: %08" PRIx32 " relocs: %d %s\n",
0287 rap_sections[section].name,
0288 header, relocs, is_rela ? "rela" : "rel");
0289
0290 for (r = 0; r < relocs; ++r)
0291 {
0292 uint32_t info = 0;
0293 uint32_t offset = 0;
0294 uint32_t addend = 0;
0295 Elf_Word type;
0296 const char* symname = NULL;
0297 uint32_t symname_size;
0298 Elf_Word symtype = 0;
0299 Elf_Word symvalue = 0;
0300
0301 if (!rtems_rtl_rap_read_uint32 (rap->decomp, &info))
0302 {
0303 free (symname_buffer);
0304 return false;
0305 }
0306
0307 if (!rtems_rtl_rap_read_uint32 (rap->decomp, &offset))
0308 {
0309 free (symname_buffer);
0310 return false;
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325 if (((info & (1 << 31)) == 0) || is_rela)
0326 {
0327 if (!rtems_rtl_rap_read_uint32 (rap->decomp, &addend))
0328 {
0329 free (symname_buffer);
0330 return false;
0331 }
0332 }
0333
0334 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0335 printf (" %2d: info=%08" PRIx32 " offset=%" PRIu32
0336 " addend=%" PRIu32 "\n",
0337 r, info, offset, addend);
0338
0339 type = ELF_R_TYPE(info);
0340
0341 if ((info & (1 << 31)) == 0)
0342 {
0343 rtems_rtl_obj_sect* symsect;
0344
0345 symsect = rtems_rtl_obj_find_section_by_index (obj, info >> 8);
0346 if (!symsect)
0347 {
0348 free (symname_buffer);
0349 rtems_rtl_set_error (EINVAL, "symsect not found: %d", info >> 8);
0350 return false;
0351 }
0352
0353 symvalue = (Elf_Addr)(uintptr_t) symsect->base + addend;
0354 }
0355 else if (rtems_rtl_elf_rel_resolve_sym (type))
0356 {
0357 rtems_rtl_obj_sym* symbol;
0358
0359 symname_size = (info & ~(3 << 30)) >> 8;
0360
0361 if ((info & (1 << 30)) != 0)
0362 {
0363 symname = rap->strtab + symname_size;
0364 }
0365 else
0366 {
0367 if (symname_size > (SYMNAME_BUFFER_SIZE - 1))
0368 {
0369 free (symname_buffer);
0370 rtems_rtl_set_error (EINVAL, "reloc symbol too big");
0371 return false;
0372 }
0373
0374 if (!rtems_rtl_obj_comp_read (rap->decomp, symname_buffer, symname_size))
0375 {
0376 free (symname_buffer);
0377 return false;
0378 }
0379
0380 symname_buffer[symname_size] = '\0';
0381 symname = symname_buffer;
0382 }
0383
0384 symbol = rtems_rtl_symbol_obj_find (obj, symname);
0385
0386 if (!symbol)
0387 {
0388 rtems_rtl_set_error (EINVAL, "global symbol not found: %s", symname);
0389 free (symname_buffer);
0390 return false;
0391 }
0392
0393 symvalue = (Elf_Addr)(uintptr_t) symbol->value;
0394 }
0395
0396 if (is_rela)
0397 {
0398 Elf_Rela rela;
0399
0400 rela.r_offset = offset;
0401 rela.r_info = type;
0402
0403 if ((info & (1 << 31)) == 0)
0404 rela.r_addend = 0;
0405 else rela.r_addend = addend;
0406
0407 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0408 printf (" %2d: rela: type:%-2d off:%" PRIu32 " addend:%d"
0409 " symname=%s symtype=%ju symvalue=0x%08jx\n",
0410 r, (int) type, offset, (int) addend,
0411 symname, (uintmax_t) symtype, (uintmax_t) symvalue);
0412
0413 if (rtems_rtl_elf_relocate_rela (obj,
0414 &rela,
0415 targetsect,
0416 symname,
0417 symtype,
0418 symvalue) == rtems_rtl_elf_rel_failure)
0419 {
0420 free (symname_buffer);
0421 return false;
0422 }
0423 }
0424 else
0425 {
0426 Elf_Rel rel;
0427
0428 rel.r_offset = offset;
0429 rel.r_info = type;
0430
0431 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0432 printf (" %2d: rel: type:%-2d off:%" PRIu32
0433 " symname=%s symtype=%ju symvalue=0x%08jx\n",
0434 r, (int) type, offset,
0435 symname, (uintmax_t) symtype, (uintmax_t) symvalue);
0436
0437 if (rtems_rtl_elf_relocate_rel (obj,
0438 &rel,
0439 targetsect,
0440 symname,
0441 symtype,
0442 symvalue) == rtems_rtl_elf_rel_failure)
0443 {
0444 free (symname_buffer);
0445 return false;
0446 }
0447 }
0448 }
0449 }
0450
0451 free (symname_buffer);
0452
0453 return true;
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463 static bool
0464 rtems_rtl_rap_load_linkmap (rtems_rtl_rap* rap, rtems_rtl_obj* obj)
0465 {
0466 void* detail;
0467 struct link_map* tmp1;
0468 section_detail* tmp2;
0469 uint32_t obj_detail_size;
0470 uint32_t pos = 0;
0471 int i;
0472 int j;
0473
0474 obj_detail_size = sizeof (struct link_map) * obj->obj_num;
0475
0476 for (i = 0; i < obj->obj_num; ++i)
0477 {
0478 obj_detail_size += (obj->sec_num[i] * sizeof (section_detail));
0479 }
0480
0481 detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
0482 obj_detail_size + rap->strtable_size, true);
0483
0484 if (!detail)
0485 {
0486 rap->strtable_size = 0;
0487 rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
0488 return false;
0489 }
0490
0491 rap->strtable = detail + obj_detail_size;
0492
0493
0494
0495
0496 if (!rtems_rtl_obj_comp_read (rap->decomp,
0497 rap->strtable,
0498 rap->strtable_size))
0499 {
0500 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, detail);
0501 return false;
0502 }
0503
0504 obj->linkmap = (struct link_map*) detail;
0505
0506 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
0507 {
0508 if (rap->rpathlen > 0)
0509 printf ("File rpath:\n");
0510 }
0511
0512 while (pos < rap->rpathlen)
0513 {
0514 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
0515 {
0516 printf (" %s\n", rap->strtable + pos);
0517 }
0518 pos = pos + strlen (rap->strtable + pos) + 1;
0519 }
0520
0521 if (rap->rpathlen > 0)
0522 pos = rap->rpathlen;
0523
0524 for (i = 0; i < obj->obj_num; ++i)
0525 {
0526 tmp1 = obj->linkmap + i;
0527 tmp1->name = rap->strtable + pos;
0528 tmp1->sec_num = obj->sec_num[i];
0529 tmp1->rpathlen = rap->rpathlen;
0530 tmp1->rpath = (char*) rap->strtable;
0531 pos += strlen (tmp1->name) + 1;
0532
0533 if (!i)
0534 {
0535 tmp1->l_next = NULL;
0536 tmp1->l_prev = NULL;
0537 }
0538 else
0539 {
0540 (tmp1 - 1)->l_next = tmp1;
0541 tmp1->l_prev = tmp1 - 1;
0542 tmp1->l_next = NULL;
0543 }
0544 }
0545
0546 tmp2 = (section_detail*) (obj->linkmap + obj->obj_num);
0547
0548 for (i = 0; i < obj->obj_num; ++i)
0549 {
0550 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
0551 {
0552 printf ("File %d: %s\n", i, (obj->linkmap + i)->name);
0553 printf ("Section: %d sections\n", (unsigned int) obj->sec_num[i]);
0554 }
0555
0556 obj->linkmap[i].sec_detail = tmp2;
0557
0558 for (j = 0; j < obj->sec_num[i]; ++j)
0559 {
0560 uint32_t name;
0561 uint32_t rap_id;
0562 uint32_t offset;
0563 uint32_t size;
0564
0565 if (!rtems_rtl_rap_read_uint32 (rap->decomp, &name) ||
0566 !rtems_rtl_rap_read_uint32 (rap->decomp, &offset) ||
0567 !rtems_rtl_rap_read_uint32 (rap->decomp, &size))
0568 {
0569 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->linkmap);
0570 obj->linkmap = NULL;
0571 return false;
0572 }
0573
0574 rap_id = offset >> 28;
0575 offset = offset & 0xfffffff;
0576
0577 tmp2->name = rap->strtable + name;
0578 tmp2->offset = offset;
0579 tmp2->rap_id = rap_id;
0580 tmp2->size = size;
0581 pos += strlen (tmp2->name) + 1;
0582
0583 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
0584 {
0585 printf ("name:%16s offset:0x%08x rap_id:%d size:0x%x\n",
0586 tmp2->name, (unsigned int) tmp2->offset,
0587 (unsigned int) tmp2->rap_id, (unsigned int) tmp2->size);
0588 }
0589
0590 tmp2 += 1;
0591 }
0592 }
0593 return true;
0594 }
0595
0596 static bool
0597 rtems_rtl_rap_load_symbols (rtems_rtl_rap* rap, rtems_rtl_obj* obj)
0598 {
0599 rtems_rtl_obj_sym* gsym;
0600 int sym;
0601
0602 obj->global_size =
0603 rap->symbols * sizeof (rtems_rtl_obj_sym) + rap->strtab_size;
0604
0605 obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
0606 obj->global_size, true);
0607 if (!obj->global_table)
0608 {
0609 obj->global_size = 0;
0610 rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
0611 return false;
0612 }
0613
0614 obj->global_syms = rap->symbols;
0615
0616 rap->strtab = (((char*) obj->global_table) +
0617 (rap->symbols * sizeof (rtems_rtl_obj_sym)));
0618
0619 if (!rtems_rtl_obj_comp_read (rap->decomp, rap->strtab, rap->strtab_size))
0620 {
0621 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table);
0622 return false;
0623 }
0624
0625 for (sym = 0, gsym = obj->global_table; sym < rap->symbols; ++sym)
0626 {
0627 rtems_rtl_obj_sect* symsect;
0628 uint32_t data;
0629 uint32_t name;
0630 uint32_t value;
0631
0632 if (!rtems_rtl_rap_read_uint32 (rap->decomp, &data) ||
0633 !rtems_rtl_rap_read_uint32 (rap->decomp, &name) ||
0634 !rtems_rtl_rap_read_uint32 (rap->decomp, &value))
0635 {
0636 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table);
0637 obj->global_table = NULL;
0638 obj->global_syms = 0;
0639 obj->global_size = 0;
0640 return false;
0641 }
0642
0643 if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
0644 printf ("rtl: sym:load: data=0x%08" PRIx32 " name=0x%08" PRIx32
0645 " value=0x%08" PRIx32 "\n",
0646 data, name, value);
0647
0648
0649
0650
0651
0652
0653
0654
0655 if (rtems_rtl_symbol_global_find (rap->strtab + name) &&
0656 (ELF_ST_BIND (data & 0xffff) != STB_WEAK))
0657 {
0658 rtems_rtl_set_error (EINVAL,
0659 "duplicate global symbol: %s", rap->strtab + name);
0660 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table);
0661 obj->global_table = NULL;
0662 obj->global_syms = 0;
0663 obj->global_size = 0;
0664 return false;
0665 }
0666
0667 symsect = rtems_rtl_obj_find_section_by_index (obj, data >> 16);
0668 if (!symsect)
0669 {
0670 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table);
0671 obj->global_table = NULL;
0672 obj->global_syms = 0;
0673 obj->global_size = 0;
0674 rtems_rtl_set_error (EINVAL, "section index not found: %" PRIu32, data >> 16);
0675 return false;
0676 }
0677
0678 rtems_chain_set_off_chain (&gsym->node);
0679 gsym->name = rap->strtab + name;
0680 gsym->value = (uint8_t*) (value + symsect->base);
0681 gsym->data = data & 0xffff;
0682
0683 if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
0684 printf ("rtl: sym:add:%-2d name:%-20s bind:%-2d type:%-2d val:%8p sect:%d\n",
0685 sym, gsym->name,
0686 (int) ELF_ST_BIND (data & 0xffff),
0687 (int) ELF_ST_TYPE (data & 0xffff),
0688 gsym->value, (int) (data >> 16));
0689
0690 ++gsym;
0691 }
0692
0693 if (obj->global_syms)
0694 rtems_rtl_symbol_obj_add (obj);
0695
0696 return true;
0697 }
0698
0699 static bool
0700 rtems_rtl_rap_parse_header (uint8_t* rhdr,
0701 size_t* rhdr_len,
0702 uint32_t* length,
0703 uint32_t* version,
0704 uint32_t* compression,
0705 uint32_t* checksum)
0706 {
0707 char* sptr = (char*) rhdr;
0708 char* eptr;
0709
0710 *rhdr_len = 0;
0711
0712
0713
0714
0715
0716 if ((rhdr[0] != 'R') || (rhdr[1] != 'A') || (rhdr[2] != 'P') || (rhdr[3] != ','))
0717 return false;
0718
0719 sptr = sptr + 4;
0720
0721
0722
0723
0724
0725 *length = strtoul (sptr, &eptr, 10);
0726
0727 if (*eptr != ',')
0728 return false;
0729
0730 sptr = eptr + 1;
0731
0732
0733
0734
0735
0736 *version = strtoul (sptr, &eptr, 10);
0737
0738 if (*eptr != ',')
0739 return false;
0740
0741 sptr = eptr + 1;
0742
0743
0744
0745
0746
0747 if ((sptr[0] == 'N') &&
0748 (sptr[1] == 'O') &&
0749 (sptr[2] == 'N') &&
0750 (sptr[3] == 'E'))
0751 {
0752 *compression = RTEMS_RTL_COMP_NONE;
0753 eptr = sptr + 4;
0754 }
0755 else if ((sptr[0] == 'L') &&
0756 (sptr[1] == 'Z') &&
0757 (sptr[2] == '7') &&
0758 (sptr[3] == '7'))
0759 {
0760 *compression = RTEMS_RTL_COMP_LZ77;
0761 eptr = sptr + 4;
0762 }
0763 else
0764 return false;
0765
0766 if (*eptr != ',')
0767 return false;
0768
0769 sptr = eptr + 1;
0770
0771
0772
0773
0774 *checksum = strtoul (sptr, &eptr, 16);
0775
0776
0777
0778
0779 if (*eptr != '\n')
0780 return false;
0781
0782 *rhdr_len = ((uint8_t*) eptr) - rhdr + 1;
0783
0784 return true;
0785 }
0786
0787 bool
0788 rtems_rtl_rap_file_check (rtems_rtl_obj* obj, int fd)
0789 {
0790 rtems_rtl_obj_cache* header;
0791 uint8_t* rhdr = NULL;
0792 size_t rlen = 64;
0793 uint32_t length = 0;
0794 uint32_t version = 0;
0795 uint32_t compression = 0;
0796 uint32_t checksum = 0;
0797
0798 rtems_rtl_obj_caches (&header, NULL, NULL);
0799
0800 if (!rtems_rtl_obj_cache_read (header, fd, obj->ooffset,
0801 (void**) &rhdr, &rlen))
0802 return false;
0803
0804 if (!rtems_rtl_rap_parse_header (rhdr,
0805 &rlen,
0806 &length,
0807 &version,
0808 &compression,
0809 &checksum))
0810 return false;
0811
0812 return true;
0813 }
0814
0815 bool
0816 rtems_rtl_rap_file_load (rtems_rtl_obj* obj, int fd)
0817 {
0818 rtems_rtl_rap rap = { 0 };
0819 uint8_t* rhdr = NULL;
0820 size_t rlen = 64;
0821 int section;
0822
0823 rtems_rtl_obj_caches (&rap.file, NULL, NULL);
0824
0825 if (!rtems_rtl_obj_cache_read (rap.file, fd, obj->ooffset,
0826 (void**) &rhdr, &rlen))
0827 return false;
0828
0829 if (!rtems_rtl_rap_parse_header (rhdr,
0830 &rlen,
0831 &rap.length,
0832 &rap.version,
0833 &rap.compression,
0834 &rap.checksum))
0835 {
0836 rtems_rtl_set_error (EINVAL, "invalid RAP file format");
0837 return false;
0838 }
0839
0840
0841
0842
0843 rtems_rtl_obj_decompress (&rap.decomp, rap.file, fd, rap.compression,
0844 rlen + obj->ooffset);
0845
0846
0847
0848
0849
0850
0851
0852 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0853 printf ("rtl: rap: input machine=%" PRIu32 "\n",
0854 rtems_rtl_obj_comp_input (rap.decomp));
0855
0856 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.machinetype))
0857 return false;
0858
0859 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0860 printf ("rtl: rap: machinetype=%" PRIu32 "\n", rap.machinetype);
0861
0862 if (!rtems_rtl_rap_machine_check (rap.machinetype))
0863 {
0864 rtems_rtl_set_error (EINVAL, "invalid machinetype");
0865 return false;
0866 }
0867
0868 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.datatype))
0869 return false;
0870
0871 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0872 printf ("rtl: rap: datatype=%" PRIu32 "\n", rap.datatype);
0873
0874 if (!rtems_rtl_rap_datatype_check (rap.datatype))
0875 {
0876 rtems_rtl_set_error (EINVAL, "invalid datatype");
0877 return false;
0878 }
0879
0880 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.class))
0881 return false;
0882
0883 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0884 printf ("rtl: rap: class=%" PRIu32 "\n", rap.class);
0885
0886 if (!rtems_rtl_rap_class_check (rap.class))
0887 {
0888 rtems_rtl_set_error (EINVAL, "invalid class");
0889 return false;
0890 }
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0901 printf ("rtl: rap: input header=%" PRIu32 "\n",
0902 rtems_rtl_obj_comp_input (rap.decomp));
0903
0904 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.init))
0905 return false;
0906
0907 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.fini))
0908 return false;
0909
0910 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.symtab_size))
0911 return false;
0912
0913 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.strtab_size))
0914 return false;
0915
0916 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.relocs_size))
0917 return false;
0918
0919 rap.symbols = rap.symtab_size / (3 * sizeof (uint32_t));
0920
0921 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
0922 printf ("rtl: rap: load: symtab=%" PRIu32 " (%" PRIu32
0923 ") strtab=%" PRIu32 " relocs=%" PRIu32 "\n",
0924 rap.symtab_size, rap.symbols,
0925 rap.strtab_size, rap.relocs_size);
0926
0927
0928
0929
0930 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &obj->obj_num))
0931 return false;
0932
0933 if (obj->obj_num > 0)
0934 {
0935 obj->sec_num = (uint32_t*) malloc (sizeof (uint32_t) * obj->obj_num);
0936
0937 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.rpathlen))
0938 return false;
0939
0940 uint32_t i;
0941 for (i = 0; i < obj->obj_num; ++i)
0942 {
0943 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &(obj->sec_num[i])))
0944 return false;
0945 }
0946
0947 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.strtable_size))
0948 return false;
0949
0950 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
0951 printf ("rtl: rap: details: obj_num=%" PRIu32 "\n", obj->obj_num);
0952
0953 if (!rtems_rtl_rap_load_linkmap (&rap, obj))
0954 return false;
0955 }
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972 for (section = 0; section < RTEMS_RTL_RAP_SECS; ++section)
0973 {
0974 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.secs[section].size))
0975 return false;
0976
0977 if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.secs[section].alignment))
0978 return false;
0979
0980 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
0981 printf ("rtl: rap: %s: size=%" PRIu32 " align=%" PRIu32 "\n",
0982 rap_sections[section].name,
0983 rap.secs[section].size,
0984 rap.secs[section].alignment);
0985
0986 if (!rtems_rtl_obj_add_section (obj,
0987 section,
0988 rap_sections[section].name,
0989 rap.secs[section].size,
0990 0,
0991 rap.secs[section].alignment,
0992 0, 0,
0993 rap_sections[section].flags))
0994 return false;
0995 }
0996
0997
0998
0999
1000
1001
1002 if (!rtems_rtl_obj_alloc_sections (obj, fd, NULL, &rap))
1003 return false;
1004
1005 if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_rap_loader, &rap))
1006 return false;
1007
1008 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
1009 printf ("rtl: rap: input symbols=%" PRIu32 "\n",
1010 rtems_rtl_obj_comp_input (rap.decomp));
1011
1012 if (!rtems_rtl_rap_load_symbols (&rap, obj))
1013 return false;
1014
1015 if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
1016 printf ("rtl: rap: input relocs=%" PRIu32 "\n",
1017 rtems_rtl_obj_comp_input (rap.decomp));
1018
1019 if (!rtems_rtl_rap_relocate (&rap, obj))
1020 return false;
1021
1022 rtems_rtl_obj_synchronize_cache (obj);
1023
1024 return true;
1025 }
1026
1027 bool
1028 rtems_rtl_rap_file_unload (rtems_rtl_obj* obj)
1029 {
1030 (void) obj;
1031 return true;
1032 }
1033
1034 rtems_rtl_loader_format*
1035 rtems_rtl_rap_file_sig (void)
1036 {
1037 return &rap_sig;
1038 }