mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
libdl: Back port C++ exception throw and catch from 4.12.
Closes #2956.
This commit is contained in:
@@ -90,7 +90,7 @@ include_rtems_rtl_HEADERS += libdl/dlfcn-shell.h
|
|||||||
include_rtems_rtl_HEADERS += libdl/rtl.h libdl/rtl-allocator.h libdl/rtl-obj-fwd.h
|
include_rtems_rtl_HEADERS += libdl/rtl.h libdl/rtl-allocator.h libdl/rtl-obj-fwd.h
|
||||||
include_rtems_rtl_HEADERS += libdl/rtl-fwd.h libdl/rtl-obj.h libdl/rtl-obj-cache.h
|
include_rtems_rtl_HEADERS += libdl/rtl-fwd.h libdl/rtl-obj.h libdl/rtl-obj-cache.h
|
||||||
include_rtems_rtl_HEADERS += libdl/rtl-obj-comp.h libdl/rtl-unresolved.h
|
include_rtems_rtl_HEADERS += libdl/rtl-obj-comp.h libdl/rtl-unresolved.h
|
||||||
include_rtems_rtl_HEADERS += libdl/rtl-indirect-ptr.h libdl/rtl-sym.h
|
include_rtems_rtl_HEADERS += libdl/rtl-indirect-ptr.h libdl/rtl-sym.h libdl/rtl-trace.h
|
||||||
include_rtems_rtl_HEADERS += libdl/rap.h libdl/rap-shell.h
|
include_rtems_rtl_HEADERS += libdl/rap.h libdl/rap-shell.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ libdl_a_SOURCES = \
|
|||||||
rtl-string.c \
|
rtl-string.c \
|
||||||
rtl-sym.c \
|
rtl-sym.c \
|
||||||
rtl-trace.c \
|
rtl-trace.c \
|
||||||
|
rtl-unwind-dw2.c \
|
||||||
rtl-unresolved.c
|
rtl-unresolved.c
|
||||||
|
|
||||||
libdl_a_SOURCES += rtl-mdreloc-@RTEMS_CPU@.c
|
libdl_a_SOURCES += rtl-mdreloc-@RTEMS_CPU@.c
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ dlerror (void)
|
|||||||
{
|
{
|
||||||
static char msg[64];
|
static char msg[64];
|
||||||
rtems_rtl_get_error (msg, sizeof (msg));
|
rtems_rtl_get_error (msg, sizeof (msg));
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -80,7 +80,8 @@
|
|||||||
#define R_ARM_ALU_SBREL_19_12 36
|
#define R_ARM_ALU_SBREL_19_12 36
|
||||||
#define R_ARM_ALU_SBREL_27_20 37
|
#define R_ARM_ALU_SBREL_27_20 37
|
||||||
#define R_ARM_V4BX 40
|
#define R_ARM_V4BX 40
|
||||||
#define R_ARM_PREL31 41
|
#define R_ARM_TARGET2 41
|
||||||
|
#define R_ARM_PREL31 42
|
||||||
|
|
||||||
#define R_ARM_MOVW_ABS_NC 43
|
#define R_ARM_MOVW_ABS_NC 43
|
||||||
#define R_ARM_MOVT_ABS 44
|
#define R_ARM_MOVT_ABS 44
|
||||||
|
|||||||
@@ -459,6 +459,10 @@ typedef struct {
|
|||||||
#define SHF_WRITE 0x1 /* Section contains writable data */
|
#define SHF_WRITE 0x1 /* Section contains writable data */
|
||||||
#define SHF_ALLOC 0x2 /* Section occupies memory */
|
#define SHF_ALLOC 0x2 /* Section occupies memory */
|
||||||
#define SHF_EXECINSTR 0x4 /* Section contains executable insns */
|
#define SHF_EXECINSTR 0x4 /* Section contains executable insns */
|
||||||
|
#define SHF_MERGE 0x10 /* Section contains data that can be merged */
|
||||||
|
#define SHF_STRINGS 0x20 /* Section contains null-terminated strings */
|
||||||
|
#define SHF_INFO_LINK 0x40 /* Section header's sh_info holds table index */
|
||||||
|
#define SHF_LINK_ORDER 0x80 /* Section has special ordering requirements */
|
||||||
|
|
||||||
#define SHF_MASKOS 0x0f000000 /* Operating system specific values */
|
#define SHF_MASKOS 0x0f000000 /* Operating system specific values */
|
||||||
#define SHF_MASKPROC 0xf0000000 /* Processor-specific values */
|
#define SHF_MASKPROC 0xf0000000 /* Processor-specific values */
|
||||||
@@ -949,13 +953,13 @@ typedef struct {
|
|||||||
#define SYMINFO_NUM 2
|
#define SYMINFO_NUM 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These constants are used for Elf32_Verdef struct's version number.
|
* These constants are used for Elf32_Verdef struct's version number.
|
||||||
*/
|
*/
|
||||||
#define VER_DEF_NONE 0
|
#define VER_DEF_NONE 0
|
||||||
#define VER_DEF_CURRENT 1
|
#define VER_DEF_CURRENT 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These constants are used for Elf32_Verdef struct's vd_flags.
|
* These constants are used for Elf32_Verdef struct's vd_flags.
|
||||||
*/
|
*/
|
||||||
#define VER_FLG_BASE 0x1
|
#define VER_FLG_BASE 0x1
|
||||||
#define VER_FLG_WEAK 0x2
|
#define VER_FLG_WEAK 0x2
|
||||||
@@ -967,7 +971,7 @@ typedef struct {
|
|||||||
#define VER_NDX_GLOBAL 1
|
#define VER_NDX_GLOBAL 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These constants are used for Elf32_Verneed struct's version number.
|
* These constants are used for Elf32_Verneed struct's version number.
|
||||||
*/
|
*/
|
||||||
#define VER_NEED_NONE 0
|
#define VER_NEED_NONE 0
|
||||||
#define VER_NEED_CURRENT 1
|
#define VER_NEED_CURRENT 1
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
|
|||||||
bool
|
bool
|
||||||
rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
||||||
void** const_base, size_t const_size,
|
void** const_base, size_t const_size,
|
||||||
|
void** eh_base, size_t eh_size,
|
||||||
void** data_base, size_t data_size,
|
void** data_base, size_t data_size,
|
||||||
void** bss_base, size_t bss_size)
|
void** bss_base, size_t bss_size)
|
||||||
{
|
{
|
||||||
@@ -173,7 +174,20 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
const_size, false);
|
const_size, false);
|
||||||
if (!*const_base)
|
if (!*const_base)
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
|
data_base, bss_base);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eh_size)
|
||||||
|
{
|
||||||
|
*eh_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
|
||||||
|
eh_size, false);
|
||||||
|
if (!*eh_base)
|
||||||
|
{
|
||||||
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
|
data_base, bss_base);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +198,8 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
data_size, false);
|
data_size, false);
|
||||||
if (!*data_base)
|
if (!*data_base)
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
|
data_base, bss_base);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +210,8 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
bss_size, false);
|
bss_size, false);
|
||||||
if (!*bss_base)
|
if (!*bss_base)
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
|
data_base, bss_base);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,12 +222,14 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
void
|
void
|
||||||
rtems_rtl_alloc_module_del (void** text_base,
|
rtems_rtl_alloc_module_del (void** text_base,
|
||||||
void** const_base,
|
void** const_base,
|
||||||
|
void** eh_base,
|
||||||
void** data_base,
|
void** data_base,
|
||||||
void** bss_base)
|
void** bss_base)
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
|
||||||
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *eh_base);
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
|
||||||
*text_base = *const_base = *data_base = *bss_base = NULL;
|
*text_base = *const_base = *eh_base = *data_base = *bss_base = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
|
|||||||
* @param text_size The size of the read/exec section.
|
* @param text_size The size of the read/exec section.
|
||||||
* @param const_base Pointer to the const base pointer.
|
* @param const_base Pointer to the const base pointer.
|
||||||
* @param const_size The size of the read only section.
|
* @param const_size The size of the read only section.
|
||||||
|
* @param eh_base Pointer to the eh base pointer.
|
||||||
|
* @param eh_size The size of the eh section.
|
||||||
* @param data_base Pointer to the data base pointer.
|
* @param data_base Pointer to the data base pointer.
|
||||||
* @param data_size The size of the read/write secton.
|
* @param data_size The size of the read/write secton.
|
||||||
* @param bss_base Pointer to the bss base pointer.
|
* @param bss_base Pointer to the bss base pointer.
|
||||||
@@ -155,6 +157,7 @@ void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
|
|||||||
*/
|
*/
|
||||||
bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
||||||
void** const_base, size_t const_size,
|
void** const_base, size_t const_size,
|
||||||
|
void** eh_base, size_t eh_size,
|
||||||
void** data_base, size_t data_size,
|
void** data_base, size_t data_size,
|
||||||
void** bss_base, size_t bss_size);
|
void** bss_base, size_t bss_size);
|
||||||
|
|
||||||
@@ -163,11 +166,13 @@ bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
*
|
*
|
||||||
* @param text_base Pointer to the text base pointer.
|
* @param text_base Pointer to the text base pointer.
|
||||||
* @param const_base Pointer to the const base pointer.
|
* @param const_base Pointer to the const base pointer.
|
||||||
|
* @param eh_base Pointer to the eh base pointer.
|
||||||
* @param data_base Pointer to the data base pointer.
|
* @param data_base Pointer to the data base pointer.
|
||||||
* @param bss_base Pointer to the bss base pointer.
|
* @param bss_base Pointer to the bss base pointer.
|
||||||
*/
|
*/
|
||||||
void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
|
void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
|
||||||
void** data_base, void** bss_base);
|
void** eh_base, void** data_base,
|
||||||
|
void** bss_base);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ _rtld_debug_state (void)
|
|||||||
int
|
int
|
||||||
_rtld_linkmap_add (rtems_rtl_obj_t* obj)
|
_rtld_linkmap_add (rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
struct link_map* l = (struct link_map*)obj->detail;
|
struct link_map* l = obj->linkmap;
|
||||||
struct link_map* prev;
|
struct link_map* prev;
|
||||||
uint32_t obj_num = obj->obj_num;
|
uint32_t obj_num = obj->obj_num;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
||||||
printf ("rtl: linkmap_add\n");
|
printf ("rtl: linkmap_add\n");
|
||||||
@@ -78,8 +78,10 @@ _rtld_linkmap_add (rtems_rtl_obj_t* obj)
|
|||||||
void
|
void
|
||||||
_rtld_linkmap_delete (rtems_rtl_obj_t* obj)
|
_rtld_linkmap_delete (rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
struct link_map* l = (struct link_map*)obj->detail;
|
struct link_map* l = obj->linkmap;
|
||||||
/* link_maps are allocated together if not 1 */
|
/*
|
||||||
|
* link_maps are allocated together if not 1
|
||||||
|
*/
|
||||||
struct link_map* e = l + obj->obj_num - 1;
|
struct link_map* e = l + obj->obj_num - 1;
|
||||||
|
|
||||||
while (e && e->l_next) e = e->l_next;
|
while (e && e->l_next) e = e->l_next;
|
||||||
@@ -90,7 +92,7 @@ _rtld_linkmap_delete (rtems_rtl_obj_t* obj)
|
|||||||
e->l_next->l_prev = NULL;
|
e->l_next->l_prev = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((l->l_prev->l_next = e->l_next) != NULL)
|
if ((l->l_prev->l_next = e->l_next) != NULL)
|
||||||
e->l_next->l_prev = l->l_prev;
|
e->l_next->l_prev = l->l_prev;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
#include "rtl-unresolved.h"
|
#include "rtl-unresolved.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,6 +170,9 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
|
|||||||
&relbuf[0], reloc_size))
|
&relbuf[0], reloc_size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the symbol details.
|
||||||
|
*/
|
||||||
if (is_rela)
|
if (is_rela)
|
||||||
off = (obj->ooffset + symsect->offset +
|
off = (obj->ooffset + symsect->offset +
|
||||||
(ELF_R_SYM (rela->r_info) * sizeof (sym)));
|
(ELF_R_SYM (rela->r_info) * sizeof (sym)));
|
||||||
@@ -246,7 +250,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
|
|||||||
if (is_rela)
|
if (is_rela)
|
||||||
{
|
{
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: rela: sym:%s(%-2d)=%08lx type:%-2d off:%08lx addend:%d\n",
|
printf ("rtl: rela: sym:%s(%d)=%08lx type:%d off:%08lx addend:%d\n",
|
||||||
symname, (int) ELF_R_SYM (rela->r_info), symvalue,
|
symname, (int) ELF_R_SYM (rela->r_info), symvalue,
|
||||||
(int) ELF_R_TYPE (rela->r_info), rela->r_offset, (int) rela->r_addend);
|
(int) ELF_R_TYPE (rela->r_info), rela->r_offset, (int) rela->r_addend);
|
||||||
if (!rtems_rtl_elf_relocate_rela (obj, rela, targetsect,
|
if (!rtems_rtl_elf_relocate_rela (obj, rela, targetsect,
|
||||||
@@ -256,7 +260,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: rel: sym:%s(%-2d)=%08lx type:%-2d off:%08lx\n",
|
printf ("rtl: rel: sym:%s(%d)=%08lx type:%d off:%08lx\n",
|
||||||
symname, (int) ELF_R_SYM (rel->r_info), symvalue,
|
symname, (int) ELF_R_SYM (rel->r_info), symvalue,
|
||||||
(int) ELF_R_TYPE (rel->r_info), rel->r_offset);
|
(int) ELF_R_TYPE (rel->r_info), rel->r_offset);
|
||||||
if (!rtems_rtl_elf_relocate_rel (obj, rel, targetsect,
|
if (!rtems_rtl_elf_relocate_rel (obj, rel, targetsect,
|
||||||
@@ -300,7 +304,7 @@ rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
|
|||||||
rela.r_info = reloc->rel[REL_R_INFO];
|
rela.r_info = reloc->rel[REL_R_INFO];
|
||||||
rela.r_addend = reloc->rel[REL_R_ADDEND];
|
rela.r_addend = reloc->rel[REL_R_ADDEND];
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: rela: sym:%-2d type:%-2d off:%08lx addend:%d\n",
|
printf ("rtl: rela: sym:%d type:%d off:%08lx addend:%d\n",
|
||||||
(int) ELF_R_SYM (rela.r_info), (int) ELF_R_TYPE (rela.r_info),
|
(int) ELF_R_SYM (rela.r_info), (int) ELF_R_TYPE (rela.r_info),
|
||||||
rela.r_offset, (int) rela.r_addend);
|
rela.r_offset, (int) rela.r_addend);
|
||||||
if (!rtems_rtl_elf_relocate_rela (reloc->obj, &rela, sect,
|
if (!rtems_rtl_elf_relocate_rela (reloc->obj, &rela, sect,
|
||||||
@@ -313,7 +317,7 @@ rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
|
|||||||
rel.r_offset = reloc->rel[REL_R_OFFSET];
|
rel.r_offset = reloc->rel[REL_R_OFFSET];
|
||||||
rel.r_info = reloc->rel[REL_R_INFO];
|
rel.r_info = reloc->rel[REL_R_INFO];
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: rel: sym:%-2d type:%-2d off:%08lx\n",
|
printf ("rtl: rel: sym:%d type:%d off:%08lx\n",
|
||||||
(int) ELF_R_SYM (rel.r_info), (int) ELF_R_TYPE (rel.r_info),
|
(int) ELF_R_SYM (rel.r_info), (int) ELF_R_TYPE (rel.r_info),
|
||||||
rel.r_offset);
|
rel.r_offset);
|
||||||
if (!rtems_rtl_elf_relocate_rel (reloc->obj, &rel, sect,
|
if (!rtems_rtl_elf_relocate_rel (reloc->obj, &rel, sect,
|
||||||
@@ -652,6 +656,11 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
|
|||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
||||||
|
printf ("rtl: section: %2d: type=%d flags=%08x link=%d info=%d\n",
|
||||||
|
section, (int) shdr.sh_type, (unsigned int) shdr.sh_flags,
|
||||||
|
(int) shdr.sh_link, (int) shdr.sh_info);
|
||||||
|
|
||||||
switch (shdr.sh_type)
|
switch (shdr.sh_type)
|
||||||
{
|
{
|
||||||
case SHT_NULL:
|
case SHT_NULL:
|
||||||
@@ -707,9 +716,16 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_WARNING))
|
/*
|
||||||
printf ("rtl: unsupported section: %2d: type=%02d flags=%02x\n",
|
* See if there are architecture specific flags?
|
||||||
section, (int) shdr.sh_type, (int) shdr.sh_flags);
|
*/
|
||||||
|
flags = rtems_rtl_elf_section_flags (obj, &shdr);
|
||||||
|
if (flags == 0)
|
||||||
|
{
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_WARNING))
|
||||||
|
printf ("rtl: unsupported section: %2d: type=%02d flags=%02x\n",
|
||||||
|
section, (int) shdr.sh_type, (int) shdr.sh_flags);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,6 +734,13 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
|
|||||||
char* name;
|
char* name;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If link ordering this section must appear in the same order in memory
|
||||||
|
* as the linked-to section relative to the sections it loads with.
|
||||||
|
*/
|
||||||
|
if ((shdr.sh_flags & SHF_LINK_ORDER) != 0)
|
||||||
|
flags |= RTEMS_RTL_OBJ_SECT_LINK;
|
||||||
|
|
||||||
len = RTEMS_RTL_ELF_STRING_MAX;
|
len = RTEMS_RTL_ELF_STRING_MAX;
|
||||||
if (!rtems_rtl_obj_cache_read (strings, fd,
|
if (!rtems_rtl_obj_cache_read (strings, fd,
|
||||||
sectstroff + shdr.sh_name,
|
sectstroff + shdr.sh_name,
|
||||||
@@ -729,6 +752,12 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
|
|||||||
if (strcmp (".dtors", name) == 0)
|
if (strcmp (".dtors", name) == 0)
|
||||||
flags |= RTEMS_RTL_OBJ_SECT_DTOR;
|
flags |= RTEMS_RTL_OBJ_SECT_DTOR;
|
||||||
|
|
||||||
|
if (rtems_rtl_elf_unwind_parse (obj, name, flags))
|
||||||
|
{
|
||||||
|
flags &= ~(RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST);
|
||||||
|
flags |= RTEMS_RTL_OBJ_SECT_EH;
|
||||||
|
}
|
||||||
|
|
||||||
if (!rtems_rtl_obj_add_section (obj, section, name,
|
if (!rtems_rtl_obj_add_section (obj, section, name,
|
||||||
shdr.sh_size, shdr.sh_offset,
|
shdr.sh_size, shdr.sh_offset,
|
||||||
shdr.sh_addralign, shdr.sh_link,
|
shdr.sh_addralign, shdr.sh_link,
|
||||||
@@ -771,16 +800,19 @@ rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
|
static bool
|
||||||
|
rtems_rtl_elf_load_linkmap (rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
rtems_chain_control* sections = NULL;
|
rtems_chain_control* sections = NULL;
|
||||||
rtems_chain_node* node = NULL;
|
rtems_chain_node* node = NULL;
|
||||||
size_t mask = 0;
|
size_t mask = 0;
|
||||||
struct link_map* l = NULL;
|
|
||||||
int sec_num = 0;
|
int sec_num = 0;
|
||||||
|
section_detail* sd;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* caculate the size of sections' name. */
|
/*
|
||||||
|
* Caculate the size of sections' name.
|
||||||
|
*/
|
||||||
|
|
||||||
for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
|
for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
|
||||||
mask <= RTEMS_RTL_OBJ_SECT_BSS;
|
mask <= RTEMS_RTL_OBJ_SECT_BSS;
|
||||||
@@ -791,7 +823,6 @@ bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
|
|||||||
while (!rtems_chain_is_tail (sections, node))
|
while (!rtems_chain_is_tail (sections, node))
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
||||||
|
|
||||||
if ((sect->size != 0) && ((sect->flags & mask) != 0))
|
if ((sect->size != 0) && ((sect->flags & mask) != 0))
|
||||||
{
|
{
|
||||||
++sec_num;
|
++sec_num;
|
||||||
@@ -801,32 +832,31 @@ bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
obj->obj_num = 1;
|
obj->obj_num = 1;
|
||||||
obj->detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
obj->linkmap = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
||||||
sizeof(struct link_map) +
|
sizeof(struct link_map) +
|
||||||
sec_num * sizeof (section_detail), true);
|
sec_num * sizeof (section_detail), true);
|
||||||
if (!obj->detail)
|
if (!obj->linkmap)
|
||||||
{
|
{
|
||||||
rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
|
rtems_rtl_set_error (ENOMEM, "no memory for obj linkmap");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = (struct link_map*) obj->detail;
|
obj->linkmap->name = obj->oname;
|
||||||
l->name = obj->oname;
|
obj->linkmap->sec_num = sec_num;
|
||||||
l->sec_num = sec_num;
|
obj->linkmap->sec_detail = (section_detail*) (obj->linkmap + 1);
|
||||||
l->sec_detail = (section_detail*) (l + 1);
|
obj->linkmap->rpathlen = 0;
|
||||||
l->rpathlen = 0;
|
obj->linkmap->rpath = NULL;
|
||||||
l->rpath = NULL;
|
obj->linkmap->l_next = NULL;
|
||||||
l->l_next = NULL;
|
obj->linkmap->l_prev = NULL;
|
||||||
l->l_prev = NULL;
|
obj->linkmap->sec_addr[rap_text] = obj->text_base;
|
||||||
l->sec_addr[rap_text] = obj->text_base;
|
obj->linkmap->sec_addr[rap_const] = obj->const_base;
|
||||||
l->sec_addr[rap_const] = obj->const_base;
|
obj->linkmap->sec_addr[rap_data] = obj->data_base;
|
||||||
l->sec_addr[rap_data] = obj->data_base;
|
obj->linkmap->sec_addr[rap_bss] = obj->bss_base;
|
||||||
l->sec_addr[rap_bss] = obj->bss_base;
|
|
||||||
|
|
||||||
|
sd = obj->linkmap->sec_detail;
|
||||||
section_detail* sd = l->sec_detail;
|
|
||||||
sections = &obj->sections;
|
sections = &obj->sections;
|
||||||
node = rtems_chain_first (sections);
|
node = rtems_chain_first (sections);
|
||||||
|
|
||||||
for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
|
for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
|
||||||
mask <= RTEMS_RTL_OBJ_SECT_BSS;
|
mask <= RTEMS_RTL_OBJ_SECT_BSS;
|
||||||
mask <<= 1)
|
mask <<= 1)
|
||||||
@@ -948,11 +978,23 @@ rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd)
|
|||||||
|
|
||||||
rtems_rtl_symbol_obj_erase_local (obj);
|
rtems_rtl_symbol_obj_erase_local (obj);
|
||||||
|
|
||||||
if (!rtems_rtl_elf_load_details (obj))
|
if (!rtems_rtl_elf_load_linkmap (obj))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rtems_rtl_elf_unwind_register (obj))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_file_unload (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
rtems_rtl_elf_unwind_deregister (obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,18 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define RTEMS_RTL_ELF_STRING_MAX (256)
|
#define RTEMS_RTL_ELF_STRING_MAX (256)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to translate unknown section flags to RTL
|
||||||
|
* section flags.
|
||||||
|
*
|
||||||
|
* @param obj The object file being relocated.
|
||||||
|
* @param shdr The ELF section header.
|
||||||
|
* @retval 0 Unknown or unsupported flags.
|
||||||
|
* @retval uint32_t RTL object file flags.
|
||||||
|
*/
|
||||||
|
uint32_t rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specific handler to check is a relocation record's type is
|
* Architecture specific handler to check is a relocation record's type is
|
||||||
* required to resolve a symbol.
|
* required to resolve a symbol.
|
||||||
@@ -136,13 +148,6 @@ bool rtems_rtl_elf_find_symbol (rtems_rtl_obj_t* obj,
|
|||||||
*/
|
*/
|
||||||
bool rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd);
|
bool rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd);
|
||||||
|
|
||||||
/**
|
|
||||||
* The ELF file details handler.
|
|
||||||
*
|
|
||||||
* @param obj Load the details of the obj.
|
|
||||||
*/
|
|
||||||
bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ELF format load handler.
|
* The ELF format load handler.
|
||||||
*
|
*
|
||||||
@@ -151,6 +156,13 @@ bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj);
|
|||||||
*/
|
*/
|
||||||
bool rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd);
|
bool rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ELF format unload handler.
|
||||||
|
*
|
||||||
|
* @param obj The object to unload.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_file_unload (rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ELF format signature handler.
|
* The ELF format signature handler.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
@@ -39,9 +40,15 @@ int
|
|||||||
rtems_rtl_get_error (char* message, size_t max_message)
|
rtems_rtl_get_error (char* message, size_t max_message)
|
||||||
{
|
{
|
||||||
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
|
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
|
||||||
int last_errno = rtl->last_errno;
|
if (rtl != NULL)
|
||||||
strncpy (message, rtl->last_error, sizeof (rtl->last_error));
|
{
|
||||||
rtems_rtl_unlock ();
|
int last_errno = rtl->last_errno;
|
||||||
return last_errno;
|
strncpy (message, rtl->last_error, sizeof (rtl->last_error));
|
||||||
}
|
rtems_rtl_unlock ();
|
||||||
|
return last_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(message, "RTL init error", max_message);
|
||||||
|
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,11 +10,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unwind.h>
|
||||||
|
#include <unwind-arm-common.h>
|
||||||
|
|
||||||
#include <rtems/rtl/rtl.h>
|
#include <rtems/rtl/rtl.h>
|
||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is possible for the compiler to emit relocations for unaligned data.
|
* It is possible for the compiler to emit relocations for unaligned data.
|
||||||
@@ -23,6 +26,8 @@
|
|||||||
#define RELOC_ALIGNED_P(x) \
|
#define RELOC_ALIGNED_P(x) \
|
||||||
(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
|
(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
|
||||||
|
|
||||||
|
#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */
|
||||||
|
|
||||||
static inline Elf_Addr
|
static inline Elf_Addr
|
||||||
load_ptr(void *where)
|
load_ptr(void *where)
|
||||||
{
|
{
|
||||||
@@ -52,6 +57,24 @@ isThumb(Elf_Word symvalue)
|
|||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Elf_SOff
|
||||||
|
sign_extend31(Elf_Addr val)
|
||||||
|
{
|
||||||
|
if (0x40000000 & val)
|
||||||
|
val = ~((Elf_Addr)0x7fffffff) | (0x7fffffff & val);
|
||||||
|
return 0x7fffffff & val;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
uint32_t flags = 0;
|
||||||
|
if (shdr->sh_type == SHT_ARM_EXIDX)
|
||||||
|
flags = RTEMS_RTL_OBJ_SECT_EH | RTEMS_RTL_OBJ_SECT_LOAD;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
{
|
{
|
||||||
@@ -87,8 +110,11 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
where = (Elf_Addr *)(sect->base + rel->r_offset);
|
where = (Elf_Addr *)(sect->base + rel->r_offset);
|
||||||
|
|
||||||
switch (ELF_R_TYPE(rel->r_info)) {
|
switch (ELF_R_TYPE(rel->r_info)) {
|
||||||
case R_TYPE(NONE):
|
case R_TYPE(NONE):
|
||||||
break;
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
|
||||||
|
printf ("rtl: NONE %p in %s\n", where, rtems_rtl_obj_oname (obj));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case R_TYPE(CALL): /* BL/BLX */
|
case R_TYPE(CALL): /* BL/BLX */
|
||||||
case R_TYPE(JUMP24): /* B/BL<cond> */
|
case R_TYPE(JUMP24): /* B/BL<cond> */
|
||||||
@@ -165,24 +191,32 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
case R_TYPE(REL32): /* word32 (S + A) | T - P */
|
case R_TYPE(REL32): /* word32 (S + A) | T - P */
|
||||||
case R_TYPE(ABS32): /* word32 (S + A) | T */
|
case R_TYPE(ABS32): /* word32 (S + A) | T */
|
||||||
case R_TYPE(GLOB_DAT): /* word32 (S + A) | T */
|
case R_TYPE(GLOB_DAT): /* word32 (S + A) | T */
|
||||||
|
case R_TYPE(PREL31): /* word32 (S + A) | T - P */
|
||||||
|
case R_TYPE(TARGET2): /* Equivalent to REL32 */
|
||||||
if (__predict_true(RELOC_ALIGNED_P(where))) {
|
if (__predict_true(RELOC_ALIGNED_P(where))) {
|
||||||
tmp = *where + symvalue;
|
tmp = *where + symvalue;
|
||||||
if (isThumb(symvalue))
|
if (isThumb(symvalue))
|
||||||
tmp |= 1;
|
tmp |= 1;
|
||||||
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
|
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
|
||||||
|
ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
|
||||||
tmp -= (Elf_Addr)where;
|
tmp -= (Elf_Addr)where;
|
||||||
|
else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
|
||||||
|
tmp = sign_extend31(tmp - (Elf_Addr)where);
|
||||||
*where = tmp;
|
*where = tmp;
|
||||||
} else {
|
} else {
|
||||||
tmp = load_ptr(where) + symvalue;
|
tmp = load_ptr(where) + symvalue;
|
||||||
if (isThumb(symvalue))
|
if (isThumb(symvalue))
|
||||||
tmp |= 1;
|
tmp |= 1;
|
||||||
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
|
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
|
||||||
|
ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
|
||||||
tmp -= (Elf_Addr)where;
|
tmp -= (Elf_Addr)where;
|
||||||
|
else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
|
||||||
|
tmp = sign_extend31(tmp - (Elf_Addr)where);
|
||||||
store_ptr(where, tmp);
|
store_ptr(where, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: REL32/ABS32/GLOB_DAT %p @ %p in %s",
|
printf ("rtl: REL32/ABS32/GLOB_DAT/PREL31/TARGET2 %p @ %p in %s\n",
|
||||||
(void *)tmp, where, rtems_rtl_obj_oname (obj));
|
(void *)tmp, where, rtems_rtl_obj_oname (obj));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -306,7 +340,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
(void *)*where, where, rtems_rtl_obj_oname (obj));
|
(void *)*where, where, rtems_rtl_obj_oname (obj));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
|
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
|
||||||
"contents = %p\n",
|
"contents = %p\n",
|
||||||
ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
|
ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
|
||||||
@@ -315,9 +349,83 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
"%s: Unsupported relocation type %ld "
|
"%s: Unsupported relocation type %ld "
|
||||||
"in non-PLT relocations",
|
"in non-PLT relocations",
|
||||||
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
|
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We location the EH sections in section flags.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
obj->loader = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An exception index table entry. */
|
||||||
|
typedef struct __EIT_entry
|
||||||
|
{
|
||||||
|
_uw fnoffset;
|
||||||
|
_uw content;
|
||||||
|
} __EIT_entry;
|
||||||
|
|
||||||
|
/* The exception index table location in the base module */
|
||||||
|
extern __EIT_entry __exidx_start;
|
||||||
|
extern __EIT_entry __exidx_end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A weak reference is in libgcc, provide a real version and provide a way to
|
||||||
|
* manage loaded modules.
|
||||||
|
*
|
||||||
|
* Passed in the return address and a reference to the number of records
|
||||||
|
* found. We set the start of the exidx data and the number of records.
|
||||||
|
*/
|
||||||
|
_Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr return_address,
|
||||||
|
int* nrec) __attribute__ ((__noinline__,
|
||||||
|
__used__,
|
||||||
|
__noclone__));
|
||||||
|
|
||||||
|
_Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr return_address,
|
||||||
|
int* nrec)
|
||||||
|
{
|
||||||
|
rtems_rtl_data_t* rtl;
|
||||||
|
rtems_chain_node* node;
|
||||||
|
__EIT_entry* exidx_start = &__exidx_start;
|
||||||
|
__EIT_entry* exidx_end = &__exidx_end;
|
||||||
|
|
||||||
|
rtl = rtems_rtl_lock ();
|
||||||
|
|
||||||
|
node = rtems_chain_first (&rtl->objects);
|
||||||
|
while (!rtems_chain_is_tail (&rtl->objects, node)) {
|
||||||
|
rtems_rtl_obj_t* obj = (rtems_rtl_obj_t*) node;
|
||||||
|
if (rtems_rtl_obj_text_inside (obj, (void*) return_address)) {
|
||||||
|
exidx_start = (__EIT_entry*) obj->eh_base;
|
||||||
|
exidx_end = (__EIT_entry*) (obj->eh_base + obj->eh_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node = rtems_chain_next (node);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_rtl_unlock ();
|
||||||
|
|
||||||
|
*nrec = exidx_end - exidx_start;
|
||||||
|
|
||||||
|
return (_Unwind_Ptr) exidx_start;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -113,3 +122,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -99,3 +108,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -101,3 +110,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -118,3 +127,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
rtems_rtl_set_error (EINVAL, "rela type record not supported");
|
rtems_rtl_set_error (EINVAL, "rela type record not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
static inline int overflow_8_check(int value)
|
static inline int overflow_8_check(int value)
|
||||||
{
|
{
|
||||||
@@ -30,6 +32,13 @@ static inline int overflow_16_check(int value)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
{
|
{
|
||||||
@@ -146,3 +155,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -188,3 +197,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -86,3 +95,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,11 +15,19 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
|
#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
|
||||||
((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
|
((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
|
||||||
#define l(x) ((u_int32_t)(x) & 0xffff)
|
#define l(x) ((u_int32_t)(x) & 0xffff)
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -158,6 +166,22 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
|
|||||||
(void *)*where, where, rtems_rtl_obj_oname (obj));
|
(void *)*where, where, rtems_rtl_obj_oname (obj));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case R_TYPE(SDAREL16):
|
||||||
|
/*
|
||||||
|
* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
|
||||||
|
* small data items.
|
||||||
|
*/
|
||||||
|
mask = 0xffff;
|
||||||
|
tmp = *((Elf32_Half*) where);
|
||||||
|
tmp &= ~mask;
|
||||||
|
tmp |= (symvalue + rela->r_addend - (Elf_Addr)where) & mask;
|
||||||
|
*((Elf32_Half*) where) = tmp;
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
|
printf ("rtl: SDAREL16 %p @ %p in %s\n",
|
||||||
|
(void *) (uintptr_t) *((Elf32_Half*) where),
|
||||||
|
where, rtems_rtl_obj_oname (obj));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
|
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
|
||||||
"contents = %p\n",
|
"contents = %p\n",
|
||||||
@@ -183,3 +207,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
printf ("rtl: rel type record not supported; please report\n");
|
printf ("rtl: rel type record not supported; please report\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following table holds for each relocation type:
|
* The following table holds for each relocation type:
|
||||||
@@ -128,6 +130,13 @@ static const int reloc_target_bitmask[] = {
|
|||||||
};
|
};
|
||||||
#define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t])
|
#define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t])
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
{
|
{
|
||||||
@@ -144,6 +153,7 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
|
|||||||
{
|
{
|
||||||
Elf_Addr *where;
|
Elf_Addr *where;
|
||||||
Elf_Word type, value, mask;
|
Elf_Word type, value, mask;
|
||||||
|
Elf_Addr tmp = 0;
|
||||||
|
|
||||||
where = (Elf_Addr *) (sect->base + rela->r_offset);
|
where = (Elf_Addr *) (sect->base + rela->r_offset);
|
||||||
|
|
||||||
@@ -219,31 +229,32 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
|
|||||||
value &= mask;
|
value &= mask;
|
||||||
|
|
||||||
if (RELOC_UNALIGNED(type)) {
|
if (RELOC_UNALIGNED(type)) {
|
||||||
/* Handle unaligned relocations. */
|
/*
|
||||||
Elf_Addr tmp = 0;
|
* Handle unaligned relocations.
|
||||||
char *ptr = (char *)where;
|
*/
|
||||||
|
char *ptr = (char*) where;
|
||||||
int i, size = RELOC_TARGET_SIZE (type) / 8;
|
int i, size = RELOC_TARGET_SIZE (type) / 8;
|
||||||
|
|
||||||
/* Read it in one byte at a time. */
|
/* Read it in one byte at a time. */
|
||||||
for (i=0; i<size; i++)
|
for (i = size - 1; i >= 0; i--)
|
||||||
tmp = (tmp << 8) | ptr[i];
|
tmp = (tmp << 8) | ptr[i];
|
||||||
|
|
||||||
tmp &= ~mask;
|
tmp &= ~mask;
|
||||||
tmp |= value;
|
tmp |= value;
|
||||||
|
|
||||||
/* Write it back out. */
|
/* Write it back out. */
|
||||||
for (i=0; i<size; i++)
|
for (i = size - 1; i >= 0; i--, tmp >>= 8)
|
||||||
ptr[i] = ((tmp >> (8*i)) & 0xff);
|
ptr[i] = tmp & 0xff;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*where &= ~mask;
|
*where &= ~mask;
|
||||||
*where |= value;
|
*where |= value;
|
||||||
|
tmp = *where;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: %s %p @ %p in %s\n",
|
printf ("rtl: %s %p @ %p in %s\n",
|
||||||
reloc_names[type], (void *)*where, where, rtems_rtl_obj_oname (obj));
|
reloc_names[ELF_R_TYPE(rela->r_info)],
|
||||||
|
(void *)tmp, where, rtems_rtl_obj_oname (obj));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -259,3 +270,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
printf ("rtl: rel type record not supported; please report\n");
|
printf ("rtl: rel type record not supported; please report\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,15 @@
|
|||||||
#include "rtl-elf.h"
|
#include "rtl-elf.h"
|
||||||
#include "rtl-error.h"
|
#include "rtl-error.h"
|
||||||
#include "rtl-trace.h"
|
#include "rtl-trace.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
|
||||||
|
const Elf_Shdr* shdr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
||||||
@@ -95,3 +104,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
|
|||||||
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
rtems_rtl_set_error (EINVAL, "rel type record not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_register (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_elf_unwind_dw2_deregister (obj);
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,14 +49,21 @@
|
|||||||
/**
|
/**
|
||||||
* The table of supported loader formats.
|
* The table of supported loader formats.
|
||||||
*/
|
*/
|
||||||
static rtems_rtl_loader_table_t loaders[RTEMS_RTL_ELF_LOADER_COUNT +
|
#define RTEMS_RTL_LOADERS (RTEMS_RTL_ELF_LOADER_COUNT + RTEMS_RTL_RAP_LOADER_COUNT)
|
||||||
RTEMS_RTL_RAP_LOADER_COUNT] =
|
static const rtems_rtl_loader_table_t loaders[RTEMS_RTL_LOADERS] =
|
||||||
{
|
{
|
||||||
#if RTEMS_RTL_RAP_LOADER
|
#if RTEMS_RTL_RAP_LOADER
|
||||||
{ rtems_rtl_rap_file_check, rtems_rtl_rap_file_load, rtems_rtl_rap_file_sig },
|
{ .check = rtems_rtl_rap_file_check,
|
||||||
|
.load = rtems_rtl_rap_file_load,
|
||||||
|
.unload = rtems_rtl_rap_file_unload,
|
||||||
|
.unload = rtems_rtl_rap_file_unload,
|
||||||
|
.signature = rtems_rtl_rap_file_sig },
|
||||||
#endif
|
#endif
|
||||||
#if RTEMS_RTL_ELF_LOADER
|
#if RTEMS_RTL_ELF_LOADER
|
||||||
{ rtems_rtl_elf_file_check, rtems_rtl_elf_file_load, rtems_rtl_elf_file_sig },
|
{ .check = rtems_rtl_elf_file_check,
|
||||||
|
.load = rtems_rtl_elf_file_load,
|
||||||
|
.unload = rtems_rtl_elf_file_unload,
|
||||||
|
.signature = rtems_rtl_elf_file_sig },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,6 +79,10 @@ rtems_rtl_obj_alloc (void)
|
|||||||
* Initialise the chains.
|
* Initialise the chains.
|
||||||
*/
|
*/
|
||||||
rtems_chain_initialize_empty (&obj->sections);
|
rtems_chain_initialize_empty (&obj->sections);
|
||||||
|
/*
|
||||||
|
* No valid format.
|
||||||
|
*/
|
||||||
|
obj->format = -1;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@@ -97,14 +108,14 @@ rtems_rtl_obj_free (rtems_rtl_obj_t* obj)
|
|||||||
}
|
}
|
||||||
if (!rtems_chain_is_node_off_chain (&obj->link))
|
if (!rtems_chain_is_node_off_chain (&obj->link))
|
||||||
rtems_chain_extract (&obj->link);
|
rtems_chain_extract (&obj->link);
|
||||||
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
|
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
|
||||||
&obj->data_base, &obj->bss_base);
|
&obj->data_base, &obj->bss_base);
|
||||||
rtems_rtl_symbol_obj_erase (obj);
|
rtems_rtl_symbol_obj_erase (obj);
|
||||||
rtems_rtl_obj_free_names (obj);
|
rtems_rtl_obj_free_names (obj);
|
||||||
if (obj->sec_num)
|
if (obj->sec_num)
|
||||||
free (obj->sec_num);
|
free (obj->sec_num);
|
||||||
if (obj->detail)
|
if (obj->linkmap)
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*)obj->detail);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->linkmap);
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -238,7 +249,7 @@ rtems_rtl_scan_decimal (const uint8_t* string, size_t len)
|
|||||||
static size_t
|
static size_t
|
||||||
rtems_rtl_sect_align (size_t offset, uint32_t alignment)
|
rtems_rtl_sect_align (size_t offset, uint32_t alignment)
|
||||||
{
|
{
|
||||||
if ((alignment > 1) && ((offset & ~alignment) != 0))
|
if ((alignment > 1) && ((offset & (alignment - 1)) != 0))
|
||||||
offset = (offset + alignment) & ~(alignment - 1);
|
offset = (offset + alignment) & ~(alignment - 1);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@@ -264,12 +275,12 @@ rtems_rtl_obj_sect_summer (rtems_chain_node* node, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
rtems_rtl_obj_section_size (rtems_rtl_obj_t* obj, uint32_t mask)
|
rtems_rtl_obj_section_size (const rtems_rtl_obj_t* obj, uint32_t mask)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_summer_t summer;
|
rtems_rtl_obj_sect_summer_t summer;
|
||||||
summer.mask = mask;
|
summer.mask = mask;
|
||||||
summer.size = 0;
|
summer.size = 0;
|
||||||
rtems_rtl_chain_iterate (&obj->sections,
|
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
|
||||||
rtems_rtl_obj_sect_summer,
|
rtems_rtl_obj_sect_summer,
|
||||||
&summer);
|
&summer);
|
||||||
return summer.size;
|
return summer.size;
|
||||||
@@ -302,12 +313,12 @@ rtems_rtl_obj_sect_aligner (rtems_chain_node* node, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
rtems_rtl_obj_section_alignment (rtems_rtl_obj_t* obj, uint32_t mask)
|
rtems_rtl_obj_section_alignment (const rtems_rtl_obj_t* obj, uint32_t mask)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_aligner_t aligner;
|
rtems_rtl_obj_sect_aligner_t aligner;
|
||||||
aligner.mask = mask;
|
aligner.mask = mask;
|
||||||
aligner.alignment = 0;
|
aligner.alignment = 0;
|
||||||
rtems_rtl_chain_iterate (&obj->sections,
|
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
|
||||||
rtems_rtl_obj_sect_aligner,
|
rtems_rtl_obj_sect_aligner,
|
||||||
&aligner);
|
&aligner);
|
||||||
return aligner.alignment;
|
return aligner.alignment;
|
||||||
@@ -401,26 +412,30 @@ rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
|
|||||||
int info,
|
int info,
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_t* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
if (size > 0)
|
||||||
sizeof (rtems_rtl_obj_sect_t), true);
|
|
||||||
if (!sect)
|
|
||||||
{
|
{
|
||||||
rtems_rtl_set_error (ENOMEM, "adding allocated section");
|
rtems_rtl_obj_sect_t* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
||||||
return false;
|
sizeof (rtems_rtl_obj_sect_t),
|
||||||
}
|
true);
|
||||||
sect->section = section;
|
if (!sect)
|
||||||
sect->name = rtems_rtl_strdup (name);
|
{
|
||||||
sect->size = size;
|
rtems_rtl_set_error (ENOMEM, "adding allocated section");
|
||||||
sect->offset = offset;
|
return false;
|
||||||
sect->alignment = alignment;
|
}
|
||||||
sect->link = link;
|
sect->section = section;
|
||||||
sect->info = info;
|
sect->name = rtems_rtl_strdup (name);
|
||||||
sect->flags = flags;
|
sect->size = size;
|
||||||
sect->base = NULL;
|
sect->offset = offset;
|
||||||
rtems_chain_append (&obj->sections, §->node);
|
sect->alignment = alignment;
|
||||||
|
sect->link = link;
|
||||||
|
sect->info = info;
|
||||||
|
sect->flags = flags;
|
||||||
|
sect->base = NULL;
|
||||||
|
rtems_chain_append (&obj->sections, §->node);
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
|
||||||
printf ("rtl: sect: %-2d: %s\n", section, name);
|
printf ("rtl: sect: %-2d: %s (%zu)\n", section, name, size);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -464,12 +479,13 @@ rtems_rtl_obj_sect_match_name (rtems_chain_node* node, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtems_rtl_obj_sect_t*
|
rtems_rtl_obj_sect_t*
|
||||||
rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj, const char* name)
|
rtems_rtl_obj_find_section (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_finder_t match;
|
rtems_rtl_obj_sect_finder_t match;
|
||||||
match.sect = NULL;
|
match.sect = NULL;
|
||||||
match.name = name;
|
match.name = name;
|
||||||
rtems_rtl_chain_iterate (&obj->sections,
|
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
|
||||||
rtems_rtl_obj_sect_match_name,
|
rtems_rtl_obj_sect_match_name,
|
||||||
&match);
|
&match);
|
||||||
return match.sect;
|
return match.sect;
|
||||||
@@ -489,61 +505,74 @@ rtems_rtl_obj_sect_match_index (rtems_chain_node* node, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtems_rtl_obj_sect_t*
|
rtems_rtl_obj_sect_t*
|
||||||
rtems_rtl_obj_find_section_by_index (rtems_rtl_obj_t* obj, int index)
|
rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj_t* obj,
|
||||||
|
int index)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_finder_t match;
|
rtems_rtl_obj_sect_finder_t match;
|
||||||
match.sect = NULL;
|
match.sect = NULL;
|
||||||
match.index = index;
|
match.index = index;
|
||||||
rtems_rtl_chain_iterate (&obj->sections,
|
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
|
||||||
rtems_rtl_obj_sect_match_index,
|
rtems_rtl_obj_sect_match_index,
|
||||||
&match);
|
&match);
|
||||||
return match.sect;
|
return match.sect;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_text_size (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_TEXT);
|
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
rtems_rtl_obj_text_alignment (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_text_alignment (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_TEXT);
|
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_const_size (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_CONST);
|
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_CONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
rtems_rtl_obj_const_alignment (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_eh_alignment (const rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_EH);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
rtems_rtl_obj_eh_size (const rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_EH);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rtems_rtl_obj_const_alignment (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_CONST);
|
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_CONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_data_size (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_DATA);
|
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
rtems_rtl_obj_data_alignment (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_data_alignment (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_DATA);
|
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_bss_size (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
|
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
rtems_rtl_obj_bss_alignment (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_bss_alignment (const rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_BSS);
|
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_BSS);
|
||||||
}
|
}
|
||||||
@@ -572,21 +601,25 @@ typedef struct
|
|||||||
static bool
|
static bool
|
||||||
rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
|
rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
||||||
rtems_rtl_obj_sect_sync_ctx_t* sync_ctx = data;
|
rtems_rtl_obj_sect_sync_ctx_t* sync_ctx = data;
|
||||||
uintptr_t old_end;
|
uintptr_t old_end;
|
||||||
uintptr_t new_start;
|
uintptr_t new_start;
|
||||||
|
|
||||||
if ( !(sect->flags & sync_ctx->mask) || !sect->size)
|
if ((sect->flags & sync_ctx->mask) == 0 || sect->size == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (sync_ctx->end_va == sync_ctx->start_va) {
|
if (sync_ctx->end_va == sync_ctx->start_va)
|
||||||
|
{
|
||||||
sync_ctx->start_va = sect->base;
|
sync_ctx->start_va = sect->base;
|
||||||
} else {
|
}
|
||||||
old_end = (uintptr_t)sync_ctx->end_va & ~(sync_ctx->cache_line_size - 1);
|
else
|
||||||
new_start = (uintptr_t)sect->base & ~(sync_ctx->cache_line_size - 1);
|
{
|
||||||
if ( (sect->base < sync_ctx->start_va) ||
|
old_end = (uintptr_t) sync_ctx->end_va & ~(sync_ctx->cache_line_size - 1);
|
||||||
(new_start - old_end > sync_ctx->cache_line_size) ) {
|
new_start = (uintptr_t) sect->base & ~(sync_ctx->cache_line_size - 1);
|
||||||
|
if ((sect->base < sync_ctx->start_va) ||
|
||||||
|
(new_start - old_end > sync_ctx->cache_line_size))
|
||||||
|
{
|
||||||
rtems_cache_instruction_sync_after_code_change(sync_ctx->start_va,
|
rtems_cache_instruction_sync_after_code_change(sync_ctx->start_va,
|
||||||
sync_ctx->end_va - sync_ctx->start_va + 1);
|
sync_ctx->end_va - sync_ctx->start_va + 1);
|
||||||
sync_ctx->start_va = sect->base;
|
sync_ctx->start_va = sect->base;
|
||||||
@@ -599,7 +632,7 @@ rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_sync_ctx_t sync_ctx;
|
rtems_rtl_obj_sect_sync_ctx_t sync_ctx;
|
||||||
|
|
||||||
@@ -610,7 +643,7 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
|
|||||||
|
|
||||||
sync_ctx.mask = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST |
|
sync_ctx.mask = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST |
|
||||||
RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_BSS |
|
RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_BSS |
|
||||||
RTEMS_RTL_OBJ_SECT_EXEC;
|
RTEMS_RTL_OBJ_SECT_EH | RTEMS_RTL_OBJ_SECT_EXEC;
|
||||||
|
|
||||||
sync_ctx.start_va = 0;
|
sync_ctx.start_va = 0;
|
||||||
sync_ctx.end_va = sync_ctx.start_va;
|
sync_ctx.end_va = sync_ctx.start_va;
|
||||||
@@ -634,6 +667,87 @@ rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj,
|
|||||||
return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
|
return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtems_rtl_obj_sections_linked_to_order (rtems_rtl_obj_t* obj,
|
||||||
|
int section,
|
||||||
|
uint32_t visited_mask)
|
||||||
|
{
|
||||||
|
rtems_chain_control* sections = &obj->sections;
|
||||||
|
rtems_chain_node* node = rtems_chain_first (sections);
|
||||||
|
/*
|
||||||
|
* Find the section being linked-to. If the linked-to link field is 0 we have
|
||||||
|
* the end and the section's order is the position we are after.
|
||||||
|
*/
|
||||||
|
while (!rtems_chain_is_tail (sections, node))
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
||||||
|
if (sect->section == section)
|
||||||
|
{
|
||||||
|
const uint32_t mask = sect->flags & RTEMS_RTL_OBJ_SECT_TYPES;
|
||||||
|
int order = 0;
|
||||||
|
if (sect->link != 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Have we already visited this type of section? Avoid nesting for
|
||||||
|
* ever.
|
||||||
|
*/
|
||||||
|
if ((sect->flags & visited_mask) != 0)
|
||||||
|
{
|
||||||
|
rtems_rtl_set_error (errno, "section link loop");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return rtems_rtl_obj_sections_linked_to_order (obj,
|
||||||
|
sect->link,
|
||||||
|
visited_mask | mask);
|
||||||
|
}
|
||||||
|
node = rtems_chain_first (sections);
|
||||||
|
while (!rtems_chain_is_tail (sections, node))
|
||||||
|
{
|
||||||
|
sect = (rtems_rtl_obj_sect_t*) node;
|
||||||
|
if ((sect->flags & mask) == mask)
|
||||||
|
{
|
||||||
|
if (sect->section == section)
|
||||||
|
return order;
|
||||||
|
++order;
|
||||||
|
}
|
||||||
|
node = rtems_chain_next (node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = rtems_chain_next (node);
|
||||||
|
}
|
||||||
|
rtems_rtl_set_error (errno, "section link not found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtems_rtl_obj_sections_link_order (uint32_t mask, rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
rtems_chain_control* sections = &obj->sections;
|
||||||
|
rtems_chain_node* node = rtems_chain_first (sections);
|
||||||
|
int order = 0;
|
||||||
|
while (!rtems_chain_is_tail (sections, node))
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
||||||
|
if ((sect->flags & mask) == mask)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the section is linked in order find the linked-to section's order
|
||||||
|
* and move the section in the section list to
|
||||||
|
*/
|
||||||
|
if (sect->link == 0)
|
||||||
|
sect->load_order = order++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sect->load_order =
|
||||||
|
rtems_rtl_obj_sections_linked_to_order (obj,
|
||||||
|
sect->link,
|
||||||
|
mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = rtems_chain_next (node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
rtems_rtl_obj_sections_loader (uint32_t mask,
|
rtems_rtl_obj_sections_loader (uint32_t mask,
|
||||||
rtems_rtl_obj_t* obj,
|
rtems_rtl_obj_t* obj,
|
||||||
@@ -646,42 +760,54 @@ rtems_rtl_obj_sections_loader (uint32_t mask,
|
|||||||
rtems_chain_node* node = rtems_chain_first (sections);
|
rtems_chain_node* node = rtems_chain_first (sections);
|
||||||
size_t base_offset = 0;
|
size_t base_offset = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
int order = 0;
|
||||||
|
|
||||||
while (!rtems_chain_is_tail (sections, node))
|
while (!rtems_chain_is_tail (sections, node))
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
|
||||||
|
|
||||||
if ((sect->size != 0) && ((sect->flags & mask) != 0))
|
if ((sect->size != 0) && ((sect->flags & mask) != 0))
|
||||||
{
|
{
|
||||||
if (!first)
|
if (sect->load_order == order)
|
||||||
base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
|
|
||||||
|
|
||||||
sect->base = base + base_offset;
|
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
|
|
||||||
printf ("rtl: loading: %s -> %8p (%zi)\n",
|
|
||||||
sect->name, sect->base, sect->size);
|
|
||||||
|
|
||||||
if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
|
|
||||||
{
|
{
|
||||||
if (!handler (obj, fd, sect, data))
|
if (!first)
|
||||||
|
base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
sect->base = base + base_offset;
|
||||||
|
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
|
||||||
|
printf ("rtl: loading:%2d: %s -> %8p (s:%zi f:%04lx a:%lu l:%02d)\n",
|
||||||
|
order, sect->name, sect->base, sect->size,
|
||||||
|
sect->flags, sect->alignment, sect->link);
|
||||||
|
|
||||||
|
if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
|
||||||
|
{
|
||||||
|
if (!handler (obj, fd, sect, data))
|
||||||
|
{
|
||||||
|
sect->base = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
|
||||||
|
{
|
||||||
|
memset (base + base_offset, 0, sect->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
sect->base = 0;
|
sect->base = 0;
|
||||||
|
rtems_rtl_set_error (errno, "section has no load/clear op");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
|
|
||||||
{
|
|
||||||
memset (base + base_offset, 0, sect->size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sect->base = 0;
|
|
||||||
rtems_rtl_set_error (errno, "section has no load op");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
base_offset += sect->size;
|
base_offset += sect->size;
|
||||||
first = false;
|
|
||||||
|
++order;
|
||||||
|
|
||||||
|
node = rtems_chain_first (sections);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = rtems_chain_next (node);
|
node = rtems_chain_next (node);
|
||||||
@@ -698,20 +824,30 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
|
|||||||
{
|
{
|
||||||
size_t text_size;
|
size_t text_size;
|
||||||
size_t const_size;
|
size_t const_size;
|
||||||
|
size_t eh_size;
|
||||||
size_t data_size;
|
size_t data_size;
|
||||||
size_t bss_size;
|
size_t bss_size;
|
||||||
|
|
||||||
text_size = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_const_alignment (obj);
|
text_size = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_const_alignment (obj);
|
||||||
const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_data_alignment (obj);
|
const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_eh_alignment (obj);
|
||||||
|
eh_size = rtems_rtl_obj_eh_size (obj) + rtems_rtl_obj_data_alignment (obj);
|
||||||
data_size = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_bss_alignment (obj);
|
data_size = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_bss_alignment (obj);
|
||||||
bss_size = rtems_rtl_obj_bss_size (obj);
|
bss_size = rtems_rtl_obj_bss_size (obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the sizes held in the object data. We need this for a fast reference.
|
||||||
|
*/
|
||||||
|
obj->text_size = text_size;
|
||||||
|
obj->eh_size = eh_size;
|
||||||
|
obj->bss_size = bss_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let the allocator manage the actual allocation. The user can use the
|
* Let the allocator manage the actual allocation. The user can use the
|
||||||
* standard heap or provide a specific allocator with memory protection.
|
* standard heap or provide a specific allocator with memory protection.
|
||||||
*/
|
*/
|
||||||
if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
|
if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
|
||||||
&obj->const_base, const_size,
|
&obj->const_base, const_size,
|
||||||
|
&obj->eh_base, eh_size,
|
||||||
&obj->data_base, data_size,
|
&obj->data_base, data_size,
|
||||||
&obj->bss_base, bss_size))
|
&obj->bss_base, bss_size))
|
||||||
{
|
{
|
||||||
@@ -720,7 +856,7 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->exec_size = text_size + const_size + data_size + bss_size;
|
obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
|
||||||
{
|
{
|
||||||
@@ -728,12 +864,22 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
|
|||||||
obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
|
obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
|
||||||
printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
|
obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
|
||||||
|
printf ("rtl: load sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
|
obj->eh_base, eh_size, rtems_rtl_obj_eh_alignment (obj));
|
||||||
printf ("rtl: load sect: data - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: load sect: data - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
|
obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
|
||||||
printf ("rtl: load sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: load sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
|
obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the load order.
|
||||||
|
*/
|
||||||
|
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_TEXT, obj);
|
||||||
|
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_CONST, obj);
|
||||||
|
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_EH, obj);
|
||||||
|
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_DATA, obj);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load all text then data then bss sections in seperate operations so each
|
* Load all text then data then bss sections in seperate operations so each
|
||||||
* type of section is grouped together.
|
* type of section is grouped together.
|
||||||
@@ -742,12 +888,14 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
|
|||||||
obj, fd, obj->text_base, handler, data) ||
|
obj, fd, obj->text_base, handler, data) ||
|
||||||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST,
|
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST,
|
||||||
obj, fd, obj->const_base, handler, data) ||
|
obj, fd, obj->const_base, handler, data) ||
|
||||||
|
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_EH,
|
||||||
|
obj, fd, obj->eh_base, handler, data) ||
|
||||||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA,
|
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA,
|
||||||
obj, fd, obj->data_base, handler, data) ||
|
obj, fd, obj->data_base, handler, data) ||
|
||||||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS,
|
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS,
|
||||||
obj, fd, obj->bss_base, handler, data))
|
obj, fd, obj->bss_base, handler, data))
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
|
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
|
||||||
&obj->data_base, &obj->bss_base);
|
&obj->data_base, &obj->bss_base);
|
||||||
obj->exec_size = 0;
|
obj->exec_size = 0;
|
||||||
return false;
|
return false;
|
||||||
@@ -972,7 +1120,7 @@ rtems_rtl_obj_archive_find (rtems_rtl_obj_t* obj, int fd)
|
|||||||
* name from the table and compare with the name we are after.
|
* name from the table and compare with the name we are after.
|
||||||
*/
|
*/
|
||||||
#define RTEMS_RTL_MAX_FILE_SIZE (256)
|
#define RTEMS_RTL_MAX_FILE_SIZE (256)
|
||||||
char name[RTEMS_RTL_MAX_FILE_SIZE];
|
char name[RTEMS_RTL_MAX_FILE_SIZE];
|
||||||
|
|
||||||
if (!rtems_rtl_seek_read (fd, extended_file_names + extended_off,
|
if (!rtems_rtl_seek_read (fd, extended_file_names + extended_off,
|
||||||
RTEMS_RTL_MAX_FILE_SIZE, (uint8_t*) &name[0]))
|
RTEMS_RTL_MAX_FILE_SIZE, (uint8_t*) &name[0]))
|
||||||
@@ -1016,7 +1164,7 @@ rtems_rtl_obj_archive_find (rtems_rtl_obj_t* obj, int fd)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd)
|
rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
@@ -1024,13 +1172,24 @@ rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd)
|
|||||||
for (l = 0; l < (sizeof (loaders) / sizeof (rtems_rtl_loader_table_t)); ++l)
|
for (l = 0; l < (sizeof (loaders) / sizeof (rtems_rtl_loader_table_t)); ++l)
|
||||||
{
|
{
|
||||||
if (loaders[l].check (obj, fd))
|
if (loaders[l].check (obj, fd))
|
||||||
|
{
|
||||||
|
obj->format = l;
|
||||||
return loaders[l].load (obj, fd);
|
return loaders[l].load (obj, fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_rtl_set_error (ENOENT, "no format loader found");
|
rtems_rtl_set_error (ENOENT, "no format loader found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
rtems_rtl_obj_file_unload (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
if (obj->format >= 0 && obj->format < RTEMS_RTL_LOADERS)
|
||||||
|
return loaders[obj->format].unload (obj);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
@@ -1057,20 +1216,16 @@ rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
|
|||||||
{
|
{
|
||||||
if (!rtems_rtl_obj_archive_find (obj, fd))
|
if (!rtems_rtl_obj_archive_find (obj, fd))
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_caches_flush ();
|
|
||||||
close (fd);
|
close (fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call the format specific loader. Currently this is a call to the ELF
|
* Call the format specific loader.
|
||||||
* loader. This call could be changed to allow probes then calls if more than
|
|
||||||
* one format is supported.
|
|
||||||
*/
|
*/
|
||||||
if (!rtems_rtl_obj_file_load (obj, fd))
|
if (!rtems_rtl_obj_file_load (obj, fd))
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_caches_flush ();
|
|
||||||
close (fd);
|
close (fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1081,8 +1236,6 @@ rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_rtl_obj_caches_flush ();
|
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1092,6 +1245,6 @@ bool
|
|||||||
rtems_rtl_obj_unload (rtems_rtl_obj_t* obj)
|
rtems_rtl_obj_unload (rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
_rtld_linkmap_delete(obj);
|
_rtld_linkmap_delete(obj);
|
||||||
rtems_rtl_symbol_obj_erase (obj);
|
rtems_rtl_obj_file_unload (obj);
|
||||||
return rtems_rtl_obj_free (obj);
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,14 +56,20 @@ typedef struct rtems_rtl_loader_format_s
|
|||||||
typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
|
typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the format loader handler. This handler loads the specific
|
* The type of the format loader load handler. This handler loads the specific
|
||||||
* format.
|
* format.
|
||||||
*/
|
*/
|
||||||
typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
|
typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the format loader handler. This handler loads the specific
|
* The type of the format loader unload handler. This handler unloads the
|
||||||
* format.
|
* specific format.
|
||||||
|
*/
|
||||||
|
typedef bool (*rtems_rtl_loader_unload) (rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the format loader signature handler. This handler checks the
|
||||||
|
* format signature.
|
||||||
*/
|
*/
|
||||||
typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
|
typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
|
||||||
|
|
||||||
@@ -72,9 +78,10 @@ typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
|
|||||||
*/
|
*/
|
||||||
typedef struct rtems_rtl_loader_table_s
|
typedef struct rtems_rtl_loader_table_s
|
||||||
{
|
{
|
||||||
rtems_rtl_loader_check check; /**< The check handler. */
|
rtems_rtl_loader_check check; /**< The check handler. */
|
||||||
rtems_rtl_loader_load load; /**< The loader. */
|
rtems_rtl_loader_load load; /**< The loader. */
|
||||||
rtems_rtl_loader_sig signature; /**< The loader's signature. */
|
rtems_rtl_loader_unload unload; /**< The unloader. */
|
||||||
|
rtems_rtl_loader_sig signature; /**< The loader's signature. */
|
||||||
} rtems_rtl_loader_table_t;
|
} rtems_rtl_loader_table_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,18 +91,30 @@ typedef struct rtems_rtl_loader_table_s
|
|||||||
#define RTEMS_RTL_OBJ_SECT_CONST (1 << 1) /**< Section holds program text. */
|
#define RTEMS_RTL_OBJ_SECT_CONST (1 << 1) /**< Section holds program text. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_DATA (1 << 2) /**< Section holds program data. */
|
#define RTEMS_RTL_OBJ_SECT_DATA (1 << 2) /**< Section holds program data. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */
|
#define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_REL (1 << 4) /**< Section holds relocation records. */
|
#define RTEMS_RTL_OBJ_SECT_EH (1 << 4) /**< Section holds exception data. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_RELA (1 << 5) /**< Section holds relocation addend
|
#define RTEMS_RTL_OBJ_SECT_REL (1 << 5) /**< Section holds relocation records. */
|
||||||
|
#define RTEMS_RTL_OBJ_SECT_RELA (1 << 6) /**< Section holds relocation addend
|
||||||
* records. */
|
* records. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_SYM (1 << 6) /**< Section holds symbols. */
|
#define RTEMS_RTL_OBJ_SECT_SYM (1 << 7) /**< Section holds symbols. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_STR (1 << 7) /**< Section holds strings. */
|
#define RTEMS_RTL_OBJ_SECT_STR (1 << 8) /**< Section holds strings. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 8) /**< Section allocates runtime memory. */
|
#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 9) /**< Section allocates runtime memory. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_LOAD (1 << 9) /**< Section is loaded from object file. */
|
#define RTEMS_RTL_OBJ_SECT_LOAD (1 << 10) /**< Section is loaded from object file. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 10) /**< Section is writable, ie data. */
|
#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 11) /**< Section is writable, ie data. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_EXEC (1 << 11) /**< Section is executable. */
|
#define RTEMS_RTL_OBJ_SECT_EXEC (1 << 12) /**< Section is executable. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_ZERO (1 << 12) /**< Section is preset to zero. */
|
#define RTEMS_RTL_OBJ_SECT_ZERO (1 << 13) /**< Section is preset to zero. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_CTOR (1 << 13) /**< Section contains constructors. */
|
#define RTEMS_RTL_OBJ_SECT_LINK (1 << 14) /**< Section is link-ordered. */
|
||||||
#define RTEMS_RTL_OBJ_SECT_DTOR (1 << 14) /**< Section contains destructors. */
|
#define RTEMS_RTL_OBJ_SECT_CTOR (1 << 15) /**< Section contains constructors. */
|
||||||
|
#define RTEMS_RTL_OBJ_SECT_DTOR (1 << 16) /**< Section contains destructors. */
|
||||||
|
#define RTEMS_RTL_OBJ_SECT_LOCD (1 << 17) /**< Section has been located. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Section types mask.
|
||||||
|
*/
|
||||||
|
#define RTEMS_RTL_OBJ_SECT_TYPES (RTEMS_RTL_OBJ_SECT_TEXT | \
|
||||||
|
RTEMS_RTL_OBJ_SECT_CONST | \
|
||||||
|
RTEMS_RTL_OBJ_SECT_DATA | \
|
||||||
|
RTEMS_RTL_OBJ_SECT_BSS | \
|
||||||
|
RTEMS_RTL_OBJ_SECT_EH)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object file is made up of sections and the can be more than
|
* An object file is made up of sections and the can be more than
|
||||||
@@ -109,13 +128,14 @@ struct rtems_rtl_obj_sect_s
|
|||||||
const char* name; /**< The section's name. */
|
const char* name; /**< The section's name. */
|
||||||
size_t size; /**< The size of the section in memory. */
|
size_t size; /**< The size of the section in memory. */
|
||||||
off_t offset; /**< Offset into the object file. Relative to
|
off_t offset; /**< Offset into the object file. Relative to
|
||||||
* the start of the object file. */
|
* the start of the object file. */
|
||||||
uint32_t alignment; /**< Alignment of this section. */
|
uint32_t alignment; /**< Alignment of this section. */
|
||||||
int link; /**< Section link field. */
|
int link; /**< Section link field. */
|
||||||
int info; /**< Secfion info field. */
|
int info; /**< Secfion info field. */
|
||||||
uint32_t flags; /**< The section's flags. */
|
uint32_t flags; /**< The section's flags. */
|
||||||
void* base; /**< The base address of the section in
|
void* base; /**< The base address of the section in
|
||||||
* memory. */
|
* memory. */
|
||||||
|
int load_order; /**< Order we load sections. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,6 +155,7 @@ struct rtems_rtl_obj_s
|
|||||||
rtems_chain_node link; /**< The node's link in the chain. */
|
rtems_chain_node link; /**< The node's link in the chain. */
|
||||||
uint32_t flags; /**< The status of the object file. */
|
uint32_t flags; /**< The status of the object file. */
|
||||||
uint32_t users; /**< References to the object file. */
|
uint32_t users; /**< References to the object file. */
|
||||||
|
int format; /**< The format of the object file. */
|
||||||
const char* fname; /**< The file name for the object. */
|
const char* fname; /**< The file name for the object. */
|
||||||
const char* oname; /**< The object file name. Can be
|
const char* oname; /**< The object file name. Can be
|
||||||
* relative. */
|
* relative. */
|
||||||
@@ -153,26 +174,27 @@ struct rtems_rtl_obj_s
|
|||||||
size_t global_size; /**< Global symbol memory usage. */
|
size_t global_size; /**< Global symbol memory usage. */
|
||||||
uint32_t unresolved; /**< The number of unresolved relocations. */
|
uint32_t unresolved; /**< The number of unresolved relocations. */
|
||||||
void* text_base; /**< The base address of the text section
|
void* text_base; /**< The base address of the text section
|
||||||
* in memory. */
|
* in memory. */
|
||||||
|
size_t text_size; /**< The size of the text section. */
|
||||||
void* const_base; /**< The base address of the const section
|
void* const_base; /**< The base address of the const section
|
||||||
* in memory. */
|
* in memory. */
|
||||||
|
void* eh_base; /**< The base address of the eh section
|
||||||
|
* in memory. */
|
||||||
|
size_t eh_size; /**< The size of the eh section. */
|
||||||
void* data_base; /**< The base address of the data section
|
void* data_base; /**< The base address of the data section
|
||||||
* in memory. */
|
* in memory. */
|
||||||
void* bss_base; /**< The base address of the bss section
|
void* bss_base; /**< The base address of the bss section
|
||||||
* in memory. */
|
* in memory. */
|
||||||
size_t bss_size; /**< The size of the bss section. */
|
size_t bss_size; /**< The size of the bss section. */
|
||||||
size_t exec_size; /**< The amount of executable memory
|
size_t exec_size; /**< The amount of executable memory
|
||||||
* allocated */
|
* allocated */
|
||||||
void* entry; /**< The entry point of the module. */
|
void* entry; /**< The entry point of the module. */
|
||||||
uint32_t checksum; /**< The checksum of the text sections. A
|
uint32_t checksum; /**< The checksum of the text sections. A
|
||||||
* zero means do not checksum. */
|
* zero means do not checksum. */
|
||||||
void* detail; /**< The file details. It contains the elf file
|
|
||||||
* detail, mainly including elf file name,
|
|
||||||
* section offset, section size, which
|
|
||||||
* elf this section belongs to.*/
|
|
||||||
uint32_t* sec_num; /**< The sec nums of each obj. */
|
uint32_t* sec_num; /**< The sec nums of each obj. */
|
||||||
uint32_t obj_num; /**< The count of elf files in an rtl obj. */
|
uint32_t obj_num; /**< The count of elf files in an rtl obj. */
|
||||||
struct link_map* linkmap; /**< For GDB. */
|
struct link_map* linkmap; /**< For GDB. */
|
||||||
|
void* loader; /**< The file details specific to a loader. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -257,6 +279,20 @@ static inline bool rtems_rtl_obj_aname_valid (const rtems_rtl_obj_t* obj)
|
|||||||
return obj->aname;
|
return obj->aname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the address inside the text section?
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @return bool There is an archive name
|
||||||
|
*/
|
||||||
|
static inline bool rtems_rtl_obj_text_inside (const rtems_rtl_obj_t* obj,
|
||||||
|
const void* address)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(address >= obj->text_base) &&
|
||||||
|
(address < (obj->text_base + obj->text_size));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an object structure on the heap.
|
* Allocate an object structure on the heap.
|
||||||
*
|
*
|
||||||
@@ -299,18 +335,6 @@ bool rtems_rtl_parse_name (const char* name,
|
|||||||
const char** oname,
|
const char** oname,
|
||||||
off_t* ooffset);
|
off_t* ooffset);
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the object file.
|
|
||||||
*
|
|
||||||
* @param obj The object file's descriptor.
|
|
||||||
* @param fd The file descriptor.
|
|
||||||
* @param load_syms Load symbols.
|
|
||||||
* @param load_dep Load dependent object files.
|
|
||||||
* @retval true The load was successful.
|
|
||||||
* @retval false The load failed. The RTL error has been set.
|
|
||||||
*/
|
|
||||||
bool rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check of the name matches the object file's object name.
|
* Check of the name matches the object file's object name.
|
||||||
*
|
*
|
||||||
@@ -371,8 +395,8 @@ void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj);
|
|||||||
* @retval NULL The section was not found.
|
* @retval NULL The section was not found.
|
||||||
* @return rtems_rtl_obj_sect_t* The named section.
|
* @return rtems_rtl_obj_sect_t* The named section.
|
||||||
*/
|
*/
|
||||||
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj,
|
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (const rtems_rtl_obj_t* obj,
|
||||||
const char* name);
|
const char* name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a section given a section's index number.
|
* Find a section given a section's index number.
|
||||||
@@ -382,21 +406,21 @@ rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj,
|
|||||||
* @retval NULL The section was not found.
|
* @retval NULL The section was not found.
|
||||||
* @return rtems_rtl_obj_sect_t* The found section.
|
* @return rtems_rtl_obj_sect_t* The found section.
|
||||||
*/
|
*/
|
||||||
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (rtems_rtl_obj_t* obj,
|
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj_t* obj,
|
||||||
int index);
|
int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text size of the object file. Only use once all the sections has been
|
* The text section size. Only use once all the sections has been added. It
|
||||||
* added. It includes alignments between sections that are part of the object's
|
* includes alignments between sections that are part of the object's text
|
||||||
* text area. The consts sections are included in this section.
|
* area. The consts sections are included in this section.
|
||||||
*
|
*
|
||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return size_t The size of the text area of the object file.
|
* @return size_t The size of the text area of the object file.
|
||||||
*/
|
*/
|
||||||
size_t rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj);
|
size_t rtems_rtl_obj_text_size (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text section alignment of the object file. Only use once all the
|
* The text section alignment for the object file. Only use once all the
|
||||||
* sections has been added. The section alignment is the alignment of the first
|
* sections has been added. The section alignment is the alignment of the first
|
||||||
* text type section loaded the text section.
|
* text type section loaded the text section.
|
||||||
*
|
*
|
||||||
@@ -406,20 +430,20 @@ size_t rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj);
|
|||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
||||||
*/
|
*/
|
||||||
uint32_t rtems_rtl_obj_text_alignment (rtems_rtl_obj_t* obj);
|
uint32_t rtems_rtl_obj_text_alignment (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The const size of the object file. Only use once all the sections has been
|
* The const section size. Only use once all the sections has been added. It
|
||||||
* added. It includes alignments between sections that are part of the object's
|
* includes alignments between sections that are part of the object's const
|
||||||
* const area. The consts sections are included in this section.
|
* area. The consts sections are included in this section.
|
||||||
*
|
*
|
||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return size_t The size of the const area of the object file.
|
* @return size_t The size of the const area of the object file.
|
||||||
*/
|
*/
|
||||||
size_t rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj);
|
size_t rtems_rtl_obj_const_size (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The const section alignment of the object file. Only use once all the
|
* The const section alignment for the object file. Only use once all the
|
||||||
* sections has been added. The section alignment is the alignment of the first
|
* sections has been added. The section alignment is the alignment of the first
|
||||||
* const type section loaded the const section.
|
* const type section loaded the const section.
|
||||||
*
|
*
|
||||||
@@ -429,20 +453,42 @@ size_t rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj);
|
|||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
||||||
*/
|
*/
|
||||||
uint32_t rtems_rtl_obj_const_alignment (rtems_rtl_obj_t* obj);
|
uint32_t rtems_rtl_obj_const_alignment (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data size of the object file. Only use once all the sections has been
|
* The eh section size. Only use once all the sections has been added. It
|
||||||
* added. It includes alignments between sections that are part of the object's
|
* includes alignments between sections that are part of the object's bss area.
|
||||||
* data area.
|
*
|
||||||
|
* @param obj The object file's descriptor.
|
||||||
|
* @return size_t The size of the bss area of the object file.
|
||||||
|
*/
|
||||||
|
size_t rtems_rtl_obj_eh_size (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The eh section alignment for the object file. Only use once all the sections
|
||||||
|
* has been added. The section alignment is the alignment of the first bss type
|
||||||
|
* section loaded the bss section.
|
||||||
|
*
|
||||||
|
* You can assume the alignment is a positive integral power of 2 if not 0 or
|
||||||
|
* 1. If 0 or 1 then there is no alignment.
|
||||||
|
*
|
||||||
|
* @param obj The object file's descriptor.
|
||||||
|
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
||||||
|
*/
|
||||||
|
uint32_t rtems_rtl_obj_eh_alignment (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data section size. Only use once all the sections has been added. It
|
||||||
|
* includes alignments between sections that are part of the object's data
|
||||||
|
* area.
|
||||||
*
|
*
|
||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return size_t The size of the data area of the object file.
|
* @return size_t The size of the data area of the object file.
|
||||||
*/
|
*/
|
||||||
size_t rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj);
|
size_t rtems_rtl_obj_data_size (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data section alignment of the object file. Only use once all the
|
* The data section alignment for the object file. Only use once all the
|
||||||
* sections has been added. The section alignment is the alignment of the first
|
* sections has been added. The section alignment is the alignment of the first
|
||||||
* data type section loaded the data section.
|
* data type section loaded the data section.
|
||||||
*
|
*
|
||||||
@@ -452,20 +498,19 @@ size_t rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj);
|
|||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
||||||
*/
|
*/
|
||||||
uint32_t rtems_rtl_obj_data_alignment (rtems_rtl_obj_t* obj);
|
uint32_t rtems_rtl_obj_data_alignment (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bss size of the object file. Only use once all the sections has been
|
* The bss section size. Only use once all the sections has been added. It
|
||||||
* added. It includes alignments between sections that are part of the object's
|
* includes alignments between sections that are part of the object's bss area.
|
||||||
* bss area.
|
|
||||||
*
|
*
|
||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return size_t The size of the bss area of the object file.
|
* @return size_t The size of the bss area of the object file.
|
||||||
*/
|
*/
|
||||||
size_t rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj);
|
size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bss section alignment of the object file. Only use once all the
|
* The bss section alignment for the object file. Only use once all the
|
||||||
* sections has been added. The section alignment is the alignment of the first
|
* sections has been added. The section alignment is the alignment of the first
|
||||||
* bss type section loaded the bss section.
|
* bss type section loaded the bss section.
|
||||||
*
|
*
|
||||||
@@ -475,7 +520,7 @@ size_t rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj);
|
|||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
|
||||||
*/
|
*/
|
||||||
uint32_t rtems_rtl_obj_bss_alignment (rtems_rtl_obj_t* obj);
|
uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relocate the object file. The object file's section are parsed for any
|
* Relocate the object file. The object file's section are parsed for any
|
||||||
|
|||||||
@@ -427,20 +427,22 @@ rtems_rtl_rap_relocate (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The structure of obj->detail is
|
* The structure of obj->linkmap is:
|
||||||
*
|
*
|
||||||
* |object_detail(0..obj_num)|section_detail(0..sec_num[0..obj_num])|
|
* |object_detail(0..obj_num)|section_detail(0..sec_num[0..obj_num])|
|
||||||
* obj_name(0..obj_num)|section_name(0..sec_num[0..obj_num])
|
* obj_name(0..obj_num)|section_name(0..sec_num[0..obj_num])
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
rtems_rtl_rap_load_linkmap (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
||||||
{
|
{
|
||||||
|
void* detail;
|
||||||
struct link_map* tmp1;
|
struct link_map* tmp1;
|
||||||
section_detail* tmp2;
|
section_detail* tmp2;
|
||||||
uint32_t obj_detail_size;
|
uint32_t obj_detail_size;
|
||||||
uint32_t pos = 0;
|
uint32_t pos = 0;
|
||||||
int i,j;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
obj_detail_size = sizeof (struct link_map) * obj->obj_num;
|
obj_detail_size = sizeof (struct link_map) * obj->obj_num;
|
||||||
|
|
||||||
@@ -449,26 +451,31 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
|||||||
obj_detail_size += (obj->sec_num[i] * sizeof (section_detail));
|
obj_detail_size += (obj->sec_num[i] * sizeof (section_detail));
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
||||||
obj_detail_size + rap->strtable_size, true);
|
obj_detail_size + rap->strtable_size, true);
|
||||||
|
|
||||||
if (!obj->detail)
|
if (!detail)
|
||||||
{
|
{
|
||||||
rap->strtable_size = 0;
|
rap->strtable_size = 0;
|
||||||
rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
|
rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rap->strtable = obj->detail + obj_detail_size;
|
rap->strtable = detail + obj_detail_size;
|
||||||
|
|
||||||
/* Read the obj names and section names */
|
/*
|
||||||
if (!rtems_rtl_obj_comp_read (rap->decomp, rap->strtable,
|
* Read the obj names and section names
|
||||||
|
*/
|
||||||
|
if (!rtems_rtl_obj_comp_read (rap->decomp,
|
||||||
|
rap->strtable,
|
||||||
rap->strtable_size))
|
rap->strtable_size))
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->detail);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, detail);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj->linkmap = (struct link_map*) detail;
|
||||||
|
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
||||||
{
|
{
|
||||||
if (rap->rpathlen > 0)
|
if (rap->rpathlen > 0)
|
||||||
@@ -489,7 +496,7 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
|||||||
|
|
||||||
for (i = 0; i < obj->obj_num; ++i)
|
for (i = 0; i < obj->obj_num; ++i)
|
||||||
{
|
{
|
||||||
tmp1 = (struct link_map*) (obj->detail) + i;
|
tmp1 = obj->linkmap + i;
|
||||||
tmp1->name = rap->strtable + pos;
|
tmp1->name = rap->strtable + pos;
|
||||||
tmp1->sec_num = obj->sec_num[i];
|
tmp1->sec_num = obj->sec_num[i];
|
||||||
tmp1->rpathlen = rap->rpathlen;
|
tmp1->rpathlen = rap->rpathlen;
|
||||||
@@ -509,17 +516,17 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp2 =(section_detail*) ((struct link_map*) (obj->detail) + obj->obj_num);
|
tmp2 = (section_detail*) (obj->linkmap + obj->obj_num);
|
||||||
|
|
||||||
for (i = 0; i < obj->obj_num; ++i)
|
for (i = 0; i < obj->obj_num; ++i)
|
||||||
{
|
{
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
||||||
{
|
{
|
||||||
printf ("File %d: %s\n", i, ((struct link_map*) obj->detail + i)->name);
|
printf ("File %d: %s\n", i, (obj->linkmap + i)->name);
|
||||||
printf ("Section: %d sections\n",(unsigned int) obj->sec_num[i]);
|
printf ("Section: %d sections\n", (unsigned int) obj->sec_num[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
((struct link_map*)obj->detail + i)->sec_detail = tmp2;
|
obj->linkmap[i].sec_detail = tmp2;
|
||||||
|
|
||||||
for (j = 0; j < obj->sec_num[i]; ++j)
|
for (j = 0; j < obj->sec_num[i]; ++j)
|
||||||
{
|
{
|
||||||
@@ -532,7 +539,8 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
|
|||||||
!rtems_rtl_rap_read_uint32 (rap->decomp, &offset) ||
|
!rtems_rtl_rap_read_uint32 (rap->decomp, &offset) ||
|
||||||
!rtems_rtl_rap_read_uint32 (rap->decomp, &size))
|
!rtems_rtl_rap_read_uint32 (rap->decomp, &size))
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->detail);
|
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->linkmap);
|
||||||
|
obj->linkmap = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,7 +915,7 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
|
|||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
|
||||||
printf ("rtl: rap: details: obj_num=%lu\n", obj->obj_num);
|
printf ("rtl: rap: details: obj_num=%lu\n", obj->obj_num);
|
||||||
|
|
||||||
if (!rtems_rtl_rap_load_details (&rap, obj))
|
if (!rtems_rtl_rap_load_linkmap (&rap, obj))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,6 +983,13 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_rap_file_unload (rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
rtems_rtl_loader_format_t*
|
rtems_rtl_loader_format_t*
|
||||||
rtems_rtl_rap_file_sig (void)
|
rtems_rtl_rap_file_sig (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,6 +40,13 @@ bool rtems_rtl_rap_file_check (rtems_rtl_obj_t* obj, int fd);
|
|||||||
*/
|
*/
|
||||||
bool rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd);
|
bool rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The RAP format unload handler.
|
||||||
|
*
|
||||||
|
* @param obj The object to unload.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_rap_file_unload (rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RAP format signature handler.
|
* The RAP format signature handler.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
* Flag the targets where off_t is 32 bits. This is not a compiler type
|
* Flag the targets where off_t is 32 bits. This is not a compiler type
|
||||||
* so we can't rely on prerdefines.
|
* so we can't rely on prerdefines.
|
||||||
*/
|
*/
|
||||||
#if defined(__m32r__) || defined(__moxie__)
|
#if defined(__moxie__)
|
||||||
#define PRIdoff_t PRIo32
|
#define PRIdoff_t PRIo32
|
||||||
#else
|
#else
|
||||||
#define PRIdoff_t PRIo64
|
#define PRIdoff_t PRIo64
|
||||||
|
|||||||
71
cpukit/libdl/rtl-unwind-dw2.c
Normal file
71
cpukit/libdl/rtl-unwind-dw2.c
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT (c) 2012-2016 Chris Johns <chrisj@rtems.org>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup rtems_rtld
|
||||||
|
*
|
||||||
|
* @brief RTEMS Run-Time Link Editor
|
||||||
|
*
|
||||||
|
* This is the RTL implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <rtems/rtl/rtl.h>
|
||||||
|
#include "rtl-elf.h"
|
||||||
|
#include "rtl-error.h"
|
||||||
|
#include "rtl-unwind.h"
|
||||||
|
#include "rtl-unwind-dw2.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These interfaces are not exported outside the GCC source.
|
||||||
|
*/
|
||||||
|
void __register_frame (void *begin);
|
||||||
|
void __deregister_frame (void *begin);
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_dw2_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
((flags & RTEMS_RTL_OBJ_SECT_CONST) != 0) &&
|
||||||
|
((strcmp(name, ".eh_frame") == 0) ||
|
||||||
|
(strncmp(name, ".gcc_except_table.", sizeof (".gcc_except_table.") - 1) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_elf_unwind_dw2_register (const rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_sect_t* sect = rtems_rtl_obj_find_section (obj, ".eh_frame");
|
||||||
|
|
||||||
|
if (sect != NULL && sect->size > 0 && sect->base != NULL)
|
||||||
|
{
|
||||||
|
__register_frame (sect->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtems_rtl_elf_unwind_dw2_deregister (const rtems_rtl_obj_t* obj)
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_sect_t* sect = rtems_rtl_obj_find_section (obj, ".eh_frame");
|
||||||
|
|
||||||
|
if (sect != NULL && sect->size > 0 && sect->base != NULL)
|
||||||
|
{
|
||||||
|
__deregister_frame (sect->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
83
cpukit/libdl/rtl-unwind-dw2.h
Normal file
83
cpukit/libdl/rtl-unwind-dw2.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT (c) 2016 Chris Johns <chrisj@rtems.org>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup rtems_rtl
|
||||||
|
*
|
||||||
|
* @brief RTEMS Run-Time Linker Unwind DWARF Support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (_RTEMS_RTL_UNWIND_DW2_H_)
|
||||||
|
#define _RTEMS_RTL_UNWIND_DW2_H_
|
||||||
|
|
||||||
|
#include "rtl-elf.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#if __SIZEOF_LONG__ >= __SIZEOF_POINTER__
|
||||||
|
typedef long rtems_rtl_elf_unwind_dw2_sleb128;
|
||||||
|
typedef unsigned long rtems_rtl_elf_unwind_dw2_uleb128;
|
||||||
|
#elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__
|
||||||
|
typedef long long rtems_rtl_elf_unwind_dw2_sleb128;
|
||||||
|
typedef unsigned long long rtems_rtl_elf_unwind_dw2_uleb128;
|
||||||
|
#else
|
||||||
|
#error No DW2 type available.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to check if a section contains exception
|
||||||
|
* handler data..
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @param name The section's name.
|
||||||
|
* @param uint32 flags The object file's flags.
|
||||||
|
* @retval true The section contains unwind information.
|
||||||
|
* @retval false The section does not contain unwind information.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_unwind_dw2_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to add an object file's unwind information to
|
||||||
|
* the base image.
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @retval true The unwind information has been registered.
|
||||||
|
* @retval false The unwind information could not be registered.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_unwind_dw2_register (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to remove an object file's unwind information
|
||||||
|
* from the base image.
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @retval true The unwind information has been deregistered.
|
||||||
|
* @retval false The unwind information could not be deregistered.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_unwind_dw2_deregister (const rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read signed and unsigned LEB128 values.
|
||||||
|
*/
|
||||||
|
const uint8_t* rtems_rtl_elf_unwind_dw2_read_uleb128 (const uint8_t* data,
|
||||||
|
rtems_rtl_elf_unwind_dw2_uleb128* val);
|
||||||
|
const uint8_t* rtems_rtl_elf_unwind_dw2_read_sleb128 (const uint8_t* data,
|
||||||
|
rtems_rtl_elf_unwind_dw2_sleb128* val);
|
||||||
|
|
||||||
|
bool rtems_rtl_elf_unwind_dw2_relocate (const Elf_Addr* where, Elf_Word value, Elf_Word mask);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif
|
||||||
63
cpukit/libdl/rtl-unwind.h
Normal file
63
cpukit/libdl/rtl-unwind.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT (c) 2016 Chris Johns <chrisj@rtems.org>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup rtems_rtl
|
||||||
|
*
|
||||||
|
* @brief RTEMS Run-Time Linker Unwind Support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (_RTEMS_RTL_UNWIND_H_)
|
||||||
|
#define _RTEMS_RTL_UNWIND_H_
|
||||||
|
|
||||||
|
#include "rtl-elf.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to check if a section contains exception
|
||||||
|
* handler data..
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @param name The section's name.
|
||||||
|
* @param uint32 flags The object file's flags.
|
||||||
|
* @retval true The section contains unwind information.
|
||||||
|
* @retval false The section does not contain unwind information.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
|
||||||
|
const char* name,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to add an object file's unwind information to
|
||||||
|
* the base image.
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @retval true The unwind information has been registered.
|
||||||
|
* @retval false The unwind information could not be registered.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specific handler to remove an object file's unwind information
|
||||||
|
* from the base image.
|
||||||
|
*
|
||||||
|
* @param obj The object file.
|
||||||
|
* @retval true The unwind information has been deregistered.
|
||||||
|
* @retval false The unwind information could not be deregistered.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
* Static RTL data is returned to the user when the linker is locked.
|
* Static RTL data is returned to the user when the linker is locked.
|
||||||
*/
|
*/
|
||||||
static rtems_rtl_data_t* rtl;
|
static rtems_rtl_data_t* rtl;
|
||||||
|
static bool rtl_data_init;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a default base global symbol loader function that is weak
|
* Define a default base global symbol loader function that is weak
|
||||||
@@ -94,12 +95,26 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_status_code sc;
|
rtems_status_code sc;
|
||||||
rtems_id lock;
|
rtems_id lock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We cannot set an error in this code because there is no RTL data to
|
||||||
|
* hold it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (rtl_data_init)
|
||||||
|
{
|
||||||
|
rtems_libio_unlock ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtl_data_init = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always in the heap.
|
* Always in the heap.
|
||||||
*/
|
*/
|
||||||
rtl = malloc (sizeof (rtems_rtl_data_t));
|
rtl = malloc (sizeof (rtems_rtl_data_t));
|
||||||
if (!rtl)
|
if (!rtl)
|
||||||
{
|
{
|
||||||
|
rtems_libio_unlock ();
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -120,6 +135,7 @@ rtems_rtl_data_init (void)
|
|||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
{
|
{
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +144,7 @@ rtems_rtl_data_init (void)
|
|||||||
{
|
{
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,6 +160,7 @@ rtems_rtl_data_init (void)
|
|||||||
{
|
{
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,6 +170,7 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_rtl_symbol_table_close (&rtl->globals);
|
rtems_rtl_symbol_table_close (&rtl->globals);
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +181,7 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_rtl_unresolved_table_close (&rtl->unresolved);
|
rtems_rtl_unresolved_table_close (&rtl->unresolved);
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +193,7 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_rtl_symbol_table_close (&rtl->globals);
|
rtems_rtl_symbol_table_close (&rtl->globals);
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +206,7 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_rtl_symbol_table_close (&rtl->globals);
|
rtems_rtl_symbol_table_close (&rtl->globals);
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +220,7 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_rtl_symbol_table_close (&rtl->globals);
|
rtems_rtl_symbol_table_close (&rtl->globals);
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +235,7 @@ rtems_rtl_data_init (void)
|
|||||||
rtems_rtl_symbol_table_close (&rtl->globals);
|
rtems_rtl_symbol_table_close (&rtl->globals);
|
||||||
rtems_semaphore_delete (lock);
|
rtems_semaphore_delete (lock);
|
||||||
free (rtl);
|
free (rtl);
|
||||||
|
rtems_libio_unlock ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +312,7 @@ rtems_rtl_obj_caches (rtems_rtl_obj_cache_t** symbols,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rtems_rtl_obj_caches_flush ()
|
rtems_rtl_obj_caches_flush (void)
|
||||||
{
|
{
|
||||||
if (rtl)
|
if (rtl)
|
||||||
{
|
{
|
||||||
@@ -438,6 +462,7 @@ rtems_rtl_load_object (const char* name, int mode)
|
|||||||
if (!rtems_rtl_obj_find_file (obj, name))
|
if (!rtems_rtl_obj_find_file (obj, name))
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_free (obj);
|
rtems_rtl_obj_free (obj);
|
||||||
|
rtems_rtl_obj_caches_flush ();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,9 +471,12 @@ rtems_rtl_load_object (const char* name, int mode)
|
|||||||
if (!rtems_rtl_obj_load (obj))
|
if (!rtems_rtl_obj_load (obj))
|
||||||
{
|
{
|
||||||
rtems_rtl_obj_free (obj);
|
rtems_rtl_obj_free (obj);
|
||||||
|
rtems_rtl_obj_caches_flush ();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtems_rtl_obj_caches_flush ();
|
||||||
|
|
||||||
rtems_rtl_unresolved_resolve ();
|
rtems_rtl_unresolved_resolve ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,6 +542,9 @@ rtems_rtl_unload_object (rtems_rtl_obj_t* obj)
|
|||||||
obj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
|
obj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
|
||||||
|
|
||||||
ok = rtems_rtl_obj_unload (obj);
|
ok = rtems_rtl_obj_unload (obj);
|
||||||
|
|
||||||
|
rtems_rtl_obj_free (obj);
|
||||||
|
rtems_rtl_obj_caches_flush ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ struct rtems_rtl_data_s
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the RTL data with out locking. This call assmes the RTL is locked.
|
* Get the RTL data with out locking. This call assumes the RTL is locked.
|
||||||
*
|
*
|
||||||
* @return rtems_rtl_data_t* The RTL data after being locked.
|
* @return rtems_rtl_data_t* The RTL data after being locked.
|
||||||
* @retval NULL The RTL data is not initialised.
|
* @retval NULL The RTL data is not initialised.
|
||||||
|
|||||||
@@ -212,6 +212,10 @@ $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h: libdl/rtl-sym.h $(PROJECT_INCLUDE)/rtems
|
|||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/rtems/rtl/rtl-trace.h: libdl/rtl-trace.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-trace.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-trace.h
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems/rtl/rap.h: libdl/rap.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
|
$(PROJECT_INCLUDE)/rtems/rtl/rap.h: libdl/rap.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rap.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rap.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rap.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rap.h
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ _SUBDIRS += syscall01
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if DLTESTS
|
if DLTESTS
|
||||||
_SUBDIRS += dl01 dl02
|
_SUBDIRS += dl01 dl02 dl03 dl04 dl05
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(top_srcdir)/../automake/test-subdirs.am
|
include $(top_srcdir)/../automake/test-subdirs.am
|
||||||
|
|||||||
@@ -127,6 +127,9 @@ deviceio01/Makefile
|
|||||||
devnullfatal01/Makefile
|
devnullfatal01/Makefile
|
||||||
dl01/Makefile
|
dl01/Makefile
|
||||||
dl02/Makefile
|
dl02/Makefile
|
||||||
|
dl03/Makefile
|
||||||
|
dl04/Makefile
|
||||||
|
dl05/Makefile
|
||||||
dumpbuf01/Makefile
|
dumpbuf01/Makefile
|
||||||
ftp01/Makefile
|
ftp01/Makefile
|
||||||
gxx01/Makefile
|
gxx01/Makefile
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
*** BEGIN OF TEST libdl (RTL) 1 ***
|
*** BEGIN OF TEST libdl (RTL) 1 ***
|
||||||
load: /dl-o1.o
|
load: /dl-o1.o
|
||||||
handle: 0x2137d8 loaded
|
handle: 0x2048cf0 loaded
|
||||||
Loaded module: argc:2
|
Loaded module: argc:2 [/opt/work/chris/rtems/kernel/rtems.git/c/src/../../testsuites/libtests/dl01/dl-o1.c]
|
||||||
[../../../../../../../../rtems.master/c/src/../../testsuites/libtests/dl01/dl-o1.c]
|
|
||||||
0: Line 1
|
0: Line 1
|
||||||
1: Line 2
|
1: Line 2
|
||||||
Loaded module: argc:3
|
Loaded module: argc:3 [/opt/work/chris/rtems/kernel/rtems.git/c/src/../../testsuites/libtests/dl01/dl-o1.c]
|
||||||
[../../../../../../../../rtems.master/c/src/../../testsuites/libtests/dl01/dl-o1.c]
|
|
||||||
0: Call 2, line 1
|
0: Call 2, line 1
|
||||||
1: Call 2, line 2
|
1: Call 2, line 2
|
||||||
2: Call 2, line 3
|
2: Call 2, line 3
|
||||||
handle: 0x2137d8 closed
|
handle: 0x2048cf0 closed
|
||||||
*** END OF TEST libdl (RTL) 1 ***
|
*** END OF TEST libdl (RTL) 1 ***
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ static void Init(rtems_task_argument arg)
|
|||||||
|
|
||||||
#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
|
#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
|
||||||
|
|
||||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
@@ -80,4 +82,3 @@ static void Init(rtems_task_argument arg)
|
|||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
#include <rtems/confdefs.h>
|
#include <rtems/confdefs.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
*** BEGIN OF TEST libdl (RTL) 2 ***
|
*** BEGIN OF TEST libdl (RTL) 2 ***
|
||||||
load: /dl-o1.o
|
load: /dl-o1.o
|
||||||
handle: 0x2150d0 has unresolved externals
|
handle: 0x204da80 has unresolved externals
|
||||||
load: /dl-o2.o
|
load: /dl-o2.o
|
||||||
handle: 0x215838 loaded
|
handle: 0x204ea98 loaded
|
||||||
Loaded module: argc:4
|
Loaded module: argc:4 [/opt/work/chris/rtems/kernel/rtems.git/c/src/../../testsuites/libtests/dl02/dl-o1.c]
|
||||||
[../../../../../../../../rtems.master/c/src/../../testsuites/libtests/dl02/dl-o1.c]
|
|
||||||
0: 1
|
0: 1
|
||||||
1: 2
|
1: 2
|
||||||
2: 3
|
2: 3
|
||||||
3: 4
|
3: 4
|
||||||
Loaded module: argc:4
|
Loaded module: argc:4 [/opt/work/chris/rtems/kernel/rtems.git/c/src/../../testsuites/libtests/dl02/dl-o2.c]
|
||||||
[../../../../../../../../rtems.master/c/src/../../testsuites/libtests/dl02/dl-o2.c]
|
|
||||||
0: 1
|
0: 1
|
||||||
1: 2
|
1: 2
|
||||||
2: 3
|
2: 3
|
||||||
3: 4
|
3: 4
|
||||||
dl_o1_callback: string in dl_o2
|
dl_o1_callback: string in dl_o2
|
||||||
rtems_main: callback count: 3
|
rtems_main: callback count: 3
|
||||||
handle: 0x2150d0 closed
|
handle: 0x204da80 closed
|
||||||
handle: 0x215838 closed
|
handle: 0x204ea98 closed
|
||||||
*** END OF TEST libdl (RTL) 2 ***
|
*** END OF TEST libdl (RTL) 2 ***
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ static void Init(rtems_task_argument arg)
|
|||||||
|
|
||||||
#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
|
#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
|
||||||
|
|
||||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
|||||||
19
testsuites/libtests/dl03/Makefile.am
Normal file
19
testsuites/libtests/dl03/Makefile.am
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
rtems_tests_PROGRAMS = dl03
|
||||||
|
dl03_SOURCES = init.c dl-cache.c
|
||||||
|
|
||||||
|
dist_rtems_tests_DATA = dl03.scn dl03.doc
|
||||||
|
|
||||||
|
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||||
|
include $(top_srcdir)/../automake/compile.am
|
||||||
|
include $(top_srcdir)/../automake/leaf.am
|
||||||
|
|
||||||
|
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||||
|
|
||||||
|
LINK_OBJS = $(dl03_OBJECTS)
|
||||||
|
LINK_LIBS = $(dl03_LDLIBS)
|
||||||
|
|
||||||
|
dl03$(EXEEXT): $(dl03_OBJECTS) $(dl03_DEPENDENCIES)
|
||||||
|
@rm -f dl03$(EXEEXT)
|
||||||
|
$(make-exe)
|
||||||
|
|
||||||
|
include $(top_srcdir)/../automake/local.am
|
||||||
296
testsuites/libtests/dl03/dl-cache.c
Normal file
296
testsuites/libtests/dl03/dl-cache.c
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <rtems/rtl/rtl.h>
|
||||||
|
#include <rtems/rtl/rtl-obj-cache.h>
|
||||||
|
#include <rtems/rtl/rtl-trace.h>
|
||||||
|
|
||||||
|
#include "dl-cache.h"
|
||||||
|
|
||||||
|
#define CACHE_SIZE (2048)
|
||||||
|
#define CACHE_SIZE_TOO_BIG (-1)
|
||||||
|
#define CACHE_BUFFER_SIZE (CACHE_SIZE * 4)
|
||||||
|
|
||||||
|
static uint8_t* contents;
|
||||||
|
|
||||||
|
static const char const* filename = "/dl-test";
|
||||||
|
|
||||||
|
static void dl_cache_create_file(void)
|
||||||
|
{
|
||||||
|
uint16_t* p;
|
||||||
|
int fd;
|
||||||
|
int i;
|
||||||
|
rtems_test_assert((contents = malloc(CACHE_BUFFER_SIZE)) != NULL);
|
||||||
|
memset(contents, 0, CACHE_BUFFER_SIZE);
|
||||||
|
p = (uint16_t*) contents;
|
||||||
|
for (i = 0; i < (CACHE_BUFFER_SIZE / sizeof(uint16_t)); ++i)
|
||||||
|
*p++ = i;
|
||||||
|
rtems_test_assert((fd = open(filename,
|
||||||
|
O_WRONLY | O_TRUNC | O_CREAT,
|
||||||
|
S_IRUSR | S_IWUSR)) >= 0);
|
||||||
|
rtems_test_assert(write(fd, contents, CACHE_BUFFER_SIZE) == CACHE_BUFFER_SIZE);
|
||||||
|
rtems_test_assert(close(fd) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dl_cache_check(void* buffer, off_t offset, size_t length)
|
||||||
|
{
|
||||||
|
uint16_t* b;
|
||||||
|
uint16_t* c;
|
||||||
|
int i;
|
||||||
|
b = buffer;
|
||||||
|
c = (uint16_t*) (contents + offset);
|
||||||
|
printf("cache: buffer: ");
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
printf("%04x/%04x ", b[i], c[i]);
|
||||||
|
printf("\n");
|
||||||
|
return memcmp(buffer, contents + offset, length) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t dl_cache_buffer_offset(rtems_rtl_obj_cache_t* cache, void* buffer)
|
||||||
|
{
|
||||||
|
return (off_t) (((uint8_t*) buffer) - ((uint8_t*) cache->buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dl_init_rtl(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Check the RTL object is created and can be locked and unlocked.
|
||||||
|
*/
|
||||||
|
rtems_test_assert(rtems_rtl_data () == NULL);
|
||||||
|
rtems_test_assert(rtems_rtl_lock () != NULL);
|
||||||
|
rtems_test_assert(rtems_rtl_unlock () == true);
|
||||||
|
rtems_test_assert(rtems_rtl_data () != NULL);
|
||||||
|
rtems_rtl_trace_set_mask(RTEMS_RTL_TRACE_ALL | RTEMS_RTL_TRACE_CACHE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dl_cache_test(void)
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_cache_t cache;
|
||||||
|
int fd;
|
||||||
|
void* buffer;
|
||||||
|
off_t offset_in;
|
||||||
|
off_t offset;
|
||||||
|
size_t length_in;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the RTL can initialise.
|
||||||
|
*/
|
||||||
|
dl_init_rtl();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the file to test the cache with.
|
||||||
|
*/
|
||||||
|
dl_cache_create_file();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the too big error is handled.
|
||||||
|
*/
|
||||||
|
printf ("cache create with large size\n");
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_open(&cache,
|
||||||
|
CACHE_SIZE_TOO_BIG) == false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a cache.
|
||||||
|
*/
|
||||||
|
printf ("cache create\n");
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_open(&cache,
|
||||||
|
CACHE_SIZE) == true);
|
||||||
|
rtems_test_assert(cache.fd == -1);
|
||||||
|
rtems_test_assert(cache.file_size == 0);
|
||||||
|
rtems_test_assert(cache.size == CACHE_SIZE);
|
||||||
|
rtems_test_assert(cache.buffer != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the file to use with the cache tests.
|
||||||
|
*/
|
||||||
|
printf ("cache file open\n");
|
||||||
|
rtems_test_assert((fd = open(filename, O_RDONLY)) >= 0);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE / 2;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == offset_in);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == offset_in);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_SIZE / 2; length_in = length = CACHE_SIZE / 2;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == offset_in);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - CACHE_SIZE; length_in = length = CACHE_SIZE;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == 0);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - (CACHE_SIZE / 2); length_in = length = CACHE_SIZE / 2;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == (CACHE_SIZE / 2));
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE / 4;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == offset_in);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE / 8;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == offset_in);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(offset == offset_in);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40; length_in = length = 16;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40; length_in = length = 40;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40; length_in = length = 80;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(length == 40);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - CACHE_SIZE + 80;
|
||||||
|
length_in = length = 20;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40;
|
||||||
|
length_in = length = 40;
|
||||||
|
printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
|
||||||
|
rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
|
||||||
|
fd,
|
||||||
|
offset_in,
|
||||||
|
&buffer,
|
||||||
|
&length) == true);
|
||||||
|
offset = dl_cache_buffer_offset(&cache, buffer);
|
||||||
|
printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
|
||||||
|
rtems_test_assert(length == length_in);
|
||||||
|
rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
|
||||||
|
|
||||||
|
rtems_rtl_obj_cache_close(&cache);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
14
testsuites/libtests/dl03/dl-cache.h
Normal file
14
testsuites/libtests/dl03/dl-cache.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(_DL_CACHE_H_)
|
||||||
|
#define _DL_CACHE_H_
|
||||||
|
|
||||||
|
int dl_cache_test(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
28
testsuites/libtests/dl03/dl03.doc
Normal file
28
testsuites/libtests/dl03/dl03.doc
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Copyright (c) 2014 Chris Johns <chrisj@rtems.org>
|
||||||
|
#
|
||||||
|
# The license and distribution terms for this file may be
|
||||||
|
# found in the file LICENSE in this distribution or at
|
||||||
|
# http://www.rtems.org/license/LICENSE.
|
||||||
|
#
|
||||||
|
|
||||||
|
This file describes the directives and concepts tested by this test set.
|
||||||
|
|
||||||
|
test set name: dl02
|
||||||
|
|
||||||
|
directives:
|
||||||
|
|
||||||
|
dlopen
|
||||||
|
dlinfo
|
||||||
|
dlsym
|
||||||
|
dlclose
|
||||||
|
|
||||||
|
concepts:
|
||||||
|
|
||||||
|
+ Load 2 interdependent ELF object files.
|
||||||
|
+ Check there are no unreolved externals. There should be unresolved
|
||||||
|
externals after the first lond and none after the second load.
|
||||||
|
+ Locate the rtems_main symbol in dl-o1.
|
||||||
|
+ Call the rtems_main sym and have that function call the second object.
|
||||||
|
Call the second download with a callback handler to a symbol in the first
|
||||||
|
object file.
|
||||||
|
+ Unload the ELF files.
|
||||||
69
testsuites/libtests/dl03/dl03.scn
Normal file
69
testsuites/libtests/dl03/dl03.scn
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
|
||||||
|
*** BEGIN OF TEST libdl (RTL) 3 ***
|
||||||
|
cache create with large size
|
||||||
|
rtl: alloc: new: OBJECT addr=0x0 size=4294967295
|
||||||
|
cache create
|
||||||
|
rtl: alloc: new: OBJECT addr=0x2038bc8 size=2048
|
||||||
|
cache file open
|
||||||
|
cache read: in: offset=0 length=1024
|
||||||
|
rtl: cache: 3: fd=-1 offset=0 length=1024 area=[0,1024] cache=[0,0] size=0
|
||||||
|
rtl: cache: 3: seek: offset=0 buffer_offset=0 read=2048 cache=[0,2048] dist=0
|
||||||
|
cache read: out: offset=0 length=1024
|
||||||
|
cache: buffer: 0000/0000 0001/0001 0002/0002 0003/0003
|
||||||
|
cache read: in: offset=0 length=2048
|
||||||
|
rtl: cache: 3: fd=3 offset=0 length=2048 area=[0,2048] cache=[0,2048] size=8192
|
||||||
|
cache read: out: offset=0 length=2048
|
||||||
|
cache: buffer: 0000/0000 0001/0001 0002/0002 0003/0003
|
||||||
|
cache read: in: offset=1024 length=1024
|
||||||
|
rtl: cache: 3: fd=3 offset=1024 length=1024 area=[1024,2048] cache=[0,2048] size=8192
|
||||||
|
cache read: out: offset=1024 length=1024
|
||||||
|
cache: buffer: 0200/0200 0201/0201 0202/0202 0203/0203
|
||||||
|
cache read: in: offset=6144 length=2048
|
||||||
|
rtl: cache: 3: fd=3 offset=6144 length=2048 area=[6144,8192] cache=[0,2048] size=8192
|
||||||
|
rtl: cache: 3: seek: offset=6144 buffer_offset=0 read=2048 cache=[6144,8192] dist=2048
|
||||||
|
cache read: out: offset=0 length=2048
|
||||||
|
cache: buffer: 0c00/0c00 0c01/0c01 0c02/0c02 0c03/0c03
|
||||||
|
cache read: in: offset=7168 length=1024
|
||||||
|
rtl: cache: 3: fd=3 offset=7168 length=1024 area=[7168,8192] cache=[6144,8192] size=8192
|
||||||
|
cache read: out: offset=1024 length=1024
|
||||||
|
cache: buffer: 0e00/0e00 0e01/0e01 0e02/0e02 0e03/0e03
|
||||||
|
cache read: in: offset=0 length=512
|
||||||
|
rtl: cache: 3: fd=3 offset=0 length=512 area=[0,512] cache=[6144,8192] size=8192
|
||||||
|
rtl: cache: 3: seek: offset=0 buffer_offset=0 read=2048 cache=[0,2048] dist=8192
|
||||||
|
cache read: out: offset=0 length=512
|
||||||
|
cache: buffer: 0000/0000 0001/0001 0002/0002 0003/0003
|
||||||
|
cache read: in: offset=0 length=256
|
||||||
|
rtl: cache: 3: fd=3 offset=0 length=256 area=[0,256] cache=[0,2048] size=8192
|
||||||
|
cache read: out: offset=0 length=256
|
||||||
|
cache: buffer: 0000/0000 0001/0001 0002/0002 0003/0003
|
||||||
|
cache read: in: offset=0 length=2048
|
||||||
|
rtl: cache: 3: fd=3 offset=0 length=2048 area=[0,2048] cache=[0,2048] size=8192
|
||||||
|
cache read: out: offset=0 length=2048
|
||||||
|
cache: buffer: 0000/0000 0001/0001 0002/0002 0003/0003
|
||||||
|
cache read: in: offset=8152 length=16
|
||||||
|
rtl: cache: 3: fd=3 offset=8152 length=16 area=[8152,8168] cache=[0,2048] size=8192
|
||||||
|
rtl: cache: 3: seek: offset=8152 buffer_offset=0 read=40 cache=[8152,8192] dist=40
|
||||||
|
cache read: out: offset=0 length=16
|
||||||
|
cache: buffer: 0fec/0fec 0fed/0fed 0fee/0fee 0fef/0fef
|
||||||
|
cache read: in: offset=8152 length=40
|
||||||
|
rtl: cache: 3: fd=3 offset=8152 length=40 area=[8152,8192] cache=[8152,8192] size=8192
|
||||||
|
cache read: out: offset=0 length=40
|
||||||
|
cache: buffer: 0fec/0fec 0fed/0fed 0fee/0fee 0fef/0fef
|
||||||
|
cache read: in: offset=8152 length=80
|
||||||
|
rtl: cache: 3: fd=3 offset=8152 length=80 area=[8152,8232] cache=[8152,8192] size=8192
|
||||||
|
rtl: cache: 3: truncate length=40
|
||||||
|
cache read: out: offset=0 length=40
|
||||||
|
cache: buffer: 0fec/0fec 0fed/0fed 0fee/0fee 0fef/0fef
|
||||||
|
cache read: in: offset=6224 length=20
|
||||||
|
rtl: cache: 3: fd=3 offset=6224 length=20 area=[6224,6244] cache=[8152,8192] size=8192
|
||||||
|
rtl: cache: 3: seek: offset=6224 buffer_offset=0 read=1968 cache=[6224,8192] dist=1968
|
||||||
|
cache read: out: offset=0 length=20
|
||||||
|
cache: buffer: 0c28/0c28 0c29/0c29 0c2a/0c2a 0c2b/0c2b
|
||||||
|
cache read: in: offset=8152 length=40
|
||||||
|
rtl: cache: 3: fd=3 offset=8152 length=40 area=[8152,8192] cache=[6224,8192] size=8192
|
||||||
|
cache read: out: offset=1928 length=40
|
||||||
|
cache: buffer: 0fec/0fec 0fed/0fed 0fee/0fee 0fef/0fef
|
||||||
|
rtl: cache: 3: close
|
||||||
|
rtl: alloc: del: OBJECT addr=0x2038bc8
|
||||||
|
*** END OF TEST libdl (RTL) 3 ***
|
||||||
67
testsuites/libtests/dl03/init.c
Normal file
67
testsuites/libtests/dl03/init.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dl-cache.h"
|
||||||
|
|
||||||
|
const char rtems_test_name[] = "libdl (RTL) 3";
|
||||||
|
|
||||||
|
/* forward declarations to avoid warnings */
|
||||||
|
static rtems_task Init(rtems_task_argument argument);
|
||||||
|
|
||||||
|
static int test(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = dl_cache_test();
|
||||||
|
if (ret)
|
||||||
|
rtems_test_exit(ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Init(rtems_task_argument arg)
|
||||||
|
{
|
||||||
|
TEST_BEGIN();
|
||||||
|
|
||||||
|
test();
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
|
||||||
|
rtems_test_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||||
|
|
||||||
|
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||||
|
|
||||||
|
#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (8U * 1024U)
|
||||||
|
|
||||||
|
#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
|
||||||
|
|
||||||
|
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT)
|
||||||
|
|
||||||
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
|
#include <rtems/confdefs.h>
|
||||||
50
testsuites/libtests/dl04/Makefile.am
Normal file
50
testsuites/libtests/dl04/Makefile.am
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
rtems_tests_PROGRAMS = dl04
|
||||||
|
# include a C++ file in the source to trick automake into adding C++ rules <sigh>.
|
||||||
|
dl04_SOURCES = init.c dl-load.c dl-cpp.cpp dl-tar.c dl-tar.h
|
||||||
|
|
||||||
|
BUILT_SOURCES = dl-tar.c dl-tar.h
|
||||||
|
|
||||||
|
dist_rtems_tests_DATA = dl04.scn dl04.doc
|
||||||
|
|
||||||
|
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||||
|
include $(top_srcdir)/../automake/compile.am
|
||||||
|
include $(top_srcdir)/../automake/leaf.am
|
||||||
|
|
||||||
|
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||||
|
|
||||||
|
LINK_OBJS = $(dl04_OBJECTS)
|
||||||
|
LINK_LIBS = $(dl04_LDLIBS)
|
||||||
|
|
||||||
|
dl-o4.o: dl-o4.cpp
|
||||||
|
|
||||||
|
dl.tar: dl-o4.o
|
||||||
|
@rm -f $@
|
||||||
|
$(PAX) -w -f $@ $<
|
||||||
|
CLEANFILES += dl.tar
|
||||||
|
|
||||||
|
dl-tar.c: dl.tar
|
||||||
|
$(BIN2C) -C $< $@
|
||||||
|
CLEANFILES += dl-tar.c
|
||||||
|
|
||||||
|
dl-tar.h: dl.tar
|
||||||
|
$(BIN2C) -H $< $@
|
||||||
|
CLEANFILES += dl-tar.h
|
||||||
|
|
||||||
|
dl04.pre$(EXEEXT): $(dl04_OBJECTS) $(dl04_DEPENDENCIES)
|
||||||
|
@rm -f dl04.pre$(EXEEXT)
|
||||||
|
$(make-exe)
|
||||||
|
rm -f dl04.pre.ralf
|
||||||
|
|
||||||
|
dl04.pre: dl04.pre$(EXEEXT)
|
||||||
|
mv $< $@
|
||||||
|
CLEANFILES += dl04.pre
|
||||||
|
|
||||||
|
dl-sym.o: dl04.pre
|
||||||
|
rtems-syms -e -c "$(CFLAGS)" -o $@ $<
|
||||||
|
|
||||||
|
dl04$(EXEEXT): $(dl04_OBJECTS) $(dl04_DEPENDENCIES) dl-sym.o
|
||||||
|
@rm -f dl04$(EXEEXT)
|
||||||
|
$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) \
|
||||||
|
-o $(basename $@)$(EXEEXT) $(LINK_OBJS) dl-sym.o $(LINK_LIBS)
|
||||||
|
|
||||||
|
include $(top_srcdir)/../automake/local.am
|
||||||
4
testsuites/libtests/dl04/dl-cpp.cpp
Normal file
4
testsuites/libtests/dl04/dl-cpp.cpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/* empty file to trick automake. */
|
||||||
|
class empty
|
||||||
|
{
|
||||||
|
};
|
||||||
37
testsuites/libtests/dl04/dl-load.c
Normal file
37
testsuites/libtests/dl04/dl-load.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <rtems/rtl/rtl-trace.h>
|
||||||
|
|
||||||
|
#include "dl-load.h"
|
||||||
|
|
||||||
|
int dl_load_test(void)
|
||||||
|
{
|
||||||
|
void* handle;
|
||||||
|
const char* err;
|
||||||
|
|
||||||
|
rtems_rtl_trace_set_mask(RTEMS_RTL_TRACE_ALL);
|
||||||
|
handle = dlopen("/dl-o4.o", RTLD_GLOBAL | RTLD_NOW);
|
||||||
|
err = dlerror();
|
||||||
|
if (err != NULL)
|
||||||
|
printf("dlopen: %s\n", err);
|
||||||
|
rtems_test_assert(handle != NULL);
|
||||||
|
rtems_test_assert(dlclose(handle) == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
14
testsuites/libtests/dl04/dl-load.h
Normal file
14
testsuites/libtests/dl04/dl-load.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(_DL_LOAD_H_)
|
||||||
|
#define _DL_LOAD_H_
|
||||||
|
|
||||||
|
int dl_load_test(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
30
testsuites/libtests/dl04/dl-o4.cpp
Normal file
30
testsuites/libtests/dl04/dl-o4.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
Foo() {};
|
||||||
|
~Foo() {};
|
||||||
|
|
||||||
|
virtual void f1() {};
|
||||||
|
virtual void f2() {};
|
||||||
|
virtual void f3() {};
|
||||||
|
virtual void f4() {};
|
||||||
|
virtual void f5() {};
|
||||||
|
virtual void f6() {};
|
||||||
|
virtual void f7() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Bar : public Foo {
|
||||||
|
};
|
||||||
|
|
||||||
|
void baz(void)
|
||||||
|
{
|
||||||
|
Bar b;
|
||||||
|
|
||||||
|
b.f1();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void func(void)
|
||||||
|
{
|
||||||
|
baz();
|
||||||
|
}
|
||||||
|
}
|
||||||
21
testsuites/libtests/dl04/dl04.doc
Normal file
21
testsuites/libtests/dl04/dl04.doc
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2016 Chris Johns <chrisj@rtems.org>
|
||||||
|
#
|
||||||
|
# The license and distribution terms for this file may be
|
||||||
|
# found in the file LICENSE in this distribution or at
|
||||||
|
# http://www.rtems.org/license/LICENSE.
|
||||||
|
#
|
||||||
|
|
||||||
|
This file describes the directives and concepts tested by this test set.
|
||||||
|
|
||||||
|
test set name: dl04
|
||||||
|
|
||||||
|
directives:
|
||||||
|
|
||||||
|
dlopen
|
||||||
|
dlerror
|
||||||
|
dlclose
|
||||||
|
|
||||||
|
concepts:
|
||||||
|
|
||||||
|
+ Load a single ELF object file containing C++ code that tests the cache handling.
|
||||||
|
+ Unload the ELF file.
|
||||||
1004
testsuites/libtests/dl04/dl04.scn
Normal file
1004
testsuites/libtests/dl04/dl04.scn
Normal file
File diff suppressed because it is too large
Load Diff
84
testsuites/libtests/dl04/init.c
Normal file
84
testsuites/libtests/dl04/init.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <rtems/rtl/rtl.h>
|
||||||
|
#include <rtems/untar.h>
|
||||||
|
|
||||||
|
#include "dl-load.h"
|
||||||
|
|
||||||
|
const char rtems_test_name[] = "libdl (RTL) 4";
|
||||||
|
|
||||||
|
/* forward declarations to avoid warnings */
|
||||||
|
static rtems_task Init(rtems_task_argument argument);
|
||||||
|
|
||||||
|
#include "dl-tar.h"
|
||||||
|
|
||||||
|
#define TARFILE_START dl_tar
|
||||||
|
#define TARFILE_SIZE dl_tar_size
|
||||||
|
|
||||||
|
static int test(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = dl_load_test();
|
||||||
|
if (ret)
|
||||||
|
rtems_test_exit(ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Init(rtems_task_argument arg)
|
||||||
|
{
|
||||||
|
int te;
|
||||||
|
|
||||||
|
TEST_BEGIN();
|
||||||
|
|
||||||
|
te = Untar_FromMemory((void *)TARFILE_START, (size_t)TARFILE_SIZE);
|
||||||
|
if (te != 0)
|
||||||
|
{
|
||||||
|
printf("untar failed: %d\n", te);
|
||||||
|
rtems_test_exit(1);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test();
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
|
||||||
|
rtems_test_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||||
|
|
||||||
|
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||||
|
|
||||||
|
#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (8U * 1024U)
|
||||||
|
|
||||||
|
#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
|
||||||
|
|
||||||
|
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
|
||||||
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
|
#include <rtems/confdefs.h>
|
||||||
50
testsuites/libtests/dl05/Makefile.am
Normal file
50
testsuites/libtests/dl05/Makefile.am
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
rtems_tests_PROGRAMS = dl05
|
||||||
|
dl05_SOURCES = init.c dl-load.c dl-cpp.cpp dl-tar.c dl-tar.h
|
||||||
|
|
||||||
|
BUILT_SOURCES = dl-tar.c dl-tar.h
|
||||||
|
|
||||||
|
dist_rtems_tests_DATA = dl05.scn dl05.doc
|
||||||
|
|
||||||
|
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||||
|
include $(top_srcdir)/../automake/compile.am
|
||||||
|
include $(top_srcdir)/../automake/leaf.am
|
||||||
|
|
||||||
|
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||||
|
|
||||||
|
LINK_OBJS = $(dl05_OBJECTS)
|
||||||
|
LINK_LIBS = $(dl05_LDLIBS)
|
||||||
|
|
||||||
|
dl-o5.o: dl-o5.cpp
|
||||||
|
|
||||||
|
dl.tar: dl-o5.o
|
||||||
|
@rm -f $@
|
||||||
|
$(PAX) -w -f $@ $<
|
||||||
|
CLEANFILES += dl.tar
|
||||||
|
|
||||||
|
dl-tar.c: dl.tar
|
||||||
|
$(BIN2C) -C $< $@
|
||||||
|
CLEANFILES += dl-tar.c
|
||||||
|
|
||||||
|
dl-tar.h: dl.tar
|
||||||
|
$(BIN2C) -H $< $@
|
||||||
|
CLEANFILES += dl-tar.h
|
||||||
|
|
||||||
|
dl05.pre$(EXEEXT): $(dl05_OBJECTS) $(dl05_DEPENDENCIES)
|
||||||
|
@rm -f dl05.pre$(EXEEXT)
|
||||||
|
$(LINK.cc) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) \
|
||||||
|
-o $(basename $@)$(EXEEXT) $(LINK_OBJS) $(LINK_LIBS)
|
||||||
|
rm -f dl05.pre.ralf
|
||||||
|
|
||||||
|
dl05.pre: dl05.pre$(EXEEXT)
|
||||||
|
mv $< $@
|
||||||
|
CLEANFILES += dl05.pre
|
||||||
|
|
||||||
|
dl-sym.o: dl05.pre
|
||||||
|
rtems-syms -e -c "$(CFLAGS)" -o $@ $<
|
||||||
|
|
||||||
|
dl05$(EXEEXT): $(dl05_OBJECTS) $(dl05_DEPENDENCIES) dl-sym.o
|
||||||
|
@rm -f dl05$(EXEEXT)
|
||||||
|
$(LINK.cc) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) \
|
||||||
|
-o $(basename $@)$(EXEEXT) $(LINK_OBJS) dl-sym.o $(LINK_LIBS)
|
||||||
|
|
||||||
|
include $(top_srcdir)/../automake/local.am
|
||||||
30
testsuites/libtests/dl05/dl-cpp.cpp
Normal file
30
testsuites/libtests/dl05/dl-cpp.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* The base image needs this to include the RTTI data.
|
||||||
|
*/
|
||||||
|
#include <cstdio>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "dl-load.h"
|
||||||
|
void exception_base(bool throw_runtime)
|
||||||
|
{
|
||||||
|
printf("%s: begin\n", __func__);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (throw_runtime)
|
||||||
|
throw std::runtime_error("eb: throw std::runtime_error");
|
||||||
|
else
|
||||||
|
throw dl_test_throw_me("eb: throw me");
|
||||||
|
}
|
||||||
|
catch (std::exception const& e)
|
||||||
|
{
|
||||||
|
printf("%s: caught: %s\n", __func__, e.what());
|
||||||
|
}
|
||||||
|
catch (dl_test_throw_me const& e)
|
||||||
|
{
|
||||||
|
printf("%s: caught: %s\n", __func__, e.what());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("%s: caught: unknown\n", __func__);
|
||||||
|
}
|
||||||
|
printf("%s: end\n", __func__);
|
||||||
|
}
|
||||||
63
testsuites/libtests/dl05/dl-load.c
Normal file
63
testsuites/libtests/dl05/dl-load.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <rtems/rtl/rtl-trace.h>
|
||||||
|
|
||||||
|
#include "dl-load.h"
|
||||||
|
|
||||||
|
int dl_load_test(void)
|
||||||
|
{
|
||||||
|
void* handle;
|
||||||
|
const char* err;
|
||||||
|
void (*func)(bool );
|
||||||
|
#if __i386__
|
||||||
|
/*
|
||||||
|
* std::runtime_error destructor locks up in atomics.
|
||||||
|
*/
|
||||||
|
bool throw_runtime = false;
|
||||||
|
#else
|
||||||
|
bool throw_runtime = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rtems_rtl_trace_set_mask(RTEMS_RTL_TRACE_ALL);
|
||||||
|
|
||||||
|
handle = dlopen("/dl-o5.o", RTLD_GLOBAL | RTLD_NOW);
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
err = dlerror();
|
||||||
|
if (err != NULL)
|
||||||
|
printf("dlopen: %s\n", err);
|
||||||
|
}
|
||||||
|
rtems_test_assert(handle != NULL);
|
||||||
|
|
||||||
|
func = dlsym(handle, "exception_dl");
|
||||||
|
if (func == NULL) {
|
||||||
|
err = dlerror ();
|
||||||
|
if (err)
|
||||||
|
printf ("dlsym: %s\n", err);
|
||||||
|
}
|
||||||
|
rtems_test_assert(func != NULL);
|
||||||
|
|
||||||
|
exception_base(throw_runtime);
|
||||||
|
|
||||||
|
func(throw_runtime);
|
||||||
|
|
||||||
|
rtems_test_assert(dlclose(handle) == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
51
testsuites/libtests/dl05/dl-load.h
Normal file
51
testsuites/libtests/dl05/dl-load.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(_DL_LOAD_H_)
|
||||||
|
#define _DL_LOAD_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void exception_base(bool throw_runtime);
|
||||||
|
void exception_dl(bool throw_runtime);
|
||||||
|
|
||||||
|
int dl_load_test(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
class dl_test_throw_me
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
dl_test_throw_me(const char* message) :
|
||||||
|
message (message) {
|
||||||
|
}
|
||||||
|
dl_test_throw_me(const dl_test_throw_me& orig) :
|
||||||
|
message (orig.message) {
|
||||||
|
}
|
||||||
|
dl_test_throw_me() :
|
||||||
|
message (0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~dl_test_throw_me() {
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* message;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
28
testsuites/libtests/dl05/dl-o5.cpp
Normal file
28
testsuites/libtests/dl05/dl-o5.cpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "dl-load.h" /* make the symbol a C linkage */
|
||||||
|
void exception_dl(bool throw_runtime)
|
||||||
|
{
|
||||||
|
printf("exception_dl: begin\n");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
printf("exception_dl: throwing...\n");
|
||||||
|
if (throw_runtime)
|
||||||
|
throw std::runtime_error("throw std::runtime_error object");
|
||||||
|
else
|
||||||
|
throw dl_test_throw_me("throw dl_test_throw_me object");
|
||||||
|
}
|
||||||
|
catch (dl_test_throw_me const& e)
|
||||||
|
{
|
||||||
|
printf("%s: caught: %s\n", __func__, e.what());
|
||||||
|
}
|
||||||
|
catch (std::exception const& e)
|
||||||
|
{
|
||||||
|
printf("%s: caught: %s\n", __func__, e.what());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("%s: caught: unknown\n", __func__);
|
||||||
|
}
|
||||||
|
printf("exception_dl: end\n");
|
||||||
|
}
|
||||||
24
testsuites/libtests/dl05/dl05.doc
Normal file
24
testsuites/libtests/dl05/dl05.doc
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Copyright (c) 2016 Chris Johns <chrisj@rtems.org>
|
||||||
|
#
|
||||||
|
# The license and distribution terms for this file may be
|
||||||
|
# found in the file LICENSE in this distribution or at
|
||||||
|
# http://www.rtems.org/license/LICENSE.
|
||||||
|
#
|
||||||
|
|
||||||
|
This file describes the directives and concepts tested by this test set.
|
||||||
|
|
||||||
|
test set name: dl04
|
||||||
|
|
||||||
|
directives:
|
||||||
|
|
||||||
|
dlopen
|
||||||
|
dlerror
|
||||||
|
dlclose
|
||||||
|
|
||||||
|
concepts:
|
||||||
|
|
||||||
|
+ Load a single ELF object file containing C++ code with an exception.
|
||||||
|
+ Throw the exception.
|
||||||
|
+ Unload the ELF file.
|
||||||
|
|
||||||
|
Note: the test fails because terminate is raised.
|
||||||
1424
testsuites/libtests/dl05/dl05.scn
Normal file
1424
testsuites/libtests/dl05/dl05.scn
Normal file
File diff suppressed because it is too large
Load Diff
86
testsuites/libtests/dl05/init.c
Normal file
86
testsuites/libtests/dl05/init.c
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <rtems/rtl/rtl.h>
|
||||||
|
#include <rtems/untar.h>
|
||||||
|
|
||||||
|
#include "dl-load.h"
|
||||||
|
|
||||||
|
const char rtems_test_name[] = "libdl (RTL) 5";
|
||||||
|
|
||||||
|
/* forward declarations to avoid warnings */
|
||||||
|
static rtems_task Init(rtems_task_argument argument);
|
||||||
|
|
||||||
|
#include "dl-tar.h"
|
||||||
|
|
||||||
|
#define TARFILE_START dl_tar
|
||||||
|
#define TARFILE_SIZE dl_tar_size
|
||||||
|
|
||||||
|
static int test(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = dl_load_test();
|
||||||
|
if (ret)
|
||||||
|
rtems_test_exit(ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Init(rtems_task_argument arg)
|
||||||
|
{
|
||||||
|
int te;
|
||||||
|
|
||||||
|
TEST_BEGIN();
|
||||||
|
|
||||||
|
te = Untar_FromMemory((void *)TARFILE_START, (size_t)TARFILE_SIZE);
|
||||||
|
if (te != 0)
|
||||||
|
{
|
||||||
|
printf("untar failed: %d\n", te);
|
||||||
|
rtems_test_exit(1);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test();
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
|
||||||
|
rtems_test_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||||
|
|
||||||
|
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||||
|
|
||||||
|
#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (32U * 1024U)
|
||||||
|
|
||||||
|
#define CONFIGURE_EXTRA_TASK_STACKS (64 * 1024)
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_POSIX_KEYS 2
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_SEMAPHORES 4
|
||||||
|
|
||||||
|
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||||
|
|
||||||
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
|
||||||
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
|
#include <rtems/confdefs.h>
|
||||||
Reference in New Issue
Block a user