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>
|
||||
|
||||
* Makefile.am (install, install-info, RECURSIVE_TARGETS): Define.
|
||||
|
@ -2646,6 +2646,178 @@ validate_offset_imm (val, hwse)
|
||||
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
|
||||
s_req (a)
|
||||
int a ATTRIBUTE_UNUSED;
|
||||
@ -2732,6 +2904,7 @@ s_bss (ignore)
|
||||
marking in_bss, then looking at s_skip for clues. */
|
||||
subseg_set (bss_section, 0);
|
||||
demand_empty_rest_of_line ();
|
||||
mapping_state (MAP_DATA);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2970,6 +3143,7 @@ opcode_select (width)
|
||||
coming from ARM mode, which is word-aligned. */
|
||||
record_alignment (now_seg, 1);
|
||||
}
|
||||
mapping_state (MAP_THUMB);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
@ -2985,6 +3159,7 @@ opcode_select (width)
|
||||
|
||||
record_alignment (now_seg, 1);
|
||||
}
|
||||
mapping_state (MAP_ARM);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -11681,6 +11856,7 @@ md_assemble (str)
|
||||
return;
|
||||
}
|
||||
|
||||
mapping_state (MAP_THUMB);
|
||||
inst.instruction = opcode->value;
|
||||
inst.size = opcode->size;
|
||||
(*opcode->parms) (p);
|
||||
@ -11706,6 +11882,7 @@ md_assemble (str)
|
||||
return;
|
||||
}
|
||||
|
||||
mapping_state (MAP_ARM);
|
||||
inst.instruction = opcode->value;
|
||||
inst.size = INSN_SIZE;
|
||||
(*opcode->parms) (p);
|
||||
@ -12809,6 +12986,7 @@ s_arm_elf_cons (nbytes)
|
||||
md_cons_align (nbytes);
|
||||
#endif
|
||||
|
||||
mapping_state (MAP_DATA);
|
||||
do
|
||||
{
|
||||
bfd_reloc_code_real_type reloc;
|
||||
|
@ -90,6 +90,9 @@ struct fix;
|
||||
#ifdef OBJ_ELF
|
||||
# define TARGET_FORMAT elf32_arm_target_format()
|
||||
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
|
||||
|
||||
#define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX)
|
||||
|
@ -22,6 +22,7 @@
|
||||
* ARM Floating Point:: Floating Point
|
||||
* ARM Directives:: ARM Machine Directives
|
||||
* ARM Opcodes:: Opcodes
|
||||
* ARM Mapping Symbols:: Mapping Symbols
|
||||
@end menu
|
||||
|
||||
@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
|
||||
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>
|
||||
|
||||
* 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 {
|
||||
run_dump_test "pic"
|
||||
|
||||
run_dump_test "mapping"
|
||||
}
|
||||
|
||||
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