Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time workaround for a bug in the bus matrix / memory controller for some of the STM32 Cortex-M4 based products (STM32L4xx).

bfd  * bfd-in2.h: Regenerate.
     * bfd-in.h (bfd_arm_stm32l4xx_fix): New enum. Specify how
     STM32L4XX instruction scanning should be done.
     (bfd_elf32_arm_set_stm32l4xx_fix)
     (bfd_elf32_arm_stm32l4xx_erratum_scan)
     (bfd_elf32_arm_stm32l4xx_fix_veneer_locations): Add prototypes.
     (bfd_elf32_arm_set_target_relocs): Add stm32l4xx fix type argument
     to prototype.
     * elf32-arm.c (STM32L4XX_ERRATUM_VENEER_SECTION_NAME)
     (STM32L4XX_ERRATUM_VENEER_ENTRY_NAME): Define macros.
     (elf32_stm32l4xx_erratum_type): New enum.
     (elf32_stm32l4xx_erratum_list): New struct. List of veneers or
     jumps to veneers.
     (_arm_elf_section_data): Add stm32l4xx_erratumcount,
     stm32l4xx_erratumlist.
     (elf32_arm_link_hash_table): Add stm32l4xx_erratum_glue_size,
     stm32l4xx_fix and num_stm32l4xx_fixes fields.
     (ctz): New function.
     (popcount): New function.
     (elf32_arm_link_hash_table_create): Initialize stm32l4xx_fix.
     (put_thumb2_insn): New function.
     (STM32L4XX_ERRATUM_LDM_VENEER_SIZE): Define. Size of a veneer for
     LDM instructions.
     (STM32L4XX_ERRATUM_VLDM_VENEER_SIZE): Define. Size of a veneer for
     VLDM instructions.
     (bfd_elf32_arm_allocate_interworking_sections): Initialise erratum
     glue section.
     (record_stm32l4xx_erratum_veneer) : New function. Create a single
     veneer, and its associated symbols.
     (bfd_elf32_arm_add_glue_sections_to_bfd): Add STM32L4XX erratum glue.
     (bfd_elf32_arm_set_stm32l4xx_fix): New function. Set the type of
     erratum workaround required.
     (bfd_elf32_arm_stm32l4xx_fix_veneer_locations): New function. Find
     out where veneers and branches to veneers have been placed in
     virtual memory after layout.
     (is_thumb2_ldmia): New function.
     (is_thumb2_ldmdb): Likewise.
     (is_thumb2_vldm ): Likewise.
     (stm32l4xx_need_create_replacing_stub): New function. Decide if a
     veneer must be emitted.
     (bfd_elf32_arm_stm32l4xx_erratum_scan): Scan the sections of an
     input BFD for potential erratum-triggering insns. Record results.
     (bfd_elf32_arm_set_target_relocs): Set stm32l4xx_fix field in
     global hash table.
     (elf32_arm_size_dynamic_sections): Collect glue information.
     (create_instruction_branch_absolute): New function.
     (create_instruction_ldmia): Likewise.
     (create_instruction_ldmdb): Likewise.
     (create_instruction_mov): Likewise.
     (create_instruction_sub): Likewise.
     (create_instruction_vldmia): Likewise.
     (create_instruction_vldmdb): Likewise.
     (create_instruction_udf_w): Likewise.
     (create_instruction_udf): Likewise.
     (push_thumb2_insn32): Likewise.
     (push_thumb2_insn16): Likewise.
     (stm32l4xx_fill_stub_udf): Likewise.
     (stm32l4xx_create_replacing_stub_ldmia): New function. Expands the
     replacing stub for ldmia instructions.
     (stm32l4xx_create_replacing_stub_ldmdb): Likewise for ldmdb.
     (stm32l4xx_create_replacing_stub_vldm): Likewise for vldm.
     (stm32l4xx_create_replacing_stub): New function. Dispatches the
     stub emission to the appropriate functions.
     (elf32_arm_write_section): Output veneers, and branches to veneers.

ld   * ld.texinfo: Description of the STM32L4xx erratum workaround.
     * emultempl/armelf.em (stm32l4xx_fix): New.
     (arm_elf_before_allocation): Choose the type of fix, scan for
     erratum.
     (gld${EMULATION_NAME}_finish): Fix veneer locations.
     (arm_elf_create_output_section_statements): Propagate
     stm32l4xx_fix value.
     (PARSE_AND_LIST_PROLOGUE): Define OPTION_STM32L4XX_FIX.
     (PARSE_AND_LIST_LONGOPTS): Add entry for handling
     --fix-stm32l4xx-629360.
     (PARSE_AND_LIST_OPTION): Add entry for helping on
     --fix-stm32l4xx-629360.
     (PARSE_AND_LIST_ARGS_CASES): Treat OPTION_STM32L4XX_FIX.

tests * ld-arm/arm-elf.exp (armelftests_common): Add STM32L4XX
       tests.
     * ld-arm/stm32l4xx-cannot-fix-far-ldm.d: New.
     * ld-arm/stm32l4xx-cannot-fix-far-ldm.s: Likewise.
     * ld-arm/stm32l4xx-cannot-fix-it-block.d: Likewise.
     * ld-arm/stm32l4xx-cannot-fix-it-block.s: Likewise.
     * ld-arm/stm32l4xx-fix-all.d: Likewise.
     * ld-arm/stm32l4xx-fix-all.s: Likewise.
     * ld-arm/stm32l4xx-fix-it-block.d: Likewise.
     * ld-arm/stm32l4xx-fix-it-block.s: Likewise.
     * ld-arm/stm32l4xx-fix-ldm.d: Likewise.
     * ld-arm/stm32l4xx-fix-ldm.s: Likewise.
     * ld-arm/stm32l4xx-fix-vldm.d: Likewise.
     * ld-arm/stm32l4xx-fix-vldm.s: Likewise.
This commit is contained in:
Laurent Alfonsi 2015-10-27 13:20:33 +00:00 committed by Nick Clifton
parent c6056a744a
commit a504d23a83
22 changed files with 2533 additions and 8 deletions

View File

@ -1,3 +1,71 @@
2015-10-27 Laurent Alfonsi <laurent.alfonsi@st.com>
Christophe Monat <christophe.monat@st.com>
* bfd-in2.h: Regenerate.
* bfd-in.h (bfd_arm_stm32l4xx_fix): New enum. Specify how
STM32L4XX instruction scanning should be done.
(bfd_elf32_arm_set_stm32l4xx_fix)
(bfd_elf32_arm_stm32l4xx_erratum_scan)
(bfd_elf32_arm_stm32l4xx_fix_veneer_locations): Add prototypes.
(bfd_elf32_arm_set_target_relocs): Add stm32l4xx fix type argument
to prototype.
* elf32-arm.c (STM32L4XX_ERRATUM_VENEER_SECTION_NAME)
(STM32L4XX_ERRATUM_VENEER_ENTRY_NAME): Define macros.
(elf32_stm32l4xx_erratum_type): New enum.
(elf32_stm32l4xx_erratum_list): New struct. List of veneers or
jumps to veneers.
(_arm_elf_section_data): Add stm32l4xx_erratumcount,
stm32l4xx_erratumlist.
(elf32_arm_link_hash_table): Add stm32l4xx_erratum_glue_size,
stm32l4xx_fix and num_stm32l4xx_fixes fields.
(ctz): New function.
(popcount): New function.
(elf32_arm_link_hash_table_create): Initialize stm32l4xx_fix.
(put_thumb2_insn): New function.
(STM32L4XX_ERRATUM_LDM_VENEER_SIZE): Define. Size of a veneer for
LDM instructions.
(STM32L4XX_ERRATUM_VLDM_VENEER_SIZE): Define. Size of a veneer for
VLDM instructions.
(bfd_elf32_arm_allocate_interworking_sections): Initialise erratum
glue section.
(record_stm32l4xx_erratum_veneer) : New function. Create a single
veneer, and its associated symbols.
(bfd_elf32_arm_add_glue_sections_to_bfd): Add STM32L4XX erratum glue.
(bfd_elf32_arm_set_stm32l4xx_fix): New function. Set the type of
erratum workaround required.
(bfd_elf32_arm_stm32l4xx_fix_veneer_locations): New function. Find
out where veneers and branches to veneers have been placed in
virtual memory after layout.
(is_thumb2_ldmia): New function.
(is_thumb2_ldmdb): Likewise.
(is_thumb2_vldm ): Likewise.
(stm32l4xx_need_create_replacing_stub): New function. Decide if a
veneer must be emitted.
(bfd_elf32_arm_stm32l4xx_erratum_scan): Scan the sections of an
input BFD for potential erratum-triggering insns. Record results.
(bfd_elf32_arm_set_target_relocs): Set stm32l4xx_fix field in
global hash table.
(elf32_arm_size_dynamic_sections): Collect glue information.
(create_instruction_branch_absolute): New function.
(create_instruction_ldmia): Likewise.
(create_instruction_ldmdb): Likewise.
(create_instruction_mov): Likewise.
(create_instruction_sub): Likewise.
(create_instruction_vldmia): Likewise.
(create_instruction_vldmdb): Likewise.
(create_instruction_udf_w): Likewise.
(create_instruction_udf): Likewise.
(push_thumb2_insn32): Likewise.
(push_thumb2_insn16): Likewise.
(stm32l4xx_fill_stub_udf): Likewise.
(stm32l4xx_create_replacing_stub_ldmia): New function. Expands the
replacing stub for ldmia instructions.
(stm32l4xx_create_replacing_stub_ldmdb): Likewise for ldmdb.
(stm32l4xx_create_replacing_stub_vldm): Likewise for vldm.
(stm32l4xx_create_replacing_stub): New function. Dispatches the
stub emission to the appropriate functions.
(elf32_arm_write_section): Output veneers, and branches to veneers.
2015-10-27 Sangamesh Mallayya <nickc@redhat.com>sangamesh.swamy@in.ibm.com>
* configure.ac (powerpc64-*-aix[5-9].*): Match powerpc64 running

View File

@ -849,6 +849,23 @@ extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan
extern void bfd_elf32_arm_vfp11_fix_veneer_locations
(bfd *, struct bfd_link_info *);
/* ARM STM STM32L4XX erratum workaround support. */
typedef enum
{
BFD_ARM_STM32L4XX_FIX_NONE,
BFD_ARM_STM32L4XX_FIX_DEFAULT,
BFD_ARM_STM32L4XX_FIX_ALL
} bfd_arm_stm32l4xx_fix;
extern void bfd_elf32_arm_set_stm32l4xx_fix
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf32_arm_stm32l4xx_erratum_scan
(bfd *, struct bfd_link_info *);
extern void bfd_elf32_arm_stm32l4xx_fix_veneer_locations
(bfd *, struct bfd_link_info *);
/* ARM Interworking support. Called from linker. */
extern bfd_boolean bfd_arm_allocate_interworking_sections
(struct bfd_link_info *);
@ -878,7 +895,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
void bfd_elf32_arm_set_target_relocs
(bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
int, int, int, int, int);
bfd_arm_stm32l4xx_fix, int, int, int, int, int);
extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
(bfd *, struct bfd_link_info *);

View File

@ -856,6 +856,23 @@ extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan
extern void bfd_elf32_arm_vfp11_fix_veneer_locations
(bfd *, struct bfd_link_info *);
/* ARM STM STM32L4XX erratum workaround support. */
typedef enum
{
BFD_ARM_STM32L4XX_FIX_NONE,
BFD_ARM_STM32L4XX_FIX_DEFAULT,
BFD_ARM_STM32L4XX_FIX_ALL
} bfd_arm_stm32l4xx_fix;
extern void bfd_elf32_arm_set_stm32l4xx_fix
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf32_arm_stm32l4xx_erratum_scan
(bfd *, struct bfd_link_info *);
extern void bfd_elf32_arm_stm32l4xx_fix_veneer_locations
(bfd *, struct bfd_link_info *);
/* ARM Interworking support. Called from linker. */
extern bfd_boolean bfd_arm_allocate_interworking_sections
(struct bfd_link_info *);
@ -885,7 +902,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
void bfd_elf32_arm_set_target_relocs
(bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
int, int, int, int, int);
bfd_arm_stm32l4xx_fix, int, int, int, int, int);
extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
(bfd *, struct bfd_link_info *);

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,22 @@
2015-10-27 Laurent Alfonsi <laurent.alfonsi@st.com>
Christophe Monat <christophe.monat@st.com>
* ld.texinfo: Add description of the STM32L4xx erratum
workaround.
* NEWS: Mention the new feature.
* emultempl/armelf.em (stm32l4xx_fix): New.
(arm_elf_before_allocation): Choose the type of fix, scan for
erratum.
(gld${EMULATION_NAME}_finish): Fix veneer locations.
(arm_elf_create_output_section_statements): Propagate
stm32l4xx_fix value.
(PARSE_AND_LIST_PROLOGUE): Define OPTION_STM32L4XX_FIX.
(PARSE_AND_LIST_LONGOPTS): Add entry for handling
--fix-stm32l4xx-629360.
(PARSE_AND_LIST_OPTION): Add entry for helping on
--fix-stm32l4xx-629360.
(PARSE_AND_LIST_ARGS_CASES): Treat OPTION_STM32L4XX_FIX.
2015-10-27 Alan Modra <amodra@gmail.com>
PR ld/19175

View File

@ -1,4 +1,7 @@
-*- text -*-
* Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time
workaround for a bug in the bus matrix / memory controller for some of
the STM32 Cortex-M4 based products (STM32L4xx)
* Add a configure option --enable-compressed-debug-sections={all,ld} to
decide whether DWARF debug sections should be compressed by default.

View File

@ -35,6 +35,7 @@ static char * target2_type = "${TARGET2_TYPE}";
static int fix_v4bx = 0;
static int use_blx = 0;
static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT;
static bfd_arm_stm32l4xx_fix stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_NONE;
static int fix_cortex_a8 = -1;
static int no_enum_size_warning = 0;
static int no_wchar_size_warning = 0;
@ -62,6 +63,10 @@ arm_elf_before_allocation (void)
due to architecture version. */
bfd_elf32_arm_set_vfp11_fix (link_info.output_bfd, &link_info);
/* Choose type of STM32L4XX erratum fix, or warn if specified fix is
unnecessary due to architecture version. */
bfd_elf32_arm_set_stm32l4xx_fix (link_info.output_bfd, &link_info);
/* Auto-select Cortex-A8 erratum fix if it wasn't explicitly specified. */
bfd_elf32_arm_set_cortex_a8_fix (link_info.output_bfd, &link_info);
@ -77,7 +82,9 @@ arm_elf_before_allocation (void)
if (!bfd_elf32_arm_process_before_allocation (is->the_bfd,
&link_info)
|| !bfd_elf32_arm_vfp11_erratum_scan (is->the_bfd, &link_info))
|| !bfd_elf32_arm_vfp11_erratum_scan (is->the_bfd, &link_info)
|| !bfd_elf32_arm_stm32l4xx_erratum_scan (is->the_bfd,
&link_info))
/* xgettext:c-format */
einfo (_("Errors encountered processing file %s"), is->filename);
}
@ -380,6 +387,10 @@ gld${EMULATION_NAME}_finish (void)
/* Figure out where VFP11 erratum veneers (and the labels returning
from same) have been placed. */
bfd_elf32_arm_vfp11_fix_veneer_locations (is->the_bfd, &link_info);
/* Figure out where STM32L4XX erratum veneers (and the labels returning
from them) have been placed. */
bfd_elf32_arm_stm32l4xx_fix_veneer_locations (is->the_bfd, &link_info);
}
}
@ -468,7 +479,8 @@ arm_elf_create_output_section_statements (void)
bfd_elf32_arm_set_target_relocs (link_info.output_bfd, &link_info,
target1_is_rel,
target2_type, fix_v4bx, use_blx,
vfp11_denorm_fix, no_enum_size_warning,
vfp11_denorm_fix, stm32l4xx_fix,
no_enum_size_warning,
no_wchar_size_warning,
pic_veneer, fix_cortex_a8,
fix_arm1176);
@ -539,6 +551,7 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_FIX_ARM1176 317
#define OPTION_NO_FIX_ARM1176 318
#define OPTION_LONG_PLT 319
#define OPTION_STM32L4XX_FIX 320
'
PARSE_AND_LIST_SHORTOPTS=p
@ -554,6 +567,7 @@ PARSE_AND_LIST_LONGOPTS='
{ "fix-v4bx-interworking", no_argument, NULL, OPTION_FIX_V4BX_INTERWORKING},
{ "use-blx", no_argument, NULL, OPTION_USE_BLX},
{ "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
{ "fix-stm32l4xx-629360", optional_argument, NULL, OPTION_STM32L4XX_FIX},
{ "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
{ "pic-veneer", no_argument, NULL, OPTION_PIC_VENEER},
{ "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
@ -576,6 +590,7 @@ PARSE_AND_LIST_OPTIONS='
fprintf (file, _(" --fix-v4bx-interworking Rewrite BX rn branch to ARMv4 interworking veneer\n"));
fprintf (file, _(" --use-blx Enable use of BLX instructions\n"));
fprintf (file, _(" --vfp11-denorm-fix Specify how to fix VFP11 denorm erratum\n"));
fprintf (file, _(" --fix-stm32l4xx-629360 Specify how to fix STM32L4XX 629360 erratum\n"));
fprintf (file, _(" --no-enum-size-warning Don'\''t warn about objects with incompatible\n"
" enum sizes\n"));
fprintf (file, _(" --no-wchar-size-warning Don'\''t warn about objects with incompatible\n"
@ -645,6 +660,19 @@ PARSE_AND_LIST_ARGS_CASES='
einfo (_("Unrecognized VFP11 fix type '\''%s'\''.\n"), optarg);
break;
case OPTION_STM32L4XX_FIX:
if (!optarg)
stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_DEFAULT;
else if (strcmp (optarg, "none") == 0)
stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_NONE;
else if (strcmp (optarg, "default") == 0)
stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_DEFAULT;
else if (strcmp (optarg, "all") == 0)
stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_ALL;
else
einfo (_("Unrecognized STM32L4XX fix type '\''%s'\''.\n"), optarg);
break;
case OPTION_NO_ENUM_SIZE_WARNING:
no_enum_size_warning = 1;
break;

View File

@ -6681,6 +6681,48 @@ Further information is available in the ``ARM1176JZ-S and ARM1176JZF-S
Programmer Advice Notice'' available on the ARM documentation website at:
http://infocenter.arm.com/.
@cindex STM32L4xx erratum workaround
@kindex --fix-stm32l4xx-629360
The @samp{--fix-stm32l4xx-629360} switch enables a link-time
workaround for a bug in the bus matrix / memory controller for some of
the STM32 Cortex-M4 based products (STM32L4xx). When accessing
off-chip memory via the affected bus for bus reads of 9 words or more,
the bus can generate corrupt data and/or abort. These are only
core-initiated accesses (not DMA), and might affect any access:
integer loads such as LDM, POP and floating-point loads such as VLDM,
VPOP. Stores are not affected.
The bug can be avoided by splitting memory accesses into the
necessary chunks to keep bus reads below 8 words.
The workaround is not enabled by default, this is equivalent to use
@samp{--fix-stm32l4xx-629360=none}. If you know you are using buggy
STM32L4xx hardware, you can enable the workaround by specifying the
linker option @samp{--fix-stm32l4xx-629360}, or the equivalent
@samp{--fix-stm32l4xx-629360=default}.
If the workaround is enabled, instructions are scanned for
potentially-troublesome sequences, and a veneer is created for each
such sequence which may trigger the erratum. The veneer consists in a
replacement sequence emulating the behaviour of the original one and a
branch back to the subsequent instruction. The original instruction is
then replaced with a branch to the veneer.
The workaround does not always preserve the memory access order for
the LDMDB instruction, when the instruction loads the PC.
The workaround is not able to handle problematic instructions when
they are in the middle of an IT block, since a branch is not allowed
there. In that case, the linker reports a warning and no replacement
occurs.
The workaround is not able to replace problematic instructions with a
PC-relative branch instruction if the @samp{.text} section is too
large. In that case, when the branch that replaces the original code
cannot be encoded, the linker reports a warning and no replacement
occurs.
@cindex NO_ENUM_SIZE_WARNING
@kindex --no-enum-size-warning
The @option{--no-enum-size-warning} switch prevents the linker from

View File

@ -1,3 +1,21 @@
2015-10-27 Laurent Alfonsi <laurent.alfonsi@st.com>
Christophe Monat <christophe.monat@st.com>
* ld-arm/arm-elf.exp (armelftests_common): Add STM32L4XX
tests.
* ld-arm/stm32l4xx-cannot-fix-far-ldm.d: New.
* ld-arm/stm32l4xx-cannot-fix-far-ldm.s: Likewise.
* ld-arm/stm32l4xx-cannot-fix-it-block.d: Likewise.
* ld-arm/stm32l4xx-cannot-fix-it-block.s: Likewise.
* ld-arm/stm32l4xx-fix-all.d: Likewise.
* ld-arm/stm32l4xx-fix-all.s: Likewise.
* ld-arm/stm32l4xx-fix-it-block.d: Likewise.
* ld-arm/stm32l4xx-fix-it-block.s: Likewise.
* ld-arm/stm32l4xx-fix-ldm.d: Likewise.
* ld-arm/stm32l4xx-fix-ldm.s: Likewise.
* ld-arm/stm32l4xx-fix-vldm.d: Likewise.
* ld-arm/stm32l4xx-fix-vldm.s: Likewise.
2015-10-27 Alan Modra <amodra@gmail.com>
* ld-gc/pr19161.d: xfail hppa-*-*.

View File

@ -159,6 +159,22 @@ set armelftests_common {
"-EL --vfp11-denorm-fix=scalar -Ttext=0x8000" "" "-EL -mfpu=vfpxd" {vfp11-fix-none.s}
{{objdump -dr vfp11-fix-none.d}}
"vfp11-fix-none"}
{"STM32L4XX erratum fix LDM"
"-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-ldm.s}
{{objdump -dr stm32l4xx-fix-ldm.d}}
"stm32l4xx-fix-ldm"}
{"STM32L4XX erratum fix VLDM"
"-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-vldm.s}
{{objdump -dr stm32l4xx-fix-vldm.d}}
"stm32l4xx-fix-vldm"}
{"STM32L4XX erratum fix ALL"
"-EL --fix-stm32l4xx-629360=all -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-all.s}
{{objdump -dr stm32l4xx-fix-all.d}}
"stm32l4xx-fix-vldm-all"}
{"STM32L4XX erratum fix in IT context"
"-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-it-block.s}
{{objdump -dr stm32l4xx-fix-it-block.d}}
"stm32l4xx-fix-it-block"}
{"Unwinding and -gc-sections" "-gc-sections" "" "" {gc-unwind.s}
{{objdump -sj.data gc-unwind.d}}
"gc-unwind"}
@ -905,3 +921,5 @@ if { ![istarget "arm*-*-nacl*"] } {
run_dump_test "unresolved-2"
run_dump_test "gc-hidden-1"
run_dump_test "protected-data"
run_dump_test "stm32l4xx-cannot-fix-it-block"
run_dump_test "stm32l4xx-cannot-fix-far-ldm"

View File

@ -0,0 +1,25 @@
#source: stm32l4xx-cannot-fix-far-ldm.s
#as:-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16
#ld:-EL --fix-stm32l4xx-629360 -Ttext=0x80000
#objdump: -dr --prefix-addresses --show-raw-insn
#name: STM32L4XX erratum : LDM cannot be patched when LDM is too far from veneer section
#warning: .*Cannot create STM32L4XX veneer. Jump out of range by 24 bytes. Cannot encode branch instruction.*
# Test the `LDM*' instructions when too far from the veneer section
# They cannot, thus should not, be patched
.*: +file format .*arm.*
Disassembly of section \.text:
00080000 <__stm32l4xx_veneer_0> 4607[[:space:]]+mov[[:space:]]+r7, r0
00080002 <__stm32l4xx_veneer_0\+0x2> e8b7 007e[[:space:]]+ldmia\.w[[:space:]]+r7\!, {r1, r2, r3, r4, r5, r6}
00080006 <__stm32l4xx_veneer_0\+0x6> e897 0380[[:space:]]+ldmia\.w[[:space:]]+r7, {r7, r8, r9}
0008000a <__stm32l4xx_veneer_0\+0xa> f3ff 978b[[:space:]]+b\.w[[:space:]]+0107ff24 <__stm32l4xx_veneer_0_r>
0008000e <__stm32l4xx_veneer_0\+0xe> de00[[:space:]]+udf[[:space:]]+#0
\.\.\.
\.\.\.
0107ff20 <_start\+0xffff00> f400 906e[[:space:]]+b\.w[[:space:]]+00080000 <__stm32l4xx_veneer_0>
\.\.\.
01080024 <__stm32l4xx_veneer_0_r\+0x100> e899 03fe[[:space:]]+ldmia\.w[[:space:]]+r9, {r1, r2, r3, r4, r5, r6, r7, r8, r9}
01080028 <__stm32l4xx_veneer_1_r> bf00[[:space:]]+nop

View File

@ -0,0 +1,27 @@
.syntax unified
.cpu cortex-m4
.fpu fpv4-sp-d16
.text
.align 1
.thumb
.thumb_func
.global _start
_start:
.space 0xFFFF00
@ Multiple load, case #2
@ ldm rx, {...} ->
@ mov ry, rx where ry is the lowest register from upper_list
@ ldm ry!, { lower_list }
@ ldm ry, { upper_list }
ldm.w r0, {r1-r9}
.space 0x100
@ Check that the linker never generates a wrong branch
@ ldm rx, {...} -> ldm rx, {...}
@ Emit a warning during the link phase and keep the same instruction
ldm.w r9, {r1-r9}
nop

View File

@ -0,0 +1,16 @@
#source: stm32l4xx-cannot-fix-it-block.s
#as:-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16
#ld:-EL --fix-stm32l4xx-629360 -Ttext=0x8000
#objdump: -dr --prefix-addresses --show-raw-insn
#name: STM32L4XX erratum : LDM cannot be patched when not last in IT block
#warning: .*multiple load detected in non-last IT block instruction.*
# Test the `LDM*' instructions when non-last in IT block
# They cannot, thus should not, be patched
.*: +file format .*arm.*
Disassembly of section \.text:
00008000 \<_start\> bf04[[:space:]]+itt[[:space:]]+eq
00008002 \<_start\+0x2\> e899 03fe[[:space:]]+ldmiaeq\.w[[:space:]]+r9, {r1, r2, r3, r4, r5, r6, r7, r8, r9}
00008006 \<_start\+0x6\> f3af 8000[[:space:]]+nopeq\.w

View File

@ -0,0 +1,16 @@
.syntax unified
.cpu cortex-m4
.fpu fpv4-sp-d16
.text
.align 1
.thumb
.thumb_func
.global _start
_start:
@ Create a situation where a multiple-load that should be
@ patched cannot be, due to its belonging to an IT block
@ but not in last position, which is the only position
@ when a branch is valid in a IT block
itt eq
ldmeq.w r9, {r1-r9}
nop.w

View File

@ -0,0 +1,83 @@
.*: file format elf32-littlearm.*
Disassembly of section \.text:
00008000 <__stm32l4xx_veneer_0>:
8000: e899 01fe ldmia\.w r9, {r1, r2, r3, r4, r5, r6, r7, r8}
8004: f000 b84a b\.w 809c <__stm32l4xx_veneer_0_r>
8008: f7f0 a000 udf\.w #0
800c: f7f0 a000 udf\.w #0
00008010 <__stm32l4xx_veneer_1>:
8010: e8b9 01fe ldmia\.w r9!, {r1, r2, r3, r4, r5, r6, r7, r8}
8014: f000 b844 b\.w 80a0 <__stm32l4xx_veneer_1_r>
8018: f7f0 a000 udf\.w #0
801c: f7f0 a000 udf\.w #0
00008020 <__stm32l4xx_veneer_2>:
8020: e919 01fe ldmdb r9, {r1, r2, r3, r4, r5, r6, r7, r8}
8024: f000 b83e b\.w 80a4 <__stm32l4xx_veneer_2_r>
8028: f7f0 a000 udf\.w #0
802c: f7f0 a000 udf\.w #0
00008030 <__stm32l4xx_veneer_3>:
8030: e939 01fe ldmdb r9!, {r1, r2, r3, r4, r5, r6, r7, r8}
8034: f000 b838 b\.w 80a8 <__stm32l4xx_veneer_3_r>
8038: f7f0 a000 udf\.w #0
803c: f7f0 a000 udf\.w #0
00008040 <__stm32l4xx_veneer_4>:
8040: e8bd 01fe ldmia\.w sp!, {r1, r2, r3, r4, r5, r6, r7, r8}
8044: f000 b832 b\.w 80ac <__stm32l4xx_veneer_4_r>
8048: f7f0 a000 udf\.w #0
804c: f7f0 a000 udf\.w #0
00008050 <__stm32l4xx_veneer_5>:
8050: ecd9 0a08 vldmia r9, {s1-s8}
8054: f000 b82c b\.w 80b0 <__stm32l4xx_veneer_5_r>
8058: f7f0 a000 udf\.w #0
805c: f7f0 a000 udf\.w #0
8060: f7f0 a000 udf\.w #0
8064: f7f0 a000 udf\.w #0
00008068 <__stm32l4xx_veneer_6>:
8068: ecf6 4a08 vldmia r6!, {s9-s16}
806c: f000 b822 b\.w 80b4 <__stm32l4xx_veneer_6_r>
8070: f7f0 a000 udf\.w #0
8074: f7f0 a000 udf\.w #0
8078: f7f0 a000 udf\.w #0
807c: f7f0 a000 udf\.w #0
00008080 <__stm32l4xx_veneer_7>:
8080: ecfd 0a08 vpop {s1-s8}
8084: f000 b818 b\.w 80b8 <__stm32l4xx_veneer_7_r>
8088: f7f0 a000 udf\.w #0
808c: f7f0 a000 udf\.w #0
8090: f7f0 a000 udf\.w #0
8094: f7f0 a000 udf\.w #0
00008098 <_start>:
8098: f7ff bfb2 b\.w 8000 <__stm32l4xx_veneer_0>
0000809c <__stm32l4xx_veneer_0_r>:
809c: f7ff bfb8 b\.w 8010 <__stm32l4xx_veneer_1>
000080a0 <__stm32l4xx_veneer_1_r>:
80a0: f7ff bfbe b\.w 8020 <__stm32l4xx_veneer_2>
000080a4 <__stm32l4xx_veneer_2_r>:
80a4: f7ff bfc4 b\.w 8030 <__stm32l4xx_veneer_3>
000080a8 <__stm32l4xx_veneer_3_r>:
80a8: f7ff bfca b\.w 8040 <__stm32l4xx_veneer_4>
000080ac <__stm32l4xx_veneer_4_r>:
80ac: f7ff bfd0 b\.w 8050 <__stm32l4xx_veneer_5>
000080b0 <__stm32l4xx_veneer_5_r>:
80b0: f7ff bfda b\.w 8068 <__stm32l4xx_veneer_6>
000080b4 <__stm32l4xx_veneer_6_r>:
80b4: f7ff bfe4 b\.w 8080 <__stm32l4xx_veneer_7>

View File

@ -0,0 +1,22 @@
.syntax unified
.cpu cortex-m4
.fpu fpv4-sp-d16
.text
.align 1
.thumb
.thumb_func
.global _start
_start:
@ All LDM treatments for word acces <= 8 go through the same
@ replication code, but decoding may vary
ldm.w r9, {r1-r8}
ldm.w r9!, {r1-r8}
ldmdb.w r9, {r1-r8}
ldmdb.w r9!, {r1-r8}
pop {r1-r8}
@ All VLDM treatments for word acces <= 8 go through the same
@ replication code, but decoding may vary
vldm r9, {s1-s8}
vldm r6!, {s9-s16}
vpop {s1-s8}

View File

@ -0,0 +1,189 @@
.*: file format elf32-littlearm.*
Disassembly of section \.text:
00008000 <__stm32l4xx_veneer_0>:
8000: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8004: e899 0380 ldmia\.w r9, {r7, r8, r9}
8008: f000 b875 b\.w 80f6 <__stm32l4xx_veneer_0_r>
800c: f7f0 a000 udf\.w #0
00008010 <__stm32l4xx_veneer_1>:
8010: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8014: e899 0380 ldmia\.w r9, {r7, r8, r9}
8018: f000 b872 b\.w 8100 <__stm32l4xx_veneer_1_r>
801c: f7f0 a000 udf\.w #0
00008020 <__stm32l4xx_veneer_2>:
8020: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8024: e899 0380 ldmia\.w r9, {r7, r8, r9}
8028: f000 b86f b\.w 810a <__stm32l4xx_veneer_2_r>
802c: f7f0 a000 udf\.w #0
00008030 <__stm32l4xx_veneer_3>:
8030: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8034: e899 0380 ldmia\.w r9, {r7, r8, r9}
8038: f000 b86e b\.w 8118 <__stm32l4xx_veneer_3_r>
803c: f7f0 a000 udf\.w #0
00008040 <__stm32l4xx_veneer_4>:
8040: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8044: e899 0380 ldmia\.w r9, {r7, r8, r9}
8048: f000 b86d b\.w 8126 <__stm32l4xx_veneer_4_r>
804c: f7f0 a000 udf\.w #0
00008050 <__stm32l4xx_veneer_5>:
8050: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8054: e899 0380 ldmia\.w r9, {r7, r8, r9}
8058: f000 b86c b\.w 8134 <__stm32l4xx_veneer_5_r>
805c: f7f0 a000 udf\.w #0
00008060 <__stm32l4xx_veneer_6>:
8060: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8064: e899 0380 ldmia\.w r9, {r7, r8, r9}
8068: f000 b86b b\.w 8142 <__stm32l4xx_veneer_6_r>
806c: f7f0 a000 udf\.w #0
00008070 <__stm32l4xx_veneer_7>:
8070: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8074: e899 0380 ldmia\.w r9, {r7, r8, r9}
8078: f000 b86c b\.w 8154 <__stm32l4xx_veneer_7_r>
807c: f7f0 a000 udf\.w #0
00008080 <__stm32l4xx_veneer_8>:
8080: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8084: e899 0380 ldmia\.w r9, {r7, r8, r9}
8088: f000 b86d b\.w 8166 <__stm32l4xx_veneer_8_r>
808c: f7f0 a000 udf\.w #0
00008090 <__stm32l4xx_veneer_9>:
8090: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8094: e899 0380 ldmia\.w r9, {r7, r8, r9}
8098: f000 b86e b\.w 8178 <__stm32l4xx_veneer_9_r>
809c: f7f0 a000 udf\.w #0
000080a0 <__stm32l4xx_veneer_a>:
80a0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
80a4: e899 0380 ldmia\.w r9, {r7, r8, r9}
80a8: f000 b86f b\.w 818a <__stm32l4xx_veneer_a_r>
80ac: f7f0 a000 udf\.w #0
000080b0 <__stm32l4xx_veneer_b>:
80b0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
80b4: e899 0380 ldmia\.w r9, {r7, r8, r9}
80b8: f000 b870 b\.w 819c <__stm32l4xx_veneer_b_r>
80bc: f7f0 a000 udf\.w #0
000080c0 <__stm32l4xx_veneer_c>:
80c0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
80c4: e899 0380 ldmia\.w r9, {r7, r8, r9}
80c8: f000 b871 b\.w 81ae <__stm32l4xx_veneer_c_r>
80cc: f7f0 a000 udf\.w #0
000080d0 <__stm32l4xx_veneer_d>:
80d0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
80d4: e899 0380 ldmia\.w r9, {r7, r8, r9}
80d8: f000 b872 b\.w 81c0 <__stm32l4xx_veneer_d_r>
80dc: f7f0 a000 udf\.w #0
000080e0 <__stm32l4xx_veneer_e>:
80e0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
80e4: e899 0380 ldmia\.w r9, {r7, r8, r9}
80e8: f000 b873 b\.w 81d2 <__stm32l4xx_veneer_e_r>
80ec: f7f0 a000 udf\.w #0
000080f0 <_start>:
80f0: bf08 it eq
80f2: f7ff bf85 beq\.w 8000 <__stm32l4xx_veneer_0>
000080f6 <__stm32l4xx_veneer_0_r>:
80f6: bf04 itt eq
80f8: f3af 8000 nopeq\.w
80fc: f7ff bf88 beq\.w 8010 <__stm32l4xx_veneer_1>
00008100 <__stm32l4xx_veneer_1_r>:
8100: bf0c ite eq
8102: f3af 8000 nopeq\.w
8106: f7ff bf8b bne\.w 8020 <__stm32l4xx_veneer_2>
0000810a <__stm32l4xx_veneer_2_r>:
810a: bf02 ittt eq
810c: f3af 8000 nopeq\.w
8110: f3af 8000 nopeq\.w
8114: f7ff bf8c beq\.w 8030 <__stm32l4xx_veneer_3>
00008118 <__stm32l4xx_veneer_3_r>:
8118: bf0a itet eq
811a: f3af 8000 nopeq\.w
811e: f3af 8000 nopne\.w
8122: f7ff bf8d beq\.w 8040 <__stm32l4xx_veneer_4>
00008126 <__stm32l4xx_veneer_4_r>:
8126: bf06 itte eq
8128: f3af 8000 nopeq\.w
812c: f3af 8000 nopeq\.w
8130: f7ff bf8e bne\.w 8050 <__stm32l4xx_veneer_5>
00008134 <__stm32l4xx_veneer_5_r>:
8134: bf0e itee eq
8136: f3af 8000 nopeq\.w
813a: f3af 8000 nopne\.w
813e: f7ff bf8f bne\.w 8060 <__stm32l4xx_veneer_6>
00008142 <__stm32l4xx_veneer_6_r>:
8142: bf01 itttt eq
8144: f3af 8000 nopeq\.w
8148: f3af 8000 nopeq\.w
814c: f3af 8000 nopeq\.w
8150: f7ff bf8e beq\.w 8070 <__stm32l4xx_veneer_7>
00008154 <__stm32l4xx_veneer_7_r>:
8154: bf03 ittte eq
8156: f3af 8000 nopeq\.w
815a: f3af 8000 nopeq\.w
815e: f3af 8000 nopeq\.w
8162: f7ff bf8d bne\.w 8080 <__stm32l4xx_veneer_8>
00008166 <__stm32l4xx_veneer_8_r>:
8166: bf05 ittet eq
8168: f3af 8000 nopeq\.w
816c: f3af 8000 nopeq\.w
8170: f3af 8000 nopne\.w
8174: f7ff bf8c beq\.w 8090 <__stm32l4xx_veneer_9>
00008178 <__stm32l4xx_veneer_9_r>:
8178: bf07 ittee eq
817a: f3af 8000 nopeq\.w
817e: f3af 8000 nopeq\.w
8182: f3af 8000 nopne\.w
8186: f7ff bf8b bne\.w 80a0 <__stm32l4xx_veneer_a>
0000818a <__stm32l4xx_veneer_a_r>:
818a: bf09 itett eq
818c: f3af 8000 nopeq\.w
8190: f3af 8000 nopne\.w
8194: f3af 8000 nopeq\.w
8198: f7ff bf8a beq\.w 80b0 <__stm32l4xx_veneer_b>
0000819c <__stm32l4xx_veneer_b_r>:
819c: bf0b itete eq
819e: f3af 8000 nopeq\.w
81a2: f3af 8000 nopne\.w
81a6: f3af 8000 nopeq\.w
81aa: f7ff bf89 bne\.w 80c0 <__stm32l4xx_veneer_c>
000081ae <__stm32l4xx_veneer_c_r>:
81ae: bf0d iteet eq
81b0: f3af 8000 nopeq\.w
81b4: f3af 8000 nopne\.w
81b8: f3af 8000 nopne\.w
81bc: f7ff bf88 beq\.w 80d0 <__stm32l4xx_veneer_d>
000081c0 <__stm32l4xx_veneer_d_r>:
81c0: bf0f iteee eq
81c2: f3af 8000 nopeq\.w
81c6: f3af 8000 nopne\.w
81ca: f3af 8000 nopne\.w
81ce: f7ff bf87 bne\.w 80e0 <__stm32l4xx_veneer_e>

View File

@ -0,0 +1,92 @@
.syntax unified
.cpu cortex-m4
.fpu fpv4-sp-d16
.text
.align 1
.thumb
.thumb_func
.global _start
_start:
@ Create a situation where a multiple-load that should be
@ patched belongs to an IT block in the position where it can
@ be, that is the last position in the IT block.
@ Mostly to cover the IT detection logic.
@ Tests correspond to LDM CASE #1.
it eq
ldmeq.w r9, {r1-r9}
itt eq
nop.w
ldmeq.w r9, {r1-r9}
ite eq
nop.w
ldmne.w r9, {r1-r9}
ittt eq
nop.w
nop.w
ldmeq.w r9, {r1-r9}
itet eq
nop.w
nop.w
ldmeq.w r9, {r1-r9}
itte eq
nop.w
nop.w
ldmne.w r9, {r1-r9}
itee eq
nop.w
nop.w
ldmne.w r9, {r1-r9}
itttt eq
nop.w
nop.w
nop.w
ldmeq.w r9, {r1-r9}
ittte eq
nop.w
nop.w
nop.w
ldmne.w r9, {r1-r9}
ittet eq
nop.w
nop.w
nop.w
ldmeq.w r9, {r1-r9}
ittee eq
nop.w
nop.w
nop.w
ldmne.w r9, {r1-r9}
itett eq
nop.w
nop.w
nop.w
ldmeq.w r9, {r1-r9}
itete eq
nop.w
nop.w
nop.w
ldmne.w r9, {r1-r9}
iteet eq
nop.w
nop.w
nop.w
ldmeq.w r9, {r1-r9}
iteee eq
nop.w
nop.w
nop.w
ldmne.w r9, {r1-r9}

View File

@ -0,0 +1,174 @@
.*: file format elf32-littlearm.*
Disassembly of section \.text:
00008000 <__stm32l4xx_veneer_0>:
8000: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8004: e899 0380 ldmia\.w r9, {r7, r8, r9}
8008: f000 b88c b\.w 8124 <__stm32l4xx_veneer_0_r>
800c: f7f0 a000 udf\.w #0
00008010 <__stm32l4xx_veneer_1>:
8010: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
8014: e899 8380 ldmia\.w r9, {r7, r8, r9, pc}
8018: f7f0 a000 udf\.w #0
801c: f7f0 a000 udf\.w #0
00008020 <__stm32l4xx_veneer_2>:
8020: 4607 mov r7, r0
8022: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
8026: e897 0380 ldmia\.w r7, {r7, r8, r9}
802a: f000 b87f b\.w 812c <__stm32l4xx_veneer_2_r>
802e: de00 udf #0
00008030 <__stm32l4xx_veneer_3>:
8030: 460f mov r7, r1
8032: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
8036: e897 0380 ldmia\.w r7, {r7, r8, r9}
803a: f000 b879 b\.w 8130 <__stm32l4xx_veneer_3_r>
803e: de00 udf #0
00008040 <__stm32l4xx_veneer_4>:
8040: 4607 mov r7, r0
8042: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
8046: e897 8380 ldmia\.w r7, {r7, r8, r9, pc}
804a: de00 udf #0
804c: f7f0 a000 udf\.w #0
00008050 <__stm32l4xx_veneer_5>:
8050: 460f mov r7, r1
8052: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
8056: e897 8380 ldmia\.w r7, {r7, r8, r9, pc}
805a: de00 udf #0
805c: f7f0 a000 udf\.w #0
00008060 <__stm32l4xx_veneer_6>:
8060: e8b0 007e ldmia\.w r0!, {r1, r2, r3, r4, r5, r6}
8064: e8b0 0380 ldmia\.w r0!, {r7, r8, r9}
8068: f000 b868 b\.w 813c <__stm32l4xx_veneer_6_r>
806c: f7f0 a000 udf\.w #0
00008070 <__stm32l4xx_veneer_7>:
8070: e8b0 007e ldmia\.w r0!, {r1, r2, r3, r4, r5, r6}
8074: e8b0 8380 ldmia\.w r0!, {r7, r8, r9, pc}
8078: f7f0 a000 udf\.w #0
807c: f7f0 a000 udf\.w #0
00008080 <__stm32l4xx_veneer_8>:
8080: e931 0380 ldmdb r1!, {r7, r8, r9}
8084: e911 007e ldmdb r1, {r1, r2, r3, r4, r5, r6}
8088: f000 b85c b\.w 8144 <__stm32l4xx_veneer_8_r>
808c: f7f0 a000 udf\.w #0
00008090 <__stm32l4xx_veneer_9>:
8090: 4651 mov r1, sl
8092: e931 0380 ldmdb r1!, {r7, r8, r9}
8096: e911 007e ldmdb r1, {r1, r2, r3, r4, r5, r6}
809a: f000 b855 b\.w 8148 <__stm32l4xx_veneer_9_r>
809e: de00 udf #0
000080a0 <__stm32l4xx_veneer_a>:
80a0: 4649 mov r1, r9
80a2: e931 0380 ldmdb r1!, {r7, r8, r9}
80a6: e911 007e ldmdb r1, {r1, r2, r3, r4, r5, r6}
80aa: f000 b84f b\.w 814c <__stm32l4xx_veneer_a_r>
80ae: de00 udf #0
000080b0 <__stm32l4xx_veneer_b>:
80b0: f1a9 0928 sub\.w r9, r9, #40 ; 0x28
80b4: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6}
80b8: e899 8380 ldmia\.w r9, {r7, r8, r9, pc}
80bc: f7f0 a000 udf\.w #0
000080c0 <__stm32l4xx_veneer_c>:
80c0: f1a1 0728 sub\.w r7, r1, #40 ; 0x28
80c4: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
80c8: e897 8380 ldmia\.w r7, {r7, r8, r9, pc}
80cc: f7f0 a000 udf\.w #0
000080d0 <__stm32l4xx_veneer_d>:
80d0: f1a0 0728 sub\.w r7, r0, #40 ; 0x28
80d4: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
80d8: e897 8380 ldmia\.w r7, {r7, r8, r9, pc}
80dc: f7f0 a000 udf\.w #0
000080e0 <__stm32l4xx_veneer_e>:
80e0: e930 0380 ldmdb r0!, {r7, r8, r9}
80e4: e930 007e ldmdb r0!, {r1, r2, r3, r4, r5, r6}
80e8: f000 b838 b\.w 815c <__stm32l4xx_veneer_e_r>
80ec: f7f0 a000 udf\.w #0
000080f0 <__stm32l4xx_veneer_f>:
80f0: f1a0 0028 sub\.w r0, r0, #40 ; 0x28
80f4: 4607 mov r7, r0
80f6: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6}
80fa: e897 8380 ldmia\.w r7, {r7, r8, r9, pc}
80fe: de00 udf #0
00008100 <__stm32l4xx_veneer_10>:
8100: e8bd 007f ldmia\.w sp!, {r0, r1, r2, r3, r4, r5, r6}
8104: e8bd 0380 ldmia\.w sp!, {r7, r8, r9}
8108: f000 b82c b\.w 8164 <__stm32l4xx_veneer_10_r>
810c: f7f0 a000 udf\.w #0
00008110 <__stm32l4xx_veneer_11>:
8110: e8bd 007f ldmia\.w sp!, {r0, r1, r2, r3, r4, r5, r6}
8114: e8bd 8380 ldmia\.w sp!, {r7, r8, r9, pc}
8118: f7f0 a000 udf\.w #0
811c: f7f0 a000 udf\.w #0
00008120 <_start>:
8120: f7ff bf6e b\.w 8000 <__stm32l4xx_veneer_0>
00008124 <__stm32l4xx_veneer_0_r>:
8124: f7ff bf74 b\.w 8010 <__stm32l4xx_veneer_1>
00008128 <__stm32l4xx_veneer_1_r>:
8128: f7ff bf7a b\.w 8020 <__stm32l4xx_veneer_2>
0000812c <__stm32l4xx_veneer_2_r>:
812c: f7ff bf80 b\.w 8030 <__stm32l4xx_veneer_3>
00008130 <__stm32l4xx_veneer_3_r>:
8130: f7ff bf86 b\.w 8040 <__stm32l4xx_veneer_4>
00008134 <__stm32l4xx_veneer_4_r>:
8134: f7ff bf8c b\.w 8050 <__stm32l4xx_veneer_5>
00008138 <__stm32l4xx_veneer_5_r>:
8138: f7ff bf92 b\.w 8060 <__stm32l4xx_veneer_6>
0000813c <__stm32l4xx_veneer_6_r>:
813c: f7ff bf98 b\.w 8070 <__stm32l4xx_veneer_7>
00008140 <__stm32l4xx_veneer_7_r>:
8140: f7ff bf9e b\.w 8080 <__stm32l4xx_veneer_8>
00008144 <__stm32l4xx_veneer_8_r>:
8144: f7ff bfa4 b\.w 8090 <__stm32l4xx_veneer_9>
00008148 <__stm32l4xx_veneer_9_r>:
8148: f7ff bfaa b\.w 80a0 <__stm32l4xx_veneer_a>
0000814c <__stm32l4xx_veneer_a_r>:
814c: f7ff bfb0 b\.w 80b0 <__stm32l4xx_veneer_b>
00008150 <__stm32l4xx_veneer_b_r>:
8150: f7ff bfb6 b\.w 80c0 <__stm32l4xx_veneer_c>
00008154 <__stm32l4xx_veneer_c_r>:
8154: f7ff bfbc b\.w 80d0 <__stm32l4xx_veneer_d>
00008158 <__stm32l4xx_veneer_d_r>:
8158: f7ff bfc2 b\.w 80e0 <__stm32l4xx_veneer_e>
0000815c <__stm32l4xx_veneer_e_r>:
815c: f7ff bfc8 b\.w 80f0 <__stm32l4xx_veneer_f>
00008160 <__stm32l4xx_veneer_f_r>:
8160: f7ff bfce b\.w 8100 <__stm32l4xx_veneer_10>
00008164 <__stm32l4xx_veneer_10_r>:
8164: f7ff bfd4 b\.w 8110 <__stm32l4xx_veneer_11>

View File

@ -0,0 +1,147 @@
.syntax unified
.cpu cortex-m4
.fpu fpv4-sp-d16
.text
.align 1
.thumb
.thumb_func
.global _start
_start:
@ LDM CASE #1 (used when rx is in upper_list)
@ ldm rx, {...} ->
@ ldm rx!, {lower_list}
@ ldm rx, {upper_list}
@ b.w
ldm.w r9, {r1-r9}
@ LDM CASE #1 bis (used when rx is in upper_list and pc is
@ in reglist)
@ ldm rx, {...} ->
@ ldm rx!, {lower_list}
@ ldm rx, {upper_list}
ldm.w r9, {r1-r9, pc}
@ LDM CASE #2 (used when rx is not in upper_list)
@ ldm rx, {...} ->
@ mov ry, rx where ry is the lowest register from upper_list
@ ldm ry!, {lower_list}
@ ldm ry, {upper_list}
@ b.w
ldm.w r0, {r1-r9}
@ LDM CASE #2 bis (used when rx is in lower_list)
@ ldm rx, {...} ->
@ mov ry, rx where ry is the lowest register from upper_list
@ ldm ry!, {lower_list}
@ ldm ry, {upper_list}
@ b.w
ldm.w r1, {r1-r9}
@ LDM CASE #2 ter (used when rx is not in upper_list and pc is
@ in reglist)
@ ldm rx, {...} ->
@ mov ry, rx where ry is the lowest register from upper_list
@ ldm ry!, {lower_list}
@ ldm ry, {upper_list}
ldm.w r0, {r1-r9, pc}
@ LDM CASE #2 quater (used when rx is in lower_list and pc is
@ in reglist)
@ ldm rx, {...} ->
@ mov ry, rx where ry is the lowest register from upper_list
@ ldm ry!, {lower_list}
@ ldm ry, {upper_list}
ldm.w r1, {r1-r9, pc}
@ LDM CASE #3 (used when rx is not in upper_list)
@ ldm rx, {...} ->
@ ldm rx!, {lower_list}
@ ldm rx!, {upper_list}
@ b.w
@ Write-back variant are unpredictable when rx appears also in
@ the loaded registers
ldm.w r0!, {r1-r9}
@ LDM CASE #3 bis (used when rx is not in upper_list and pc is
@ in reglist)
@ ldm rx, {...} ->
@ ldm rx!, {lower_list}
@ ldm rx!, {upper_list}
ldm.w r0!, {r1-r9, pc}
@ LDM CASE #4 (used when pc is not in reglist and rx is in
@ lower_list)
@ ldmb rx, {...} ->
@ ldmb rx!, {upper_list}
@ ldmb rx, {lower_list}
ldmdb.w r1, {r1-r9}
@ LDM CASE #5 (used when pc is not in reglist and rx is not in
@ lower_list)
@ It looks like it this mean that it could be in upper_list or not
@ ldmdb rx, {...} ->
@ mov ry, rx where ry is the lowest register from lower_list
@ ldmdb ry!, {upper_list}
@ ldmdb ry , {lower_list}
@ b.w
ldmdb.w sl, {r1-r9}
@ LDM CASE #5 bis (used when pc is not in reglist and rx is in
@ upper_list)
@ ldmdb rx, {...} ->
@ mov ry, rx where ry is the lowest register from lower_list
@ ldmdb ry!, {upper_list}
@ ldmdb ry , {lower_list}
@ b.w
ldmdb.w r9, {r1-r9}
@ LDM CASE #6 (used when pc is in reglist and rx is in
@ upper_list)
@ ldmdb rx, {...} ->
@ sub rx, rx, #size (lower_list + upper_list)
@ ldm rx!, {lower_list}
@ ldm rx, {upper_list}
@ This case reverses the load order
ldmdb.w r9, {r1-r9, pc}
@ LDM CASE #6 bis (used when pc is in reglist and rx is in
@ lower_list)
@ ldmdb rx, {...} ->
@ sub rx, rx, #size (lower_list + upper_list)
@ ldm rx!, {lower_list}
@ ldm rx, {upper_list}
ldmdb.w r1, {r1-r9, pc}
@ LDM CASE #7 (used when pc is in reglist and rx is not in
@ upper_list)
@ ldmdb rx, {...} ->
@ sub ry, rx, #size (lower_list + upper_list) where ry is the lowest
@ register of the upper list
@ ldm ry!, {lower_list}
@ ldm ry , {upper_list}
@ This case reverses the load order
ldmdb.w r0, {r1-r9, pc}
@ LDM CASE #8 (used when pc is in not in reglist)
@ ldmdb rx!, {...} ->
@ ldm rx!, {upper_list}
@ ldm rx!, {lower_list}
@ b.w
ldmdb.w r0!, {r1-r9}
@ LDM CASE #9 (Used when pc is in reglist)
@ ldmdb rx!, {...} ->
@ sub rx, rx, #size (lower_list + upper_list)
@ mov ry, rx where ry is the lowest register from upper_list
@ ldm ry!, {lower_list}
@ ldm ry , {upper_list}
ldmdb.w r0!, {r1-r9, pc}
@ POP CASE #1 (list does not include pc)
@ pop {...} -> pop {lower_list} pop {upper_list}
@ b.w
pop {r0-r9}
@ POP CASE #2 (list includes PC)
@ pop {...} -> pop {lower_list} pop {upper_list}
pop {r0-r9, pc}

View File

@ -0,0 +1,49 @@
.*: file format elf32-littlearm.*
Disassembly of section \.text:
00008000 <__stm32l4xx_veneer_0>:
8000: ecf9 0a08 vldmia r9!, {s1-s8}
8004: ecf9 4a08 vldmia r9!, {s9-s16}
8008: ecf9 8a08 vldmia r9!, {s17-s24}
800c: ecf9 ca07 vldmia r9!, {s25-s31}
8010: f1a9 097c sub\.w r9, r9, #124 ; 0x7c
8014: f000 b826 b\.w 8064 <__stm32l4xx_veneer_0_r>
00008018 <__stm32l4xx_veneer_1>:
8018: ecf6 4a08 vldmia r6!, {s9-s16}
801c: ecf6 8a08 vldmia r6!, {s17-s24}
8020: ecf6 ca05 vldmia r6!, {s25-s29}
8024: f000 b820 b\.w 8068 <__stm32l4xx_veneer_1_r>
8028: f7f0 a000 udf\.w #0
802c: f7f0 a000 udf\.w #0
00008030 <__stm32l4xx_veneer_2>:
8030: ecfd 0a08 vpop {s1-s8}
8034: ecfd 4a01 vpop {s9}
8038: f000 b818 b\.w 806c <__stm32l4xx_veneer_2_r>
803c: f7f0 a000 udf\.w #0
8040: f7f0 a000 udf\.w #0
8044: f7f0 a000 udf\.w #0
00008048 <__stm32l4xx_veneer_3>:
8048: ed7b 0a08 vldmdb fp!, {s1-s8}
804c: ed7b 4a08 vldmdb fp!, {s9-s16}
8050: ed7b 8a08 vldmdb fp!, {s17-s24}
8054: ed7b ca07 vldmdb fp!, {s25-s31}
8058: f000 b80a b\.w 8070 <__stm32l4xx_veneer_3_r>
805c: f7f0 a000 udf\.w #0
00008060 <_start>:
8060: f7ff bfce b\.w 8000 <__stm32l4xx_veneer_0>
00008064 <__stm32l4xx_veneer_0_r>:
8064: f7ff bfd8 b\.w 8018 <__stm32l4xx_veneer_1>
00008068 <__stm32l4xx_veneer_1_r>:
8068: f7ff bfe2 b\.w 8030 <__stm32l4xx_veneer_2>
0000806c <__stm32l4xx_veneer_2_r>:
806c: f7ff bfec b\.w 8048 <__stm32l4xx_veneer_3>

View File

@ -0,0 +1,26 @@
.syntax unified
.cpu cortex-m4
.fpu fpv4-sp-d16
.text
.align 1
.thumb
.thumb_func
.global _start
_start:
@ VLDM CASE #1
@ vldm rx, {...}
@ -> vldm rx!, {8_words_or_less} for each
@ -> sub rx, rx, #size (list)
vldm r9, {s1-s31}
@ VLDM CASE #2
@ vldm rx!, {...}
@ -> vldm rx!, {8_words_or_less} for each needed 8_word
@ This also handles vpop instruction (when rx is sp)
vldm r6!, {s9-s29}
@ Explicit VPOP test
vpop {s1-s9}
@ vldmd rx!, {...}
@ -> vldmb rx!, {8_words_or_less} for each needed 8_word
vldmdb r11!, {s1-s31}