mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 05:47:26 +08:00
gas: arm: handle multiple .directives on a single line (PR29519)
There's been a long-standing bug in the arm backend where target-specific directives did not correctly handle lines with multiple statements. This patch fixes the issue for all the cases I've been able to find. It does result in a slight change in behaviour when errors are encountered: where, previously, .cpu arm6 bar would result in the error "junk at end of line, first unrecognized character is `b'", we now get "unknown cpu `arm6 bar'", which I think is slightly more helpful anyway. Similar errors are generated for other directives.
This commit is contained in:
@ -2851,12 +2851,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)
|
|||||||
char saved_char;
|
char saved_char;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
|
input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
|
||||||
while (*input_line_pointer != 0
|
|
||||||
&& *input_line_pointer != ' '
|
|
||||||
&& *input_line_pointer != '\n')
|
|
||||||
++input_line_pointer;
|
|
||||||
|
|
||||||
saved_char = *input_line_pointer;
|
saved_char = *input_line_pointer;
|
||||||
*input_line_pointer = 0;
|
*input_line_pointer = 0;
|
||||||
|
|
||||||
@ -3208,6 +3203,7 @@ s_code (int unused ATTRIBUTE_UNUSED)
|
|||||||
default:
|
default:
|
||||||
as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
|
as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
|
||||||
}
|
}
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3230,7 +3226,7 @@ s_force_thumb (int ignore ATTRIBUTE_UNUSED)
|
|||||||
static void
|
static void
|
||||||
s_thumb_func (int ignore ATTRIBUTE_UNUSED)
|
s_thumb_func (int ignore ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
s_thumb (0);
|
s_thumb (0); /* Will check for end-of-line. */
|
||||||
|
|
||||||
/* The following label is the name/address of the start of a Thumb function.
|
/* The following label is the name/address of the start of a Thumb function.
|
||||||
We need to know this for the interworking support. */
|
We need to know this for the interworking support. */
|
||||||
@ -3781,6 +3777,7 @@ s_ltorg (int ignored ATTRIBUTE_UNUSED)
|
|||||||
literal_pool * pool;
|
literal_pool * pool;
|
||||||
char sym_name[20];
|
char sym_name[20];
|
||||||
|
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
pool = find_literal_pool ();
|
pool = find_literal_pool ();
|
||||||
if (pool == NULL
|
if (pool == NULL
|
||||||
|| pool->symbol == NULL
|
|| pool->symbol == NULL
|
||||||
@ -33365,11 +33362,17 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
|
|||||||
char saved_char;
|
char saved_char;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
|
||||||
input_line_pointer++;
|
|
||||||
saved_char = *input_line_pointer;
|
saved_char = *input_line_pointer;
|
||||||
*input_line_pointer = 0;
|
*input_line_pointer = 0;
|
||||||
|
|
||||||
|
if (!*name)
|
||||||
|
{
|
||||||
|
as_bad (_(".cpu: missing cpu name"));
|
||||||
|
*input_line_pointer = saved_char;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip the first "all" entry. */
|
/* Skip the first "all" entry. */
|
||||||
for (opt = arm_cpus + 1; opt->name != NULL; opt++)
|
for (opt = arm_cpus + 1; opt->name != NULL; opt++)
|
||||||
if (streq (opt->name, name))
|
if (streq (opt->name, name))
|
||||||
@ -33395,7 +33398,6 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
|
|||||||
}
|
}
|
||||||
as_bad (_("unknown cpu `%s'"), name);
|
as_bad (_("unknown cpu `%s'"), name);
|
||||||
*input_line_pointer = saved_char;
|
*input_line_pointer = saved_char;
|
||||||
ignore_rest_of_line ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a .arch directive. */
|
/* Parse a .arch directive. */
|
||||||
@ -33408,11 +33410,17 @@ s_arm_arch (int ignored ATTRIBUTE_UNUSED)
|
|||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
|
||||||
input_line_pointer++;
|
|
||||||
saved_char = *input_line_pointer;
|
saved_char = *input_line_pointer;
|
||||||
*input_line_pointer = 0;
|
*input_line_pointer = 0;
|
||||||
|
|
||||||
|
if (!*name)
|
||||||
|
{
|
||||||
|
as_bad (_(".arch: missing architecture name"));
|
||||||
|
*input_line_pointer = saved_char;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip the first "all" entry. */
|
/* Skip the first "all" entry. */
|
||||||
for (opt = arm_archs + 1; opt->name != NULL; opt++)
|
for (opt = arm_archs + 1; opt->name != NULL; opt++)
|
||||||
if (streq (opt->name, name))
|
if (streq (opt->name, name))
|
||||||
@ -33443,11 +33451,17 @@ s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
|
|||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
|
||||||
input_line_pointer++;
|
|
||||||
saved_char = *input_line_pointer;
|
saved_char = *input_line_pointer;
|
||||||
*input_line_pointer = 0;
|
*input_line_pointer = 0;
|
||||||
|
|
||||||
|
if (!*name)
|
||||||
|
{
|
||||||
|
as_bad (_(".object_arch: missing architecture name"));
|
||||||
|
*input_line_pointer = saved_char;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip the first "all" entry. */
|
/* Skip the first "all" entry. */
|
||||||
for (opt = arm_archs + 1; opt->name != NULL; opt++)
|
for (opt = arm_archs + 1; opt->name != NULL; opt++)
|
||||||
if (streq (opt->name, name))
|
if (streq (opt->name, name))
|
||||||
@ -33474,11 +33488,17 @@ s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
|
|||||||
int adding_value = 1;
|
int adding_value = 1;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
|
||||||
input_line_pointer++;
|
|
||||||
saved_char = *input_line_pointer;
|
saved_char = *input_line_pointer;
|
||||||
*input_line_pointer = 0;
|
*input_line_pointer = 0;
|
||||||
|
|
||||||
|
if (!*name)
|
||||||
|
{
|
||||||
|
as_bad (_(".arch_extension: missing architecture extension"));
|
||||||
|
*input_line_pointer = saved_char;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen (name) >= 2
|
if (strlen (name) >= 2
|
||||||
&& startswith (name, "no"))
|
&& startswith (name, "no"))
|
||||||
{
|
{
|
||||||
@ -33557,7 +33577,6 @@ s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
|
|||||||
as_bad (_("unknown architecture extension `%s'\n"), name);
|
as_bad (_("unknown architecture extension `%s'\n"), name);
|
||||||
|
|
||||||
*input_line_pointer = saved_char;
|
*input_line_pointer = saved_char;
|
||||||
ignore_rest_of_line ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a .fpu directive. */
|
/* Parse a .fpu directive. */
|
||||||
@ -33570,11 +33589,17 @@ s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
|
|||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = input_line_pointer;
|
name = input_line_pointer;
|
||||||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
|
||||||
input_line_pointer++;
|
|
||||||
saved_char = *input_line_pointer;
|
saved_char = *input_line_pointer;
|
||||||
*input_line_pointer = 0;
|
*input_line_pointer = 0;
|
||||||
|
|
||||||
|
if (!*name)
|
||||||
|
{
|
||||||
|
as_bad (_(".fpu: missing fpu name"));
|
||||||
|
*input_line_pointer = saved_char;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (opt = arm_fpus; opt->name != NULL; opt++)
|
for (opt = arm_fpus; opt->name != NULL; opt++)
|
||||||
if (streq (opt->name, name))
|
if (streq (opt->name, name))
|
||||||
{
|
{
|
||||||
@ -33587,7 +33612,6 @@ s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
|
|||||||
#endif
|
#endif
|
||||||
ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
|
ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
|
||||||
*input_line_pointer = saved_char;
|
*input_line_pointer = saved_char;
|
||||||
demand_empty_rest_of_line ();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
gas/testsuite/gas/arm/directives.d
Normal file
18
gas/testsuite/gas/arm/directives.d
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# name: multiple directives on one line
|
||||||
|
# source: directives.s
|
||||||
|
# as: --fatal-warnings
|
||||||
|
# readelf: -A
|
||||||
|
# This test is only valid on EABI based ports.
|
||||||
|
# target: *-*-*eabi* *-*-nacl*
|
||||||
|
|
||||||
|
Attribute Section: aeabi
|
||||||
|
File Attributes
|
||||||
|
Tag_CPU_name: "custom_name"
|
||||||
|
Tag_CPU_arch: v8
|
||||||
|
Tag_CPU_arch_profile: Application
|
||||||
|
Tag_ARM_ISA_use: Yes
|
||||||
|
Tag_THUMB_ISA_use: Thumb-2
|
||||||
|
Tag_FP_arch: FP for ARMv8
|
||||||
|
Tag_ABI_align_preserved: 8-byte, except leaf SP
|
||||||
|
Tag_MPextension_use: Allowed
|
||||||
|
Tag_Virtualization_use: TrustZone and Virtualization Extensions
|
11
gas/testsuite/gas/arm/directives.s
Normal file
11
gas/testsuite/gas/arm/directives.s
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
@ Check that various arm-specific directives can appear on the same line
|
||||||
|
.cpu cortex-a5 ; .arch armv8-a ; .arch_extension fp ; .arch_extension nosimd ; .syntax unified ; .thumb; .code 16 ; movs r0, r1
|
||||||
|
t1 .req r1 ; t2 .req r2 ;
|
||||||
|
movs t1, t2 @ mov r1, r2
|
||||||
|
|
||||||
|
.unreq t1;.unreq t2;
|
||||||
|
t1 .req r2
|
||||||
|
t2 .req r3
|
||||||
|
movs t1, t2 @ movs r2, r3
|
||||||
|
vmov.f32 s0, s1
|
||||||
|
.eabi_attribute Tag_CPU_name, "custom_name" ; .eabi_attribute Tag_ABI_align8_preserved, 1;
|
Reference in New Issue
Block a user