2006-05-11 Paul Brook <paul@codesourcery.com>

bfd/
	* elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs.
	(elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs.
	(elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto.
	* reloc.c: Ditto.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
	* libcoff.h: Regenerate.
gas/
	* config/tc-arm.c (parse_half): New function.
	(operand_parse_code): Remove OP_Iffff.  Add OP_HALF.
	(parse_operands): Ditto.
	(do_mov16): Reject invalid relocations.
	(do_t_mov16): Ditto.  Use Thumb reloc numbers.
	(insns): Replace Iffff with HALF.
	(md_apply_fix): Add MOVW and MOVT relocs.
	(tc_gen_reloc): Ditto.
	* doc/c-arm.texi: Document relocation operators
ld/testsuite/
	* ld-arm/arm-elf.exp: Add arm-movwt.
	* ld-arm/arm-movwt.d: New test.
	* ld-arm/arm-movwt.s: New test.
	* ld-arm/arm.ld: Add .far.
This commit is contained in:
Paul Brook 2006-05-11 15:17:34 +00:00
parent e28387c3bf
commit b6895b4f37
13 changed files with 443 additions and 17 deletions

View file

@ -1,3 +1,13 @@
2006-05-11 Paul Brook <paul@codesourcery.com>
* elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs.
(elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs.
(elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto.
* reloc.c: Ditto.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* libcoff.h: Regenerate.
2006-05-11 Mike Bland <mbland@google.com>
* elf.c (_bfd_elf_init_private_section_data): Don't change

View file

@ -2897,6 +2897,16 @@ pc-relative or some form of GOT-indirect relocation. */
/* 31-bit PC relative address. */
BFD_RELOC_ARM_PREL31,
/* Low and High halfword relocations for MOVW and MOVT instructions. */
BFD_RELOC_ARM_MOVW,
BFD_RELOC_ARM_MOVT,
BFD_RELOC_ARM_MOVW_PCREL,
BFD_RELOC_ARM_MOVT_PCREL,
BFD_RELOC_ARM_THUMB_MOVW,
BFD_RELOC_ARM_THUMB_MOVT,
BFD_RELOC_ARM_THUMB_MOVW_PCREL,
BFD_RELOC_ARM_THUMB_MOVT_PCREL,
/* Relocations for setting up GOTs and PLTs for shared libraries. */
BFD_RELOC_ARM_JUMP_SLOT,
BFD_RELOC_ARM_GLOB_DAT,

View file

@ -1366,6 +1366,14 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
{BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32},
{BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT},
{BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY},
{BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC},
{BFD_RELOC_ARM_MOVT, R_ARM_MOVT_ABS},
{BFD_RELOC_ARM_MOVW_PCREL, R_ARM_MOVW_PREL_NC},
{BFD_RELOC_ARM_MOVT_PCREL, R_ARM_MOVT_PREL},
{BFD_RELOC_ARM_THUMB_MOVW, R_ARM_THM_MOVW_ABS_NC},
{BFD_RELOC_ARM_THUMB_MOVT, R_ARM_THM_MOVT_ABS},
{BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC},
{BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL},
};
static reloc_howto_type *
@ -4080,6 +4088,76 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
}
return bfd_reloc_ok;
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
{
bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
if (globals->use_rel)
{
addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
signed_addend = (addend ^ 0x10000) - 0x10000;
}
value += signed_addend;
if (sym_flags == STT_ARM_TFUNC)
value |= 1;
if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL)
value -= (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset);
if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL)
value >>= 16;
insn &= 0xfff0f000;
insn |= value & 0xfff;
insn |= (value & 0xf000) << 4;
bfd_put_32 (input_bfd, insn, hit_data);
}
return bfd_reloc_ok;
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
{
bfd_vma insn;
insn = bfd_get_16 (input_bfd, hit_data) << 16;
insn |= bfd_get_16 (input_bfd, hit_data + 2);
if (globals->use_rel)
{
addend = ((insn >> 4) & 0xf000)
| ((insn >> 15) & 0x0800)
| ((insn >> 4) & 0x0700)
| (insn & 0x00ff);
signed_addend = (addend ^ 0x10000) - 0x10000;
}
value += signed_addend;
if (sym_flags == STT_ARM_TFUNC)
value |= 1;
if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL)
value -= (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset);
if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL)
value >>= 16;
insn &= 0xfbf08f00;
insn |= (value & 0xf000) << 4;
insn |= (value & 0x0800) << 15;
insn |= (value & 0x0700) << 4;
insn |= (value & 0x00ff);
bfd_put_16 (input_bfd, insn >> 16, hit_data);
bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
}
return bfd_reloc_ok;
default:
return bfd_reloc_notsupported;
}
@ -5651,6 +5729,14 @@ elf32_arm_gc_sweep_hook (bfd * abfd,
case R_ARM_JUMP24:
case R_ARM_PREL31:
case R_ARM_THM_CALL:
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
/* Should the interworking branches be here also? */
if (h != NULL)
@ -5861,6 +5947,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_ARM_JUMP24:
case R_ARM_PREL31:
case R_ARM_THM_CALL:
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
/* Should the interworking branches be listed here? */
if (h != NULL)
{
@ -5877,12 +5971,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
refers to is in a different object. We can't tell for
sure yet, because something later might force the
symbol local. */
if (r_type == R_ARM_PC24
|| r_type == R_ARM_CALL
|| r_type == R_ARM_JUMP24
|| r_type == R_ARM_PREL31
|| r_type == R_ARM_PLT32
|| r_type == R_ARM_THM_CALL)
if (r_type != R_ARM_ABS32 && r_type != R_ARM_REL32)
h->needs_plt = 1;
/* If we create a PLT entry, this relocation will reference

View file

@ -1208,6 +1208,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_SBREL32",
"BFD_RELOC_ARM_TARGET2",
"BFD_RELOC_ARM_PREL31",
"BFD_RELOC_ARM_MOVW",
"BFD_RELOC_ARM_MOVT",
"BFD_RELOC_ARM_MOVW_PCREL",
"BFD_RELOC_ARM_MOVT_PCREL",
"BFD_RELOC_ARM_THUMB_MOVW",
"BFD_RELOC_ARM_THUMB_MOVT",
"BFD_RELOC_ARM_THUMB_MOVW_PCREL",
"BFD_RELOC_ARM_THUMB_MOVT_PCREL",
"BFD_RELOC_ARM_JUMP_SLOT",
"BFD_RELOC_ARM_GLOB_DAT",
"BFD_RELOC_ARM_GOT32",

View file

@ -2701,6 +2701,24 @@ ENUM
BFD_RELOC_ARM_PREL31
ENUMDOC
31-bit PC relative address.
ENUM
BFD_RELOC_ARM_MOVW
ENUMX
BFD_RELOC_ARM_MOVT
ENUMX
BFD_RELOC_ARM_MOVW_PCREL
ENUMX
BFD_RELOC_ARM_MOVT_PCREL
ENUMX
BFD_RELOC_ARM_THUMB_MOVW
ENUMX
BFD_RELOC_ARM_THUMB_MOVT
ENUMX
BFD_RELOC_ARM_THUMB_MOVW_PCREL
ENUMX
BFD_RELOC_ARM_THUMB_MOVT_PCREL
ENUMDOC
Low and High halfword relocations for MOVW and MOVT instructions.
ENUM
BFD_RELOC_ARM_JUMP_SLOT

View file

@ -1,3 +1,15 @@
2006-05-11 Paul Brook <paul@codesourcery.com>
* config/tc-arm.c (parse_half): New function.
(operand_parse_code): Remove OP_Iffff. Add OP_HALF.
(parse_operands): Ditto.
(do_mov16): Reject invalid relocations.
(do_t_mov16): Ditto. Use Thumb reloc numbers.
(insns): Replace Iffff with HALF.
(md_apply_fix): Add MOVW and MOVT relocs.
(tc_gen_reloc): Ditto.
* doc/c-arm.texi: Document relocation operators
2006-05-11 Paul Brook <paul@codesourcery.com>
* config/tc-arm.c (arm_fix_adjustable): Return 0 for function symbols.

View file

@ -4435,6 +4435,46 @@ parse_address (char **str, int i)
return SUCCESS;
}
/* Parse an operand for a MOVW or MOVT instruction. */
static int
parse_half (char **str)
{
char * p;
p = *str;
skip_past_char (&p, '#');
if (strncasecmp (p, ":lower16:", 9) == 0)
inst.reloc.type = BFD_RELOC_ARM_MOVW;
else if (strncasecmp (p, ":upper16:", 9) == 0)
inst.reloc.type = BFD_RELOC_ARM_MOVT;
if (inst.reloc.type != BFD_RELOC_UNUSED)
{
p += 9;
skip_whitespace(p);
}
if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
return FAIL;
if (inst.reloc.type == BFD_RELOC_UNUSED)
{
if (inst.reloc.exp.X_op != O_constant)
{
inst.error = _("constant expression expected");
return FAIL;
}
if (inst.reloc.exp.X_add_number < 0
|| inst.reloc.exp.X_add_number > 0xffff)
{
inst.error = _("immediate value out of range");
return FAIL;
}
}
*str = p;
return SUCCESS;
}
/* Miscellaneous. */
/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
@ -4925,7 +4965,6 @@ enum operand_parse_code
OP_I64, /* 1 .. 64 */
OP_I64z, /* 0 .. 64 */
OP_I255, /* 0 .. 255 */
OP_Iffff, /* 0 .. 65535 */
OP_I4b, /* immediate, prefix optional, 1 .. 4 */
OP_I7b, /* 0 .. 7 */
@ -4937,6 +4976,7 @@ enum operand_parse_code
OP_EXP, /* arbitrary expression */
OP_EXPi, /* same, with optional immediate prefix */
OP_EXPr, /* same, with optional relocation suffix */
OP_HALF, /* 0 .. 65535 or low/high reloc. */
OP_CPSF, /* CPS flags */
OP_ENDI, /* Endianness specifier */
@ -5197,7 +5237,6 @@ parse_operands (char *str, const unsigned char *pattern)
case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
case OP_Iffff: po_imm_or_fail ( 0, 0xffff, FALSE); break;
case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
case OP_oI7b:
@ -5263,6 +5302,11 @@ parse_operands (char *str, const unsigned char *pattern)
}
break;
/* Operand for MOVW or MOVT. */
case OP_HALF:
po_misc_or_fail (parse_half (&str));
break;
/* Register or expression */
case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
@ -6438,10 +6482,22 @@ do_mov (void)
static void
do_mov16 (void)
{
bfd_vma imm;
bfd_boolean top;
top = (inst.instruction & 0x00400000) != 0;
constraint (top && inst.reloc.type == BFD_RELOC_ARM_MOVW,
_(":lower16: not allowed this instruction"));
constraint (!top && inst.reloc.type == BFD_RELOC_ARM_MOVT,
_(":upper16: not allowed instruction"));
inst.instruction |= inst.operands[0].reg << 12;
/* The value is in two pieces: 0:11, 16:19. */
inst.instruction |= (inst.operands[1].imm & 0x00000fff);
inst.instruction |= (inst.operands[1].imm & 0x0000f000) << 4;
if (inst.reloc.type == BFD_RELOC_UNUSED)
{
imm = inst.reloc.exp.X_add_number;
/* The value is in two pieces: 0:11, 16:19. */
inst.instruction |= (imm & 0x00000fff);
inst.instruction |= (imm & 0x0000f000) << 4;
}
}
static void
@ -8709,11 +8765,30 @@ do_t_mov_cmp (void)
static void
do_t_mov16 (void)
{
bfd_vma imm;
bfd_boolean top;
top = (inst.instruction & 0x00800000) != 0;
if (inst.reloc.type == BFD_RELOC_ARM_MOVW)
{
constraint (top, _(":lower16: not allowed this instruction"));
inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVW;
}
else if (inst.reloc.type == BFD_RELOC_ARM_MOVT)
{
constraint (!top, _(":upper16: not allowed this instruction"));
inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVT;
}
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= (inst.operands[1].imm & 0xf000) << 4;
inst.instruction |= (inst.operands[1].imm & 0x0800) << 15;
inst.instruction |= (inst.operands[1].imm & 0x0700) << 4;
inst.instruction |= (inst.operands[1].imm & 0x00ff);
if (inst.reloc.type == BFD_RELOC_UNUSED)
{
imm = inst.reloc.exp.X_add_number;
inst.instruction |= (imm & 0xf000) << 4;
inst.instruction |= (imm & 0x0800) << 15;
inst.instruction |= (imm & 0x0700) << 4;
inst.instruction |= (imm & 0x00ff);
}
}
static void
@ -13425,8 +13500,8 @@ static const struct asm_opcode insns[] =
TCE(ubfx, 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
TCE(mls, 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
TCE(movw, 3000000, f2400000, 2, (RRnpc, Iffff), mov16, t_mov16),
TCE(movt, 3400000, f2c00000, 2, (RRnpc, Iffff), mov16, t_mov16),
TCE(movw, 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
TCE(movt, 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
TCE(rbit, 3ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
TC3(ldrht, 03000b0, f8300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
@ -16761,6 +16836,47 @@ md_apply_fix (fixS * fixP,
fixP->fx_done = 0;
return;
case BFD_RELOC_ARM_MOVW:
case BFD_RELOC_ARM_MOVT:
case BFD_RELOC_ARM_THUMB_MOVW:
case BFD_RELOC_ARM_THUMB_MOVT:
if (fixP->fx_done || !seg->use_rela_p)
{
/* REL format relocations are limited to a 16-bit addend. */
if (!fixP->fx_done)
{
if (value < -0x1000 || value > 0xffff)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("offset too big"));
}
else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
|| fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
{
value >>= 16;
}
if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
|| fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
{
newval = get_thumb32_insn (buf);
newval &= 0xfbf08f00;
newval |= (value & 0xf000) << 4;
newval |= (value & 0x0800) << 15;
newval |= (value & 0x0700) << 4;
newval |= (value & 0x00ff);
put_thumb32_insn (buf, newval);
}
else
{
newval = md_chars_to_number (buf, 4);
newval &= 0xfff0f000;
newval |= value & 0x0fff;
newval |= (value & 0xf000) << 4;
md_number_to_chars (buf, newval, 4);
}
}
return;
case BFD_RELOC_UNUSED:
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
@ -16815,6 +16931,34 @@ tc_gen_reloc (asection *section, fixS *fixp)
break;
}
case BFD_RELOC_ARM_MOVW:
if (fixp->fx_pcrel)
{
code = BFD_RELOC_ARM_MOVW_PCREL;
break;
}
case BFD_RELOC_ARM_MOVT:
if (fixp->fx_pcrel)
{
code = BFD_RELOC_ARM_MOVT_PCREL;
break;
}
case BFD_RELOC_ARM_THUMB_MOVW:
if (fixp->fx_pcrel)
{
code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
break;
}
case BFD_RELOC_ARM_THUMB_MOVT:
if (fixp->fx_pcrel)
{
code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
break;
}
case BFD_RELOC_NONE:
case BFD_RELOC_ARM_PCREL_BRANCH:
case BFD_RELOC_ARM_PCREL_BLX:

View file

@ -284,6 +284,7 @@ as position-independent code (PIC).
@menu
* ARM-Chars:: Special Characters
* ARM-Regs:: Register Names
* ARM-Relocations:: Relocations
@end menu
@node ARM-Chars
@ -323,7 +324,46 @@ Either @samp{#} or @samp{$} can be used to indicate immediate operands.
@cindex ARM floating point (@sc{ieee})
The ARM family uses @sc{ieee} floating-point numbers.
@node ARM-Relocations
@subsection ARM relocation generation
@cindex data relocations, ARM
@cindex ARM data relocations
Specific data relocations can be generated by putting the relocation name
in parentheses after the symbol name. For example:
@smallexample
.word foo(TARGET1)
@end smallexample
This will generate an @samp{R_ARM_TARGET1} relocation against the symbol
@var{foo}.
The following relocations are supported:
@code{GOT},
@code{GOTOFF},
@code{TARGET1},
@code{TARGET2},
@code{SBREL},
@code{TLSGD},
@code{TLSLDM},
@code{TLSLDO},
@code{GOTTPOFF}
and
@code{TPOFF}.
For compatibility with older toolchains the assembler also accepts
@code{(PLT)} after branch targets. This will generate the deprecated
@samp{R_ARM_PLT32} relocation.
@cindex MOVW and MOVT relocations, ARM
Relocations for @samp{MOVW} and @samp{MOVT} instructions can be generated
by prefixing the value with @samp{#:lower16:} and @samp{#:upper16}
respectively. For example to load the 32-bit addresss of foo into r0:
@smallexample
MOVW r0, #:lower16:foo
MOVT r0, #:upper16:foo
@end smallexample
@node ARM Directives
@section ARM Machine Directives

View file

@ -1,3 +1,10 @@
2006-05-11 Paul Brook <paul@codesourcery.com>
* ld-arm/arm-elf.exp: Add arm-movwt.
* ld-arm/arm-movwt.d: New test.
* ld-arm/arm-movwt.s: New test.
* ld-arm/arm.ld: Add .far.
2006-05-11 Mike Bland <mbland@google.com>
* ld-elf/stab.d: New.

View file

@ -122,6 +122,9 @@ set armelftests {
{"thumb-rel32" "-static -T arm.ld" "" {thumb-rel32.s}
{{objdump -s thumb-rel32.d}}
"thumb-rel32"}
{"MOVW/MOVT" "-static -T arm.ld" "" {arm-movwt.s}
{{objdump -dw arm-movwt.d}}
"arm-movwt"}
}
run_ld_link_tests $armelftests

View file

@ -0,0 +1,39 @@
.*: file format.*
Disassembly of section .text:
00008000 <[^>]*>:
8000: e3000000 movw r0, #0 ; 0x0
8004: e3411234 movt r1, #4660 ; 0x1234
8008: e3082000 movw r2, #32768 ; 0x8000
800c: e3413233 movt r3, #4659 ; 0x1233
8010: e3004011 movw r4, #17 ; 0x11
8014: e3415234 movt r5, #4660 ; 0x1234
8018: e3086011 movw r6, #32785 ; 0x8011
801c: e3417233 movt r7, #4659 ; 0x1233
00008020 <[^>]*>:
8020: f240 0700 movw r7, #0 ; 0x0
8024: f2c1 2634 movt r6, #4660 ; 0x1234
8028: f248 0500 movw r5, #32768 ; 0x8000
802c: f2c1 2433 movt r4, #4659 ; 0x1233
8030: f240 0311 movw r3, #17 ; 0x11
8034: f2c1 2234 movt r2, #4660 ; 0x1234
8038: f248 0111 movw r1, #32785 ; 0x8011
803c: f2c1 2033 movt r0, #4659 ; 0x1233
Disassembly of section .far:
12340000 <[^>]*>:
12340000: e3080000 movw r0, #32768 ; 0x8000
12340004: e34e0dcc movt r0, #60876 ; 0xedcc
12340008: e3080021 movw r0, #32801 ; 0x8021
1234000c: e34e0dcc movt r0, #60876 ; 0xedcc
12340010 <[^>]*>:
12340010: f248 0000 movw r0, #32768 ; 0x8000
12340014: f6ce 50cc movt r0, #60876 ; 0xedcc
12340018: f248 0021 movw r0, #32801 ; 0x8021
1234001c: f6ce 50cc movt r0, #60876 ; 0xedcc

View file

@ -0,0 +1,44 @@
.text
.arch armv6t2
.syntax unified
.global _start
.type _start, %function
_start:
base1:
arm1:
movw r0, #:lower16:arm2
movt r1, #:upper16:arm2
movw r2, #:lower16:(arm2 - arm1)
movt r3, #:upper16:(arm2 - arm1)
movw r4, #:lower16:thumb2
movt r5, #:upper16:thumb2
movw r6, #:lower16:(thumb2 - arm1)
movt r7, #:upper16:(thumb2 - arm1)
.thumb
.type thumb1, %function
.thumb_func
thumb1:
movw r7, #:lower16:arm2
movt r6, #:upper16:arm2
movw r5, #:lower16:(arm2 - arm1)
movt r4, #:upper16:(arm2 - arm1)
movw r3, #:lower16:thumb2
movt r2, #:upper16:thumb2
movw r1, #:lower16:(thumb2 - arm1)
movt r0, #:upper16:(thumb2 - arm1)
.section .far, "ax", %progbits
.arm
arm2:
movw r0, #:lower16:(arm1 - arm2)
movt r0, #:upper16:(arm1 - arm2)
movw r0, #:lower16:(thumb1 - arm2)
movt r0, #:upper16:(thumb1 - arm2)
.thumb
.type thumb2, %function
.thumb_func
thumb2:
movw r0, #:lower16:(arm1 - arm2)
movt r0, #:upper16:(arm1 - arm2)
movw r0, #:lower16:(thumb1 - arm2)
movt r0, #:upper16:(thumb1 - arm2)

View file

@ -14,5 +14,7 @@ SECTIONS
} =0
. = 0x9000;
.got : { *(.got) *(.got.plt)}
. = 0x12340000;
.far : { *(.far) }
.ARM.attribues 0 : { *(.ARM.atttributes) }
}