2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Code to dynamically load ELF executables
8 1997/12/13: Changed filename to internalloadseg_elf.c
9 Original file was created by digulla.
14 #include <aros/asmcall.h>
15 #include <aros/debug.h>
16 #include <aros/macros.h>
17 #include <exec/memory.h>
19 #include <dos/dosasl.h>
20 #include <libraries/debug.h>
21 #include <resources/processor.h>
22 #include <proto/dos.h>
23 #include <proto/arossupport.h>
24 #include <proto/debug.h>
25 #include <proto/exec.h>
30 #include "internalloadseg.h"
31 #include "dos_intern.h"
32 #include "include/loadseg.h"
39 } __attribute__((packed
));
41 #define BPTR2HUNK(bptr) ((struct hunk *)((void *)bptr - offsetof(struct hunk, next)))
42 #define HUNK2BPTR(hunk) MKBADDR(&hunk->next)
44 static int elf_read_block
51 struct DosLibrary
*DOSBase
54 if (ilsSeek(file
, offset
, OFFSET_BEGINNING
) < 0)
57 return read_block(file
, buffer
, size
, funcarray
, DOSBase
);
60 static void *load_block
66 struct DosLibrary
*DOSBase
69 D(bug("[ELF Loader] Load Block\n"));
70 D(bug("[ELF Loader] (size=%d)\n",size
));
71 D(bug("[ELF Loader] (funcarray=0x%x)\n",funcarray
));
72 D(bug("[ELF Loader] (funcarray[1]=0x%x)\n",funcarray
[1]));
73 void *block
= ilsAllocMem(size
, MEMF_ANY
);
76 if (!elf_read_block(file
, offset
, block
, size
, funcarray
, DOSBase
))
79 ilsFreeMem(block
, size
);
82 SetIoErr(ERROR_NO_FREE_STORE
);
87 static ULONG
read_shnum(BPTR file
, struct elfheader
*eh
, SIPTR
*funcarray
, struct DosLibrary
*DOSBase
)
89 ULONG shnum
= eh
->shnum
;
91 /* the ELF header only uses 16 bits to store the count of section headers,
92 * so it can't handle more than 65535 headers. if the count is 0, and an
93 * offset is defined, then the real count can be found in the first
94 * section header (which always exists).
96 * similarly, if the string table index is SHN_XINDEX, then the actual
97 * index is found in the first section header also.
99 * see the System V ABI 2001-04-24 draft for more details.
105 if (eh
->shoff
== 0) {
106 D(bug("[ELF Loader] No section header\n"));
107 SetIoErr(ERROR_NOT_EXECUTABLE
);
111 if (elf_read_block(file
, eh
->shoff
, &sh
, sizeof(sh
), funcarray
, DOSBase
))
114 /* wider section header count is in the size field */
117 /* sanity, if they're still invalid then this isn't elf */
119 D(bug("[ELF Loader] Empty section header\n"));
120 SetIoErr(ERROR_NOT_EXECUTABLE
);
127 static int load_header(BPTR file
, struct elfheader
*eh
, SIPTR
*funcarray
, struct DosLibrary
*DOSBase
)
129 if (elf_read_block(file
, 0, eh
, sizeof(struct elfheader
), funcarray
, DOSBase
))
132 if (eh
->ident
[0] != 0x7f || eh
->ident
[1] != 'E' ||
133 eh
->ident
[2] != 'L' || eh
->ident
[3] != 'F') {
134 D(bug("[ELF Loader] Not an ELF object\n"));
135 SetIoErr(ERROR_NOT_EXECUTABLE
);
138 D(bug("[ELF Loader] ELF object\n"));
140 /* WANT_CLASS should be defined for your target */
141 if (eh
->ident
[EI_CLASS
] != AROS_ELF_CLASS
||
142 eh
->ident
[EI_VERSION
] != EV_CURRENT
||
143 eh
->type
!= ET_REL
||
144 eh
->ident
[EI_DATA
] != AROS_ELF_DATA
||
145 eh
->machine
!= AROS_ELF_MACHINE
)
147 D(bug("[ELF Loader] Object is of wrong type\n"));
148 D(bug("[ELF Loader] EI_CLASS is %d - should be %d\n", eh
->ident
[EI_CLASS
] , AROS_ELF_CLASS
));
149 D(bug("[ELF Loader] EI_VERSION is %d - should be %d\n", eh
->ident
[EI_VERSION
], EV_CURRENT
));
150 D(bug("[ELF Loader] type is %d - should be %d\n", eh
->type
, ET_REL
));
151 D(bug("[ELF Loader] EI_DATA is %d - should be %d\n", eh
->ident
[EI_DATA
] , AROS_ELF_DATA
));
152 D(bug("[ELF Loader] machine is %d - should be %d\n", eh
->machine
, AROS_ELF_MACHINE
));
154 SetIoErr(ERROR_NOT_EXECUTABLE
);
164 BPTR
**next_hunk_ptr
,
169 struct DosLibrary
*DOSBase
179 /* The size of the hunk is the size of the section, plus
180 the size of the hunk structure, plus the size of the alignment (if necessary)*/
181 hunk_size
= sh
->size
+ sizeof(struct hunk
);
185 hunk_size
+= sh
->addralign
;
187 /* Also create space for a trampoline, if necessary */
188 if (sh
->flags
& SHF_EXECINSTR
)
189 hunk_size
+= sizeof(struct FullJumpVec
);
193 CONST_STRPTR nameext
;
195 nameext
= strrchr(strtab
+ sh
->name
, '.');
197 if (strcmp(nameext
, ".MEMF_CHIP")==0) {
198 memflags
|= MEMF_CHIP
;
199 } else if (strcmp(nameext
, ".MEMF_LOCAL")==0) {
200 memflags
|= MEMF_LOCAL
;
201 } else if (strcmp(nameext
, ".MEMF_KICK")==0) {
202 memflags
|= MEMF_KICK
;
203 } else if (strcmp(nameext
, ".MEMF_FAST")==0) {
204 memflags
|= MEMF_FAST
;
205 } else if (strcmp(nameext
, ".MEMF_PUBLIC")==0) {
206 memflags
|= MEMF_PUBLIC
;
211 hunk
= ilsAllocMem(hunk_size
, memflags
| MEMF_PUBLIC
| (sh
->type
== SHT_NOBITS
? MEMF_CLEAR
: 0));
215 hunk
->size
= hunk_size
;
217 /* In case we are required to honour alignment, and If this section contains
218 executable code, create a trampoline to its beginning, so that even if the
219 alignment requirements make the actual code go much after the end of the
220 hunk structure, the code can still be reached in the usual way. */
223 if (sh
->flags
& SHF_EXECINSTR
)
225 sh
->addr
= (char *)AROS_ROUNDUP2
227 (IPTR
)hunk
->data
+ sizeof(struct FullJumpVec
), sh
->addralign
229 __AROS_SET_FULLJMP((struct FullJumpVec
*)hunk
->data
, sh
->addr
);
232 sh
->addr
= (char *)AROS_ROUNDUP2((IPTR
)hunk
->data
, sh
->addralign
);
235 sh
->addr
= hunk
->data
;
237 /* Link the previous one with the new one */
238 BPTR2HUNK(*next_hunk_ptr
)->next
= HUNK2BPTR(hunk
);
240 D(bug("[dos] hunk @ %p, size=%08x, addr @ %p\n", hunk
, hunk
->size
, sh
->addr
));
242 /* Update the pointer to the previous one, which is now the current one */
243 *next_hunk_ptr
= &hunk
->next
;
245 if (sh
->type
!= SHT_NOBITS
)
246 return !elf_read_block(file
, sh
->offset
, sh
->addr
, sh
->size
, funcarray
, DOSBase
);
252 SetIoErr(ERROR_NO_FREE_STORE
);
259 struct elfheader
*eh
,
262 struct sheader
*symtab_shndx
,
263 struct DosLibrary
*DOSBase
266 struct sheader
*shrel
= &sh
[shrel_idx
];
267 struct sheader
*shsymtab
= &sh
[SHINDEX(shrel
->link
)];
268 struct sheader
*toreloc
= &sh
[SHINDEX(shrel
->info
)];
270 struct symbol
*symtab
= (struct symbol
*)shsymtab
->addr
;
271 struct relo
*rel
= (struct relo
*)shrel
->addr
;
274 * Ignore relocs if the target section has no allocation. that can happen
275 * eg. with a .debug PROGBITS and a .rel.debug section
277 if (!(toreloc
->flags
& SHF_ALLOC
))
280 ULONG numrel
= shrel
->size
/ shrel
->entsize
;
283 for (i
=0; i
<numrel
; i
++, rel
++)
292 * R_ARM_V4BX are actually special marks for the linker.
293 * They even never have a target (shindex == SHN_UNDEF),
294 * so we simply ignore them before doing any checks.
296 if (ELF_R_TYPE(rel
->info
) == R_ARM_V4BX
)
300 sym
= &symtab
[ELF_R_SYM(rel
->info
)];
301 p
= toreloc
->addr
+ rel
->offset
;
303 if (sym
->shindex
!= SHN_XINDEX
)
304 shindex
= sym
->shindex
;
307 if (symtab_shndx
== NULL
) {
308 D(bug("[ELF Loader] got symbol with shndx 0xfff, but there's no symtab shndx table\n"));
309 SetIoErr(ERROR_BAD_HUNK
);
312 shindex
= ((ULONG
*)symtab_shndx
->addr
)[ELF_R_SYM(rel
->info
)];
315 DB2(bug("[ELF Loader] Processing symbol %s\n", sh
[SHINDEX(shsymtab
->link
)].addr
+ sym
->name
));
321 D(bug("[ELF Loader] COMMON symbol '%s'\n",
322 (STRPTR
)sh
[SHINDEX(shsymtab
->link
)].addr
+ sym
->name
));
323 SetIoErr(ERROR_BAD_HUNK
);
332 if (ELF_R_TYPE(rel
->info
) != 0) {
333 D(bug("[ELF Loader] Undefined symbol '%s'\n",
334 (STRPTR
)sh
[SHINDEX(shsymtab
->link
)].addr
+ sym
->name
));
335 SetIoErr(ERROR_BAD_HUNK
);
341 s
= (IPTR
)sh
[SHINDEX(shindex
)].addr
+ sym
->value
;
344 switch (ELF_R_TYPE(rel
->info
))
346 #if defined(__i386__)
348 case R_386_32
: /* 32bit absolute */
352 case R_386_PC32
: /* 32bit PC relative */
359 #elif defined(__x86_64__)
360 case R_X86_64_64
: /* 64bit direct/absolute */
361 *(UQUAD
*)p
= s
+ rel
->addend
;
364 case R_X86_64_PC32
: /* PC relative 32 bit signed */
365 *(ULONG
*)p
= s
+ rel
->addend
- (IPTR
) p
;
369 *(ULONG
*)p
= (UQUAD
)s
+ (UQUAD
)rel
->addend
;
373 *(LONG
*)p
= (QUAD
)s
+ (QUAD
)rel
->addend
;
376 case R_X86_64_NONE
: /* No reloc */
379 #elif defined(__mc68000__)
382 *p
= s
+ rel
->addend
;
386 *(UWORD
*)p
= s
+ rel
->addend
;
390 *(UBYTE
*)p
= s
+ rel
->addend
;
394 *p
= s
+ rel
->addend
- (ULONG
)p
;
398 *(UWORD
*)p
= s
+ rel
->addend
- (ULONG
)p
;
402 *(UBYTE
*)p
= s
+ rel
->addend
- (ULONG
)p
;
408 #elif defined(__ppc__) || defined(__powerpc__)
411 *p
= s
+ rel
->addend
;
414 case R_PPC_ADDR16_LO
:
416 unsigned short *c
= (unsigned short *) p
;
417 *c
= (s
+ rel
->addend
) & 0xffff;
421 case R_PPC_ADDR16_HA
:
423 unsigned short *c
= (unsigned short *) p
;
424 ULONG temp
= s
+ rel
->addend
;
426 if ((temp
& 0x8000) != 0)
433 unsigned short *c
= (unsigned short *) p
;
434 *c
= (s
+ rel
->addend
- (ULONG
) p
) & 0xffff;
440 unsigned short *c
= (unsigned short *) p
;
441 ULONG temp
= s
+ rel
->addend
- (ULONG
) p
;
443 if ((temp
& 0x8000) != 0)
450 *p
|= (s
+ rel
->addend
- (ULONG
) p
) & 0x3fffffc;
454 *p
= s
+ rel
->addend
- (ULONG
) p
;
460 #elif defined(__arm__)
466 /* On ARM the 24 bit offset is shifted by 2 to the right */
467 signed long offset
= (*p
& 0x00ffffff) << 2;
468 /* If highest bit set, make offset negative */
469 if (offset
& 0x02000000)
470 offset
-= 0x04000000;
472 if (offset
>= 0x02000000 ||
473 offset
<= -0x02000000)
475 bug("[ELF Loader] Relocation type %d %d out of range!\n", i
, ELF_R_TYPE(rel
->info
));
476 SetIoErr(ERROR_BAD_HUNK
);
479 offset
+= s
- (ULONG
)p
;
483 *p
|= offset
& 0x00ffffff;
488 case R_ARM_THM_JUMP24
:
490 ULONG upper
,lower
,sign
,j1
,j2
;
493 upper
= *((UWORD
*)p
);
494 lower
= *((UWORD
*)p
+1);
496 sign
= (upper
>> 10) & 1;
497 j1
= (lower
>> 13) & 1;
498 j2
= (lower
>> 11) & 1;
500 offset
= (sign
<< 24) | ((~(j1
^ sign
) & 1) << 23) |
501 ((~(j2
^ sign
) & 1) << 22) |
502 ((upper
& 0x03ff) << 12) |
503 ((lower
& 0x07ff) << 1);
505 if (offset
& 0x01000000)
506 offset
-= 0x02000000;
508 if (offset
>= 0x01000000 ||
509 offset
<= -0x01000000)
511 bug("[ELF Loader] Relocation type %d %d out of range!\n", i
, ELF_R_TYPE(rel
->info
));
512 SetIoErr(ERROR_BAD_HUNK
);
515 offset
+= s
- (ULONG
)p
;
517 sign
= (offset
>> 24) & 1;
518 j1
= sign
^ (~(offset
>> 23) & 1);
519 j2
= sign
^ (~(offset
>> 22) & 1);
521 *(UWORD
*)p
= (UWORD
)((upper
& 0xf800) | (sign
<< 10) |
522 ((offset
>> 12) & 0x03ff));
523 *((UWORD
*)p
+ 1) = (UWORD
)((lower
& 0xd000) |
524 (j1
<< 13) | (j2
<< 11) | ((offset
>> 1) & 0x07ff));
529 case R_ARM_THM_MOVW_ABS_NC
:
530 case R_ARM_THM_MOVT_ABS
:
535 upper
= *((UWORD
*)p
);
536 lower
= *((UWORD
*)p
+1);
538 offset
= ((upper
& 0x000f) << 12) |
539 ((upper
& 0x0400) << 1) |
540 ((lower
& 0x7000) >> 4) |
543 offset
= (offset
^ 0x8000) - 0x8000;
547 if (ELF_R_TYPE(rel
->info
) == R_ARM_THM_MOVT_ABS
)
550 *(UWORD
*)p
= (UWORD
)((upper
& 0xfbf0) |
551 ((offset
& 0xf000) >> 12) |
552 ((offset
& 0x0800) >> 1));
553 *((UWORD
*)p
+ 1) = (UWORD
)((lower
& 0x8f00) |
554 ((offset
& 0x0700)<< 4) |
559 case R_ARM_MOVW_ABS_NC
:
562 signed long offset
= *p
;
563 offset
= ((offset
& 0xf0000) >> 4) | (offset
& 0xfff);
564 offset
= (offset
^ 0x8000) - 0x8000;
568 if (ELF_R_TYPE(rel
->info
) == R_ARM_MOVT_ABS
)
572 *p
|= ((offset
& 0xf000) << 4) | (offset
& 0x0fff);
576 case R_ARM_TARGET2
: /* maps to R_ARM_ABS32 under EABI for AROS*/
577 case R_ARM_TARGET1
: /* use for constructurs/destructurs, maps to R_ARM_ABS32 */
586 # error Your architecture is not supported
590 D(bug("[ELF Loader] Unrecognized relocation type %d %d\n", i
, ELF_R_TYPE(rel
->info
)));
591 SetIoErr(ERROR_BAD_HUNK
);
602 * On ARM < v6 all LONG accesses must be LONG-aligned
603 * TODO: This is useful and can be moved to some public include file.
605 #if (__ARM_ARCH__ > 5)
607 #define READLONG_UNALIGNED(src) src
611 static inline ULONG
readlong_unaligned(ULONG
*src
)
616 "ldrb %0, [%2, #0]\n\t"
617 "ldrb %1, [%2, #1]\n\t"
618 "orr %0, %0, %1, lsl #8\n\t"
619 "ldrb %1, [%2, #2]\n\t"
620 "orr %0, %0, %1, lsl #16\n\t"
621 "ldrb %1, [%2, #3]\n\t"
622 "orr %0, %0, %1, lsl #24"
623 :"=&r"(res
), "=&r"(tmp
) : "r"(src
)
629 #define READLONG_UNALIGNED(src) readlong_unaligned(&src);
633 * This code parses special .ARM.Attributes section and
634 * extracts system requirements from it. Things like float ABI,
635 * minimum CPU and FPU version are described there.
638 static UBYTE arm_cpus
[] =
648 CPUFAMILY_ARM_6
, /* 6KZ */
649 CPUFAMILY_ARM_6
, /* 6T2 */
650 CPUFAMILY_ARM_6
, /* 6K */
652 CPUFAMILY_ARM_6
, /* 6-M */
653 CPUFAMILY_ARM_6
, /* 6S-M */
654 CPUFAMILY_ARM_7
/* 7E-M */
657 static BOOL
ARM_ParseAttrs(UBYTE
*data
, ULONG len
, struct DosLibrary
*DOSBase
)
659 struct attrs_section
*attrs
;
661 if (data
[0] != ATTR_VERSION_CURRENT
)
663 DATTR(bug("[ELF.ARM] Unknown attributes version: 0x%02\n", data
[0]));
667 attrs
= (void *)data
+ 1;
670 ULONG attrs_size
= READLONG_UNALIGNED(attrs
->size
);
672 if (!strcmp(attrs
->vendor
, "aeabi"))
674 struct attrs_subsection
*aeabi_attrs
= (void *)attrs
->vendor
+ 6;
675 ULONG aeabi_len
= attrs_size
- 10;
677 DATTR(bug("[ELF.ARM] Found aeabi attributes @ 0x%p (length %u)\n", aeabi_attrs
, aeabi_len
));
679 while (aeabi_len
> 0)
681 ULONG aeabi_attrs_size
= READLONG_UNALIGNED(aeabi_attrs
->size
);
683 if (aeabi_attrs
->tag
== Tag_File
)
685 UBYTE
*file_subsection
= (void *)aeabi_attrs
+ sizeof(struct attrs_subsection
);
686 UBYTE file_len
= aeabi_attrs_size
- sizeof(struct attrs_subsection
);
688 DATTR(bug("[ELF.ARM] Found file-wide attributes @ 0x%p (length %u)\n", file_subsection
, file_len
));
695 tag
= *file_subsection
++;
700 DATTR(bug("[ELF.ARM] Mailformed attribute tag %d (no data)\n", tag
));
706 case Tag_CPU_raw_name
:
708 case Tag_compatibility
:
709 case Tag_also_compatible_with
:
710 case Tag_conformance
:
711 /* These two are NULL-terminated strings. Just skip. */
715 if (*file_subsection
++ == 0)
721 /* Read ULEB128 value */
727 byte
= *file_subsection
++;
730 val
|= (byte
& 0x7F) << shift
;
741 DATTR(bug("[ELF.ARM] ARM CPU architecture set to %d\n", val
));
743 if (val
> ELF_CPU_ARMv7EM
)
745 DATTR(bug("[ELF.ARM] Unknown CPU tag value (%d)\n", val
));
749 if (arm_cpus
[val
] > IDosBase(DOSBase
)->arm_Arch
)
751 DATTR(bug("[ELF.ARM] CPU Requirements too high (system %d, file %d)\n", IDosBase(DOSBase
)->arm_Arch
, arm_cpus
[val
]));
757 DATTR(bug("[ELF.ARM] ARM FPU architecture set to %d\n", val
));
766 if (!IDosBase(DOSBase
)->arm_VFP
)
768 DATTR(bug("[ELF.ARM] VFP required but missing\n"));
774 case ELF_FP_v3_Short
:
775 if (!IDosBase(DOSBase
)->arm_VFP_v3
)
777 DATTR(bug("[ELF.ARM] VFPv3 required but missing\n"));
783 /* This includes VFPv4 for now */
784 DATTR(bug("[ELF.ARM] VFP %d required -- unsupported\n", val
));
792 /* We allow to execute only files which contain attributes section */
795 aeabi_attrs
= (void *)aeabi_attrs
+ aeabi_attrs_size
;
796 aeabi_len
-= aeabi_attrs_size
;
801 attrs
= (void *)attrs
+ attrs_size
;
809 BPTR InternalLoadSeg_ELF
814 LONG
*stack __unused
,
815 struct DosLibrary
*DOSBase
820 struct sheader
*symtab_shndx
= NULL
;
821 struct sheader
*strtab
= NULL
;
823 BPTR
*next_hunk_ptr
= &hunks
;
825 BOOL exec_hunk_seen
= FALSE
;
828 /* load and validate ELF header */
829 if (!load_header(file
, &eh
, funcarray
, DOSBase
))
832 int_shnum
= read_shnum(file
, &eh
, funcarray
, DOSBase
);
836 /* load section headers */
837 if (!(sh
= load_block(file
, eh
.shoff
, int_shnum
* eh
.shentsize
, funcarray
, DOSBase
)))
841 for (i
= 0; i
< int_shnum
; i
++)
843 if (sh
[i
].type
== SHT_ARM_ATTRIBUTES
)
845 ULONG len
= sh
[i
].size
;
846 UBYTE
*data
= load_block(file
, sh
[i
].offset
, len
, funcarray
, DOSBase
);
850 BOOL res
= ARM_ParseAttrs(data
, len
, DOSBase
);
852 ilsFreeMem(data
, len
);
856 D(bug("[ELF Loader] Can't parse ARM attributes\n"));
857 SetIoErr(ERROR_NOT_EXECUTABLE
);
865 /* Iterate over the section headers in order to do some stuff... */
866 for (i
= 0; i
< int_shnum
; i
++)
869 Load the symbol and string table(s).
871 NOTICE: the ELF standard, at the moment (Nov 2002) explicitely states
872 that only one symbol table per file is allowed. However, it
873 also states that this may change in future... we already handle it.
875 if (sh
[i
].type
== SHT_SYMTAB
|| sh
[i
].type
== SHT_STRTAB
|| sh
[i
].type
== SHT_SYMTAB_SHNDX
)
877 sh
[i
].addr
= load_block(file
, sh
[i
].offset
, sh
[i
].size
, funcarray
, DOSBase
);
881 if (sh
[i
].type
== SHT_STRTAB
) {
882 if (strtab
== NULL
) {
885 D(bug("[ELF Loader] file contains multiple strtab tables. only using the first one\n"));
889 if (sh
[i
].type
== SHT_SYMTAB_SHNDX
) {
890 if (symtab_shndx
== NULL
)
891 symtab_shndx
= &sh
[i
];
893 D(bug("[ELF Loader] file contains multiple symtab shndx tables. only using the first one\n"));
898 /* Now that we have the string and symbol tables loaded,
899 * load the rest of the hunks.
901 for (i
= 0; i
< int_shnum
; i
++)
903 /* Skip the already loaded hunks */
904 if (sh
[i
].type
== SHT_SYMTAB
|| sh
[i
].type
== SHT_STRTAB
|| sh
[i
].type
== SHT_SYMTAB_SHNDX
)
907 /* Load the section in memory if needed, and make a hunk out of it */
908 if (sh
[i
].flags
& SHF_ALLOC
)
912 /* Only allow alignment if this is an executable hunk
913 or if an executable hunk has been loaded already,
914 so to avoid the situation in which a data hunk has its
915 content displaced from the hunk's header in case it's the
916 first hunk (this happens with Keymaps, for instance). */
917 if (sh
[i
].flags
& SHF_EXECINSTR
)
918 exec_hunk_seen
= TRUE
;
920 if (!load_hunk(file
, &next_hunk_ptr
, &sh
[i
], strtab
? strtab
->addr
: NULL
, funcarray
, exec_hunk_seen
, DOSBase
))
926 /* Relocate the sections */
927 for (i
= 0; i
< int_shnum
; i
++)
929 /* Does this relocation section refer to a hunk? If so, addr must be != 0 */
930 if ((sh
[i
].type
== AROS_ELF_REL
) && sh
[SHINDEX(sh
[i
].info
)].addr
)
932 sh
[i
].addr
= load_block(file
, sh
[i
].offset
, sh
[i
].size
, funcarray
, DOSBase
);
933 if (!sh
[i
].addr
|| !relocate(&eh
, sh
, i
, symtab_shndx
, DOSBase
))
936 ilsFreeMem(sh
[i
].addr
, sh
[i
].size
);
941 /* Everything is loaded now. Register the module at kernel.resource */
942 register_elf(file
, hunks
, &eh
, sh
, DOSBase
);
947 /* There were some errors, deallocate The hunks */
949 InternalUnLoadSeg(hunks
, (VOID_FUNC
)funcarray
[2]);
955 * Clear the caches to let the CPU see the new data and instructions.
956 * We check for SysBase's lib_Version, since this code is also built
957 * as linklib for AmigaOS version of AROS bootstrap, and it can be
958 * running on AOS 1.3 or lower.
960 if (SysBase
->LibNode
.lib_Version
>= 36)
966 struct hunk
*hunk
= BPTR2HUNK(BADDR(curr
));
968 CacheClearE(hunk
->data
, hunk
->size
, CACRF_ClearD
| CACRF_ClearI
);
974 /* deallocate the symbol tables */
975 for (i
= 0; i
< int_shnum
; i
++)
977 if (((sh
[i
].type
== SHT_SYMTAB
) || (sh
[i
].type
== SHT_STRTAB
)) && (sh
[i
].addr
!= NULL
))
978 ilsFreeMem(sh
[i
].addr
, sh
[i
].size
);
981 /* Free the section headers */
982 ilsFreeMem(sh
, int_shnum
* eh
.shentsize
);