aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2003-11-13 14:19:01 +0000
committerNick Clifton <nickc@redhat.com>2003-11-13 14:19:01 +0000
commit6057a28fab69bec497751ab60161975a4b546f2b (patch)
tree8f7e6ea724e6c8305777b42b5f0a8c9016c14ab8 /gas
parent39add00a8a2831b679d1333f026f5e106c6fdeaf (diff)
downloadfsf-binutils-gdb-6057a28fab69bec497751ab60161975a4b546f2b.zip
fsf-binutils-gdb-6057a28fab69bec497751ab60161975a4b546f2b.tar.gz
fsf-binutils-gdb-6057a28fab69bec497751ab60161975a4b546f2b.tar.bz2
Add support for ARM ELF Mapping symbols
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/config/tc-arm.c178
-rw-r--r--gas/config/tc-arm.h3
-rw-r--r--gas/doc/c-arm.texi30
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/arm/arm.exp2
-rw-r--r--gas/testsuite/gas/arm/mapping.d18
-rw-r--r--gas/testsuite/gas/arm/mapping.s19
8 files changed, 271 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2b52cde..cfe80e4 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 5117a25..bdfa05c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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;
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 3b98b33..ee99236 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -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)
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index 1108014..dfb5f86 100644
--- a/gas/doc/c-arm.texi
+++ b/gas/doc/c-arm.texi
@@ -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.
+
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 1036558..c10a143 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp
index 20e5178..3d9685d 100644
--- a/gas/testsuite/gas/arm/arm.exp
+++ b/gas/testsuite/gas/arm/arm.exp
@@ -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"
diff --git a/gas/testsuite/gas/arm/mapping.d b/gas/testsuite/gas/arm/mapping.d
new file mode 100644
index 0000000..8102209
--- /dev/null
+++ b/gas/testsuite/gas/arm/mapping.d
@@ -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
diff --git a/gas/testsuite/gas/arm/mapping.s b/gas/testsuite/gas/arm/mapping.s
new file mode 100644
index 0000000..c9cee8d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mapping.s
@@ -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