About "Add per-section compilation and linking support" and libdl
Сергей Круглов
sergkruglov at bk.ru
Mon Jan 25 13:50:29 UTC 2016
I don’t know how to issue ticket to trac and link https://devel.rtems.org/wiki/NewTicket not working
1. Current version libdl incorrect relocate MIPS16hi/lo (not supported nested instructions) and I wrote small patch for this (similar gnu as for mips)
diff -Naur ./org/rtl-mdreloc-mips.c ./new/rtl-mdreloc-mips.c
--- ./org/rtl-mdreloc-mips.c 2015-03-27 14:59:47 +0300
+++ ./new/rtl-mdreloc-mips.c 2016-01-21 17:59:09 +0300
@@ -36,6 +36,18 @@
* symbol is STT_SECTION, it must be STB_LOCAL. Thus
* just consider symtype here.
*/
+
+struct mips_hi16 {
+ Elf_Addr *where_hi16;
+ Elf_Addr ahl;
+};
+
+extern struct {
+ Elf_Addr *where_hi16;
+ Elf_Addr ahl;
+} *mips_hi16_list;
+extern int mips_hi16_list_cnt;
+
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
const Elf_Rel* rel,
@@ -50,10 +62,6 @@
Elf_Word local = 0;
uint32_t t;
-
- static Elf_Addr *where_hi16;
- static Elf_Addr ahl;
-
where = (Elf_Addr *)(sect->base + rel->r_offset);
addend = *where;
@@ -119,9 +127,15 @@
break;
case R_TYPE(HI16):
- ahl = addend << 16;
- where_hi16 = where;
+ mips_hi16_list_cnt++;
+ if (mips_hi16_list_cnt > 32) {
+ printf("rtl:Error, too many HI16 relocs!\n");
+ return false;
+ }
+ mips_hi16_list++;
+ mips_hi16_list->where_hi16 = where;
+ mips_hi16_list->ahl = addend << 16;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: R_MIPS_HI16 %p @ %p in %s\n",
@@ -129,31 +143,37 @@
break;
case R_TYPE(LO16):
- //ahl += (int16_t)addend;
- t = ahl + (int16_t)addend;
- tmp = symvalue;
- if (tmp == 0)
- return false;
-
- addend &= 0xffff0000;
- addend |= (uint16_t)(t + tmp);
- *where = addend;
-
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf("*where %lx where %p\n", *where, where);
-
- addend = *where_hi16;
- addend &= 0xffff0000;
- addend |= ((t + tmp) - (int16_t)(t + tmp)) >> 16;
- *where_hi16 = addend;
-
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf("*where_hi %lx where_hi %p\n", *where_hi16, where_hi16);
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: R_MIPS_LO16 %p @ %p in %s\n",
- (void *)*(where), where, rtems_rtl_obj_oname (obj));
- break;
+ t = (int16_t) addend;
+ tmp = symvalue;
+ if (tmp == 0)
+ return false;
+ /* reloc low part */
+ addend &= 0xffff0000;
+ addend |= (uint16_t) (t + tmp);
+ *where = addend;
+
+ if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
+ printf("*where %x where %x\n", *where, where);
+ /* reloc hi parts */
+ while (mips_hi16_list_cnt != 0) {
+ addend = *(mips_hi16_list->where_hi16);
+ addend &= 0xffff0000;
+ addend |= ((mips_hi16_list->ahl + t + tmp)
+ - (int16_t) (mips_hi16_list->ahl + t + tmp)) >> 16;
+ *(mips_hi16_list->where_hi16) = addend;
+ if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
+ printf("*where_hi %x where_hi %x ahl=%08x\n",
+ *(mips_hi16_list->where_hi16),
+ mips_hi16_list->where_hi16, mips_hi16_list->ahl);
+ mips_hi16_list--;
+ mips_hi16_list_cnt--;
+ }
+
+ if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: R_MIPS_LO16 %p @ %p in %s\n", (void *) *(where), where,
+ rtems_rtl_obj_oname(obj));
+ break;
case R_TYPE(PC16):
tmp = addend & 0xffff;
diff -Naur ./org/rtl-rap.c ./new/rtl-rap.c
--- ./org/rtl-rap.c 2015-03-23 11:08:38 +0300
+++ ./new/rtl-rap.c 2016-01-21 17:52:15 +0300
@@ -217,6 +217,13 @@
return rtems_rtl_obj_comp_read (rap->decomp, sect->base, sect->size);
}
+struct {
+ Elf_Addr *where_hi16;
+ Elf_Addr ahl;
+} *mips_hi16_list;
+
+int mips_hi16_list_cnt;
+
static bool
rtems_rtl_rap_relocate (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
{
@@ -270,6 +277,13 @@
rap_sections[section].name,
header, relocs, is_rela ? "rela" : "rel");
+ mips_hi16_list = malloc(sizeof(*mips_hi16_list) * (32 + 1));
+ if (mips_hi16_list == NULL) {
+ printf("rtl: No enough memory for hi16_list\n");
+ return false;
+ }
+ mips_hi16_list_cnt = 0;
+
for (r = 0; r < relocs; ++r)
{
uint32_t info = 0;
@@ -419,6 +433,14 @@
}
}
}
+
+ free(mips_hi16_list);
+ if (mips_hi16_list_cnt != 0) {
+ printf("rtl:Error, not empty mips_hi16_list!\n");
+ free(symname_buffer);
+ return false;
+ }
+
}
free (symname_buffer);
2. Small patch for imfs_memfile (I some time ago offered).
If variable unsigned int block == 0 – for loop work incorrectly (and I have this after error fs).
diff -Naur ./orgimfs/imfs_memfile.c ./newimfs/imfs_memfile.c
--- ./orgimfs/imfs_memfile.c 2015-02-16 10:03:17 +0300
+++ ./newimfs/imfs_memfile.c 2016-01-22 11:13:15 +0300
@@ -188,9 +188,10 @@
offset = 0;
}
} else {
- for ( ; block>=old_blocks ; block-- ) {
- IMFS_memfile_remove_block( memfile, block );
- }
+ if ( !block )
+ for ( ; block>=old_blocks ; block-- ) {
+ IMFS_memfile_remove_block( memfile, block );
+ }
rtems_set_errno_and_return_minus_one( ENOSPC );
}
}
3. For test per-section compilation and dynamic linking support I wrote 3 small project (indifferently cpu)
project a) static library libtst.a with tst.c
tst.c
int abcd=5;
void funcA(void)
{
abcd=7;
}
void funcB(void)
{
}
project b) minimal rtems project have only Init function and linked with this libtst.a
extern void funcA(void);
extern int abcd;
rtems_task Init(rtems_task_argument argument) {
funcA();
abcd = 9;
rtems_task_delete(RTEMS_SELF);
}
project c) make rap file with test.c and linked library libtst.a and kernel image
test.c
extern void funcB(void);
void rtems(void)
{
funcB();
}
Map file without per-section compilation
testrap.rap:
Strings: 0x00000074 (116) size: 14
0 (0x000000):
1 (0x000001): rtems
2 (0x000007): rtems
3 (0x00000d):
Symbols: 0x00000082 (130) size: 12
data section value name
0: 0x0012 .text 0x00000000 rtems
Relocations: 0x0000008e (142)
.text: info offset addend symbol name
0: 0x80000504 0x00000008 0x00000000 funcB
Map file with per-section compilation
testrap.rap:
Strings: 0x00000090 (144) size: 31
0 (0x000000):
1 (0x000001): rtems
2 (0x000007): funcA
3 (0x00000d): abcd
4 (0x000012): funcB
5 (0x000018): rtems
6 (0x00001e):
Symbols: 0x000000af (175) size: 48
data section value name
0: 0x0012 .text 0x00000000 rtems
1: 0x0012 .text 0x00000000 funcA
2: 0x0011 .data 0x00000000 abcd
3: 0x0012 .text 0x00000000 funcB
Relocations: 0x000000df (223)
.text: info offset addend symbol name
0: 0xc0001204 0x00000008 0x00000000
1: 0xc0000d05 0x00000024 0x00000000
2: 0xc0000d06 0x0000002c 0x00000000
If use per-section compilation while insert funcB (from library libtst.a) get full tst.o from library.
Objects funcA and abcd duplicate already available in kernel.
I do not know as it to correct and remove excess symbols and objects.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20160125/26ddad7e/attachment-0002.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: wlEmoticon-sadsmile[1].png
Type: image/png
Size: 1090 bytes
Desc: not available
URL: <http://lists.rtems.org/pipermail/users/attachments/20160125/26ddad7e/attachment-0002.png>
More information about the users
mailing list