Created
May 4, 2013 12:33
-
-
Save MrVan/5517361 to your computer and use it in GitHub Desktop.
1. Basic Reloc types are implemented.
ARM REL TYPE:
R_ARM_JUMP24 R_ARM_ABS32 R_ARM_CALL R_ARM_MOVW_ABS_NC R_ARM_MOVT_ABS R_ARM_V4BX //This should be fixed. arm thumb switch? THUMB REL TYPE:
R_ARM_THM_CALL R_ARM_ABS32 R_ARM_THM_MOVW_ABS_NC R_ARM_THM_MOVT_ABS R_ARM_THM_JUMP24
2. Implement several group reloc types. But not sure what are they used …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 516531d199ec2302c0f932c61b9542a70492948b Mon Sep 17 00:00:00 2001 | |
From: Peng Fan <van.freenix@gmail.com> | |
Date: Sat, 4 May 2013 20:26:59 +0800 | |
Subject: [PATCH] ARM Support | |
--- | |
.gitignore | 4 + | |
Makefile | 8 + | |
bspinit.c | 2 + | |
libbsd/include/arch/arm/machine/elf_machdep.h | 25 ++ | |
main.c | 3 + | |
rtems.py | 9 +- | |
rtl-mdreloc-arm.c | 447 +++++++++++++++++++++++-- | |
rtl-obj.c | 2 + | |
rtl-rap.c | 110 +++--- | |
rtl-sym.c | 40 ++- | |
rtl.c | 7 +- | |
shell-init | 6 +- | |
wscript | 28 +- | |
x1.S | 53 +++ | |
x2.S | 32 ++ | |
xa.c | 14 + | |
16 files changed, 702 insertions(+), 88 deletions(-) | |
create mode 100644 Makefile | |
mode change 100644 => 100755 wscript | |
create mode 100644 x1.S | |
create mode 100644 x2.S | |
diff --git a/.gitignore b/.gitignore | |
index 60089a0..56e23ab 100644 | |
--- a/.gitignore | |
+++ b/.gitignore | |
@@ -1,3 +1,7 @@ | |
.lock-waf* | |
build | |
*.pyc | |
+*.sh | |
+./tags | |
+cscope.* | |
+./debug-rld | |
diff --git a/Makefile b/Makefile | |
new file mode 100644 | |
index 0000000..38e5611 | |
--- /dev/null | |
+++ b/Makefile | |
@@ -0,0 +1,8 @@ | |
+all: FORCE | |
+ make -C /home/freenix/work/gsoc/rtems/rtl/rel-test | |
+ waf | |
+FORCE: | |
+ | |
+.phony: clean | |
+clean: | |
+ waf clean | |
diff --git a/bspinit.c b/bspinit.c | |
index 9c50d03..e10cce4 100644 | |
--- a/bspinit.c | |
+++ b/bspinit.c | |
@@ -12,6 +12,7 @@ | |
#include <bsp.h> | |
#include <bsp/bootcard.h> | |
+#undef RTEMS_NETWORKING /* commented by freenix */ | |
#ifdef RTEMS_NETWORKING | |
#include <rtems/rtems_bsdnet.h> | |
#endif | |
@@ -76,6 +77,7 @@ void Init (rtems_task_argument arg) | |
} | |
} | |
+ printk("Init\n"); | |
#ifdef RTEMS_NETWORKING | |
rtems_bsdnet_initialize_network (); | |
#endif | |
diff --git a/libbsd/include/arch/arm/machine/elf_machdep.h b/libbsd/include/arch/arm/machine/elf_machdep.h | |
index 963ff64..09e0995 100644 | |
--- a/libbsd/include/arch/arm/machine/elf_machdep.h | |
+++ b/libbsd/include/arch/arm/machine/elf_machdep.h | |
@@ -40,6 +40,7 @@ | |
#define R_ARM_PC24 1 | |
#define R_ARM_ABS32 2 | |
#define R_ARM_REL32 3 | |
+#define R_ARM_LDR_PC_G0 4 | |
#define R_ARM_PC13 4 | |
#define R_ARM_ABS16 5 | |
#define R_ARM_ABS12 6 | |
@@ -47,6 +48,7 @@ | |
#define R_ARM_ABS8 8 | |
#define R_ARM_SBREL32 9 | |
#define R_ARM_THM_PC22 10 | |
+#define R_ARM_THM_CALL 10 | |
#define R_ARM_THM_PC8 11 | |
#define R_ARM_AMP_VCALL9 12 | |
#define R_ARM_SWI24 13 | |
@@ -69,6 +71,11 @@ | |
#define R_ARM_GOT32 26 | |
#define R_ARM_PLT32 27 | |
+#define R_ARM_CALL 28 | |
+#define R_ARM_JUMP24 29 | |
+#define R_ARM_THM_JUMP24 30 | |
+#define R_ARM_BASE_ABS 31 | |
+ | |
#define R_ARM_ALU_PCREL_7_0 32 | |
#define R_ARM_ALU_PCREL_15_8 33 | |
#define R_ARM_ALU_PCREL_23_15 34 | |
@@ -76,6 +83,24 @@ | |
#define R_ARM_ALU_SBREL_19_12 36 | |
#define R_ARM_ALU_SBREL_27_20 37 | |
+#define R_ARM_V4BX 40 | |
+ | |
+#define R_ARM_PREL31 41 | |
+ | |
+#define R_ARM_MOVW_ABS_NC 43 | |
+#define R_ARM_MOVT_ABS 44 | |
+ | |
+#define R_ARM_THM_MOVW_ABS_NC 47 | |
+#define R_ARM_THM_MOVT_ABS 48 | |
+ | |
+#define R_ARM_THM_JUMP19 51 | |
+#define R_ARM_LDR_PC_G1 62 | |
+#define R_ARM_LDR_PC_G2 63 | |
+ | |
+#define R_ARM_LDR_SB_G0 75 | |
+#define R_ARM_LDR_SB_G1 76 | |
+#define R_ARM_LDR_SB_G2 77 | |
+ | |
/* 96-111 are reserved to G++. */ | |
#define R_ARM_GNU_VTENTRY 100 | |
#define R_ARM_GNU_VTINHERIT 101 | |
diff --git a/main.c b/main.c | |
index a8f8640..d0397ce 100644 | |
--- a/main.c | |
+++ b/main.c | |
@@ -375,6 +375,9 @@ main (int argc, char* argv[]) | |
{ | |
struct termios term; | |
int ret; | |
+ printf("%s\n", __func__); | |
+ //__asm__ __volatile__ ("ldr r3, [r1], #4"); | |
+ printf("%s\n", __func__); | |
#if pc586 | |
int arg; | |
diff --git a/rtems.py b/rtems.py | |
index 5558f84..d80cc52 100644 | |
--- a/rtems.py | |
+++ b/rtems.py | |
@@ -388,6 +388,9 @@ def _find_installed_archs(config, path, version): | |
for d in os.listdir(path): | |
if d.endswith('-rtems' + version): | |
archs += [d] | |
+ for d in os.listdir(path): | |
+ if d.endswith('-rtemseabi' + version): | |
+ archs += [d] | |
else: | |
a = subprocess.check_output([config, '--list-format', '"%(arch)s"']) | |
a = a[:-1].replace('"', '') | |
@@ -403,6 +406,10 @@ def _check_archs(config, req, path, version): | |
arch = a + '-rtems' + version | |
if arch in installed: | |
archs += [arch] | |
+ for a in req.split(','): | |
+ arch = a + '-rtemseabi' + version | |
+ if arch in installed: | |
+ archs += [arch] | |
archs.sort() | |
return archs | |
@@ -429,7 +436,7 @@ def _check_arch_bsps(req, config, path, archs, version): | |
return [] | |
found = False | |
for arch in archs: | |
- a = '%s-rtems%s' % (abl[0], version) | |
+ a = '%s-rtemseabi%s' % (abl[0], version) | |
if a == arch: | |
found = True | |
break | |
diff --git a/rtl-mdreloc-arm.c b/rtl-mdreloc-arm.c | |
index e55da1f..7fc4987 100644 | |
--- a/rtl-mdreloc-arm.c | |
+++ b/rtl-mdreloc-arm.c | |
@@ -4,6 +4,14 @@ | |
/* $NetBSD: mdreloc.c,v 1.33 2010/01/14 12:12:07 skrll Exp $ */ | |
+ | |
+/* | |
+ * Added by Peng Fan | |
+ * Code Name Type Class Operation Instruction | |
+ * 29 R_ARM_CALL Static ARM ((S + A) | T) - P | |
+ * 30 R_ARM_JUMP24 Static ARM ((S + A) | T) - P | |
+ */ | |
+ | |
#include <sys/cdefs.h> | |
#include <errno.h> | |
@@ -40,6 +48,30 @@ store_ptr(void *where, Elf_Addr val) | |
memcpy(where, &val, sizeof(val)); | |
} | |
+static inline Elf_Word | |
+calc_grp_kn(Elf_Word residual) | |
+{ | |
+ int msb; | |
+ | |
+ if (residual == 0) | |
+ return 0; | |
+ for (msb = 30; (msb >= 0) && !(residual & (3 << msb)); msb -= 2) | |
+ ; | |
+ return (((msb - 6) < 0) ? 0 : (msb - 6)); | |
+} | |
+ | |
+static Elf_Word | |
+cal_group_reloc_mask(Elf_Word residual, int n) | |
+{ | |
+ int i; | |
+ | |
+ for (i = 0; i <= n; i++) { | |
+ Elf_Word shift = calc_grp_kn(residual); | |
+ residual &= ~(residual & (0xff << shift)); | |
+ } | |
+ return residual; | |
+} | |
+ | |
bool | |
rtems_rtl_elf_rel_resolve_sym (Elf_Word type) | |
{ | |
@@ -68,62 +100,212 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, | |
{ | |
Elf_Addr *where; | |
Elf_Addr tmp; | |
+ Elf32_Sword addend; | |
+ Elf32_Word val; | |
where = (Elf_Addr *)(sect->base + rel->r_offset); | |
switch (ELF_R_TYPE(rel->r_info)) { | |
case R_TYPE(NONE): | |
break; | |
+ case R_TYPE(ABS8): { | |
+ /* | |
+ * operation: S + A; | |
+ * overflow: yes; class: data; | |
+ * Addend = sign_extend(P[8:0]); | |
+ */ | |
+ tmp = *where; | |
+ addend = tmp & 0xff; | |
+ if (addend & 0x80) | |
+ addend |= 0xffffff00; | |
+ if ((addend > 0xff) || (addend < -0x80)) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "ABS8 relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ *where = addend + symvalue; /* S + A */ | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: ABS8 %p @ %p in %s\n", | |
+ (void *)tmp, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+ case R_TYPE(ABS16): { | |
+ /* | |
+ * operation: S + A; | |
+ * overflow: yes; class: data; | |
+ * Addend = sign_extend(P[16:0]); | |
+ */ | |
+ tmp = *where; | |
+ addend = tmp & 0xffff; | |
+ if (addend & 0x8000) | |
+ addend |= 0xffff0000; | |
+ if ((addend > 0xffff) || (addend < -0x8000)) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "ABS16 relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ *where = addend + symvalue; /* S + A */ | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: ABS16 %p @ %p in %s\n", | |
+ (void *)tmp, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+ case R_TYPE(PREL31): { | |
+ /* | |
+ * operation: (S + A) | T - P; | |
+ * class:data; | |
+ * Addend = sign_extend(P[30:0]); | |
+ */ | |
+ tmp = *where; | |
+ addend = tmp & 0x7fffffff; | |
+ if (addend & 0x40000000); | |
+ addend |= 0x80000000; | |
+ if ((addend > 0x7fffffff) || (addend < -0x3fffffff)) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "PREL31 relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ tmp = symvalue + addend; | |
+ if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
+ tmp |= 1; /* (S + A) | T */ | |
+ *where = tmp - (Elf_Addr)where; /* (S + A) | T - P */ | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: PREL31 %p @ %p in %s\n", | |
+ (void *)tmp, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
#if 1 /* XXX should not occur */ | |
- case R_TYPE(PC24): { /* word32 S - P + A */ | |
- Elf32_Sword addend; | |
+ /* Thumb will supported in future */ | |
+ | |
+ case R_TYPE(PC24): | |
+ /* Deprecated */ | |
+ case R_TYPE(CALL): | |
+ /* | |
+ * operation: ((S + A) | T - P); | |
+ * overflow: yes; insn: bl/blx; result mask: X&0x03fffffe; | |
+ * addend: sign_extend(insn[23:0] << 2); | |
+ * fall through | |
+ */ | |
+ case R_TYPE(JUMP24): { | |
+ /* | |
+ * operation: ((S + A) | T - P); | |
+ * overflow: yes; insn: bl<cond>/b; result mask: X&0x03fffffe; | |
+ * addend: sign_extend(insn[23:0] << 2); | |
+ */ | |
/* | |
* Extract addend and sign-extend if needed. | |
*/ | |
addend = *where; | |
if (addend & 0x00800000) | |
- addend |= 0xff000000; | |
+ addend |= 0xff000000; //sign extended | |
- tmp = (Elf_Addr)sect->base + symvalue | |
- - (Elf_Addr)where + (addend << 2); | |
- | |
- if ((tmp & 0xfe000000) != 0xfe000000 && | |
- (tmp & 0xfe000000) != 0) { | |
- rtems_rtl_set_error (EINVAL, | |
- "R_ARM_PC24 in %s relocation @ %p failed " \ | |
- "(displacement %ld (%#lx) out of range)", | |
- rtems_rtl_obj_oname (obj), where, (long) tmp, (long) tmp); | |
- return false; | |
- } | |
+ tmp = symvalue + (addend << 2); | |
+ if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
+ tmp |= 1; | |
+ tmp -= (Elf_Addr)where; | |
tmp >>= 2; | |
*where = (*where & 0xff000000) | (tmp & 0x00ffffff); | |
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
- printf ("rtl: PC24 %p @ %p in %s", | |
+ printf ("rtl: JUMP24/PC24/CALL %p @ %p in %s\n", | |
(void *)*where, where, rtems_rtl_obj_oname (obj)); | |
break; | |
} | |
#endif | |
- case R_TYPE(ABS32): /* word32 B + S + A */ | |
- case R_TYPE(GLOB_DAT): /* word32 B + S */ | |
+ case R_TYPE(V4BX): { /* Miscellaneous */ | |
+ /* Note: Not sure whether this should be implemented */ | |
+#if 1 | |
+ tmp = *where; | |
+ tmp &= 0xf000000f; /* Keep cond and Rm*/ | |
+ tmp |= 0x01a0f000; /* Mov PC, Rm */ | |
+#endif | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: V4BX %p @ %p in %s\n", | |
+ (void *)*where, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+ | |
+ /* Encoding of imm16 argument for movt and movw ARM instructions | |
+ * from ARM ARM: | |
+ * | |
+ * imm16 := imm4 | imm12 | |
+ * | |
+ * f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0 | |
+ * +-------+---------------+-------+-------+-----------------------+ | |
+ * | | |imm4 | |imm12 | | |
+ * +-------+---------------+-------+-------+-----------------------+ | |
+ */ | |
+ case R_TYPE(MOVT_ABS): | |
+ /* | |
+ * operation: S + A | |
+ * overflow:yes; insn: movt; result masks: x&0xffff0000; | |
+ * insn[19:16] = (Result_Mask(X)>>16)>>12; | |
+ * insn[11:0] = (Result_Mask(X)>>16)&0xfff; | |
+ */ | |
+ case R_TYPE(MOVW_ABS_NC): { | |
+ /* | |
+ * operation: (S + A) | T; | |
+ * overflow: no; insn:movw; result mask:x&0xffff; | |
+ * insn[19:16] = (Result_Mask(X)>>16) >> 12; | |
+ * insn[11:0] = Result_Mask(X)&0xfff | |
+ * | |
+ */ | |
+ tmp = *where; | |
+ addend = ((val >> 4) & 0xf000) | (val & 0xfff); | |
+ if (addend & 0x8000) | |
+ addend |= 0xffff0000; | |
+ tmp = symvalue + addend; /* S + A */ | |
+ if (ELF_R_TYPE(rel->r_info) == R_ARM_MOVW_ABS_NC ) { | |
+ if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
+ tmp |= 1; /* (S + A) | T */ | |
+ tmp &= 0xffff; /* result mask */ | |
+ } else if (ELF_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) { | |
+ tmp >>= 16; | |
+ if (((int)tmp >= 0x8000) || ((int)tmp < -0x8000)) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "MOVT_ABS relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ | |
+ } | |
+ *where = (*where & 0xfff0f000) | ((tmp & 0xf000) << 4) | (tmp & 0xfff); | |
+ | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: MOVT_ABS/MOVW_ABS_NC %p @ %p in %s\n", | |
+ (void *)*where, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+ | |
+ | |
+ case R_TYPE(REL32):/* word32 (S + A) | T - P*/ | |
+ case R_TYPE(ABS32):/* word32 (S + A) | T */ | |
+ case R_TYPE(GLOB_DAT): /* word32 (S + A) | T */ | |
if (__predict_true(RELOC_ALIGNED_P(where))) { | |
- tmp = *where + (Elf_Addr)sect->base + symvalue; | |
+ tmp = *where + symvalue; /* S + A */ | |
/* Set the Thumb bit, if needed. */ | |
if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
tmp |= 1; | |
+ if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32)) | |
+ tmp -= (Elf_Addr)where; | |
*where = tmp; | |
} else { | |
tmp = load_ptr(where) + symvalue; | |
/* Set the Thumb bit, if needed. */ | |
if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
tmp |= 1; | |
+ if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32)) | |
+ tmp -= (Elf_Addr)where; | |
store_ptr(where, tmp); | |
} | |
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
- printf ("rtl: ABS32/GLOB_DAT %p @ %p in %s", | |
+ printf ("rtl: ABS32/GLOB_DAT %p @ %p in %s\n", | |
(void *)tmp, where, rtems_rtl_obj_oname (obj)); | |
break; | |
@@ -136,7 +318,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, | |
store_ptr(where, tmp); | |
} | |
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
- printf ("rtl: RELATIVE in %s --> %p", | |
+ printf ("rtl: RELATIVE in %s --> %p\n", | |
rtems_rtl_obj_oname (obj), (void *)tmp); | |
break; | |
@@ -151,6 +333,228 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, | |
printf ("rtl: COPY (avoid in main)"); | |
break; | |
+ /* Group relocation */ | |
+ /* Note: should be checked */ | |
+ case R_TYPE(LDR_PC_G0): | |
+ case R_TYPE(LDR_PC_G1): | |
+ case R_TYPE(LDR_PC_G2): | |
+ case R_TYPE(LDR_SB_G0): | |
+ case R_TYPE(LDR_SB_G1): | |
+ case R_TYPE(LDR_SB_G2): { | |
+ /* | |
+ * operation: S + A - P; | |
+ * overflow: yes; insn: ldr/str/ldrb/strb class:ARM; result mask: | |
+ * ABS(X)&G0(LDR); Addend: insn[11:0] * {(insn[23] == 0)?-1:1}; | |
+ * insn[23] = (X>=0); insn[11:0] = Result_Mask(X); | |
+ */ | |
+ | |
+ Elf_Word residual; | |
+ Elf_Word group = 0; | |
+ Elf_Sword X; | |
+ Elf_Word r_type; | |
+ r_type = ELF_R_TYPE(rel->r_info); | |
+ | |
+ switch (r_type) { | |
+ case R_TYPE(LDR_PC_G0): | |
+ case R_TYPE(LDR_SB_G0): | |
+ group = 0; | |
+ break; | |
+ case R_TYPE(LDR_PC_G1): | |
+ case R_TYPE(LDR_SB_G1): | |
+ group = 1; | |
+ break; | |
+ case R_TYPE(LDR_PC_G2): | |
+ case R_TYPE(LDR_SB_G2): | |
+ group = 2; | |
+ break; | |
+ default: | |
+ printf("abort\n"); | |
+ return false; | |
+ } | |
+ | |
+ tmp = *where; | |
+ const int sign = (tmp & 0x00800000) ? 1 : -1; | |
+ addend = (tmp & 0xfff) * sign; | |
+ if ((r_type == R_TYPE(LDR_PC_G0)) || | |
+ (r_type == R_TYPE(LDR_PC_G1)) || | |
+ (r_type == R_TYPE(LDR_PC_G2))) | |
+ X = symvalue + addend - (Elf_Addr)where; | |
+ else | |
+ X = symvalue + addend - (Elf_Addr)where; | |
+ printf("symvalue %x, addend %x, where %x X %x\n", symvalue, addend, where,X); | |
+ | |
+ residual = cal_group_reloc_mask(abs(X), group - 1); | |
+ printf("residual %x\n", residual); | |
+ | |
+ if (residual >= 0x1000) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "GROUP relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ | |
+ tmp &= 0xff7ff000; | |
+ if (X >= 0) | |
+ tmp |= 1 << 23; | |
+ tmp |= residual; | |
+ *where = tmp; | |
+ | |
+ break; | |
+ } | |
+ | |
+ /*--------------Thumb32----------------*/ | |
+//#ifdef THUMB_SUPPORT | |
+ /* Encoding of imm16 argument for movt and movw Thumb2 instructions | |
+ * from ARM ARM: | |
+ * | |
+ * imm16 := imm4 | i | imm3 | imm8 | |
+ * | |
+ * f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0 | |
+ * +---------+-+-----------+-------++-+-----+-------+---------------+ | |
+ * | |i| |imm4 || |imm3 | |imm8 | | |
+ * +---------+-+-----------+-------++-+-----+-------+---------------+ | |
+ */ | |
+ case R_TYPE(THM_MOVT_ABS): /* word32 S + A*/ | |
+ case R_TYPE(THM_MOVW_ABS_NC): { /* word32 (S + A) | T */ | |
+ tmp = *where; | |
+ addend = (tmp & 0x00ff) | ((tmp >> 4) & 0x0700) | | |
+ ((tmp >> 15) & 0x0800) | ((tmp >> 4) & 0xf000); | |
+ if (addend & 0x8000) | |
+ addend |= 0xffff0000; | |
+ tmp = symvalue + addend; | |
+ if (ELF_R_TYPE(rel->r_info) == R_ARM_THM_MOVW_ABS_NC ) { | |
+ if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
+ tmp |= 1; /* (S + A) | T */ | |
+ tmp &= 0xffff; | |
+ } else if (ELF_R_TYPE(rel->r_info) == R_ARM_THM_MOVW_ABS_NC ) { | |
+ tmp >>= 16; | |
+ } | |
+ | |
+ *where = (*where & 0xfbf08f00) | (((tmp >> 11) & 0x1) << 26) | | |
+ (((tmp >> 12) & 0xf) << 16) | (((tmp >> 8) & 0x7) << 12) | | |
+ (tmp & 0xff); | |
+ | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: THM_MOVT_ABS/THM_MOVW_ABS_NC %p @ %p in %s\n", | |
+ (void *)*where, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+ | |
+ | |
+ /* Encoding of imm argument for BL/B.W Thumb2 instructions | |
+ * from ARM ARM: | |
+ * | |
+ * imm32 := SignExtend(S:I1:I2:imm10:imm11:'0') | |
+ * I1 = not (j1 eor S); I2 = not (j2 eor S) | |
+ * | |
+ * f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0 | |
+ * +---------+-+--------------------+---+--+-+--+---------------------+ | |
+ * |1 1 1 1 0|S| imm10 |1 1|J1|1|J2| imm11 | | |
+ * +---------+-+--------------------+---+--+-+--+---------------------+ | |
+ */ | |
+ case R_TYPE(THM_JUMP24): /* same to THM_CALL; insn b.w */ | |
+ case R_TYPE(THM_CALL): { | |
+ /* | |
+ * operation: (S + A) | T - P; | |
+ * overflow: yes; insn: bl; class: Thumb32 ;result mask: x & 0x01fffffe; | |
+ */ | |
+ uint32_t sign, i1, i2; | |
+ uint16_t lower_insn, upper_insn; | |
+ upper_insn = *(uint16_t *)where; | |
+ lower_insn = *((uint16_t *)where + 1); | |
+ printf("upper_insn 0x%04x lower_insn 0x%04x\n", upper_insn, lower_insn); | |
+ sign = (upper_insn & (1 << 10)) >> 10; | |
+ i1 = ((lower_insn >> 13) & 1) ^ sign ? 0 : 1; | |
+ i2 = ((lower_insn >> 11) & 1) ^ sign ? 0 : 1; | |
+ tmp = (i1 << 23) | (i2 << 22) | ((upper_insn & 0x3ff) << 12) | ((lower_insn & 0x7ff) << 1); | |
+ addend = (tmp | ((sign ? 0 : 1) << 24)) - (1 << 24); | |
+ | |
+ tmp = symvalue + addend; | |
+ if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
+ tmp |= 1; | |
+ tmp = tmp - (Elf_Addr)where; | |
+ | |
+ if (((int32_t)tmp > (int32_t)(1<<24)) || ((int32_t)tmp < (int32_t)(0xff<<24))) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "THM_CALL/THM_JUMP24 relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ | |
+ sign = (tmp >> 24) & 1; | |
+ *(uint16_t *)where = (uint16_t)((upper_insn & 0xf800) | (sign << 10) | | |
+ ((tmp >> 12) & 0x3ff)); | |
+ *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0xd000) | | |
+ ((sign ^ (~(tmp >> 23) & 1)) << 13) | | |
+ ((sign ^ (~(tmp >> 22) & 1)) << 11) | | |
+ ((tmp >> 1) & 0x7ff)); | |
+ upper_insn = *(uint16_t *)where; | |
+ lower_insn = *((uint16_t *)where + 1); | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: THM_CALL/JUMP24 %p @ %p in %s\n", | |
+ (void *)*where, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+ | |
+ /* Encoding of imm argument for B<c>.W Thumb2 instructions | |
+ * from ARM ARM: | |
+ * | |
+ * imm32 := SignExtend(S:J2:J1:imm6:imm11:'0') | |
+ * I1 = not (j1 eor S); I2 = not (j2 eor S) | |
+ * | |
+ * f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0 | |
+ * +---------+-+-------+-------------+---+--+-+--+---------------------+ | |
+ * |1 1 1 1 0|S| cond | imm6 |1 0|J1|0|J2| imm11 | | |
+ * +---------+-+-------+-------------+---+--+-+--+---------------------+ | |
+ */ | |
+ case R_TYPE(THM_JUMP19): { | |
+ /* | |
+ * operation ((S + A) | T) - P | |
+ * overflow: yes;class:Thumb32; insn: B<cond>.W; result mask: X & 0x001ffffe | |
+ */ | |
+ uint32_t sign, j1, j2; | |
+ uint16_t lower_insn, upper_insn, upper, lower; | |
+ upper_insn = *(uint16_t *)where; | |
+ lower_insn = *((uint16_t *)where + 1); | |
+ printf("upper_insn 0x%04x lower_insn 0x%04x\n", upper_insn, lower_insn); | |
+ sign = (upper_insn >> 10) & 0x1; | |
+ upper = upper_insn & 0x3f; | |
+ if (((upper >> 7) & 0x7) == 0x7) { | |
+ printf("THM_JUMP19 failed\n"); | |
+ return false; /*if cond <3:1> == '111', see Related codings*/ | |
+ } | |
+ j1 = (lower_insn >> 13) & 0x1; | |
+ j2 = (lower_insn >> 11) & 0x1; | |
+ lower = lower_insn & 0x7ff; | |
+ | |
+ tmp = ((j2 << 19) | (j1 << 18) | (upper << 12) | (lower << 1)); | |
+ addend = (tmp | ((sign ? 0 : 1) << 20)) - (1 << 20); | |
+ tmp = symvalue + addend; | |
+ if (ELF_ST_TYPE(syminfo) == STT_ARM_TFUNC) | |
+ tmp |= 1; | |
+ tmp = tmp - (Elf_Addr)where; | |
+ | |
+ if (((int32_t)tmp > (int32_t)(1<<20)) || ((int32_t)tmp < (int32_t)(0xfff<<20))) { | |
+ rtems_rtl_set_error (EINVAL, "%s: Overflow %ld " | |
+ "THM_JUMP19 relocations", | |
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
+ return false; | |
+ } | |
+ sign = (tmp >> 20) & 0x1; | |
+ j2 = (tmp >> 19) & 0x1; | |
+ j1 = (tmp >> 18) & 0x1; | |
+ *(uint16_t*)where = (upper_insn & 0xfbc0) | (sign << 10) | ((tmp >> 12) & 0x3f); | |
+ *((uint16_t*)where + 1) = (lower_insn & 0xd000) | (j1 << 13) | | |
+ (j2 << 11) | ((tmp >> 1) & 0x7ff); | |
+ | |
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) | |
+ printf ("rtl: THM_JUMP19 %p @ %p in %s\n", | |
+ (void *)*where, where, rtems_rtl_obj_oname (obj)); | |
+ break; | |
+ } | |
+//#endif | |
+ | |
+ /*--------------End Thumb32-------------*/ | |
default: | |
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, " | |
"contents = %p\n", | |
@@ -161,8 +565,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, | |
"in non-PLT relocations", | |
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); | |
return false; | |
- } | |
- | |
+ } | |
return true; | |
} | |
diff --git a/rtl-obj.c b/rtl-obj.c | |
index ddf4a0b..6f73d2d 100644 | |
--- a/rtl-obj.c | |
+++ b/rtl-obj.c | |
@@ -326,9 +326,11 @@ bool | |
rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name) | |
{ | |
const char* n1 = obj->oname; | |
+ printf("obj->oname %s, name %s\n", obj->oname, name); | |
while ((*n1 != '\0') && (*n1 != '\n') && (*n1 != '/') && | |
(*name != '\0') && (*name != '/') && (*n1 == *name)) | |
{ | |
+ printf("%c %c\n", *n1, *name); | |
++n1; | |
++name; | |
} | |
diff --git a/rtl-rap.c b/rtl-rap.c | |
index efe2362..9722f02 100644 | |
--- a/rtl-rap.c | |
+++ b/rtl-rap.c | |
@@ -317,59 +317,61 @@ rtems_rtl_rap_relocate (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj) | |
type = info & 0xff; | |
- if ((info & (1 << 31)) == 0) | |
- { | |
- rtems_rtl_obj_sect_t* symsect; | |
- | |
- symsect = rtems_rtl_obj_find_section_by_index (obj, info >> 8); | |
- if (!symsect) | |
- { | |
- free (symname_buffer); | |
- return false; | |
- } | |
- | |
- symvalue = (Elf_Word) symsect->base + addend; | |
- } | |
- else if (rtems_rtl_elf_rel_resolve_sym (type)) | |
- { | |
- rtems_rtl_obj_sym_t* symbol; | |
- | |
- symname_size = (info & ~(3 << 30)) >> 8; | |
- | |
- if ((info & (1 << 30)) != 0) | |
- { | |
- symname = rap->strtab + symname_size; | |
- } | |
- else | |
- { | |
- if (symname_size > (SYMNAME_BUFFER_SIZE - 1)) | |
- { | |
- free (symname_buffer); | |
- rtems_rtl_set_error (EINVAL, "reloc symbol too big"); | |
- return false; | |
- } | |
- | |
- if (!rtems_rtl_obj_comp_read (rap->decomp, symname_buffer, symname_size)) | |
- { | |
- free (symname_buffer); | |
- return false; | |
- } | |
- | |
- symname_buffer[symname_size] = '\0'; | |
- symname = symname_buffer; | |
- } | |
- | |
- symbol = rtems_rtl_symbol_obj_find (obj, symname); | |
- | |
- if (!symbol) | |
- { | |
- rtems_rtl_set_error (EINVAL, "global symbol not found: %s", symname); | |
- free (symname_buffer); | |
- return false; | |
- } | |
- | |
- symvalue = (Elf_Word) symbol->value; | |
- } | |
+ if (type != R_ARM_V4BX) { /* V4BX does not have target symbol */ | |
+ if ((info & (1 << 31)) == 0) | |
+ { | |
+ rtems_rtl_obj_sect_t* symsect; | |
+ | |
+ symsect = rtems_rtl_obj_find_section_by_index (obj, info >> 8); | |
+ if (!symsect) | |
+ { | |
+ free (symname_buffer); | |
+ return false; | |
+ } | |
+ | |
+ symvalue = (Elf_Word) symsect->base + addend; | |
+ } | |
+ else if (rtems_rtl_elf_rel_resolve_sym (type)) | |
+ { | |
+ rtems_rtl_obj_sym_t* symbol; | |
+ | |
+ symname_size = (info & ~(3 << 30)) >> 8; | |
+ | |
+ if ((info & (1 << 30)) != 0) | |
+ { | |
+ symname = rap->strtab + symname_size; | |
+ } | |
+ else | |
+ { | |
+ if (symname_size > (SYMNAME_BUFFER_SIZE - 1)) | |
+ { | |
+ free (symname_buffer); | |
+ rtems_rtl_set_error (EINVAL, "reloc symbol too big"); | |
+ return false; | |
+ } | |
+ | |
+ if (!rtems_rtl_obj_comp_read (rap->decomp, symname_buffer, symname_size)) | |
+ { | |
+ free (symname_buffer); | |
+ return false; | |
+ } | |
+ | |
+ symname_buffer[symname_size] = '\0'; | |
+ symname = symname_buffer; | |
+ } | |
+ | |
+ symbol = rtems_rtl_symbol_obj_find (obj, symname); | |
+ | |
+ if (!symbol) | |
+ { | |
+ rtems_rtl_set_error (EINVAL, "global symbol not found: %s", symname); | |
+ free (symname_buffer); | |
+ return false; | |
+ } | |
+ | |
+ symvalue = (Elf_Word) symbol->value; | |
+ } | |
+ } | |
if (is_rela) | |
{ | |
@@ -615,6 +617,7 @@ rtems_rtl_rap_file_check (rtems_rtl_obj_t* obj, int fd) | |
uint32_t compression = 0; | |
uint32_t checksum = 0; | |
+ printf("__func__ %s\n", __func__); | |
rtems_rtl_obj_caches (&header, NULL, NULL); | |
if (!rtems_rtl_obj_cache_read (header, fd, obj->ooffset, | |
@@ -639,6 +642,7 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd) | |
uint8_t* rhdr = NULL; | |
size_t rlen = 64; | |
int section; | |
+ printf("__func__ %s\n", __func__); | |
rtems_rtl_obj_caches (&rap.file, NULL, NULL); | |
diff --git a/rtl-sym.c b/rtl-sym.c | |
index 0e29693..2724c49 100644 | |
--- a/rtl-sym.c | |
+++ b/rtl-sym.c | |
@@ -86,6 +86,7 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj, | |
const unsigned char* esyms, | |
unsigned int size) | |
{ | |
+ printf("%s size %d\n", __func__, size); | |
rtems_rtl_symbols_t* symbols; | |
rtems_rtl_obj_sym_t* sym; | |
size_t count; | |
@@ -94,21 +95,42 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj, | |
count = 0; | |
s = 0; | |
+ int i = 0; | |
+#if 0 | |
+ for(i = 0; i< 1024; i++) { | |
+ if (i%32==0) | |
+ printf("\n"); | |
+ printf("%02x ", *(esyms+i)); | |
+ } | |
+ printf("\n"); | |
+#endif | |
while ((s < size) && (esyms[s] != 0)) | |
{ | |
int l = strlen ((char*) &esyms[s]); | |
+#if 0 | |
+ printf("%d s %d length %d | ", count,s,l); | |
+ for (i=0; i< l; i++) | |
+ { | |
+ printf("%02x ", *(esyms+s+i)); | |
+ } | |
+#endif | |
+ //printf("count %d s %d %s\n",count,s, esyms+s); | |
+ | |
if ((esyms[s + l] != '\0') || ((s + l) > size)) | |
{ | |
rtems_rtl_set_error (EINVAL, "invalid exported symbol table"); | |
return false; | |
} | |
++count; | |
- s += l + sizeof (unsigned long) + 1; | |
+ //s += l + sizeof (unsigned long) + 1; | |
+ s += ((l+1+3)&(~3)) + sizeof (unsigned long); | |
} | |
/* | |
* Check this is the correct end of the table. | |
*/ | |
+ s=(s+4); //align for arm | |
+#if 0 | |
marker = esyms[s + 1]; | |
marker <<= 8; | |
marker |= esyms[s + 2]; | |
@@ -116,6 +138,16 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj, | |
marker |= esyms[s + 3]; | |
marker <<= 8; | |
marker |= esyms[s + 4]; | |
+#endif | |
+#if 1 | |
+ marker = esyms[s + 0]; | |
+ marker <<= 8; | |
+ marker |= esyms[s + 1]; | |
+ marker <<= 8; | |
+ marker |= esyms[s + 2]; | |
+ marker <<= 8; | |
+ marker |= esyms[s + 3]; | |
+#endif | |
if (marker != 0xdeadbeefUL) | |
{ | |
@@ -155,7 +187,8 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj, | |
int b; | |
sym->name = (const char*) &esyms[s]; | |
- s += strlen (sym->name) + 1; | |
+ //s += strlen (sym->name) + 1; | |
+ s += ((strlen(sym->name)+1+3)&(~3)); | |
for (b = 0; b < sizeof (void*); ++b, ++s) | |
copy_voidp.data[b] = esyms[s]; | |
sym->value = copy_voidp.value; | |
@@ -208,9 +241,10 @@ rtems_rtl_symbol_obj_find (rtems_rtl_obj_t* obj, const char* name) | |
* Check the object file's symbols first. If not found search the | |
* global symbol table. | |
*/ | |
- for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym) | |
+ for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym){ | |
if (strcmp (name, sym->name) == 0) | |
return sym; | |
+ } | |
return rtems_rtl_symbol_global_find (name); | |
} | |
diff --git a/rtl.c b/rtl.c | |
index 9429046..0a542b3 100644 | |
--- a/rtl.c | |
+++ b/rtl.c | |
@@ -201,7 +201,9 @@ rtems_rtl_data_init (void) | |
return false; | |
} | |
+ printf("1111\n"); | |
rtl->base = rtems_rtl_obj_alloc (); | |
+ printf("2222\n"); | |
if (!rtl->base) | |
{ | |
rtems_rtl_obj_comp_close (&rtl->decomp); | |
@@ -381,8 +383,10 @@ rtems_rtl_find_obj (const char* name) | |
while (!rtems_chain_is_tail (&rtl->objects, node)) | |
{ | |
rtems_rtl_obj_t* obj = (rtems_rtl_obj_t*) node; | |
- if (rtems_rtl_match_name (obj, name)) | |
+ if (rtems_rtl_match_name (obj, name)) { | |
+ printf("match %s %s\n", obj->oname, name); | |
return obj; | |
+ } | |
node = rtems_chain_next (node); | |
} | |
@@ -401,6 +405,7 @@ rtems_rtl_load_object (const char* name, int mode) | |
* See if the object module has already been loaded. | |
*/ | |
obj = rtems_rtl_find_obj (name); | |
+ printf("111 %x\n", obj); | |
if (!obj) | |
{ | |
/* | |
diff --git a/shell-init b/shell-init | |
index fcc9784..609d61b 100644 | |
--- a/shell-init | |
+++ b/shell-init | |
@@ -1,5 +1,5 @@ | |
#rtl-trace set all | |
-#rtl-trace set load load-sect symbol reloc #unresolved | |
+rtl-trace set load load-sect symbol reloc #unresolved | |
#dlo libx.a:xa.c.1.o | |
#dlo libx.a:x-long-name-to-create-gnu-extension-in-archive.c.1.o | |
#dlo x.rap | |
@@ -9,5 +9,5 @@ | |
#dlo c/bsdport.rap | |
#dlo bsdport.rap | |
-rap ld ./bsdport.rap | |
-rap ls | |
+#rap ld ./test.rap | |
+#rap ls | |
diff --git a/wscript b/wscript | |
old mode 100644 | |
new mode 100755 | |
index 9f9417a..640c777 | |
--- a/wscript | |
+++ b/wscript | |
@@ -52,7 +52,8 @@ def build(bld): | |
bld.defines = ['PACKAGE_VERSION="' + version + '"', | |
'RTEMS_RTL_ELF_LOADER=1', | |
'RTEMS_RTL_RAP_LOADER=1'] | |
- bld.cflags = ['-g', '-O'] | |
+ #bld.cflags = ['-g', '-O', '-DRTEMS_RTL_TRACE=1'] | |
+ bld.cflags = ['-g', '-DRTEMS_RTL_TRACE=1'] | |
if re.match('pc[3456]86', bsp) is not None: | |
bld.defines += ['RTEMS_APP_IDEDISK=1'] | |
@@ -74,6 +75,13 @@ def build(bld): | |
source = ['xa.c', | |
'x-long-name-to-create-gnu-extension-in-archive.c']) | |
+ bld(target = 'x', | |
+ features = 'c cstlib', | |
+ includes = bld.includes, | |
+ defines = bld.defines, | |
+ source = ['x1.S', | |
+ 'x2.S']) #freenix | |
+ | |
# | |
# The RTL library. | |
# | |
@@ -141,11 +149,12 @@ def build(bld): | |
# finally the second link occurs with the global symbol table to create the | |
# executable to install. | |
# | |
- # Create the root file system for the prelink. | |
+ # Create the root file system for the prelink format=gnu fanpeng. | |
+ # rule = 'tar cf - ${SRC} > ${TGT} --format=gnu') | |
# | |
bld(target = 'fs-root.tar', | |
source = ['shell-init', 'libx.a'], | |
- rule = 'tar cf - ${SRC} > ${TGT}') | |
+ rule = 'tar --format=ustar -cf ${TGT} ${SRC}') | |
bld.objects(name = 'rootfs.prelink', | |
target = 'fs-root-tarfile.o', | |
source = 'fs-root.tar', | |
@@ -181,15 +190,24 @@ def build(bld): | |
source = ['xa.c', | |
'x-long-name-to-create-gnu-extension-in-archive.c']) | |
+ bld(target = 'test.rap', | |
+ features = 'c rap', | |
+ xxxx = 'hello', | |
+ rtems_linkflags = ['--base', 'rtld.prelink', | |
+ '--entry', 'my_main'], | |
+ source = ['x1.S', | |
+ 'x2.S']) #freenix | |
+ | |
if re.match('pc[3456]86', bsp) is not None: | |
raps = ['bsdport.rap'] | |
else: | |
raps = [] | |
+ # rule = 'tar cf - ${SRC} > ${TGT}') | |
bld(target = 'fs-root.tar', | |
name = 'fs', | |
- source = ['shell-init', 'libx.a', 'x.rap'] + raps, | |
- rule = 'tar cf - ${SRC} > ${TGT}') | |
+ source = ['shell-init', 'libx.a', 'x.rap', 'test.rap'] + raps, | |
+ rule = 'tar --format=ustar -cf ${TGT} ${SRC} y.rap') | |
bld.objects(name = 'rootfs', | |
target = 'fs-root-tarfile.o', | |
source = 'fs-root.tar', | |
diff --git a/x1.S b/x1.S | |
new file mode 100644 | |
index 0000000..b743b9f | |
--- /dev/null | |
+++ b/x1.S | |
@@ -0,0 +1,53 @@ | |
+@ Tests for LDR group relocations. | |
+ | |
+ .global localsym | |
+ .global grouptest | |
+ .type f, %function | |
+ .type localsym, %function | |
+ .type grouptest, %function | |
+ | |
+ .text | |
+ .macro ldrtest load store sym offset | |
+ | |
+ \load r0, [r0, #:pc_g0:(\sym \offset)] | |
+ \load r0, [r0, #:pc_g1:(\sym \offset)] | |
+ \load r0, [r0, #:pc_g2:(\sym \offset)] | |
+ \load r0, [r0, #:sb_g0:(\sym \offset)] | |
+ \load r0, [r0, #:sb_g1:(\sym \offset)] | |
+ \load r0, [r0, #:sb_g2:(\sym \offset)] | |
+ | |
+ \store r0, [r0, #:pc_g0:(\sym \offset)] | |
+ \store r0, [r0, #:pc_g1:(\sym \offset)] | |
+ \store r0, [r0, #:pc_g2:(\sym \offset)] | |
+ \store r0, [r0, #:sb_g0:(\sym \offset)] | |
+ \store r0, [r0, #:sb_g1:(\sym \offset)] | |
+ \store r0, [r0, #:sb_g2:(\sym \offset)] | |
+ | |
+ | |
+ .endm | |
+grouptest: | |
+@ LDR/STR/LDRB/STRB only have 12 bits available for the magnitude of the addend. | |
+@ So these should all (just) work. | |
+ push {lr} | |
+ nop | |
+ nop | |
+ nop | |
+ ldrtest ldr str f "+ 1024" | |
+ ldrtest ldrb strb f "+ 1024" | |
+ ldrtest ldr str f "- 1024" | |
+ ldrtest ldrb strb f "- 1024" | |
+ | |
+@ The same as the above, but for a local symbol. These should not be | |
+@ resolved by the assembler but instead left to the linker. | |
+ | |
+ ldrtest ldr str localsym "+ 1024" | |
+ ldrtest ldrb strb localsym "+ 1024" | |
+ ldrtest ldr str localsym "- 1024" | |
+ ldrtest ldrb strb localsym "- 1024" | |
+ mov r0, #0 | |
+ pop {pc} | |
+ | |
+ | |
+localsym: | |
+ mov r0, #0 | |
+ | |
diff --git a/x2.S b/x2.S | |
new file mode 100644 | |
index 0000000..7deb3dc | |
--- /dev/null | |
+++ b/x2.S | |
@@ -0,0 +1,32 @@ | |
+ .global f | |
+ .global my_main | |
+ .global rtems | |
+ .type f, %function | |
+ .type my_main, %function | |
+ .type rtems, %function | |
+ .text | |
+ .section .text.f,"ax",%progbits | |
+f: | |
+ push {lr} | |
+ ldr r0, =strstr | |
+ bl printf | |
+ mov r0, #0 | |
+ pop {pc} | |
+ nop | |
+ .word 0x98765432 | |
+ nop | |
+ b f | |
+ .section .text.my_main,"ax",%progbits | |
+ .type my_main, %function | |
+my_main: | |
+ b my_main | |
+ .section .text.my_main,"ax",%progbits | |
+ .type my_main, %function | |
+rtems: | |
+ push {lr} | |
+ ldr r0, =strstr | |
+ bl printf | |
+ mov r0, #0 | |
+ pop {pc} | |
+strstr: | |
+ .string "\r\n12345\r\n\0" | |
diff --git a/xa.c b/xa.c | |
index 20c927b..db63987 100644 | |
--- a/xa.c | |
+++ b/xa.c | |
@@ -3,9 +3,23 @@ | |
#include "x.h" | |
void hello(void); | |
+int z_writeln(int argc, const char* argv[]); | |
void | |
hello (void) | |
{ | |
x_writeln ("hello world"); | |
} | |
+ | |
+int rtems(int argc, const char **argv) | |
+{ | |
+ hello(); | |
+ printf("rtems\n"); | |
+ z_writeln(argc, argv); | |
+#if 0 | |
+ *(volatile unsigned int *)0x7F008800 = 0x11110000; | |
+ *(volatile unsigned int *)0x7F008808 = ~(0xf<<4); | |
+#endif | |
+ return 0; | |
+} | |
+ | |
-- | |
1.7.10.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment