From 6057a28fab69bec497751ab60161975a4b546f2b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 13 Nov 2003 14:19:01 +0000 Subject: [PATCH] Add support for ARM ELF Mapping symbols --- gas/ChangeLog | 14 +++ gas/config/tc-arm.c | 178 ++++++++++++++++++++++++++++++++ gas/config/tc-arm.h | 3 + gas/doc/c-arm.texi | 30 ++++++ gas/testsuite/ChangeLog | 7 ++ gas/testsuite/gas/arm/arm.exp | 2 + gas/testsuite/gas/arm/mapping.d | 18 ++++ gas/testsuite/gas/arm/mapping.s | 19 ++++ 8 files changed, 271 insertions(+) create mode 100644 gas/testsuite/gas/arm/mapping.d create mode 100644 gas/testsuite/gas/arm/mapping.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 2b52cde8f5..cfe80e4faf 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2003-11-13 Nick Clifton + + * 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 * Makefile.am (install, install-info, RECURSIVE_TARGETS): Define. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 5117a257d3..bdfa05ce99 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 3b98b33426..ee99236d3b 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 1108014010..dfb5f8653d 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 10365585bb..c10a1434d3 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2003-11-13 Nick Clifton + + * 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 * 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 20e51783c7..3d9685db9b 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 0000000000..8102209340 --- /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 0000000000..c9cee8d4fa --- /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