Add support for ARM ELF Mapping symbols
This commit is contained in:
parent
39add00a8a
commit
6057a28fab
@ -1,3 +1,17 @@
|
|||||||
|
2003-11-13 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* tc-arm.c (mapping_state): New function. Emit a mapping
|
||||||
|
symbol if necessary.
|
||||||
|
(arm_elf_change_section): New function. Intercept section
|
||||||
|
changes and generate mapping symbols.
|
||||||
|
(s_bss): Likewise.
|
||||||
|
(s_arm_elf_cons): Likewise.
|
||||||
|
(opcode_select): Choose the correct mapping state.
|
||||||
|
(md_assemble): Likewise.
|
||||||
|
* tc-arm.h (md_elf_section_change_hook): Define.
|
||||||
|
* doc/c-arm.texi (ARM Mapping Symbols): New node.
|
||||||
|
* NEWS: Mention new feature.
|
||||||
|
|
||||||
2003-11-12 Daniel Jacobowitz <drow@mvista.com>
|
2003-11-12 Daniel Jacobowitz <drow@mvista.com>
|
||||||
|
|
||||||
* Makefile.am (install, install-info, RECURSIVE_TARGETS): Define.
|
* Makefile.am (install, install-info, RECURSIVE_TARGETS): Define.
|
||||||
|
@ -2646,6 +2646,178 @@ validate_offset_imm (val, hwse)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
enum mstate
|
||||||
|
{
|
||||||
|
MAP_DATA,
|
||||||
|
MAP_ARM,
|
||||||
|
MAP_THUMB
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This code is to handle mapping symbols as defined in the ARM ELF spec.
|
||||||
|
(This text is taken from version B-02 of the spec):
|
||||||
|
|
||||||
|
4.4.7 Mapping and tagging symbols
|
||||||
|
|
||||||
|
A section of an ARM ELF file can contain a mixture of ARM code,
|
||||||
|
Thumb code, and data. There are inline transitions between code
|
||||||
|
and data at literal pool boundaries. There can also be inline
|
||||||
|
transitions between ARM code and Thumb code, for example in
|
||||||
|
ARM-Thumb inter-working veneers. Linkers, machine-level
|
||||||
|
debuggers, profiling tools, and disassembly tools need to map
|
||||||
|
images accurately. For example, setting an ARM breakpoint on a
|
||||||
|
Thumb location, or in a literal pool, can crash the program
|
||||||
|
being debugged, ruining the debugging session.
|
||||||
|
|
||||||
|
ARM ELF entities are mapped (see section 4.4.7.1 below) and
|
||||||
|
tagged (see section 4.4.7.2 below) using local symbols (with
|
||||||
|
binding STB_LOCAL). To assist consumers, mapping and tagging
|
||||||
|
symbols should be collated first in the symbol table, before
|
||||||
|
other symbols with binding STB_LOCAL.
|
||||||
|
|
||||||
|
To allow properly collated mapping and tagging symbols to be
|
||||||
|
skipped by consumers that have no interest in them, the first
|
||||||
|
such symbol should have the name $m and its st_value field equal
|
||||||
|
to the total number of mapping and tagging symbols (including
|
||||||
|
the $m) in the symbol table.
|
||||||
|
|
||||||
|
4.4.7.1 Mapping symbols
|
||||||
|
|
||||||
|
$a Labels the first byte of a sequence of ARM instructions.
|
||||||
|
Its type is STT_FUNC.
|
||||||
|
|
||||||
|
$d Labels the first byte of a sequence of data items.
|
||||||
|
Its type is STT_OBJECT.
|
||||||
|
|
||||||
|
$t Labels the first byte of a sequence of Thumb instructions.
|
||||||
|
Its type is STT_FUNC.
|
||||||
|
|
||||||
|
This list of mapping symbols may be extended in the future.
|
||||||
|
|
||||||
|
Section-relative mapping symbols
|
||||||
|
|
||||||
|
Mapping symbols defined in a section define a sequence of
|
||||||
|
half-open address intervals that cover the address range of the
|
||||||
|
section. Each interval starts at the address defined by a
|
||||||
|
mapping symbol, and continues up to, but not including, the
|
||||||
|
address defined by the next (in address order) mapping symbol or
|
||||||
|
the end of the section. A corollary is that there must be a
|
||||||
|
mapping symbol defined at the beginning of each section.
|
||||||
|
Consumers can ignore the size of a section-relative mapping
|
||||||
|
symbol. Producers can set it to 0.
|
||||||
|
|
||||||
|
Absolute mapping symbols
|
||||||
|
|
||||||
|
Because of the need to crystallize a Thumb address with the
|
||||||
|
Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
|
||||||
|
STT_FUNC defined in section SHN_ABS) need to be mapped with $a
|
||||||
|
or $t.
|
||||||
|
|
||||||
|
The extent of a mapping symbol defined in SHN_ABS is [st_value,
|
||||||
|
st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
|
||||||
|
where [x, y) denotes the half-open address range from x,
|
||||||
|
inclusive, to y, exclusive.
|
||||||
|
|
||||||
|
In the absence of a mapping symbol, a consumer can interpret a
|
||||||
|
function symbol with an odd value as the Thumb code address
|
||||||
|
obtained by clearing the least significant bit of the
|
||||||
|
value. This interpretation is deprecated, and it may not work in
|
||||||
|
the future.
|
||||||
|
|
||||||
|
Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
|
||||||
|
the EABI (which is still under development), so they are not
|
||||||
|
implemented here. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
mapping_state (enum mstate state)
|
||||||
|
{
|
||||||
|
static enum mstate mapstate = MAP_DATA;
|
||||||
|
symbolS * symbolP;
|
||||||
|
const char * symname;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
if (mapstate == state)
|
||||||
|
/* The mapping symbol has already been emitted.
|
||||||
|
There is nothing else to do. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
mapstate = state;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case MAP_DATA:
|
||||||
|
symname = "$d";
|
||||||
|
type = BSF_OBJECT;
|
||||||
|
break;
|
||||||
|
case MAP_ARM:
|
||||||
|
symname = "$a";
|
||||||
|
type = BSF_FUNCTION;
|
||||||
|
break;
|
||||||
|
case MAP_THUMB:
|
||||||
|
symname = "$t";
|
||||||
|
type = BSF_FUNCTION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
|
||||||
|
symbol_table_insert (symbolP);
|
||||||
|
symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case MAP_ARM:
|
||||||
|
THUMB_SET_FUNC (symbolP, 0);
|
||||||
|
ARM_SET_THUMB (symbolP, 0);
|
||||||
|
ARM_SET_INTERWORK (symbolP, support_interwork);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAP_THUMB:
|
||||||
|
THUMB_SET_FUNC (symbolP, 1);
|
||||||
|
ARM_SET_THUMB (symbolP, 1);
|
||||||
|
ARM_SET_INTERWORK (symbolP, support_interwork);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAP_DATA:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we change sections we need to issue a new mapping symbol. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
arm_elf_change_section (void)
|
||||||
|
{
|
||||||
|
flagword flags;
|
||||||
|
|
||||||
|
if (!SEG_NORMAL (now_seg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
flags = bfd_get_section_flags (stdoutput, now_seg);
|
||||||
|
|
||||||
|
/* We can ignore sections that only contain debug info. */
|
||||||
|
if ((flags & SEC_ALLOC) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (flags & SEC_CODE)
|
||||||
|
{
|
||||||
|
if (thumb_mode)
|
||||||
|
mapping_state (MAP_THUMB);
|
||||||
|
else
|
||||||
|
mapping_state (MAP_ARM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* This section does not contain code. Therefore it must contain data. */
|
||||||
|
mapping_state (MAP_DATA);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define mapping_state(a)
|
||||||
|
#endif /* OBJ_ELF */
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
s_req (a)
|
s_req (a)
|
||||||
int a ATTRIBUTE_UNUSED;
|
int a ATTRIBUTE_UNUSED;
|
||||||
@ -2732,6 +2904,7 @@ s_bss (ignore)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2970,6 +3143,7 @@ opcode_select (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:
|
||||||
@ -2985,6 +3159,7 @@ opcode_select (width)
|
|||||||
|
|
||||||
record_alignment (now_seg, 1);
|
record_alignment (now_seg, 1);
|
||||||
}
|
}
|
||||||
|
mapping_state (MAP_ARM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -11681,6 +11856,7 @@ md_assemble (str)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapping_state (MAP_THUMB);
|
||||||
inst.instruction = opcode->value;
|
inst.instruction = opcode->value;
|
||||||
inst.size = opcode->size;
|
inst.size = opcode->size;
|
||||||
(*opcode->parms) (p);
|
(*opcode->parms) (p);
|
||||||
@ -11706,6 +11882,7 @@ md_assemble (str)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapping_state (MAP_ARM);
|
||||||
inst.instruction = opcode->value;
|
inst.instruction = opcode->value;
|
||||||
inst.size = INSN_SIZE;
|
inst.size = INSN_SIZE;
|
||||||
(*opcode->parms) (p);
|
(*opcode->parms) (p);
|
||||||
@ -12809,6 +12986,7 @@ s_arm_elf_cons (nbytes)
|
|||||||
md_cons_align (nbytes);
|
md_cons_align (nbytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mapping_state (MAP_DATA);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
bfd_reloc_code_real_type reloc;
|
bfd_reloc_code_real_type reloc;
|
||||||
|
@ -90,6 +90,9 @@ struct fix;
|
|||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
# define TARGET_FORMAT elf32_arm_target_format()
|
# define TARGET_FORMAT elf32_arm_target_format()
|
||||||
extern const char * elf32_arm_target_format PARAMS ((void));
|
extern const char * elf32_arm_target_format PARAMS ((void));
|
||||||
|
|
||||||
|
# define md_elf_section_change_hook() arm_elf_change_section
|
||||||
|
extern void arm_elf_change_section (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX)
|
#define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
* ARM Floating Point:: Floating Point
|
* ARM Floating Point:: Floating Point
|
||||||
* ARM Directives:: ARM Machine Directives
|
* ARM Directives:: ARM Machine Directives
|
||||||
* ARM Opcodes:: Opcodes
|
* ARM Opcodes:: Opcodes
|
||||||
|
* ARM Mapping Symbols:: Mapping Symbols
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node ARM Options
|
@node ARM Options
|
||||||
@ -439,3 +440,32 @@ For information on the ARM or Thumb instruction sets, see @cite{ARM
|
|||||||
Software Development Toolkit Reference Manual}, Advanced RISC Machines
|
Software Development Toolkit Reference Manual}, Advanced RISC Machines
|
||||||
Ltd.
|
Ltd.
|
||||||
|
|
||||||
|
@node ARM Mapping Symbols
|
||||||
|
@section Mapping Symbols
|
||||||
|
|
||||||
|
The ARM ELF specification requires that special symbols be inserted
|
||||||
|
into object files to mark certain features:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@cindex @code{$a}
|
||||||
|
@item $a
|
||||||
|
At the start of a region of code containing ARM instructions.
|
||||||
|
|
||||||
|
@cindex @code{$t}
|
||||||
|
@item $t
|
||||||
|
At the start of a region of code containing THUMB instructions.
|
||||||
|
|
||||||
|
@cindex @code{$d}
|
||||||
|
@item $d
|
||||||
|
At the start of a region of data.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The assembler will automatically insert these symbols for you - there
|
||||||
|
is no need to code them yourself. Support for tagging symbols ($b,
|
||||||
|
$f, $p and $m) which is also mentioned in the current ARM ELF
|
||||||
|
specification is not implemented. This is because they have been
|
||||||
|
dropped from the new EABI and so tools cannot rely upon their
|
||||||
|
presence.
|
||||||
|
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2003-11-13 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* gas/arm/mapping.s: New test: Source for ARM ELF mapping
|
||||||
|
symbols test.
|
||||||
|
* gas/arm/mapping.d: New file: Expected output.
|
||||||
|
* gas/arm/arm.exp: Run new test.
|
||||||
|
|
||||||
2003-11-06 Nick Clifton <nickc@redhat.com>
|
2003-11-06 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* gas/arm/req.s: New test file. Check .req and .unreq psuedo ops.
|
* gas/arm/req.s: New test file. Check .req and .unreq psuedo ops.
|
||||||
|
@ -68,6 +68,8 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then {
|
|||||||
|
|
||||||
if {[istarget *-*-elf*] || [istarget *-*-linux*]} then {
|
if {[istarget *-*-elf*] || [istarget *-*-linux*]} then {
|
||||||
run_dump_test "pic"
|
run_dump_test "pic"
|
||||||
|
|
||||||
|
run_dump_test "mapping"
|
||||||
}
|
}
|
||||||
|
|
||||||
gas_test "offset.s" "" $stdoptlist "OFFSET_IMM regression"
|
gas_test "offset.s" "" $stdoptlist "OFFSET_IMM regression"
|
||||||
|
18
gas/testsuite/gas/arm/mapping.d
Normal file
18
gas/testsuite/gas/arm/mapping.d
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#objdump: --syms
|
||||||
|
#name: ARM Mapping Symbols
|
||||||
|
|
||||||
|
# Test the generation of ARM ELF Mapping Symbols
|
||||||
|
|
||||||
|
.*: +file format.*arm.*
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
0+00 l d .text 0+0
|
||||||
|
0+00 l d .data 0+0
|
||||||
|
0+00 l d .bss 0+0
|
||||||
|
0+00 l F .text 0+0 \$a
|
||||||
|
0+08 l .text 0+0 \$t
|
||||||
|
0+00 l O .data 0+0 \$d
|
||||||
|
0+00 l d foo 0+0
|
||||||
|
0+00 l foo 0+0 \$t
|
||||||
|
0+00 g .text 0+0 mapping
|
||||||
|
0+08 g .text 0+0 thumb_mapping
|
19
gas/testsuite/gas/arm/mapping.s
Normal file
19
gas/testsuite/gas/arm/mapping.s
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.text
|
||||||
|
.arm
|
||||||
|
.global mapping
|
||||||
|
mapping:
|
||||||
|
nop
|
||||||
|
bl mapping
|
||||||
|
|
||||||
|
.global thumb_mapping
|
||||||
|
.thumb_func
|
||||||
|
thumb_mapping:
|
||||||
|
.thumb
|
||||||
|
nop
|
||||||
|
bl thumb_mapping
|
||||||
|
|
||||||
|
.data
|
||||||
|
.word 0x123456
|
||||||
|
|
||||||
|
.section foo,"ax"
|
||||||
|
nop
|
Loading…
Reference in New Issue
Block a user