Skip to content

Commit 9ede691

Browse files
committed
[elf] Refactor dynamic linker
- Reduce RAM usage - Fix bugs - Tested rel_type (with Cortex-M0) - R_ARM_JUMP_SLOT - R_ARM_RELATIVE
1 parent e17fd49 commit 9ede691

File tree

14 files changed

+1543
-1031
lines changed

14 files changed

+1543
-1031
lines changed

src/components/finsh/msh.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ int msh_exec_module(const char *cmd_line, int size)
217217
/* try to open program */
218218
fd = open(pg_name, O_RDONLY, 0);
219219

220-
/* search in /bin path */
220+
/* search in /mo path */
221221
if (fd < 0)
222222
{
223-
rt_snprintf(pg_name, length - 1, "/bin/%.*s", cmd_length, cmd_line);
223+
rt_snprintf(pg_name, length - 1, "/mo/%.*s", cmd_length, cmd_line);
224224
fd = open(pg_name, O_RDONLY, 0);
225225
}
226226
}
@@ -232,10 +232,10 @@ int msh_exec_module(const char *cmd_line, int size)
232232
strcat(pg_name, ".mo");
233233
fd = open(pg_name, O_RDONLY, 0);
234234

235-
/* search in /bin path */
235+
/* search in /mo path */
236236
if (fd < 0)
237237
{
238-
rt_snprintf(pg_name, length - 1, "/bin/%.*s.mo", cmd_length, cmd_line);
238+
rt_snprintf(pg_name, length - 1, "/mo/%.*s.mo", cmd_length, cmd_line);
239239
fd = open(pg_name, O_RDONLY, 0);
240240
}
241241
}

src/components/libc/libdl/arch/arm.c

Lines changed: 74 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Change Logs:
77
* Date Author Notes
88
* 2018/08/29 Bernard first version
9+
* 2019/04/25 onelife refactor
910
*/
1011

1112
#include "include/rtthread.h"
@@ -15,112 +16,115 @@
1516

1617
#include "../dlelf.h"
1718

18-
#ifdef __arm__
19-
int dlmodule_relocate(struct rt_dlmodule *module, Elf32_Rel *rel, Elf32_Addr sym_val)
20-
{
21-
Elf32_Addr *where, tmp;
19+
#ifdef RT_USING_ULOG
20+
# define LOG_LVL LOG_LVL_INFO
21+
# define LOG_TAG "MO_ARM"
22+
# include "components/utilities/ulog/ulog.h"
23+
#else /* RT_USING_ULOG */
24+
# define LOG_E(format, args...) rt_kprintf(format "\n", ##args)
25+
# define LOG_D LOG_E
26+
#endif /* RT_USING_ULOG */
27+
28+
29+
Elf32_Addr dlmodule_relocate(rt_uint8_t rel_type, Elf32_Addr *where,
30+
Elf32_Addr sym_val) {
31+
/* Tested rel_type:
32+
- R_ARM_JUMP_SLOT
33+
- R_ARM_RELATIVE
34+
*/
35+
Elf32_Addr tmp;
2236
Elf32_Sword addend, offset;
2337
rt_uint32_t upper, lower, sign, j1, j2;
38+
union {
39+
Elf32_Word word;
40+
Elf32_Half half[2];
41+
} tmp2;
2442

25-
where = (Elf32_Addr *)((rt_uint8_t *)module->mem_space
26-
+ rel->r_offset
27-
- module->vstart_addr);
28-
switch (ELF32_R_TYPE(rel->r_info))
29-
{
43+
switch (rel_type) {
3044
case R_ARM_NONE:
31-
break;
45+
LOG_E("R_ARM_NONE");
46+
return 0;
47+
48+
case R_ARM_GLOB_DAT:
49+
case R_ARM_JUMP_SLOT:
50+
/* (S + A) | T */
51+
return sym_val;
52+
53+
case R_ARM_RELATIVE:
54+
/* B(S) + A */
55+
return sym_val + *where;
56+
3257
case R_ARM_ABS32:
33-
*where += (Elf32_Addr)sym_val;
34-
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_ABS32: %x -> %x\n",
35-
where, *where));
36-
break;
58+
LOG_I("R_ARM_ABS32");
59+
return sym_val + *where;
60+
3761
case R_ARM_PC24:
3862
case R_ARM_PLT32:
3963
case R_ARM_CALL:
4064
case R_ARM_JUMP24:
65+
LOG_I("R_ARM_CALL");
4166
addend = *where & 0x00ffffff;
42-
if (addend & 0x00800000)
67+
if (addend & 0x00800000) {
4368
addend |= 0xff000000;
69+
}
4470
tmp = sym_val - (Elf32_Addr)where + (addend << 2);
4571
tmp >>= 2;
46-
*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
47-
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_PC24: %x -> %x\n",
48-
where, *where));
49-
break;
72+
return (*where & 0xff000000) | (tmp & 0x00ffffff);
73+
5074
case R_ARM_REL32:
51-
*where += sym_val - (Elf32_Addr)where;
52-
RT_DEBUG_LOG(RT_DEBUG_MODULE,
53-
("R_ARM_REL32: %x -> %x, sym %x, offset %x\n",
54-
where, *where, sym_val, rel->r_offset));
55-
break;
75+
LOG_I("R_ARM_REL32");
76+
return sym_val - (Elf32_Addr)where + *where;
77+
5678
case R_ARM_V4BX:
57-
*where &= 0xf000000f;
58-
*where |= 0x01a0f000;
59-
break;
79+
LOG_I("R_ARM_V4BX");
80+
return ((Elf32_Addr)where & 0xf000000f) | 0x01a0f000;
6081

61-
case R_ARM_GLOB_DAT:
62-
case R_ARM_JUMP_SLOT:
63-
*where = (Elf32_Addr)sym_val;
64-
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_JUMP_SLOT: 0x%x -> 0x%x 0x%x\n",
65-
where, *where, sym_val));
66-
break;
67-
#if 0 /* To do */
82+
#if 0 /* todo */
6883
case R_ARM_GOT_BREL:
69-
temp = (Elf32_Addr)sym_val;
70-
*where = (Elf32_Addr)&temp;
71-
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_GOT_BREL: 0x%x -> 0x%x 0x%x\n",
72-
where, *where, sym_val));
73-
break;
74-
#endif
84+
LOG_I("R_ARM_GOT_BREL");
85+
temp = sym_val;
86+
return (Elf32_Addr)&temp;
87+
#endif
7588

76-
case R_ARM_RELATIVE:
77-
*where = (Elf32_Addr)sym_val + *where;
78-
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_RELATIVE: 0x%x -> 0x%x 0x%x\n",
79-
where, *where, sym_val));
80-
break;
8189
case R_ARM_THM_CALL:
8290
case R_ARM_THM_JUMP24:
91+
LOG_I("R_ARM_THM_CALL");
8392
upper = *(rt_uint16_t *)where;
8493
lower = *(rt_uint16_t *)((Elf32_Addr)where + 2);
85-
8694
sign = (upper >> 10) & 1;
8795
j1 = (lower >> 13) & 1;
8896
j2 = (lower >> 11) & 1;
89-
offset = (sign << 24) |
90-
((~(j1 ^ sign) & 1) << 23) |
91-
((~(j2 ^ sign) & 1) << 22) |
92-
((upper & 0x03ff) << 12) |
97+
offset = (sign << 24) | \
98+
((~(j1 ^ sign) & 1) << 23) | \
99+
((~(j2 ^ sign) & 1) << 22) | \
100+
((upper & 0x03ff) << 12) | \
93101
((lower & 0x07ff) << 1);
94-
if (offset & 0x01000000)
102+
if (offset & 0x01000000) {
95103
offset -= 0x02000000;
104+
}
96105
offset += sym_val - (Elf32_Addr)where;
97106

98-
if (!(offset & 1) ||
99-
offset <= (rt_int32_t)0xff000000 ||
100-
offset >= (rt_int32_t)0x01000000)
101-
{
102-
rt_kprintf("Module: Only Thumb addresses allowed\n");
103-
104-
return -1;
107+
if (!(offset & 1) || offset <= (rt_int32_t)0xff000000 || \
108+
offset >= (rt_int32_t)0x01000000) {
109+
LOG_E("R_ARM_THM_CALL: bad Thumb sym_val");
110+
return -RT_ERROR;
105111
}
106112

107113
sign = (offset >> 24) & 1;
108114
j1 = sign ^ (~(offset >> 23) & 1);
109115
j2 = sign ^ (~(offset >> 22) & 1);
110-
*(rt_uint16_t *)where = (rt_uint16_t)((upper & 0xf800) |
111-
(sign << 10) |
112-
((offset >> 12) & 0x03ff));
113-
*(rt_uint16_t *)(where + 2) = (rt_uint16_t)((lower & 0xd000) |
114-
(j1 << 13) | (j2 << 11) |
115-
((offset >> 1) & 0x07ff));
116-
upper = *(rt_uint16_t *)where;
117-
lower = *(rt_uint16_t *)((Elf32_Addr)where + 2);
118-
break;
116+
tmp2.half[0] = (rt_uint16_t)((upper & 0xf800) | \
117+
(sign << 10) | \
118+
((offset >> 12) & 0x03ff));
119+
tmp2.half[1] = (rt_uint16_t)((lower & 0xd000) | \
120+
(j1 << 13) | (j2 << 11) | \
121+
((offset >> 1) & 0x07ff));
122+
return tmp2.word;
123+
119124
default:
120-
return -1;
125+
LOG_E("bad rel_type %d", rel_type);
126+
return 0;
121127
}
122-
123-
return 0;
124128
}
125129

126130
#endif /* __arm__ */

src/components/libc/libdl/dlclose.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,18 @@
1414

1515
#include "dlmodule.h"
1616

17-
int dlclose(void *handle)
18-
{
19-
struct rt_dlmodule *module;
2017

21-
RT_ASSERT(handle != RT_NULL);
18+
int dlclose(void *handle) {
19+
rt_dlmodule_t *module = (rt_dlmodule_t *)handle;
2220

23-
module = (struct rt_dlmodule *)handle;
21+
RT_ASSERT(handle != RT_NULL);
2422

2523
rt_enter_critical();
2624
module->nref--;
27-
if (module->nref <= 0)
28-
{
25+
if (module->nref <= 0) {
2926
rt_exit_critical();
30-
3127
dlmodule_destroy(module);
32-
}
33-
else
34-
{
28+
} else {
3529
rt_exit_critical();
3630
}
3731

0 commit comments

Comments
 (0)