forked from Imagelibrary/rtems
libdl: Realloc text memory if there are trampolines
- Add resize to the allocator interface - Rework the trampoline variables in the obj struct to make better sense of what is happening Closes #4944
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
|
* COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj@rtems.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -69,6 +69,7 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
|
|||||||
enum rtems_rtl_alloc_cmd {
|
enum rtems_rtl_alloc_cmd {
|
||||||
RTEMS_RTL_ALLOC_NEW, /**< Allocate new memory. */
|
RTEMS_RTL_ALLOC_NEW, /**< Allocate new memory. */
|
||||||
RTEMS_RTL_ALLOC_DEL, /**< Delete allocated memory. */
|
RTEMS_RTL_ALLOC_DEL, /**< Delete allocated memory. */
|
||||||
|
RTEMS_RTL_ALLOC_RESIZE, /**< Resize allocated memory. */
|
||||||
RTEMS_RTL_ALLOC_LOCK, /**< Lock the allocator. */
|
RTEMS_RTL_ALLOC_LOCK, /**< Lock the allocator. */
|
||||||
RTEMS_RTL_ALLOC_UNLOCK, /**< Unlock the allocator. */
|
RTEMS_RTL_ALLOC_UNLOCK, /**< Unlock the allocator. */
|
||||||
RTEMS_RTL_ALLOC_WR_ENABLE, /**< Enable writes to the memory. */
|
RTEMS_RTL_ALLOC_WR_ENABLE, /**< Enable writes to the memory. */
|
||||||
@@ -142,6 +143,25 @@ void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero);
|
|||||||
*/
|
*/
|
||||||
void rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address);
|
void rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Runtime Loader allocator resize resizes allocated memory.
|
||||||
|
*
|
||||||
|
* This call resizes a previously allocated block of memory. If the
|
||||||
|
* provided address cannot be resized it is deleted and a new block is
|
||||||
|
* allocated and the contents of the existing memory is copied.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param tag The type of allocation request.
|
||||||
|
* @param address The memory address to resize. A NULL is ignored.
|
||||||
|
* @param size The size of the allocation.
|
||||||
|
* @param zero If true the memory is cleared.
|
||||||
|
* @return void* The memory address or NULL is not memory available.
|
||||||
|
*/
|
||||||
|
void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
|
||||||
|
void* address,
|
||||||
|
size_t size,
|
||||||
|
bool zero);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Runtime Loader allocator lock. An allocator that depends on a
|
* The Runtime Loader allocator lock. An allocator that depends on a
|
||||||
* separate allocation process, for example the heap, may need to be
|
* separate allocation process, for example the heap, may need to be
|
||||||
@@ -266,6 +286,30 @@ bool rtems_rtl_alloc_module_new (void** text_base, size_t text_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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize the allocated memory for a module given the new size of the text,
|
||||||
|
* const, data and bss sections. If any part of the allocation fails the
|
||||||
|
* allocated is deleted.
|
||||||
|
*
|
||||||
|
* @param text_base Pointer to the text base pointer.
|
||||||
|
* @param text_size The size of the read/exec section.
|
||||||
|
* @param const_base Pointer to the const base pointer.
|
||||||
|
* @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_size The size of the read/write secton.
|
||||||
|
* @param bss_base Pointer to the bss base pointer.
|
||||||
|
* @param bss_size The size of the read/write.
|
||||||
|
* @retval true The memory has been allocated.
|
||||||
|
* @retval false The allocation of memory has failed.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
|
||||||
|
void** const_base, size_t const_size,
|
||||||
|
void** eh_base, size_t eh_size,
|
||||||
|
void** data_base, size_t data_size,
|
||||||
|
void** bss_base, size_t bss_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free the memory allocated to a module.
|
* Free the memory allocated to a module.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -198,65 +198,66 @@ typedef bool (*rtems_rtl_obj_depends_iterator) (rtems_rtl_obj* obj,
|
|||||||
*/
|
*/
|
||||||
struct rtems_rtl_obj
|
struct rtems_rtl_obj
|
||||||
{
|
{
|
||||||
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. */
|
||||||
size_t users; /**< Users of this object file, number of loads. */
|
size_t users; /**< Users of this object file, number of loads. */
|
||||||
size_t refs; /**< References to the object file. */
|
size_t refs; /**< References to the object file. */
|
||||||
int format; /**< The format of 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. */
|
||||||
const char* aname; /**< The archive name containing the
|
const char* aname; /**< The archive name containing the
|
||||||
* object. NULL means the object is not
|
* object. NULL means the object is not
|
||||||
* in a lib */
|
* in a lib */
|
||||||
off_t ooffset; /**< The object offset in the archive. */
|
off_t ooffset; /**< The object offset in the archive. */
|
||||||
size_t fsize; /**< Size of the object file. */
|
size_t fsize; /**< Size of the object file. */
|
||||||
rtems_chain_control sections; /**< The sections of interest in the object
|
rtems_chain_control sections; /**< The sections of interest in the object
|
||||||
* file. */
|
* file. */
|
||||||
rtems_chain_control dependents; /**< The dependent object files. */
|
rtems_chain_control dependents; /**< The dependent object files. */
|
||||||
rtems_rtl_obj_sym* local_table; /**< Local symbol table. */
|
rtems_rtl_obj_sym* local_table; /**< Local symbol table. */
|
||||||
size_t local_syms; /**< Local symbol count. */
|
size_t local_syms; /**< Local symbol count. */
|
||||||
size_t local_size; /**< Local symbol memory usage. */
|
size_t local_size; /**< Local symbol memory usage. */
|
||||||
rtems_rtl_obj_sym* global_table; /**< Global symbol table. */
|
rtems_rtl_obj_sym* global_table; /**< Global symbol table. */
|
||||||
size_t global_syms; /**< Global symbol count. */
|
size_t global_syms; /**< Global symbol count. */
|
||||||
size_t global_size; /**< Global symbol memory usage. */
|
size_t global_size; /**< Global symbol memory usage. */
|
||||||
size_t unresolved; /**< The number of unresolved relocations. */
|
size_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. */
|
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. */
|
||||||
size_t const_size; /**< The size of the const section. */
|
size_t const_size; /**< The size of the const section. */
|
||||||
void* eh_base; /**< The base address of the eh section in
|
void* eh_base; /**< The base address of the eh section in
|
||||||
* memory. */
|
* memory. */
|
||||||
size_t eh_size; /**< The size of the eh section. */
|
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. */
|
||||||
size_t data_size; /**< The size of the data section. */
|
size_t data_size; /**< The size of the data section. */
|
||||||
void* bss_base; /**< The base address of the bss section in
|
void* bss_base; /**< The base address of the bss section in
|
||||||
* memory. */
|
* 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. */
|
||||||
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
|
uint32_t obj_num; /**< The count of elf files in an rtl
|
||||||
* obj. */
|
* obj. */
|
||||||
void* trampoline; /**< Trampoline memory. Used for fixups or
|
void* tramp_base; /**< Trampoline memory. Used for fixups or
|
||||||
* veneers */
|
* veneers */
|
||||||
size_t tramp_size; /**< Size of a tramopline slot. */
|
size_t tramp_size; /**< Size of a trampoline memory. */
|
||||||
size_t tramps_size; /**< Size of the trampoline memory. */
|
size_t tramp_slots; /**< The number of tampoline slots. */
|
||||||
void* tramp_brk; /**< Trampoline memory allocator. MD
|
size_t tramp_slot_size; /**< The number of tampoline slots. */
|
||||||
* relocators can take memory from the
|
void* tramp_brk; /**< Trampoline memory allocator. MD
|
||||||
* break up to the size. */
|
* relocators can take memory from the
|
||||||
size_t tramp_relocs; /**< Number of slots reserved for
|
* break up to the size. */
|
||||||
* relocs. The remainder are for
|
size_t tramp_relocs; /**< Number of slots reserved for
|
||||||
* unresolved symbols. */
|
* relocs. The remainder are for
|
||||||
struct link_map* linkmap; /**< For GDB. */
|
* unresolved symbols. */
|
||||||
void* loader; /**< The file details specific to a
|
struct link_map* linkmap; /**< For GDB. */
|
||||||
* loader. */
|
void* loader; /**< The file details specific to a
|
||||||
|
* loader. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -386,6 +387,17 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj,
|
|||||||
sym < (obj->global_table + obj->global_syms));
|
sym < (obj->global_table + obj->global_syms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the object file have any trampolines?
|
||||||
|
*
|
||||||
|
* @param obj The object file's descriptor to check for available space.
|
||||||
|
* @retval bool Returns @true if the object file has trampolines
|
||||||
|
*/
|
||||||
|
static inline size_t rtems_rtl_obj_has_trampolines (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
return obj->tramp_slot_size != 0 && obj->tramp_slots != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is there space in the trampoline memory for a trapoline.
|
* Is there space in the trampoline memory for a trapoline.
|
||||||
*
|
*
|
||||||
@@ -395,7 +407,7 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj,
|
|||||||
*/
|
*/
|
||||||
static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
|
static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
|
||||||
{
|
{
|
||||||
return (char*) obj->tramp_brk - (char*) obj->trampoline;
|
return (char*) obj->tramp_brk - (char*) obj->tramp_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -408,8 +420,8 @@ static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
|
|||||||
static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
|
static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
|
||||||
const size_t size)
|
const size_t size)
|
||||||
{
|
{
|
||||||
return (obj->trampoline != NULL &&
|
return (obj->tramp_base != NULL &&
|
||||||
(rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramps_size);
|
(rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramp_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -420,20 +432,19 @@ static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
|
|||||||
*/
|
*/
|
||||||
static inline size_t rtems_rtl_obj_trampoline_slots (const rtems_rtl_obj* obj)
|
static inline size_t rtems_rtl_obj_trampoline_slots (const rtems_rtl_obj* obj)
|
||||||
{
|
{
|
||||||
return obj->trampoline == NULL || obj->tramp_size == 0 ?
|
return obj->tramp_slots;
|
||||||
0 : obj->tramps_size / obj->tramp_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of trampolines.
|
* Number of trampoline slot available.
|
||||||
*
|
*
|
||||||
* @param obj The object file's descriptor.
|
* @param obj The object file's descriptor.
|
||||||
* @retval size_t The number of trampolines.
|
* @retval size_t The number of trampoline slots available.
|
||||||
*/
|
*/
|
||||||
static inline size_t rtems_rtl_obj_trampolines (const rtems_rtl_obj* obj)
|
static inline size_t rtems_rtl_obj_trampolines (const rtems_rtl_obj* obj)
|
||||||
{
|
{
|
||||||
return obj->trampoline == NULL || obj->tramp_size == 0 ?
|
return obj->tramp_base == NULL || obj->tramp_slots == 0 ?
|
||||||
0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_size;
|
0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_slot_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -571,22 +582,6 @@ rtems_rtl_obj_sect* rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj
|
|||||||
int index,
|
int index,
|
||||||
uint32_t mask);
|
uint32_t mask);
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a table for trampoline fixup calls.
|
|
||||||
*
|
|
||||||
* @param obj The object file's descriptor.
|
|
||||||
* @retval true The table was allocated.
|
|
||||||
* @retval false The alloction failed.
|
|
||||||
*/
|
|
||||||
bool rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Erase the object file descriptor's trampoline table..
|
|
||||||
*
|
|
||||||
* @param obj The object file's descriptor.
|
|
||||||
*/
|
|
||||||
void rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a table for dependent objects.
|
* Allocate a table for dependent objects.
|
||||||
*
|
*
|
||||||
@@ -749,6 +744,24 @@ size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj);
|
|||||||
*/
|
*/
|
||||||
uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj);
|
uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The trampoline size.
|
||||||
|
*
|
||||||
|
* @param obj The object file's descriptor.
|
||||||
|
* @return size_t The size of the trampoline memory of the object file.
|
||||||
|
*/
|
||||||
|
size_t rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The trampolinme alignment for the architecture.
|
||||||
|
*
|
||||||
|
* This is implemented and set in the architecture backend.
|
||||||
|
*
|
||||||
|
* @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_tramp_alignment (const rtems_rtl_obj* 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
|
||||||
* relocation type sections.
|
* relocation type sections.
|
||||||
@@ -810,11 +823,19 @@ bool rtems_rtl_obj_load_symbols (rtems_rtl_obj* obj,
|
|||||||
* @retval true The object has been sucessfully loaded.
|
* @retval true The object has been sucessfully loaded.
|
||||||
* @retval false The load failed. The RTL error has been set.
|
* @retval false The load failed. The RTL error has been set.
|
||||||
*/
|
*/
|
||||||
bool
|
bool rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
|
||||||
rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
|
int fd,
|
||||||
int fd,
|
rtems_rtl_obj_sect_handler handler,
|
||||||
rtems_rtl_obj_sect_handler handler,
|
void* data);
|
||||||
void* data);
|
|
||||||
|
/**
|
||||||
|
* Resize the sections.
|
||||||
|
*
|
||||||
|
* @param obj The object file's descriptor.
|
||||||
|
* @retval true The object has been sucessfully loaded.
|
||||||
|
* @retval false The load failed. The RTL error has been set.
|
||||||
|
*/
|
||||||
|
bool rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the sections that have been allocated memory in the target. The bss
|
* Load the sections that have been allocated memory in the target. The bss
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
|
* COPYRIGHT (c) 2012,2023 Chris Johns <chrisj@rtems.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -54,6 +54,9 @@ rtems_rtl_alloc_heap (rtems_rtl_alloc_cmd cmd,
|
|||||||
free (*address);
|
free (*address);
|
||||||
*address = NULL;
|
*address = NULL;
|
||||||
break;
|
break;
|
||||||
|
case RTEMS_RTL_ALLOC_RESIZE:
|
||||||
|
*address = realloc (*address, size);
|
||||||
|
break;
|
||||||
case RTEMS_RTL_ALLOC_LOCK:
|
case RTEMS_RTL_ALLOC_LOCK:
|
||||||
_RTEMS_Lock_allocator();
|
_RTEMS_Lock_allocator();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
|
* COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj@rtems.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -110,6 +110,39 @@ rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address)
|
|||||||
rtems_rtl_unlock ();
|
rtems_rtl_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
|
||||||
|
void* address,
|
||||||
|
size_t size,
|
||||||
|
bool zero)
|
||||||
|
{
|
||||||
|
rtems_rtl_data* rtl = rtems_rtl_lock ();
|
||||||
|
const void* prev_address = address;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resize memory of an existing allocation. The address field is set
|
||||||
|
* by the allocator and may change.
|
||||||
|
*/
|
||||||
|
if (rtl != NULL)
|
||||||
|
rtl->allocator.allocator (RTEMS_RTL_ALLOC_RESIZE, tag, &address, size);
|
||||||
|
|
||||||
|
rtems_rtl_unlock ();
|
||||||
|
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
|
||||||
|
printf ("rtl: alloc: resize: %s%s prev-addr=%p addr=%p size=%zu\n",
|
||||||
|
rtems_rtl_trace_tag_label (tag), prev_address == address ? "" : " MOVED",
|
||||||
|
prev_address, address, size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only zero the memory if asked to and the resize was successful. We
|
||||||
|
* cannot clear the resized area if bigger than the previouis allocation
|
||||||
|
* because we do not have the original size.
|
||||||
|
*/
|
||||||
|
if (address != NULL && zero)
|
||||||
|
memset (address, 0, size);
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
|
rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
|
||||||
{
|
{
|
||||||
@@ -277,45 +310,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
{
|
{
|
||||||
*text_base = *const_base = *data_base = *bss_base = NULL;
|
*text_base = *const_base = *data_base = *bss_base = NULL;
|
||||||
|
|
||||||
if (text_size)
|
if (data_size != 0)
|
||||||
{
|
|
||||||
*text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
|
|
||||||
text_size, false);
|
|
||||||
if (!*text_base)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const_size)
|
|
||||||
{
|
|
||||||
*const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
|
|
||||||
const_size, false);
|
|
||||||
if (!*const_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_eh_tag (),
|
|
||||||
eh_size, false);
|
|
||||||
if (!*eh_base)
|
|
||||||
{
|
|
||||||
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
|
||||||
data_base, bss_base);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_size)
|
|
||||||
{
|
{
|
||||||
*data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
|
*data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
|
||||||
data_size, false);
|
data_size, false);
|
||||||
if (!*data_base)
|
if (*data_base == NULL)
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
data_base, bss_base);
|
data_base, bss_base);
|
||||||
@@ -323,11 +322,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss_size)
|
if (bss_size != 0)
|
||||||
{
|
{
|
||||||
*bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
|
*bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
|
||||||
bss_size, false);
|
bss_size, false);
|
||||||
if (!*bss_base)
|
if (*bss_base == NULL)
|
||||||
{
|
{
|
||||||
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
data_base, bss_base);
|
data_base, bss_base);
|
||||||
@@ -335,6 +334,100 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eh_size != 0)
|
||||||
|
{
|
||||||
|
*eh_base = rtems_rtl_alloc_new (rtems_rtl_alloc_eh_tag (),
|
||||||
|
eh_size, false);
|
||||||
|
if (*eh_base == NULL)
|
||||||
|
{
|
||||||
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
|
data_base, bss_base);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const_size != 0)
|
||||||
|
{
|
||||||
|
*const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
|
||||||
|
const_size, false);
|
||||||
|
if (*const_base == NULL)
|
||||||
|
{
|
||||||
|
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
|
||||||
|
data_base, bss_base);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text_size != 0)
|
||||||
|
{
|
||||||
|
*text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
|
||||||
|
text_size, false);
|
||||||
|
if (*text_base == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
|
||||||
|
void** const_base, size_t const_size,
|
||||||
|
void** eh_base, size_t eh_size,
|
||||||
|
void** data_base, size_t data_size,
|
||||||
|
void** bss_base, size_t bss_size)
|
||||||
|
{
|
||||||
|
if (data_size != 0)
|
||||||
|
{
|
||||||
|
*data_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_data_tag (),
|
||||||
|
*data_base, data_size, false);
|
||||||
|
if (*data_base == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bss_size != 0)
|
||||||
|
{
|
||||||
|
*bss_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_bss_tag (),
|
||||||
|
*bss_base, bss_size, false);
|
||||||
|
if (*bss_base == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eh_size != 0)
|
||||||
|
{
|
||||||
|
*eh_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_eh_tag (),
|
||||||
|
*eh_base, eh_size, false);
|
||||||
|
if (*eh_base == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const_size != 0)
|
||||||
|
{
|
||||||
|
*const_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_const_tag (),
|
||||||
|
*const_base, const_size, false);
|
||||||
|
if (*const_base == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text_size != 0)
|
||||||
|
{
|
||||||
|
*text_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_text_tag (),
|
||||||
|
*text_base, text_size, false);
|
||||||
|
if (*text_base == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -805,7 +805,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unresolved || rs == rtems_rtl_elf_rel_tramp_add)
|
if (unresolved || rs == rtems_rtl_elf_rel_tramp_add)
|
||||||
tramp->obj->tramps_size += tramp->obj->tramp_size;
|
++tramp->obj->tramp_slots;
|
||||||
if (rs == rtems_rtl_elf_rel_failure)
|
if (rs == rtems_rtl_elf_rel_failure)
|
||||||
{
|
{
|
||||||
*failure = true;
|
*failure = true;
|
||||||
@@ -818,7 +818,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
|
rtems_rtl_elf_find_trampolines (rtems_rtl_obj* obj, size_t unresolved)
|
||||||
{
|
{
|
||||||
rtems_rtl_tramp_data td = { 0 };
|
rtems_rtl_tramp_data td = { 0 };
|
||||||
td.obj = obj;
|
td.obj = obj;
|
||||||
@@ -829,21 +829,20 @@ rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
|
|||||||
if (td.failure)
|
if (td.failure)
|
||||||
return false;
|
return false;
|
||||||
rtems_rtl_trampoline_remove (obj);
|
rtems_rtl_trampoline_remove (obj);
|
||||||
obj->tramp_relocs = obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size;
|
obj->tramp_relocs = obj->tramp_slots;
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: tramp:elf: tramps: %zu count:%zu total:%zu\n",
|
printf ("rtl: tramp:elf: tramps: slots:%zu count:%zu total:%zu\n",
|
||||||
obj->tramp_relocs, td.count, td.total);
|
obj->tramp_relocs, td.count, td.total);
|
||||||
/*
|
/*
|
||||||
* Add on enough space to handle the unresolved externals that need to be
|
* Add on enough space to handle the unresolved externals that need to be
|
||||||
* resolved at some point in time. They could all require fixups and
|
* resolved at some point in time. They could all require fixups and
|
||||||
* trampolines.
|
* trampolines.
|
||||||
*/
|
*/
|
||||||
obj->tramps_size += obj->tramp_size * unresolved;
|
obj->tramp_slots += unresolved;
|
||||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
printf ("rtl: tramp:elf: slots: %zu (%zu)\n",
|
printf ("rtl: tramp:elf: slots:%zu (%zu)\n",
|
||||||
obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size,
|
obj->tramp_slots, obj->tramp_slots * obj->tramp_slot_size);
|
||||||
obj->tramps_size);
|
return true;
|
||||||
return rtems_rtl_obj_alloc_trampoline (obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -1730,7 +1729,7 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
|
|||||||
/*
|
/*
|
||||||
* Set the format's architecture's maximum tramp size.
|
* Set the format's architecture's maximum tramp size.
|
||||||
*/
|
*/
|
||||||
obj->tramp_size = rtems_rtl_elf_relocate_tramp_max_size ();
|
obj->tramp_slot_size = rtems_rtl_elf_relocate_tramp_max_size ();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the section information first so we have the memory map of the object
|
* Parse the section information first so we have the memory map of the object
|
||||||
@@ -1779,13 +1778,23 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
|
|||||||
if (!rtems_rtl_obj_alloc_sections (obj, fd, rtems_rtl_elf_arch_alloc, &ehdr))
|
if (!rtems_rtl_obj_alloc_sections (obj, fd, rtems_rtl_elf_arch_alloc, &ehdr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!rtems_rtl_elf_dependents (obj, &relocs))
|
if (!rtems_rtl_elf_dependents (obj, &relocs))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!rtems_rtl_elf_alloc_trampoline (obj, relocs.unresolved))
|
if (!rtems_rtl_elf_find_trampolines (obj, relocs.unresolved))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resize the sections to allocate the trampoline memory as part of
|
||||||
|
* the text section.
|
||||||
|
*/
|
||||||
|
if (rtems_rtl_obj_has_trampolines (obj))
|
||||||
|
{
|
||||||
|
if (!rtems_rtl_obj_resize_sections (obj))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -163,6 +163,12 @@ get_veneer_size(int type)
|
|||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint64_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
@@ -386,6 +392,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
|
|||||||
target -= (uintptr_t)where >> 12;
|
target -= (uintptr_t)where >> 12;
|
||||||
|
|
||||||
if (checkoverflow(target, 21, raddr, " x 4k", where, off)) {
|
if (checkoverflow(target, 21, raddr, " x 4k", where, off)) {
|
||||||
|
printf("]] %d\n", __LINE__);
|
||||||
return rtems_rtl_elf_rel_failure;
|
return rtems_rtl_elf_rel_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,6 +423,10 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
|
|||||||
return rtems_rtl_elf_rel_failure;
|
return rtems_rtl_elf_rel_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
|
||||||
|
printf ("rtl: JUMP26/PC26/CALL: insn=%p where=%p target=%p raddr=%p parsing=%d\n",
|
||||||
|
insn, (void*) where, (void*) target, (void*) raddr, parsing);
|
||||||
|
|
||||||
target = (intptr_t)target >> 2;
|
target = (intptr_t)target >> 2;
|
||||||
|
|
||||||
if (((Elf_Sword)target > 0x1FFFFFF) || ((Elf_Sword)target < -0x2000000)) {
|
if (((Elf_Sword)target > 0x1FFFFFF) || ((Elf_Sword)target < -0x2000000)) {
|
||||||
@@ -435,9 +446,8 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
|
|||||||
return rtems_rtl_elf_rel_failure;
|
return rtems_rtl_elf_rel_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
tramp_addr = ((Elf_Addr)(uintptr_t)obj->tramp_brk) | (symvalue & 1);
|
tramp_addr = ((Elf_Addr)(uintptr_t) obj->tramp_brk) | (symvalue & 1);
|
||||||
obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
|
obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
|
||||||
|
|
||||||
target = tramp_addr + rela->r_addend - (uintptr_t)where;
|
target = tramp_addr + rela->r_addend - (uintptr_t)where;
|
||||||
target = (uintptr_t)target >> 2;
|
target = (uintptr_t)target >> 2;
|
||||||
}
|
}
|
||||||
@@ -462,6 +472,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
|
|||||||
raddr = (Elf_Addr)symvalue + rela->r_addend;
|
raddr = (Elf_Addr)symvalue + rela->r_addend;
|
||||||
target = raddr - (uintptr_t)where;
|
target = raddr - (uintptr_t)where;
|
||||||
if (checkoverflow(target, 32, raddr, "", where, off)) {
|
if (checkoverflow(target, 32, raddr, "", where, off)) {
|
||||||
|
printf("]] %d\n", __LINE__);
|
||||||
return rtems_rtl_elf_rel_failure;
|
return rtems_rtl_elf_rel_failure;
|
||||||
}
|
}
|
||||||
*where32 = target;
|
*where32 = target;
|
||||||
|
|||||||
@@ -108,6 +108,12 @@ get_veneer_size(int type)
|
|||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,6 +99,12 @@ load_ptr(void *where)
|
|||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,6 +92,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -207,6 +207,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,6 +89,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void) {
|
rtems_rtl_elf_relocate_tramp_max_size (void) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -209,6 +209,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
(void) obj;
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rtems_rtl_elf_relocate_tramp_max_size (void)
|
rtems_rtl_elf_relocate_tramp_max_size (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ rtems_rtl_obj_free (rtems_rtl_obj* obj)
|
|||||||
rtems_rtl_obj_erase_sections (obj);
|
rtems_rtl_obj_erase_sections (obj);
|
||||||
rtems_rtl_obj_erase_dependents (obj);
|
rtems_rtl_obj_erase_dependents (obj);
|
||||||
rtems_rtl_symbol_obj_erase (obj);
|
rtems_rtl_symbol_obj_erase (obj);
|
||||||
rtems_rtl_obj_erase_trampoline (obj);
|
|
||||||
rtems_rtl_obj_free_names (obj);
|
rtems_rtl_obj_free_names (obj);
|
||||||
if (obj->sec_num != NULL)
|
if (obj->sec_num != NULL)
|
||||||
free (obj->sec_num);
|
free (obj->sec_num);
|
||||||
@@ -599,26 +598,6 @@ rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
|
|||||||
return match.sect;
|
return match.sect;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj)
|
|
||||||
{
|
|
||||||
if (obj->tramps_size == 0)
|
|
||||||
return true;
|
|
||||||
obj->trampoline = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
|
|
||||||
obj->tramps_size,
|
|
||||||
true);
|
|
||||||
if (obj->trampoline == NULL)
|
|
||||||
rtems_rtl_set_error (ENOMEM, "no memory for the trampoline");
|
|
||||||
obj->tramp_brk = obj->trampoline;
|
|
||||||
return obj->trampoline != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj)
|
|
||||||
{
|
|
||||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->trampoline);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
|
rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
|
||||||
{
|
{
|
||||||
@@ -828,6 +807,12 @@ rtems_rtl_obj_bss_size (const rtems_rtl_obj* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
return obj->tramp_slots * obj->tramp_slot_size;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj)
|
rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj)
|
||||||
{
|
{
|
||||||
@@ -919,10 +904,10 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj* obj)
|
|||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->trampoline != NULL)
|
if (obj->tramp_base != NULL)
|
||||||
{
|
{
|
||||||
rtems_cache_instruction_sync_after_code_change(obj->trampoline,
|
rtems_cache_instruction_sync_after_code_change(obj->tramp_base,
|
||||||
obj->tramps_size);
|
obj->tramp_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,19 +1054,29 @@ rtems_rtl_obj_sections_locate (uint32_t mask,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static void
|
||||||
rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
|
rtems_rtl_obj_set_sizes (rtems_rtl_obj* obj)
|
||||||
int fd,
|
|
||||||
rtems_rtl_obj_sect_handler handler,
|
|
||||||
void* data)
|
|
||||||
{
|
{
|
||||||
size_t text_size;
|
size_t text_size;
|
||||||
|
size_t tramp_size;
|
||||||
size_t const_size;
|
size_t const_size;
|
||||||
size_t eh_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);
|
||||||
|
tramp_size = rtems_rtl_obj_tramp_size (obj);
|
||||||
|
|
||||||
|
if (tramp_size != 0)
|
||||||
|
{
|
||||||
|
text_size += rtems_rtl_obj_tramp_alignment (obj);
|
||||||
|
tramp_size += rtems_rtl_obj_const_alignment (obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text_size += rtems_rtl_obj_const_alignment (obj);
|
||||||
|
}
|
||||||
|
|
||||||
const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_eh_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);
|
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);
|
||||||
@@ -1090,68 +1085,39 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
|
|||||||
/*
|
/*
|
||||||
* Set the sizes held in the object data. We need this for a fast reference.
|
* Set the sizes held in the object data. We need this for a fast reference.
|
||||||
*/
|
*/
|
||||||
obj->text_size = text_size;
|
obj->text_size = text_size + tramp_size;
|
||||||
|
obj->tramp_size = tramp_size;
|
||||||
obj->const_size = const_size;
|
obj->const_size = const_size;
|
||||||
obj->data_size = data_size;
|
obj->data_size = data_size;
|
||||||
obj->eh_size = eh_size;
|
obj->eh_size = eh_size;
|
||||||
obj->bss_size = bss_size;
|
obj->bss_size = bss_size;
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform any specific allocations for sections.
|
|
||||||
*/
|
|
||||||
if (handler != NULL)
|
|
||||||
{
|
|
||||||
if (!rtems_rtl_obj_section_handler (RTEMS_RTL_OBJ_SECT_TYPES,
|
|
||||||
obj,
|
|
||||||
fd,
|
|
||||||
handler,
|
|
||||||
data))
|
|
||||||
{
|
|
||||||
obj->exec_size = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Let the allocator manage the actual allocation. The user can use the
|
|
||||||
* standard heap or provide a specific allocator with memory protection.
|
|
||||||
*/
|
|
||||||
if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
|
|
||||||
&obj->const_base, const_size,
|
|
||||||
&obj->eh_base, eh_size,
|
|
||||||
&obj->data_base, data_size,
|
|
||||||
&obj->bss_base, bss_size))
|
|
||||||
{
|
|
||||||
obj->exec_size = 0;
|
|
||||||
rtems_rtl_set_error (ENOMEM, "no memory to load obj");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->exec_size = text_size + const_size + eh_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))
|
static void
|
||||||
|
rtems_rtl_obj_print_sizes (rtems_rtl_obj* obj, const char* label)
|
||||||
|
{
|
||||||
|
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
|
||||||
{
|
{
|
||||||
printf ("rtl: load sect: text - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: %s sect: text - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
|
label, obj->text_base, obj->text_size, rtems_rtl_obj_text_alignment (obj));
|
||||||
printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: %s sect: tramp - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
|
label, obj->tramp_base, obj->tramp_size, rtems_rtl_obj_tramp_alignment (obj));
|
||||||
printf ("rtl: load sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: %s sect: const - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->eh_base, eh_size, rtems_rtl_obj_eh_alignment (obj));
|
label, obj->const_base, obj->const_size, rtems_rtl_obj_const_alignment (obj));
|
||||||
printf ("rtl: load sect: data - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: %s sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
|
label, obj->eh_base, obj->eh_size, rtems_rtl_obj_eh_alignment (obj));
|
||||||
printf ("rtl: load sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
|
printf ("rtl: %s sect: data - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
|
label, obj->data_base, obj->data_size, rtems_rtl_obj_data_alignment (obj));
|
||||||
|
printf ("rtl: %s sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
|
||||||
|
label, obj->bss_base, obj->bss_size, rtems_rtl_obj_bss_alignment (obj));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* Determine the load order.
|
rtems_rtl_obj_locate (rtems_rtl_obj* obj)
|
||||||
*/
|
{
|
||||||
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);
|
|
||||||
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_BSS, obj);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locate all text, data and bss sections in seperate operations so each type of
|
* Locate all text, data and bss sections in seperate operations so each type of
|
||||||
* section is grouped together.
|
* section is grouped together.
|
||||||
@@ -1171,6 +1137,110 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
|
|||||||
rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
|
rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
|
||||||
rtems_rtl_alloc_bss_tag (),
|
rtems_rtl_alloc_bss_tag (),
|
||||||
obj, obj->bss_base);
|
obj, obj->bss_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
|
||||||
|
int fd,
|
||||||
|
rtems_rtl_obj_sect_handler handler,
|
||||||
|
void* data)
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_set_sizes (obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform any specific allocations for sections.
|
||||||
|
*/
|
||||||
|
if (handler != NULL)
|
||||||
|
{
|
||||||
|
if (!rtems_rtl_obj_section_handler (RTEMS_RTL_OBJ_SECT_TYPES,
|
||||||
|
obj,
|
||||||
|
fd,
|
||||||
|
handler,
|
||||||
|
data))
|
||||||
|
{
|
||||||
|
obj->exec_size = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let the allocator manage the actual allocation. The user can use the
|
||||||
|
* standard heap or provide a specific allocator with memory protection.
|
||||||
|
*/
|
||||||
|
if (!rtems_rtl_alloc_module_new (&obj->text_base, obj->text_size,
|
||||||
|
&obj->const_base, obj->const_size,
|
||||||
|
&obj->eh_base, obj->eh_size,
|
||||||
|
&obj->data_base, obj->data_size,
|
||||||
|
&obj->bss_base, obj->bss_size))
|
||||||
|
{
|
||||||
|
obj->exec_size = 0;
|
||||||
|
rtems_rtl_set_error (ENOMEM, "no memory to load obj");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the trampoline base if there are trampolines
|
||||||
|
*/
|
||||||
|
if (obj->tramp_size != 0)
|
||||||
|
{
|
||||||
|
obj->tramp_base = obj->tramp_brk =
|
||||||
|
obj->text_base + obj->text_size - obj->tramp_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_rtl_obj_print_sizes (obj, "alloc");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_BSS, obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locate the sections to the allocated section bases
|
||||||
|
*/
|
||||||
|
rtems_rtl_obj_locate (obj);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj)
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_set_sizes (obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let the allocator manage the resizing.
|
||||||
|
*/
|
||||||
|
if (!rtems_rtl_alloc_module_resize (&obj->text_base, obj->text_size,
|
||||||
|
&obj->const_base, obj->const_size,
|
||||||
|
&obj->eh_base, obj->eh_size,
|
||||||
|
&obj->data_base, obj->data_size,
|
||||||
|
&obj->bss_base, obj->bss_size))
|
||||||
|
{
|
||||||
|
rtems_rtl_obj_free (obj);
|
||||||
|
obj->exec_size = 0;
|
||||||
|
rtems_rtl_set_error (ENOMEM, "no memory resize obj");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the trampoline base if there are trampolines
|
||||||
|
*/
|
||||||
|
if (obj->tramp_size != 0)
|
||||||
|
{
|
||||||
|
obj->tramp_base = obj->tramp_brk =
|
||||||
|
obj->text_base + obj->text_size - obj->tramp_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_rtl_obj_print_sizes (obj, "resize");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locate the sections to the allocated section bases
|
||||||
|
*/
|
||||||
|
rtems_rtl_obj_locate (obj);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,7 +572,7 @@ rtems_rtl_obj_printer (rtems_rtl_obj_print* print, rtems_rtl_obj* obj)
|
|||||||
rtems_printf (print->printer, "%-*cslots : %zu\n", indent + 4, ' ',
|
rtems_printf (print->printer, "%-*cslots : %zu\n", indent + 4, ' ',
|
||||||
slots);
|
slots);
|
||||||
rtems_printf (print->printer, "%-*csize : %zu\n", indent + 4, ' ',
|
rtems_printf (print->printer, "%-*csize : %zu\n", indent + 4, ' ',
|
||||||
obj->tramps_size);
|
obj->tramp_size);
|
||||||
rtems_printf (print->printer, "%-*cslot size : %zu\n", indent + 4, ' ',
|
rtems_printf (print->printer, "%-*cslot size : %zu\n", indent + 4, ' ',
|
||||||
obj->tramp_size);
|
obj->tramp_size);
|
||||||
rtems_printf (print->printer, "%-*cused : %zu\n", indent + 4, ' ',
|
rtems_printf (print->printer, "%-*cused : %zu\n", indent + 4, ' ',
|
||||||
|
|||||||
@@ -116,8 +116,12 @@ static void dl_check_resolved(void* handle, bool has_unresolved)
|
|||||||
rtems_test_assert (unresolved == 0);
|
rtems_test_assert (unresolved == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf ("handel: %p: %sunresolved externals\n",
|
if (handle == RTLD_SELF)
|
||||||
handle, unresolved != 0 ? "" : "no ");
|
printf ("handle: RTL_SELF: %sunresolved externals\n",
|
||||||
|
unresolved != 0 ? "" : "no ");
|
||||||
|
else
|
||||||
|
printf ("handle: %p: %sunresolved externals\n",
|
||||||
|
handle, unresolved != 0 ? "" : "no ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* dl_load_obj (const char* name, bool has_unresolved)
|
static void* dl_load_obj (const char* name, bool has_unresolved)
|
||||||
@@ -152,12 +156,20 @@ static void dl_close (void* handle)
|
|||||||
|
|
||||||
static int dl_call (void* handle, const char* func)
|
static int dl_call (void* handle, const char* func)
|
||||||
{
|
{
|
||||||
|
static call_sig last_call;
|
||||||
call_sig call = dlsym (handle, func);
|
call_sig call = dlsym (handle, func);
|
||||||
if (call == NULL)
|
if (call == NULL)
|
||||||
{
|
{
|
||||||
printf("dlsym failed: symbol not found: %s\n", func);
|
printf("dlsym failed: symbol not found: %s\n", func);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (last_call != NULL && last_call != call)
|
||||||
|
{
|
||||||
|
printf("Call location different: moved by: %i (call:%p last:%p)\n",
|
||||||
|
(int) (call - last_call),
|
||||||
|
call, last_call);
|
||||||
|
}
|
||||||
|
last_call = call;
|
||||||
call ();
|
call ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user