binutils/testsuite/
* binutils-all/arm/thumb2-cond.s: Use instructions instead of .short. gas/ * config/obj-elf.c (obj_elf_ident): Notify section change to the hook. * config/tc-arm.c (make_mapping_symbol): New function, from mapping_state. Save mapping symbols in the frag. (insert_data_mapping_symbol): New. (mapping_state): Use make_mapping_symbol, improve state transitions. (mapping_state_2): New. Provide dummy definition. (opcode_select): Do not call mapping_state. (s_bss): Call md_elf_section_change_hook instead of mapping_state. (output_inst): Update use of tc_frag_data. (new_automatic_it_block): Call mapping_state before emitting the IT instruction. (md_assemble): Move mapping_state to just before outputting the new instruction. (arm_handle_align): Update use of tc_frag_data. Call insert_data_mapping_symbol. (arm_init_frag): Update use of tc_frag_data. Call mapping_state_2. (arm_elf_change_section): Always update the mapping symbol FSM state. (check_mapping_symbols): New function. (arm_adjust_symtab): Use check_mapping_symbols. * config/tc-arm.h (struct arm_frag_type): New. (TC_FRAG_TYPE): Change to struct arm_frag_type. (TC_FRAG_INIT): Pass max_chars. (arm_init_frag): Update prototype. gas/testsuite/ * gas/arm/mapdir.d, gas/arm/mapdir.s: New files. * gas/arm/mapping.d: Adapted to new symbols generation. * gas/arm/mapping2.d: New test case. * gas/arm/mapping2.s: New file. * gas/arm/mapping3.d: New test case. * gas/arm/mapping3.s: New file. * gas/arm/mapping4.d: New test case. * gas/arm/mapping4.s: New file. * gas/arm/mapshort-eabi.d: Adapted to new symbols generation. * gas/elf/section2.e-armeabi: Adapted to new symbols generation.
This commit is contained in:
parent
79d0a52d5d
commit
cd000bffb2
24 changed files with 467 additions and 49 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2009-07-31 Daniel Gutson <dgutson@codesourcery.com>
|
||||||
|
Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
|
* binutils-all/arm/thumb2-cond.s: Use instructions instead of
|
||||||
|
.short.
|
||||||
|
|
||||||
2009-07-29 Alan Modra <amodra@bigpond.net.au>
|
2009-07-29 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* binutils-all/testranges.s: Replace .value with .short.
|
* binutils-all/testranges.s: Replace .value with .short.
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
.thumb
|
.arch armv7
|
||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
foo:
|
foo:
|
||||||
.short 0xf000, 0xf800
|
bl 1f
|
||||||
.short 0xbf38
|
1: it cc
|
||||||
.short 0xf000, 0xbf04
|
bcc.w .+0xe0c
|
||||||
bx lr
|
bx lr
|
||||||
|
|
|
@ -1,3 +1,31 @@
|
||||||
|
2009-07-31 Daniel Gutson <dgutson@codesourcery.com>
|
||||||
|
Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
|
* config/obj-elf.c (obj_elf_ident): Notify section change to the hook.
|
||||||
|
* config/tc-arm.c (make_mapping_symbol): New function, from
|
||||||
|
mapping_state. Save mapping symbols in the frag.
|
||||||
|
(insert_data_mapping_symbol): New.
|
||||||
|
(mapping_state): Use make_mapping_symbol, improve state transitions.
|
||||||
|
(mapping_state_2): New. Provide dummy definition.
|
||||||
|
(opcode_select): Do not call mapping_state.
|
||||||
|
(s_bss): Call md_elf_section_change_hook instead of mapping_state.
|
||||||
|
(output_inst): Update use of tc_frag_data.
|
||||||
|
(new_automatic_it_block): Call mapping_state before emitting the
|
||||||
|
IT instruction.
|
||||||
|
(md_assemble): Move mapping_state to just before outputting the
|
||||||
|
new instruction.
|
||||||
|
(arm_handle_align): Update use of tc_frag_data.
|
||||||
|
Call insert_data_mapping_symbol.
|
||||||
|
(arm_init_frag): Update use of tc_frag_data. Call
|
||||||
|
mapping_state_2.
|
||||||
|
(arm_elf_change_section): Always update the mapping symbol FSM state.
|
||||||
|
(check_mapping_symbols): New function.
|
||||||
|
(arm_adjust_symtab): Use check_mapping_symbols.
|
||||||
|
* config/tc-arm.h (struct arm_frag_type): New.
|
||||||
|
(TC_FRAG_TYPE): Change to struct arm_frag_type.
|
||||||
|
(TC_FRAG_INIT): Pass max_chars.
|
||||||
|
(arm_init_frag): Update prototype.
|
||||||
|
|
||||||
2009-07-31 Anthony Green <green@moxielogic.com>
|
2009-07-31 Anthony Green <green@moxielogic.com>
|
||||||
|
|
||||||
* configure.tgt (generic_target): Add moxie-uclinux support.
|
* configure.tgt (generic_target): Add moxie-uclinux support.
|
||||||
|
|
|
@ -1737,6 +1737,9 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
|
||||||
SEC_READONLY | SEC_HAS_CONTENTS
|
SEC_READONLY | SEC_HAS_CONTENTS
|
||||||
| SEC_MERGE | SEC_STRINGS);
|
| SEC_MERGE | SEC_STRINGS);
|
||||||
comment_section->entsize = 1;
|
comment_section->entsize = 1;
|
||||||
|
#ifdef md_elf_section_change_hook
|
||||||
|
md_elf_section_change_hook ();
|
||||||
|
#endif
|
||||||
p = frag_more (1);
|
p = frag_more (1);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2433,20 +2433,15 @@ s_unreq (int a ATTRIBUTE_UNUSED)
|
||||||
|
|
||||||
static enum mstate mapstate = MAP_UNDEFINED;
|
static enum mstate mapstate = MAP_UNDEFINED;
|
||||||
|
|
||||||
void
|
/* Create a new mapping symbol for the transition to STATE. */
|
||||||
mapping_state (enum mstate state)
|
|
||||||
|
static void
|
||||||
|
make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
|
||||||
{
|
{
|
||||||
symbolS * symbolP;
|
symbolS * symbolP;
|
||||||
const char * symname;
|
const char * symname;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
if (mapstate == state)
|
|
||||||
/* The mapping symbol has already been emitted.
|
|
||||||
There is nothing else to do. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
mapstate = state;
|
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case MAP_DATA:
|
case MAP_DATA:
|
||||||
|
@ -2461,16 +2456,11 @@ mapping_state (enum mstate state)
|
||||||
symname = "$t";
|
symname = "$t";
|
||||||
type = BSF_NO_FLAGS;
|
type = BSF_NO_FLAGS;
|
||||||
break;
|
break;
|
||||||
case MAP_UNDEFINED:
|
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
seg_info (now_seg)->tc_segment_info_data.mapstate = state;
|
symbolP = symbol_new (symname, now_seg, value, frag);
|
||||||
|
|
||||||
symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
|
|
||||||
symbol_table_insert (symbolP);
|
|
||||||
symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
|
symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
|
@ -2489,11 +2479,103 @@ mapping_state (enum mstate state)
|
||||||
|
|
||||||
case MAP_DATA:
|
case MAP_DATA:
|
||||||
default:
|
default:
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the mapping symbols for future reference. Also check that
|
||||||
|
we do not place two mapping symbols at the same offset within a
|
||||||
|
frag. We'll handle overlap between frags in
|
||||||
|
check_mapping_symbols. */
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
know (frag->tc_frag_data.first_map == NULL);
|
||||||
|
frag->tc_frag_data.first_map = symbolP;
|
||||||
|
}
|
||||||
|
if (frag->tc_frag_data.last_map != NULL)
|
||||||
|
know (S_GET_VALUE (frag->tc_frag_data.last_map) < S_GET_VALUE (symbolP));
|
||||||
|
frag->tc_frag_data.last_map = symbolP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We must sometimes convert a region marked as code to data during
|
||||||
|
code alignment, if an odd number of bytes have to be padded. The
|
||||||
|
code mapping symbol is pushed to an aligned address. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
insert_data_mapping_symbol (enum mstate state,
|
||||||
|
valueT value, fragS *frag, offsetT bytes)
|
||||||
|
{
|
||||||
|
/* If there was already a mapping symbol, remove it. */
|
||||||
|
if (frag->tc_frag_data.last_map != NULL
|
||||||
|
&& S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
|
||||||
|
{
|
||||||
|
symbolS *symp = frag->tc_frag_data.last_map;
|
||||||
|
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
know (frag->tc_frag_data.first_map == symp);
|
||||||
|
frag->tc_frag_data.first_map = NULL;
|
||||||
|
}
|
||||||
|
frag->tc_frag_data.last_map = NULL;
|
||||||
|
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
|
||||||
|
}
|
||||||
|
|
||||||
|
make_mapping_symbol (MAP_DATA, value, frag);
|
||||||
|
make_mapping_symbol (state, value + bytes, frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mapping_state_2 (enum mstate state, int max_chars);
|
||||||
|
|
||||||
|
/* Set the mapping state to STATE. Only call this when about to
|
||||||
|
emit some STATE bytes to the file. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mapping_state (enum mstate state)
|
||||||
|
{
|
||||||
|
#define TRANSITION(from, to) (mapstate == (from) && state == (to))
|
||||||
|
|
||||||
|
if (mapstate == state)
|
||||||
|
/* The mapping symbol has already been emitted.
|
||||||
|
There is nothing else to do. */
|
||||||
|
return;
|
||||||
|
else if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
|
||||||
|
/* This case will be evaluated later in the next else. */
|
||||||
|
return;
|
||||||
|
else if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
|
||||||
|
|| TRANSITION (MAP_UNDEFINED, MAP_THUMB))
|
||||||
|
{
|
||||||
|
/* Only add the symbol if the offset is > 0:
|
||||||
|
if we're at the first frag, check it's size > 0;
|
||||||
|
if we're not at the first frag, then for sure
|
||||||
|
the offset is > 0. */
|
||||||
|
struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
|
||||||
|
const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
|
||||||
|
|
||||||
|
if (add_symbol)
|
||||||
|
make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping_state_2 (state, 0);
|
||||||
|
#undef TRANSITION
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same as mapping_state, but MAX_CHARS bytes have already been
|
||||||
|
allocated. Put the mapping symbol that far back. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
mapping_state_2 (enum mstate state, int max_chars)
|
||||||
|
{
|
||||||
|
if (mapstate == state)
|
||||||
|
/* The mapping symbol has already been emitted.
|
||||||
|
There is nothing else to do. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
mapstate = state;
|
||||||
|
seg_info (now_seg)->tc_segment_info_data.mapstate = state;
|
||||||
|
make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define mapping_state(x) /* nothing */
|
#define mapping_state(x) /* nothing */
|
||||||
|
#define mapping_state_2(x, y) /* nothing */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find the real, Thumb encoded start of a Thumb function. */
|
/* Find the real, Thumb encoded start of a Thumb function. */
|
||||||
|
@ -2549,7 +2631,6 @@ opcode_select (int width)
|
||||||
coming from ARM mode, which is word-aligned. */
|
coming from ARM mode, which is word-aligned. */
|
||||||
record_alignment (now_seg, 1);
|
record_alignment (now_seg, 1);
|
||||||
}
|
}
|
||||||
mapping_state (MAP_THUMB);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
|
@ -2565,7 +2646,6 @@ opcode_select (int width)
|
||||||
|
|
||||||
record_alignment (now_seg, 1);
|
record_alignment (now_seg, 1);
|
||||||
}
|
}
|
||||||
mapping_state (MAP_ARM);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2804,7 +2884,10 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
|
||||||
marking in_bss, then looking at s_skip for clues. */
|
marking in_bss, then looking at s_skip for clues. */
|
||||||
subseg_set (bss_section, 0);
|
subseg_set (bss_section, 0);
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
mapping_state (MAP_DATA);
|
|
||||||
|
#ifdef md_elf_section_change_hook
|
||||||
|
md_elf_section_change_hook ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -14711,7 +14794,7 @@ output_inst (const char * str)
|
||||||
what type of NOP padding to use, if necessary. We override any previous
|
what type of NOP padding to use, if necessary. We override any previous
|
||||||
setting so that if the mode has changed then the NOPS that we use will
|
setting so that if the mode has changed then the NOPS that we use will
|
||||||
match the encoding of the last instruction in the frag. */
|
match the encoding of the last instruction in the frag. */
|
||||||
frag_now->tc_frag_data = thumb_mode | MODE_RECORDED;
|
frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
|
||||||
|
|
||||||
if (thumb_mode && (inst.size > THUMB_SIZE))
|
if (thumb_mode && (inst.size > THUMB_SIZE))
|
||||||
{
|
{
|
||||||
|
@ -15015,6 +15098,7 @@ new_automatic_it_block (int cond)
|
||||||
now_it.mask = 0x18;
|
now_it.mask = 0x18;
|
||||||
now_it.cc = cond;
|
now_it.cc = cond;
|
||||||
now_it.block_length = 1;
|
now_it.block_length = 1;
|
||||||
|
mapping_state (MAP_THUMB);
|
||||||
now_it.insn = output_it_inst (cond, now_it.mask, NULL);
|
now_it.insn = output_it_inst (cond, now_it.mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15393,7 +15477,6 @@ md_assemble (char *str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping_state (MAP_THUMB);
|
|
||||||
inst.instruction = opcode->tvalue;
|
inst.instruction = opcode->tvalue;
|
||||||
|
|
||||||
if (!parse_operands (p, opcode->operands))
|
if (!parse_operands (p, opcode->operands))
|
||||||
|
@ -15434,6 +15517,9 @@ md_assemble (char *str)
|
||||||
|| ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier)))
|
|| ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier)))
|
||||||
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
|
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
|
||||||
arm_ext_v6t2);
|
arm_ext_v6t2);
|
||||||
|
|
||||||
|
if (!inst.error)
|
||||||
|
mapping_state (MAP_THUMB);
|
||||||
}
|
}
|
||||||
else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
|
else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
|
||||||
{
|
{
|
||||||
|
@ -15456,7 +15542,6 @@ md_assemble (char *str)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping_state (MAP_ARM);
|
|
||||||
inst.instruction = opcode->avalue;
|
inst.instruction = opcode->avalue;
|
||||||
if (opcode->tag == OT_unconditionalF)
|
if (opcode->tag == OT_unconditionalF)
|
||||||
inst.instruction |= 0xF << 28;
|
inst.instruction |= 0xF << 28;
|
||||||
|
@ -15476,6 +15561,8 @@ md_assemble (char *str)
|
||||||
else
|
else
|
||||||
ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
|
ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
|
||||||
*opcode->avariant);
|
*opcode->avariant);
|
||||||
|
if (!inst.error)
|
||||||
|
mapping_state (MAP_ARM);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -18309,6 +18396,9 @@ arm_handle_align (fragS * fragP)
|
||||||
char * p;
|
char * p;
|
||||||
const char * noop;
|
const char * noop;
|
||||||
const char *narrow_noop = NULL;
|
const char *narrow_noop = NULL;
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
enum mstate state;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fragP->fr_type != rs_align_code)
|
if (fragP->fr_type != rs_align_code)
|
||||||
return;
|
return;
|
||||||
|
@ -18320,9 +18410,9 @@ arm_handle_align (fragS * fragP)
|
||||||
if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
|
if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
|
||||||
bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
|
bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
|
||||||
|
|
||||||
gas_assert ((fragP->tc_frag_data & MODE_RECORDED) != 0);
|
gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
|
||||||
|
|
||||||
if (fragP->tc_frag_data & (~ MODE_RECORDED))
|
if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
|
||||||
{
|
{
|
||||||
if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
|
if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
|
||||||
{
|
{
|
||||||
|
@ -18332,12 +18422,18 @@ arm_handle_align (fragS * fragP)
|
||||||
else
|
else
|
||||||
noop = thumb_noop[0][target_big_endian];
|
noop = thumb_noop[0][target_big_endian];
|
||||||
noop_size = 2;
|
noop_size = 2;
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
state = MAP_THUMB;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k) != 0]
|
noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k) != 0]
|
||||||
[target_big_endian];
|
[target_big_endian];
|
||||||
noop_size = 4;
|
noop_size = 4;
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
state = MAP_ARM;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fragP->fr_var = noop_size;
|
fragP->fr_var = noop_size;
|
||||||
|
@ -18345,6 +18441,9 @@ arm_handle_align (fragS * fragP)
|
||||||
if (bytes & (noop_size - 1))
|
if (bytes & (noop_size - 1))
|
||||||
{
|
{
|
||||||
fix = bytes & (noop_size - 1);
|
fix = bytes & (noop_size - 1);
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
|
||||||
|
#endif
|
||||||
memset (p, 0, fix);
|
memset (p, 0, fix);
|
||||||
p += fix;
|
p += fix;
|
||||||
bytes -= fix;
|
bytes -= fix;
|
||||||
|
@ -18412,22 +18511,47 @@ arm_frag_align_code (int n, int max)
|
||||||
and used a long time before its type is set, so beware of assuming that
|
and used a long time before its type is set, so beware of assuming that
|
||||||
this initialisationis performed first. */
|
this initialisationis performed first. */
|
||||||
|
|
||||||
|
#ifndef OBJ_ELF
|
||||||
void
|
void
|
||||||
arm_init_frag (fragS * fragP)
|
arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
/* Record whether this frag is in an ARM or a THUMB area. */
|
||||||
|
fragP->tc_frag_data.thumb_mode = thumb_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* OBJ_ELF is defined. */
|
||||||
|
void
|
||||||
|
arm_init_frag (fragS * fragP, int max_chars)
|
||||||
{
|
{
|
||||||
/* If the current ARM vs THUMB mode has not already
|
/* If the current ARM vs THUMB mode has not already
|
||||||
been recorded into this frag then do so now. */
|
been recorded into this frag then do so now. */
|
||||||
if ((fragP->tc_frag_data & MODE_RECORDED) == 0)
|
if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
|
||||||
fragP->tc_frag_data = thumb_mode | MODE_RECORDED;
|
{
|
||||||
|
fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
|
||||||
|
|
||||||
|
/* Record a mapping symbol for alignment frags. We will delete this
|
||||||
|
later if the alignment ends up empty. */
|
||||||
|
switch (fragP->fr_type)
|
||||||
|
{
|
||||||
|
case rs_align:
|
||||||
|
case rs_align_test:
|
||||||
|
case rs_fill:
|
||||||
|
mapping_state_2 (MAP_DATA, max_chars);
|
||||||
|
break;
|
||||||
|
case rs_align_code:
|
||||||
|
mapping_state_2 (thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OBJ_ELF
|
|
||||||
/* When we change sections we need to issue a new mapping symbol. */
|
/* When we change sections we need to issue a new mapping symbol. */
|
||||||
|
|
||||||
void
|
void
|
||||||
arm_elf_change_section (void)
|
arm_elf_change_section (void)
|
||||||
{
|
{
|
||||||
flagword flags;
|
|
||||||
segment_info_type *seginfo;
|
segment_info_type *seginfo;
|
||||||
|
|
||||||
/* Link an unlinked unwind index table section to the .text section. */
|
/* Link an unlinked unwind index table section to the .text section. */
|
||||||
|
@ -18438,15 +18562,9 @@ arm_elf_change_section (void)
|
||||||
if (!SEG_NORMAL (now_seg))
|
if (!SEG_NORMAL (now_seg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flags = bfd_get_section_flags (stdoutput, now_seg);
|
|
||||||
|
|
||||||
/* We can ignore sections that only contain debug info. */
|
|
||||||
if ((flags & SEC_ALLOC) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
seginfo = seg_info (now_seg);
|
seginfo = seg_info (now_seg);
|
||||||
mapstate = seginfo->tc_segment_info_data.mapstate;
|
|
||||||
marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency;
|
marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency;
|
||||||
|
mapstate = seginfo->tc_segment_info_data.mapstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -20985,6 +21103,73 @@ arm_cleanup (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
/* Remove any excess mapping symbols generated for alignment frags in
|
||||||
|
SEC. We may have created a mapping symbol before a zero byte
|
||||||
|
alignment; remove it if there's a mapping symbol after the
|
||||||
|
alignment. */
|
||||||
|
static void
|
||||||
|
check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
|
||||||
|
void *dummy ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
segment_info_type *seginfo = seg_info (sec);
|
||||||
|
fragS *fragp;
|
||||||
|
|
||||||
|
if (seginfo == NULL || seginfo->frchainP == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (fragp = seginfo->frchainP->frch_root;
|
||||||
|
fragp != NULL;
|
||||||
|
fragp = fragp->fr_next)
|
||||||
|
{
|
||||||
|
symbolS *sym = fragp->tc_frag_data.last_map;
|
||||||
|
fragS *next = fragp->fr_next;
|
||||||
|
|
||||||
|
/* Variable-sized frags have been converted to fixed size by
|
||||||
|
this point. But if this was variable-sized to start with,
|
||||||
|
there will be a fixed-size frag after it. So don't handle
|
||||||
|
next == NULL. */
|
||||||
|
if (sym == NULL || next == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (S_GET_VALUE (sym) < next->fr_address)
|
||||||
|
/* Not at the end of this frag. */
|
||||||
|
continue;
|
||||||
|
know (S_GET_VALUE (sym) == next->fr_address);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (next->tc_frag_data.first_map != NULL)
|
||||||
|
{
|
||||||
|
/* Next frag starts with a mapping symbol. Discard this
|
||||||
|
one. */
|
||||||
|
symbol_remove (sym, &symbol_rootP, &symbol_lastP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next->fr_next == NULL)
|
||||||
|
{
|
||||||
|
/* This mapping symbol is at the end of the section. Discard
|
||||||
|
it. */
|
||||||
|
know (next->fr_fix == 0 && next->fr_var == 0);
|
||||||
|
symbol_remove (sym, &symbol_rootP, &symbol_lastP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As long as we have empty frags without any mapping symbols,
|
||||||
|
keep looking. */
|
||||||
|
/* If the next frag is non-empty and does not start with a
|
||||||
|
mapping symbol, then this mapping symbol is required. */
|
||||||
|
if (next->fr_address != next->fr_next->fr_address)
|
||||||
|
break;
|
||||||
|
|
||||||
|
next = next->fr_next;
|
||||||
|
}
|
||||||
|
while (next != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Adjust the symbol table. This marks Thumb symbols as distinct from
|
/* Adjust the symbol table. This marks Thumb symbols as distinct from
|
||||||
ARM ones. */
|
ARM ones. */
|
||||||
|
|
||||||
|
@ -21059,6 +21244,9 @@ arm_adjust_symtab (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove any overlapping mapping symbols generated by alignment frags. */
|
||||||
|
bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,8 +199,21 @@ void arm_copy_symbol_attributes (symbolS *, symbolS *);
|
||||||
/* For frags in code sections we need to record whether they contain
|
/* For frags in code sections we need to record whether they contain
|
||||||
ARM code or THUMB code. This is that if they have to be aligned,
|
ARM code or THUMB code. This is that if they have to be aligned,
|
||||||
they can contain the correct type of no-op instruction. */
|
they can contain the correct type of no-op instruction. */
|
||||||
#define TC_FRAG_TYPE int
|
struct arm_frag_type
|
||||||
#define TC_FRAG_INIT(fragp) arm_init_frag (fragp)
|
{
|
||||||
|
int thumb_mode;
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
/* If there is a mapping symbol at offset 0 in this frag,
|
||||||
|
it will be saved in FIRST_MAP. If there are any mapping
|
||||||
|
symbols in this frag, the last one will be saved in
|
||||||
|
LAST_MAP. */
|
||||||
|
symbolS *first_map, *last_map;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TC_FRAG_TYPE struct arm_frag_type
|
||||||
|
/* NOTE: max_chars is a local variable from frag_var / frag_variant. */
|
||||||
|
#define TC_FRAG_INIT(fragp) arm_init_frag (fragp, max_chars)
|
||||||
#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
|
#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
|
||||||
|
|
||||||
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
|
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
|
||||||
|
@ -307,7 +320,7 @@ extern char * arm_canonicalize_symbol_name (char *);
|
||||||
extern void arm_adjust_symtab (void);
|
extern void arm_adjust_symtab (void);
|
||||||
extern void armelf_frob_symbol (symbolS *, int *);
|
extern void armelf_frob_symbol (symbolS *, int *);
|
||||||
extern void cons_fix_new_arm (fragS *, int, int, expressionS *);
|
extern void cons_fix_new_arm (fragS *, int, int, expressionS *);
|
||||||
extern void arm_init_frag (struct frag *);
|
extern void arm_init_frag (struct frag *, int);
|
||||||
extern void arm_handle_align (struct frag *);
|
extern void arm_handle_align (struct frag *);
|
||||||
extern bfd_boolean arm_fix_adjustable (struct fix *);
|
extern bfd_boolean arm_fix_adjustable (struct fix *);
|
||||||
extern int arm_elf_section_type (const char *, size_t);
|
extern int arm_elf_section_type (const char *, size_t);
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
2009-07-15 Daniel Gutson <dgutson@codesourcery.com>
|
||||||
|
Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
|
* gas/arm/mapdir.d, gas/arm/mapdir.s: New files.
|
||||||
|
* gas/arm/mapping.d: Adapted to new symbols generation.
|
||||||
|
* gas/arm/mapping2.d: New test case.
|
||||||
|
* gas/arm/mapping2.s: New file.
|
||||||
|
* gas/arm/mapping3.d: New test case.
|
||||||
|
* gas/arm/mapping3.s: New file.
|
||||||
|
* gas/arm/mapping4.d: New test case.
|
||||||
|
* gas/arm/mapping4.s: New file.
|
||||||
|
* gas/arm/mapshort-eabi.d: Adapted to new symbols generation.
|
||||||
|
* gas/elf/section2.e-armeabi: Adapted to new symbols generation.
|
||||||
|
|
||||||
2009-07-27 Jan Beulich <jbeulich@novell.com>
|
2009-07-27 Jan Beulich <jbeulich@novell.com>
|
||||||
|
|
||||||
* gas/elf/file.[ds]: New.
|
* gas/elf/file.[ds]: New.
|
||||||
|
|
6
gas/testsuite/gas/arm/insn-error-a.d
Normal file
6
gas/testsuite/gas/arm/insn-error-a.d
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Check that changing arm -> thumb state immediately
|
||||||
|
# after an invalid instruction does not cause an internal error.
|
||||||
|
#name: invalid instruction recovery test - ARM version
|
||||||
|
#objdump: -d --prefix-addresses --show-raw-insn
|
||||||
|
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
|
#error-output: insn-error-a.l
|
2
gas/testsuite/gas/arm/insn-error-a.l
Normal file
2
gas/testsuite/gas/arm/insn-error-a.l
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[^:]*: Assembler messages:
|
||||||
|
[^:]*:4: Error: ARM register expected -- `movne r33,r9'
|
6
gas/testsuite/gas/arm/insn-error-a.s
Normal file
6
gas/testsuite/gas/arm/insn-error-a.s
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.syntax unified
|
||||||
|
.arch armv7a
|
||||||
|
.arm
|
||||||
|
movne r33,r9
|
||||||
|
.thumb
|
||||||
|
|
6
gas/testsuite/gas/arm/insn-error-t.d
Normal file
6
gas/testsuite/gas/arm/insn-error-t.d
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Check that changing thumb -> arm state immediately
|
||||||
|
# after an invalid instruction does not cause an internal error.
|
||||||
|
#name: invalid instruction recovery test - Thumb version
|
||||||
|
#objdump: -d --prefix-addresses --show-raw-insn
|
||||||
|
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
|
#error-output: insn-error-t.l
|
2
gas/testsuite/gas/arm/insn-error-t.l
Normal file
2
gas/testsuite/gas/arm/insn-error-t.l
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[^:]*: Assembler messages:
|
||||||
|
[^:]*:4: Error: thumb conditional instruction should be in IT block -- `movne r1,r9'
|
6
gas/testsuite/gas/arm/insn-error-t.s
Normal file
6
gas/testsuite/gas/arm/insn-error-t.s
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.syntax unified
|
||||||
|
.arch armv7a
|
||||||
|
.thumb
|
||||||
|
movne r1,r9
|
||||||
|
.arm
|
||||||
|
|
35
gas/testsuite/gas/arm/mapdir.d
Normal file
35
gas/testsuite/gas/arm/mapdir.d
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#as: -EL -I$srcdir/$subdir
|
||||||
|
#objdump: --syms --special-syms -d
|
||||||
|
#name: ARM Mapping Symbols for .arm/.thumb
|
||||||
|
# This test is only valid on EABI based ports.
|
||||||
|
#target: *-*-*eabi *-*-symbianelf *-*-linux-* *-*-elf
|
||||||
|
#source: mapdir.s
|
||||||
|
|
||||||
|
|
||||||
|
.*: +file format .*arm.*
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
0+00 l d .text 00000000 .text
|
||||||
|
0+00 l d .data 00000000 .data
|
||||||
|
0+00 l d .bss 00000000 .bss
|
||||||
|
0+00 l d .fini_array 00000000 .fini_array
|
||||||
|
0+00 l .fini_array 00000000 \$d
|
||||||
|
0+00 l O .fini_array 00000000 __do_global_dtors_aux_fini_array_entry
|
||||||
|
0+00 l d .code 00000000 .code
|
||||||
|
0+00 l .code 00000000 \$a
|
||||||
|
0+00 l d .tcode 00000000 .tcode
|
||||||
|
0+00 l .tcode 00000000 \$t
|
||||||
|
0+00 l d .ARM.attributes 00000000 .ARM.attributes
|
||||||
|
0+00 \*UND\* 00000000 __do_global_dtors_aux
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .code:
|
||||||
|
|
||||||
|
00000000 <.code>:
|
||||||
|
0: e1a00000 nop ; \(mov r0, r0\)
|
||||||
|
|
||||||
|
Disassembly of section .tcode:
|
||||||
|
|
||||||
|
00000000 <.tcode>:
|
||||||
|
0: 46c0 nop ; \(mov r8, r8\)
|
23
gas/testsuite/gas/arm/mapdir.s
Normal file
23
gas/testsuite/gas/arm/mapdir.s
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Test that .arm / .thumb do not cause mapping symbols to be
|
||||||
|
# generated. This could lead to duplicate mapping symbols at
|
||||||
|
# the same address.
|
||||||
|
|
||||||
|
.section .fini_array,"aw",%fini_array
|
||||||
|
.thumb
|
||||||
|
.align 2
|
||||||
|
.type __do_global_dtors_aux_fini_array_entry, %object
|
||||||
|
__do_global_dtors_aux_fini_array_entry:
|
||||||
|
.word __do_global_dtors_aux
|
||||||
|
|
||||||
|
.section .code,"ax",%progbits
|
||||||
|
.thumb
|
||||||
|
.arm
|
||||||
|
nop
|
||||||
|
|
||||||
|
# .bss should not automatically emit $d.
|
||||||
|
.bss
|
||||||
|
|
||||||
|
# Make sure that mapping symbols are placed in the correct section.
|
||||||
|
.thumb
|
||||||
|
.section .tcode,"ax",%progbits
|
||||||
|
nop
|
|
@ -13,7 +13,6 @@ SYMBOL TABLE:
|
||||||
0+00 l d .bss 0+0 (|.bss)
|
0+00 l d .bss 0+0 (|.bss)
|
||||||
0+00 l .text 0+0 \$a
|
0+00 l .text 0+0 \$a
|
||||||
0+08 l .text 0+0 \$t
|
0+08 l .text 0+0 \$t
|
||||||
0+00 l .data 0+0 \$d
|
|
||||||
0+00 l d foo 0+0 (|foo)
|
0+00 l d foo 0+0 (|foo)
|
||||||
0+00 l foo 0+0 \$t
|
0+00 l foo 0+0 \$t
|
||||||
#Maybe section symbol for .ARM.attributes
|
#Maybe section symbol for .ARM.attributes
|
||||||
|
|
19
gas/testsuite/gas/arm/mapping2.d
Normal file
19
gas/testsuite/gas/arm/mapping2.d
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#objdump: --syms --special-syms
|
||||||
|
#name: ARM Mapping Symbols Test 2
|
||||||
|
# This test is only valid on ELF based ports.
|
||||||
|
#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
|
|
||||||
|
.*: +file format.*arm.*
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
00000000 l d .text 00000000 .text
|
||||||
|
00000000 l d .data 00000000 .data
|
||||||
|
00000000 l d .bss 00000000 .bss
|
||||||
|
00000000 l .text 00000000 \$t
|
||||||
|
00000002 l .text 00000000 foo
|
||||||
|
00000000 l d .note 00000000 .note
|
||||||
|
00000000 l d .comment 00000000 .comment
|
||||||
|
00000000 l d .ARM.attributes 00000000 .ARM.attributes
|
||||||
|
00000000 g F .text 00000008 main
|
||||||
|
|
||||||
|
|
19
gas/testsuite/gas/arm/mapping2.s
Normal file
19
gas/testsuite/gas/arm/mapping2.s
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
.syntax unified
|
||||||
|
.arch armv7-a
|
||||||
|
.fpu softvfp
|
||||||
|
.version "dfg"
|
||||||
|
.thumb
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.global main
|
||||||
|
.thumb
|
||||||
|
.thumb_func
|
||||||
|
.type main, %function
|
||||||
|
main:
|
||||||
|
push {r4, lr}
|
||||||
|
foo:
|
||||||
|
pop {r4, lr}
|
||||||
|
bx lr
|
||||||
|
.size main, .-main
|
||||||
|
.ident ""
|
||||||
|
|
16
gas/testsuite/gas/arm/mapping3.d
Normal file
16
gas/testsuite/gas/arm/mapping3.d
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#objdump: --syms --special-syms
|
||||||
|
#name: ARM Mapping Symbols Test 3
|
||||||
|
# This test is only valid on ELF based ports.
|
||||||
|
#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
|
|
||||||
|
.*: +file format.*arm.*
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
00000000 l d .text 00000000 .text
|
||||||
|
00000000 l d .data 00000000 .data
|
||||||
|
00000000 l d .bss 00000000 .bss
|
||||||
|
00000000 l .text 00000000 \$d
|
||||||
|
00000004 l .text 00000000 \$a
|
||||||
|
00000000 l d .ARM.attributes 00000000 .ARM.attributes
|
||||||
|
|
||||||
|
|
5
gas/testsuite/gas/arm/mapping3.s
Normal file
5
gas/testsuite/gas/arm/mapping3.s
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.syntax unified
|
||||||
|
.arch armv7-a
|
||||||
|
.text
|
||||||
|
.word 0
|
||||||
|
nop
|
15
gas/testsuite/gas/arm/mapping4.d
Normal file
15
gas/testsuite/gas/arm/mapping4.d
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#objdump: --syms --special-syms
|
||||||
|
#name: ARM Mapping Symbols Test 4
|
||||||
|
# This test is only valid on ELF based ports.
|
||||||
|
#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
|
|
||||||
|
.*: +file format.*arm.*
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
00000000 l d .text 00000000 .text
|
||||||
|
00000000 l d .data 00000000 .data
|
||||||
|
00000000 l d .bss 00000000 .bss
|
||||||
|
00000000 l .text 00000000 \$a
|
||||||
|
00000000 l d .ARM.attributes 00000000 .ARM.attributes
|
||||||
|
|
||||||
|
|
7
gas/testsuite/gas/arm/mapping4.s
Normal file
7
gas/testsuite/gas/arm/mapping4.s
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.text
|
||||||
|
nop
|
||||||
|
.data
|
||||||
|
.word 0
|
||||||
|
.text
|
||||||
|
nop
|
||||||
|
|
|
@ -22,7 +22,6 @@ SYMBOL TABLE:
|
||||||
0+1c l .text 00000000 \$d
|
0+1c l .text 00000000 \$d
|
||||||
0+1f l .text 00000000 bar
|
0+1f l .text 00000000 bar
|
||||||
0+00 l .data 00000000 wibble
|
0+00 l .data 00000000 wibble
|
||||||
0+00 l .data 00000000 \$d
|
|
||||||
0+00 l d .ARM.attributes 00000000 .ARM.attributes
|
0+00 l d .ARM.attributes 00000000 .ARM.attributes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
Symbol table '.symtab' contains 7 entries:
|
Symbol table '.symtab' contains 6 entries:
|
||||||
Num: Value[ ]* Size Type Bind Vis Ndx Name
|
Num: Value[ ]* Size Type Bind Vis Ndx Name
|
||||||
0: 0+0 0 NOTYPE LOCAL DEFAULT UND
|
0: 0+0 0 NOTYPE LOCAL DEFAULT UND
|
||||||
1: 0+0 0 SECTION LOCAL DEFAULT 1
|
1: 0+0 0 SECTION LOCAL DEFAULT 1
|
||||||
2: 0+0 0 SECTION LOCAL DEFAULT 2
|
2: 0+0 0 SECTION LOCAL DEFAULT 2
|
||||||
3: 0+0 0 SECTION LOCAL DEFAULT 3
|
3: 0+0 0 SECTION LOCAL DEFAULT 3
|
||||||
4: 0+0 0 SECTION LOCAL DEFAULT 4
|
4: 0+0 0 SECTION LOCAL DEFAULT 4
|
||||||
5: 0+0 0 NOTYPE LOCAL DEFAULT 4 \$d
|
5: 0+0 0 SECTION LOCAL DEFAULT 5
|
||||||
6: 0+0 0 SECTION LOCAL DEFAULT 5
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue