[ARM] Add support for thumb1 pcrop relocations.

To support thumb1 execute-only code we need to support four new
relocations (R_ARM_THM_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G1_NC,
R_ARM_THM_ALU_ABS_G2_NC and  R_ARM_THM_ALU_ABS_G3_NC).
These relocations allow the static linker to finalize construction
of symbol address.
Typical sequence of code to get address of the symbol foo is then
the following :
	movs	r3, #:upper8_15:#foo
	lsls	r3, #8
	adds	r3, #:upper0_7:#foo
	lsls	r3, #8
	adds	r3, #:lower8_15:#foo
	lsls	r3, #8
	adds	r3, #:lower0_7:#foo
This will give following sequence of text and relocations after
assembly :
   4:	2300      	movs	r3, #0
			4: R_ARM_THM_ALU_ABS_G3_NC	foo
   6:	021b      	lsls	r3, r3, #8
   8:	3300      	adds	r3, #0
			8: R_ARM_THM_ALU_ABS_G2_NC	foo
   a:	021b      	lsls	r3, r3, #8
   c:	3300      	adds	r3, #0
			c: R_ARM_THM_ALU_ABS_G1_NC	foo
   e:	021b      	lsls	r3, r3, #8
  10:	3300      	adds	r3, #0
			10: R_ARM_THM_ALU_ABS_G0_NC	foo
This commit is contained in:
Mickael Guene 2015-12-16 10:09:05 +01:00 committed by Christophe Lyon
parent 9c35a52902
commit 72d98d16ed
16 changed files with 458 additions and 6 deletions

View File

@ -3516,6 +3516,12 @@ pc-relative or some form of GOT-indirect relocation. */
/* ARM support for STT_GNU_IFUNC. */
BFD_RELOC_ARM_IRELATIVE,
/* Thumb1 relocations to support execute-only code. */
BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,
BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,
BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,
BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,
/* These relocs are only used within the ARM assembler. They are not
(at present) written to any object files. */
BFD_RELOC_ARM_IMMEDIATE,

View File

@ -1689,6 +1689,60 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
0x00000000, /* src_mask */
0x00000000, /* dst_mask */
FALSE), /* pcrel_offset */
EMPTY_HOWTO (130),
EMPTY_HOWTO (131),
HOWTO (R_ARM_THM_ALU_ABS_G0_NC,/* type. */
0, /* rightshift. */
1, /* size (0 = byte, 1 = short, 2 = long). */
16, /* bitsize. */
FALSE, /* pc_relative. */
0, /* bitpos. */
complain_overflow_bitfield,/* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_ARM_THM_ALU_ABS_G0_NC",/* name. */
FALSE, /* partial_inplace. */
0x00000000, /* src_mask. */
0x00000000, /* dst_mask. */
FALSE), /* pcrel_offset. */
HOWTO (R_ARM_THM_ALU_ABS_G1_NC,/* type. */
0, /* rightshift. */
1, /* size (0 = byte, 1 = short, 2 = long). */
16, /* bitsize. */
FALSE, /* pc_relative. */
0, /* bitpos. */
complain_overflow_bitfield,/* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_ARM_THM_ALU_ABS_G1_NC",/* name. */
FALSE, /* partial_inplace. */
0x00000000, /* src_mask. */
0x00000000, /* dst_mask. */
FALSE), /* pcrel_offset. */
HOWTO (R_ARM_THM_ALU_ABS_G2_NC,/* type. */
0, /* rightshift. */
1, /* size (0 = byte, 1 = short, 2 = long). */
16, /* bitsize. */
FALSE, /* pc_relative. */
0, /* bitpos. */
complain_overflow_bitfield,/* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_ARM_THM_ALU_ABS_G2_NC",/* name. */
FALSE, /* partial_inplace. */
0x00000000, /* src_mask. */
0x00000000, /* dst_mask. */
FALSE), /* pcrel_offset. */
HOWTO (R_ARM_THM_ALU_ABS_G3_NC,/* type. */
0, /* rightshift. */
1, /* size (0 = byte, 1 = short, 2 = long). */
16, /* bitsize. */
FALSE, /* pc_relative. */
0, /* bitpos. */
complain_overflow_bitfield,/* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_ARM_THM_ALU_ABS_G3_NC",/* name. */
FALSE, /* partial_inplace. */
0x00000000, /* src_mask. */
0x00000000, /* dst_mask. */
FALSE), /* pcrel_offset. */
};
/* 160 onwards: */
@ -1889,7 +1943,11 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
{BFD_RELOC_ARM_LDC_SB_G0, R_ARM_LDC_SB_G0},
{BFD_RELOC_ARM_LDC_SB_G1, R_ARM_LDC_SB_G1},
{BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2},
{BFD_RELOC_ARM_V4BX, R_ARM_V4BX}
{BFD_RELOC_ARM_V4BX, R_ARM_V4BX},
{BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC, R_ARM_THM_ALU_ABS_G3_NC},
{BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC},
{BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC},
{BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC}
};
static reloc_howto_type *
@ -11023,6 +11081,33 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
}
return bfd_reloc_ok;
case R_ARM_THM_ALU_ABS_G0_NC:
case R_ARM_THM_ALU_ABS_G1_NC:
case R_ARM_THM_ALU_ABS_G2_NC:
case R_ARM_THM_ALU_ABS_G3_NC:
{
const int shift_array[4] = {0, 8, 16, 24};
bfd_vma insn = bfd_get_16 (input_bfd, hit_data);
bfd_vma addr = value;
int shift = shift_array[r_type - R_ARM_THM_ALU_ABS_G0_NC];
/* Compute address. */
if (globals->use_rel)
signed_addend = insn & 0xff;
addr += signed_addend;
if (branch_type == ST_BRANCH_TO_THUMB)
addr |= 1;
/* Clean imm8 insn. */
insn &= 0xff00;
/* And update with correct part of address. */
insn |= (addr >> shift) & 0xff;
/* Update insn. */
bfd_put_16 (input_bfd, insn, hit_data);
}
*unresolved_reloc_p = FALSE;
return bfd_reloc_ok;
default:
return bfd_reloc_notsupported;
}

View File

@ -1545,6 +1545,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_LDC_SB_G2",
"BFD_RELOC_ARM_V4BX",
"BFD_RELOC_ARM_IRELATIVE",
"BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC",
"BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC",
"BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC",
"BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC",
"BFD_RELOC_ARM_IMMEDIATE",
"BFD_RELOC_ARM_ADRL_IMMEDIATE",
"BFD_RELOC_ARM_T32_IMMEDIATE",

View File

@ -3271,6 +3271,17 @@ ENUM
ENUMDOC
ARM support for STT_GNU_IFUNC.
ENUM
BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
ENUMX
BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC
ENUMX
BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC
ENUMX
BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC
ENUMDOC
Thumb1 relocations to support execute-only code.
ENUM
BFD_RELOC_ARM_IMMEDIATE
ENUMX

View File

@ -5273,7 +5273,28 @@ static struct group_reloc_table_entry group_reloc_table[] =
BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
BFD_RELOC_ARM_LDC_SB_G2 } }; /* LDC */
BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
/* Absolute thumb alu relocations. */
{ "lower0_7",
BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
0, /* LDR. */
0, /* LDRS. */
0 }, /* LDC. */
{ "lower8_15",
BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
0, /* LDR. */
0, /* LDRS. */
0 }, /* LDC. */
{ "upper0_7",
BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
0, /* LDR. */
0, /* LDRS. */
0 }, /* LDC. */
{ "upper8_15",
BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
0, /* LDR. */
0, /* LDRS. */
0 } }; /* LDC. */
/* Given the address of a pointer pointing to the textual name of a group
relocation as may appear in assembler source, attempt to find its details
@ -10394,7 +10415,9 @@ do_t_add_sub (void)
{
inst.instruction = THUMB_OP16(opcode);
inst.instruction |= (Rd << 4) | Rs;
inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
|| inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
if (inst.size_req != 2)
inst.relax = opcode;
}
@ -11745,9 +11768,13 @@ do_t_mov_cmp (void)
inst.instruction = THUMB_OP16 (opcode);
inst.instruction |= Rn << 8;
if (inst.size_req == 2)
inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
{
if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
|| inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
}
else
inst.relax = opcode;
inst.relax = opcode;
}
else
{
@ -18608,7 +18635,7 @@ static const struct asm_opcode insns[] =
CL("cmnp", 170f000, 2, (RR, SH), cmp),
tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
tC3("movs", 1b00000, _movs, 2, (RR, SH), mov, t_mov_cmp),
tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
@ -23242,6 +23269,68 @@ md_apply_fix (fixS * fixP,
}
return;
case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
gas_assert (!fixP->fx_done);
{
bfd_vma insn;
bfd_boolean is_mov;
bfd_vma encoded_addend = value;
/* Check that addend can be encoded in instruction. */
if (!seg->use_rela_p && (value < 0 || value > 255))
as_bad_where (fixP->fx_file, fixP->fx_line,
_("the offset 0x%08lX is not representable"),
(unsigned long) encoded_addend);
/* Extract the instruction. */
insn = md_chars_to_number (buf, THUMB_SIZE);
is_mov = (insn & 0xf800) == 0x2000;
/* Encode insn. */
if (is_mov)
{
if (!seg->use_rela_p)
insn |= encoded_addend;
}
else
{
int rd, rs;
/* Extract the instruction. */
/* Encoding is the following
0x8000 SUB
0x00F0 Rd
0x000F Rs
*/
/* The following conditions must be true :
- ADD
- Rd == Rs
- Rd <= 7
*/
rd = (insn >> 4) & 0xf;
rs = insn & 0xf;
if ((insn & 0x8000) || (rd != rs) || rd > 7)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Unable to process relocation for thumb opcode: %lx"),
(unsigned long) insn);
/* Encode as ADD immediate8 thumb 1 code. */
insn = 0x3000 | (rd << 8);
/* Place the encoded addend into the first 8 bits of the
instruction. */
if (!seg->use_rela_p)
insn |= encoded_addend;
}
/* Update the instruction. */
md_number_to_chars (buf, insn, THUMB_SIZE);
}
break;
case BFD_RELOC_ARM_ALU_PC_G0_NC:
case BFD_RELOC_ARM_ALU_PC_G0:
case BFD_RELOC_ARM_ALU_PC_G1_NC:
@ -23579,6 +23668,10 @@ tc_gen_reloc (asection *section, fixS *fixp)
case BFD_RELOC_ARM_LDC_SB_G1:
case BFD_RELOC_ARM_LDC_SB_G2:
case BFD_RELOC_ARM_V4BX:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
code = fixp->fx_r_type;
break;
@ -23881,6 +23974,12 @@ arm_fix_adjustable (fixS * fixP)
|| fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
return FALSE;
/* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
offsets, so keep these symbols. */
if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
&& fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
return FALSE;
return TRUE;
}
#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */

View File

@ -537,6 +537,22 @@ respectively. For example to load the 32-bit address of foo into r0:
MOVT r0, #:upper16:foo
@end smallexample
Relocations @samp{R_ARM_THM_ALU_ABS_G0_NC}, @samp{R_ARM_THM_ALU_ABS_G1_NC},
@samp{R_ARM_THM_ALU_ABS_G2_NC} and @samp{R_ARM_THM_ALU_ABS_G3_NC} can be
generated by prefixing the value with @samp{#:lower0_7:#},
@samp{#:lower8_15:#}, @samp{#:upper0_7:#} and @samp{#:upper8_15:#}
respectively. For example to load the 32-bit address of foo into r0:
@smallexample
MOVS r0, #:upper8_15:#foo
LSLS r0, r0, #8
ADDS r0, #:upper0_7:#foo
LSLS r0, r0, #8
ADDS r0, #:lower8_15:#foo
LSLS r0, r0, #8
ADDS r0, #:lower0_7:#foo
@end smallexample
@node ARM-Neon-Alignment
@subsection NEON Alignment Specifiers

View File

@ -0,0 +1,16 @@
#objdump: -dr --prefix-addresses --show-raw-insn
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
#name: ADDS relocations against local symbols for armv6s-m
.*: +file format .*arm.*
Disassembly of section .text:
0[0-9a-f]+ <[^>]+> 3000 adds r0, #0
0: R_ARM_THM_ALU_ABS_G3_NC bar
0[0-9a-f]+ <[^>]+> 3000 adds r0, #0
2: R_ARM_THM_ALU_ABS_G2_NC bar
0[0-9a-f]+ <[^>]+> 3000 adds r0, #0
4: R_ARM_THM_ALU_ABS_G1_NC bar
0[0-9a-f]+ <[^>]+> 3000 adds r0, #0
6: R_ARM_THM_ALU_ABS_G0_NC bar
#...

View File

@ -0,0 +1,13 @@
.arch armv6s-m
.text
.syntax unified
.thumb
foo:
adds r0, #:upper8_15:#bar
adds r0, #:upper0_7:#bar
adds r0, #:lower8_15:#bar
adds r0, #:lower0_7:#bar
.space 0x10000
bar:

View File

@ -0,0 +1,16 @@
#objdump: -dr --prefix-addresses --show-raw-insn
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
#name: MOVS relocations against local symbols for armv6s-m
.*: +file format .*arm.*
Disassembly of section .text:
0[0-9a-f]+ <[^>]+> 2000 movs r0, #0
0: R_ARM_THM_ALU_ABS_G3_NC bar
0[0-9a-f]+ <[^>]+> 2000 movs r0, #0
2: R_ARM_THM_ALU_ABS_G2_NC bar
0[0-9a-f]+ <[^>]+> 2000 movs r0, #0
4: R_ARM_THM_ALU_ABS_G1_NC bar
0[0-9a-f]+ <[^>]+> 2000 movs r0, #0
6: R_ARM_THM_ALU_ABS_G0_NC bar
#...

View File

@ -0,0 +1,13 @@
.arch armv6s-m
.text
.syntax unified
.thumb
foo:
movs r0, #:upper8_15:#bar
movs r0, #:upper0_7:#bar
movs r0, #:lower8_15:#bar
movs r0, #:lower0_7:#bar
.space 0x10000
bar:

View File

@ -230,6 +230,11 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
RELOC_NUMBER (R_ARM_ME_TOO, 128) /* obsolete */
RELOC_NUMBER (R_ARM_THM_TLS_DESCSEQ ,129)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G0_NC,132)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G1_NC,133)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G2_NC,134)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G3_NC,135)
RELOC_NUMBER (R_ARM_IRELATIVE, 160)
/* Extensions? R=read-only? */

View File

@ -223,6 +223,12 @@ set armelftests_common {
"" {pcrel-shared.s}
{{readelf -dr pcrel-shared.rd}}
"pcrel-shared.so"}
{"MOVS thumb1 relocations" "-static -T arm.ld" "" "" {thumb1-movs.s}
{{objdump -dw thumb1-movs.d}}
"thumb1-movs"}
{"ADDS thumb1 relocations" "-static -T arm.ld" "" "" {thumb1-adds.s}
{{objdump -dw thumb1-adds.d}}
"thumb1-adds"}
}
set armelftests_nonacl {

View File

@ -0,0 +1,38 @@
.*: file format.*
Disassembly of section .text:
00008000 <[^>]*>:
8000: 3012 adds r0, #18
8002: 3134 adds r1, #52 ; 0x34
8004: 3280 adds r2, #128 ; 0x80
8006: 3301 adds r3, #1
8008: 3401 adds r4, #1
800a: 3500 adds r5, #0
800c: 3600 adds r6, #0
800e: 3700 adds r7, #0
00008010 <[^>]*>:
8010: 3012 adds r0, #18
8012: 3100 adds r1, #0
8014: 3200 adds r2, #0
8016: 33ca adds r3, #202 ; 0xca
8018: 3700 adds r7, #0
801a: 3634 adds r6, #52 ; 0x34
801c: 3581 adds r5, #129 ; 0x81
801e: 3423 adds r4, #35 ; 0x23
00008020 <[^>]*>:
8020: 01 .byte 0x01
00008021 <[^>]*>:
8021: 02 .byte 0x02
Disassembly of section .far:
12340000 <[^>]*>:
12340000: 3000 adds r0, #0
12340002: 3100 adds r1, #0
12340004: 3200 adds r2, #0
12340006: 3301 adds r3, #1

View File

@ -0,0 +1,43 @@
.text
.arch armv6s-m
.syntax unified
.global _start
.thumb_func
.type _start, %function
_start:
.thumb_func
.type thumb1, %function
thumb1:
adds r0, #:upper8_15:#thumb3
adds r1, #:upper0_7:#thumb3
adds r2, #:lower8_15:#thumb1
adds r3, #:lower0_7:#thumb1
adds r4, #:lower0_7:#thumb3
adds r5, #:lower8_15:#thumb3
adds r6, #:upper0_7:#thumb1
adds r7, #:upper8_15:#thumb1
.thumb_func
.type thumb2, %function
thumb2:
adds r0, #:upper8_15:#thumb3
adds r1, #:upper0_7:#(var2 + 1)
adds r2, #:lower8_15:#(thumb3 + 255)
adds r3, #:lower0_7:#(var1 + 0xaa)
adds r7, #:upper8_15:#var1 + 4
adds r6, #:upper0_7:#thumb3
adds r5, #:lower8_15:#var2 + 0xff
adds r4, #:lower0_7:#var2 - (-2)
var1:
.byte 1
var2:
.byte 2
.section .far, "ax", %progbits
.thumb_func
.type thumb3, %function
thumb3:
adds r0, #:upper8_15:#thumb1
adds r1, #:upper0_7:#thumb2
adds r2, #:lower8_15:#thumb3
adds r3, #:lower0_7:#thumb1

View File

@ -0,0 +1,38 @@
.*: file format.*
Disassembly of section .text:
00008000 <[^>]*>:
8000: 2012 movs r0, #18
8002: 2134 movs r1, #52 ; 0x34
8004: 2280 movs r2, #128 ; 0x80
8006: 2301 movs r3, #1
8008: 2401 movs r4, #1
800a: 2500 movs r5, #0
800c: 2600 movs r6, #0
800e: 2700 movs r7, #0
00008010 <[^>]*>:
8010: 2012 movs r0, #18
8012: 2100 movs r1, #0
8014: 2281 movs r2, #129 ; 0x81
8016: 2320 movs r3, #32
8018: 2700 movs r7, #0
801a: 2600 movs r6, #0
801c: 2581 movs r5, #129 ; 0x81
801e: 2422 movs r4, #34 ; 0x22
00008020 <[^>]*>:
8020: 01 .byte 0x01
00008021 <[^>]*>:
8021: 02 .byte 0x02
Disassembly of section .far:
12340000 <[^>]*>:
12340000: 2000 movs r0, #0
12340002: 2100 movs r1, #0
12340004: 2200 movs r2, #0
12340006: 2301 movs r3, #1

View File

@ -0,0 +1,43 @@
.text
.arch armv6s-m
.syntax unified
.global _start
.thumb_func
.type _start, %function
_start:
.thumb_func
.type thumb1, %function
thumb1:
movs r0, #:upper8_15:#thumb3
movs r1, #:upper0_7:#thumb3
movs r2, #:lower8_15:#thumb1
movs r3, #:lower0_7:#thumb1
movs r4, #:lower0_7:#thumb3
movs r5, #:lower8_15:#thumb3
movs r6, #:upper0_7:#thumb1
movs r7, #:upper8_15:#thumb1
.thumb_func
.type thumb2, %function
thumb2:
movs r0, #:upper8_15:#(thumb3 + 0)
movs r1, #:upper0_7:#(thumb2 + 1)
movs r2, #:lower8_15:#(var1 + 255)
movs r3, #:lower0_7:#var1
movs r7, #:upper8_15:#var1 + 4
movs r6, #:upper0_7:#var2
movs r5, #:lower8_15:#var2 + 0xff
movs r4, #:lower0_7:#var2 - (-1)
var1:
.byte 1
var2:
.byte 2
.section .far, "ax", %progbits
.thumb_func
.type thumb3, %function
thumb3:
movs r0, #:upper8_15:#thumb1
movs r1, #:upper0_7:#thumb2
movs r2, #:lower8_15:#thumb3
movs r3, #:lower0_7:#thumb1