GNUPro® Toolkit
GNUPro Toolkit Reference for eCos
ARM7
eCos 1.2.1
April 1999
Table of Contents

Copyright Ó 1999 CYGNUS SOLUTIONS, Inc. All rights reserved.
No part of this document may be reproduced in any form or by any means without the prior express written consent of CYGNUS SOLUTIONS, Inc.
No part of this document may be changed and/or modified without the prior express written consent of CYGNUS SOLUTIONS, Inc.
GNUPro®, the GNUPro® logo, and the Cygnus Solutions logo are registered trademarks of
CYGNUS SOLUTIONS, Inc. All other brand and product names are trademarks of their respective owners.

Corporate Headquarters

CYGNUS SOLUTIONS
1325 Chesapeake Terrace
Sunnyvale, CA 94089 USA
TEL: +1 408 542 9600 Support:
Within USA/Canada: +1 800 CYGNUS1
Outside USA/Canada: +1 408 542 9601 FAX: +1 408 542 9699
EMAIL: info@cygnus.com
WEBSITE: http://www.cygnus.com/

Cygnus Japan

NIHON CYGNUS SOLUTIONS
Madre Matsuda Building
4-13 Kioi-cho Chiyoda-ku
Tokyo 102-0094 JAPAN
TEL: +81-3-3234-3896
FAX: +81-3-3239-3300
EMAIL: info@cygnus.co.jp
WEBSITE: http://www.cygnus.co.jp/

Cygnus Europe

CYGNUS SOLUTIONS
35-36 Cambridge Place
Cambridge CB2 1NS
United Kingdom
TEL: +44 1223 728728
FAX: +44 1223 728777

Part #: 300-400-1010060-1.2.1
Table of Contents

Introduction

Tool naming conventions
Toolkit features

Processor version(s)
Targets Supported
Hosts Supported
Object file format

GNUPro on Windows NT

Windows environment settings
Case Sensitivity

GNUPro on Redhat Linux

Reference

Compiler

ARM7-specific command-line options
Preprocessor symbols
ARM7-specific attributes

New compiler and linker features

Initialization prioritization
Selective linking

ABI Summary

Data types sizes and alignments
Subroutine calls
The Stack Frame
C Language Calling Conventions
Function Return Values

Assembler

ARM7-specific command-line options
Syntax
Special characters
Register names
Addressing modes
Floating point
Opcodes
Synthetic Instructions

Linker

ARM7-specific command-line options

Debugger

ARM7-specific command-line options
Debugging programs with multiple threads

Appendix A: ARM7-specific Assembler Error Messages

Appendix B: Bibliography

Introduction

The GNUPro Toolkit for eCos is a complete solution for C and C++ development for the ARM7. The tools include the compiler, assembler, linker, and interactive debugger. Linker and debugger support is also included for the PID Series evaluation board. In addition to this manual, please read Getting started with eCos. Tool naming conventions

Cross-development tools in the Cygnus GNUPro Toolkit normally have names that reflect the target processor and the object file format output by the tools (for example ELF). This makes it possible to install more than one set of tools in the same binary directory, including both native and cross-development tools.

The complete tool name is a three-part hyphenated string. The first part indicates the processor family (arm). The second part indicates the file format output by the tool (elf). The third part is the generic tool name (gcc). For example, the GCC compiler for the ARM7 is arm-elf-gcc.

The ARM7 package includes the following supported tools:

Tool Description | Tool Name
GCC compiler | arm-elf-gcc
C++ compiler | arm-elf-c++
GAS assembler | arm-elf-as
GLD linker | arm-elf-ld
Binary Utilities | arm-elf-ar arm-elf-nm arm-elf-objcopy arm-elf-objdump arm-elf-ranlib arm-elf-size arm-elf-strings arm-elf-strip
GDB debugger | arm-elf-gdb

The binaries for a Windows NT hosted toolchain are installed with an .exe suffix. However, the .exe suffix does not need to be specified when running the executable.

Toolkit features

The following describes ARM7-specific features of the GNUPro Toolkit. Processor version(s) ARM7 Targets Supported PID Series evaluation board

Both big-endian and little-endian mode may be selected. The default is
little endian.

Hosts Supported

CPU | Operating System | Vendor
x86 | Windows NT 4.0 | Microsoft
x86 | Redhat Linux 5.x | Redhat

Object file format The ARM7 tools support the ELF object file format. Refer to Chapter 4, System V Application Binary Interface (Prentice Hall, 1990.). Use ld (refer to Using LD in GNUPro Utilities) or objcopy (refer to The GNU Binary Utilities in GNUPro Utilities) to produce S-records.
GNUPro on Windows NT

Windows environment settings The Windows NT hosted toolchain requires the following environmental settings to function properly. Assuming the release is installed in:

C:\cygnus\gnupro\i386-cygwin32\arm-elf\ecos-99r1
SET PROOT=C:\cygnus\gnupro\i386-cygwin32\arm-elf\ecos-99r1
SET PATH=%PROOT%\H-i386-cygwin32\bin;%PATH%
SET INFOPATH=%PROOT%\info
REM Set TMPDIR to point to a ramdisk if you have one
SET TMPDIR=C:\TEMP For the Sourceware release of eCos, ensure that the Cygwin B20.1 tools are also installed. Assuming these are installed in their default location in
C:\cygnus\cygwin-b20 then add the environmental setting:
SET PATH=C:\cygnus\cygwin-b20\H-i586-cygwin32\bin;%PATH%
If you are using the eCos Developers Kit CD release (not included in the sourceware release), a working environment can be established by using the following shortcut from the Windows Start menu:
Programs->Cygnus eCos->eCos Development Environment This will bring up a window running bash, and your Windows environment will be automatically set up. Case Sensitivity The following strings are case sensitive under Windows NT:

- command line options
- assembler labels
- linker script commands
- section names

The following strings are not case sensitive under Windows NT:

- gdb commands
- assembler instructions and register names

Case sensitivity for Windows NT is dependent on system configuration. By default, file names under Windows NT are not case sensitive. GNUPro on Redhat Linux

The GNUPro Tools for Redhat Linux are supplied in a ZIP format file. Detailed instructions for installation can be found on the eCos sourceware site:
http://sourceware.cygnus.com/ecos/
Assuming the sources for the tools were installed in
/usr/cygnus/ecosSWtools-arm-990321/src
By following the instructions in the Installation Guide, you should eventually have the tools installed in
/usr/cygnus/ecosSWtools-arm-990321/H-i386-pc-linux-gnu/bin
In which case, we recommend you have the following settings in your appropriate shell startup script.

For Bourne shell compatible shells:
PROOT=/usr/cygnus/ecosSWtools-arm-990321
PATH=$PROOT/H-i386-pc-linux-gnu/bin:$PATH
INFOPATH=$PROOT/info:${INFOPATH-/usr/local/info:/usr/info}
MANPATH=$PROOT/man:${MANPATH-/usr/local/man:/usr/man}
export PATH INFOPATH MANPATH
For C-shell compatible shells:
setenv PROOT /usr/cygnus/ecosSWtools-arm-990321

if ( "$?MANPATH" == "0" ) then
setenv MANPATH "/usr/local/man:/usr/man"
endif

if ( "$?INFOPATH" == "0" ) then
setenv INFOPATH "/usr/local/info:/usr/info"
endif

setenv MANPATH $PROOT/man:$MANPATH
setenv INFOPATH $PROOT/info:$INFOPATH
set path = ( $PROOT/H-i386-pc-linux-gnu/bin $path )

Reference

Compiler

This section describes ARM7 and ARM7T-specific features of the GNUPro Compiler. ARM7-specific command-line options For a list of available generic compiler options, see GNU CC Command Options in Using GNU CC in GNUPro Compiler Tools. In addition, the following arm-elf-gcc specific command-line options are supported: -mapcs-frame Generate a stack frame upon entry to a function, as defined in the ARM Procedure Calling Standard.
-mno-apcs-frame Do not generate a stack frame upon entry to a function. The APCS specifies generating stack frames produces slightly smaller and faster code. This is the default setting.
-mapcs-32 Procedure Calling Standard. This is the default setting.
-mapcs-26 Produce assembly code which conforms to the 26 bit version of the ARM Procedure Calling Standard, as used by earlier versions of the ARM processor (ARM2, ARM3).

This option is not supported for use with eCos.

-mapcs-stack-check Produce assembly code which checks the amount of stack space available upon entry to a function and which calls a suitable function if their is insufficient space available.

This option is not supported for use with eCos.

-mno-apcs-stack-check Do not produce code to check for stack space upon entry to a function. This is the default setting.
-mapcs-reentrant Produce assembly code that is position independent and reentrant.
-mno-apcs-rentrant Do not produce position independent, reentrant assembly code. This is the default setting.
-mshort-load-bytes Two byte values should be loaded by performing two individual byte loads and then merging the results. This allows shorts to be loaded from
non-aligned addresses without generating a memory access fault.
-mno-short-load-bytes Two byte values should be loaded using the most space efficient method. On an ARM processor that supports half word loads these instructions will be used. This is the default setting.
-mfpe Floating point instructions should be emulated by the ARM Floating Point Emulator code, which is supplied by the operating system.
-mfpe=N Floating point instructions should be emulated by the ARM Floating Point Emulator code version N. Valid version numbers are 2 and 3. 2 is the default setting.
-msoft-float Floating point instructions should be emulated by library calls. This is the default setting.
-mhard-float Floating point instructions can be performed in hardware.
-mbig-endian Produce assembly code which is targeted for a big endian processor.
-mlittle-endian Produce assembly code which is targeted for a little endian processor. This is the default setting.
-mwords-little-endian Produce assembly code which is targeted for a big endian processor, but which stores words in a little endian format. This is for backward compatibility with older versions of GCC.
-mthumb-interwork Produce assembly code which supports calls between the ARM instruction set and the THUMB instruction set.
-mno-thumb-interwork Do not produce code specifically intended to support calling between ARM and THUMB instruction sets. This is the default setting.

Note: In regard to the two previous options, ARM/Thumb inter-working is not supported by eCos at this time.

-msched-prolog Allow instructions in function prologues to be rearranged to improve performance. This is the default setting.
-mno-sched-prolog Do not allow the instructions in function prologues to be rearranged. This guarantees that function prologues will have a well-defined form, depending upon their nature.
-mcpu=XXXX Produce assembly code specifically for the indicated processor. The variable XXXX can be one of the following processors.

arm2
arm250
arm3
arm6
arm600
arm610
arm620
arm7
arm7m arm7m is the default setting
arm7d
arm7dm
arm7di
arm7dmi
arm70
arm700
arm700i
arm710
arm710c
arm7100
arm7500
arm7500fe
arm7tdmi
arm8

-march=XXXX Produce assembly code specifically for an ARM processor of the indicated architecture. The variable XXXX can be one of the following architectures.

armv2
armv2a
armv3
armv3m
armv4 armv4 is the default setting
armv4t

Preprocessor symbols The following arm-elf-gcc specific preprocessor symbols are supported:

Symbol | Condition
arm | Is always defined.
__semi__ | Is always defined.
__APCS_32__ | If -mapcs-26 has NOT been specified.
__APCS_26__ | If -mapcs-26 has been specified.
__SOFTFP__ | If -mhard-float has NOT been specified.
__ARMWEL__ | If -mwords-little-endian has been specified.
__ARMEB__ | If -mbig-endian has been specified.
__ARMEL__ | If -mbig-endian has NOT been specified.
__arm2 | If -mcpu=arm2 has been specified.
__arm250 | If -mcpu=arm250 has been specified.
__arm3 | If -mcpu=arm3 has been specified.
__arm6 | If -mcpu=arm6 has been specified.
__arm60 | If -mcpu=arm60 has been specified.
__arm600 | If -mcpu=arm600 has been specified.
__arm610 | If -mcpu=arm610 has been specified.
__arm620 | If -mcpu=arm620 has been specified.
__arm7 | If -mcpu=arm7 has been specified.
__arm7m | If -mcpu=arm7m has been specified.
__arm7d | If -mcpu=arm7d has been specified.
__arm7dm | If -mcpu=arm7dm has been specified.
__arm7di | If -mcpu=arm7di has been specified.
__arm7dmi | If -mcpu=arm7dmi has been specified.
__arm70 | If -mcpu=arm70 has been specified.
__arm700 | If -mcpu=arm700 has been specified.
__arm700i | If -mcpu=arm700i has been specified.
__arm710 | If -mcpu=arm710 has been specified.
__arm710c | If -mcpu=arm710c has been specified.
__arm7100 | If -mcpu=arm7100 has been specified.
__arm7500 | If -mcpu=arm7500 has been specified.
__arm7500fe | If -mcpu=arm7500fe has been specified.
__arm7tdmi | If -mcpu=arm7tdmi has been specified.
__arm8 | If -mcpu=arm8 has been specified.

ARM7-specific attributes There are no ARM7-specific attributes. See Declaring Attributes of Functions and Specifying Attributes of Variables in Extensions to the C Language Family in Using GNU CC in GNUPro Compiler Tools for more information.
New compiler and linker features

The GNUPro compiler and linker have been improved by Cygnus to provide even more benefits for customers developing for embedded targets. These features are guaranteed order of initialization at startup, and selective linking. Initialization prioritization In C++, you can define static and global objects with constructors, or initialize static and global variables from a function. This means that the constructors or functions are run before the rest of your program starts. However, when you have these objects spread over multiple files, the C++ standard does not specify the order in which they are initialized, and for all practical purposes the order is random. For an embedded system, this can be a problem, as you may want to ensure that a static scheduler object is initialized before static threads can attach to it, or that devices are initialized before they are used. GNUPro solves this problem by allowing you to define a priority when the static or global is declared. The following example shows the syntax:

static object_t myobj __attribute__((init_priority (30000) ));

The syntax is slightly different if the object takes any arguments to its constructor:

static object_t myobj __attribute__((init_priority (30000) )) = \ object_t(arg1, arg2);

The numeric priority can be from 1 to 65535, with 1 being the highest priority, and 65535 being the lowest. The default priority for objects without this attribute is 65535. Constructors with a higher priority are guaranteed execution before constructors with lower priority.

In all cases, you must provide the argument -finit-priority to the compiler on its command-line for it to recognize this attribute when you are compiling your C++ source files.

If you are using eCos, be warned that eCos uses initialization priorities internally. Ensure you choose an appropriate priority level so that other eCos subsystems will have initialized before you refer to them in your own constructor.

Selective linking When writing C and C++ code, it is sometimes natural to include more than one function in a source file. For example in C++, it is common to have all methods for a particular class contained in the same C++ source file. However, there is a drawback that, conventionally, if you use just one of these functions, then all the functions defined in that file also get included in the final executable image. For an embedded system, this can substantially and unnecessarily increase the size of the final image stored in ROM, or loaded into RAM when debugging.

The GNUPro C and C++ compilers can now optionally remove these unnecessary functions from the final image. They also ensure that any shared global data is removed that is only referenced by functions that are removed. This can be done by including the options -ffunction-sections and -fdata-sections on the command-line, when you invoke the C or C++ compiler. The -ffunction-sections option removes unnecessary functions, and the -fdata-sections option removes unnecessary data.

In addition, when classes define virtual methods in C++, it is possible to remove any unused methods from the final image by passing the option
-fvtable-gc to the C++ compiler on its command-line.

In all cases, you must also supply a command-line option when linking. If invoking the linker ld directly, use --gc-sections on its command-line; alternatively, if you are using the preferred method of linking your executable, using the form gcc -o <program name> <file1>.o <file2>.o, then also pass the option -Wl,--gc-sections on the compiler command-line, for example:
gcc -o prog f1.o f2.o -Wl,--gc-sections

ABI Summary

The ARM7 tools adhere by default to the APCS (ARM Procedure Call Standard). The ARM7T tools adhere to the TPCS (Thumb Procedure Call Standard). The following ABI summary is consistent with both these standards. Data types sizes and alignments

The following table shows the size and alignment for all data types:

Type | Size (bytes) | Alignment (bytes)
char | 1 byte | 1 byte
short | 2 bytes | 2 bytes
int | 4 bytes | 4 bytes
unsigned | 4 bytes | 4 bytes
long | 4 bytes | 4 bytes
long long | 8 bytes | 8 bytes
float | 4 bytes | 4 bytes
double | 8 bytes | 8 bytes
pointer | 4 bytes | 4 bytes

- Alignment within aggregates (structs and unions) is as above, with padding added if needed
- Aggregates have alignment equal to that of their most aligned member
- Aggregates have sizes which are a multiple of their alignment

Subroutine calls

The following describes the calling conventions for subroutine calls. The first table outlines the registers used for passing parameters. The second table outlines other register usage.

Parameter registers:
general-purpose | r0-r3

Register usage:
volatile | r0-r3, r12
non-volatile | r4-r10
frame pointer | r11
stack pointer | r13
return address | r14
program counter | r15

- Structures that are less than or equal to 32 bits in length are passed as values.
- Structures that are greater than 32 bits in length are passed as pointers.

The Stack Frame

This section describes ARM stack frame:

- The stack grows downwards from high addresses to low addresses.
- A leaf function need not allocate a stack frame if it does not need one.
- A frame pointer need not be allocated.
- The stack pointer shall always be aligned to 4 byte boundaries.
- The stack pointer always points to the lowest addressed word currently stored on the stack.

Stack frames for functions that take a fixed number of arguments look like this:

Stack frames for functions that take a variable number of arguments look like this:

C Language Calling Conventions

Argument Representation A floating-point value occupies one, two, or three words, as appropriate to its type. Floating point values are encoded in IEEE 754 format, with the most significant word of a double having the lowest address.

Note: When targetting little-endian ARMs, the words that make up a double will be stored in big-endian order, while the bytes inside each word will be stored in little-endian order.
The C compiler widens arguments of type float to type double to support inter-working between ANSI C and classic C.

Char, short, pointer and other integral values occupy one word in an argument list. Character and short values are widened by the C compiler during argument marshalling.

A structure always occupies an integral number of words (unless this is overridden by the -mstructure-size-boundry command line option). Argument List Collation Argument values are collated in the order written in the source program

The first four words of the argument values are loaded into r0 through r3, and the remainder are pushed on to the stack in reverse order (so that arguments later in the argument list have higher addresses than those earlier in the argument list). As a consequence, a FP value can be passed in integer registers, or even split between an integer register and the stack.

Function Return Values

The following sections describe how different data types are returned. Floats and Integer-like values Floats and integer-like values are returned in register r0.

A type is integer-like if its size is less than or equal to one word and if the type is a structure, union or array, then all of its addressable sub-fields must have an offset of zero.

For example:
struct {int a:8, b:8, c:8, d:8;}
is integer-like, as is;
union {int i; char*p;}
but
struct {char A; char B; char c; char D;}
is not, because it is possible to take the address of fields B, C or D, and their offsets from the start of the structure are not zero.

Doubles and long long integers Doubles and long long integers are returned in registers r0 and r1. For doubles r0 always contains the most significant word of the double. For long long values r0 only contains the most significant word if the target is
big-endian. Other values All other values are returned by placing them into a suitably sized area of memory provided for this purpose by the functions caller. A pointer to this area of memory is passed to the function as a hidden first argument, generated at compile time:
LargeType t;
t = func(arg);
is implemented as:
LargeType t;
(void) func(&t,arg);

Assembler

This section describes ARM7-specific features of the GNUPro Assembler. ARM7-specific command-line options For a list of available generic assembler options, see Command-Line Options in Using AS in GNUPro Utilities. The following are ARM7/7T specific assembler command-line options.

-m[arm][1|2|250|3|6|7[t][d][m][i]] Select processor variant.
-m[arm]v[2|2a|3|3m|4|4t] Select architecture variant.
-mthumb Only allow Thumb instructions.

This option is not supported for use with eCos.

-mall Allow any instruction.
-mfpa10 Select the v1.0 floating point architecture.
-mfpa11 Select the v1.1 floating point architecture.
-mfpe-old Dont allow floating-point multiple instructions.
-mno-fpu Dont allow any floating-point instructions.
-mthumb-interwork Mark the assembled code as supporting inter-working.

This option is not supported for use with eCos.

-mapcs-32 Mark the code as supporting the 26 bit variant of the ARM Procedure calling standard. This is the default.
-mapcs-26 Mark the code as supporting the 26 bit variant of the ARM Procedure calling standard.
-EB Assemble code for a big endian CPU.
-EL Assemble code for a little endian CPU. This is the default. Syntax The ARM7 syntax is based on the syntax in ARMs ARM7 Architecture Manual. Special characters Assembler comments start with the @ (at symbol) and extend to the end of the line. Register names These are the register names supported for the ARM7/7T, in the format:
{<name>, <register number>}

General registers
{r0, 0} | {r1, 1} | {r2, 2} | {r3, 3}
{r4, 4} | {r5, 5} | {r6, 6} | {r7, 7}
{r8, 8} | {r9, 9} | {r10, 10} | {r11, 11}
{r12, 12} | {r13, 13}, | {r14, 14}, | {r15, 15}

:

APCS names for the general registers:
{a1, 0} | {a2, 1} | {a3, 2} | {a4, 3},
{v1, 4} | {v2, 5} | {v3, 6} | {v4, 7},
{v5, 8} | {v6, 9} | {sb, 9} | {v7, 10},
{sl, 10} | {fp, 11} | {ip, 12} | {sp, 13},
{lr, 14} | {pc, 15} |  |

Floating point registers:
{f0, 16} | {f1, 17} | {f2, 18} | {f3, 19}
{f4, 20} | {f5, 21} | {f6, 22} | {f7, 23}
{c0, 32} | {c1, 33} | {c2, 34} | {c3, 35}
{c4, 36} | {c5, 37} | {c6, 38} | {c7, 39}
{c8, 40} | {c9, 41} | {c10, 42} | {c11, 43}
{c12, 44} | {c13, 45} | {c14, 46} | {c15, 47}
{cr0, 32} | {cr1, 33} | {cr2, 34} | {cr3, 35}
{cr4, 36} | {cr5, 37} | {cr6, 38} | {cr7, 39}
{cr8, 40} | {cr9, 41} | {cr10, 42} | {cr11, 43}
{cr12, 44} | {cr13, 45} | {cr14, 46} | {cr15, 47}

Addressing modes

Floating point The assembler supports hardware floating point, but the compiler does not. Opcodes For detailed information on the ARM7 machine instruction set, see ARM7 Series Instruction Manual. The GNU Assembler (GAS) implements all the standard opcodes. Synthetic Instructions The assembler supports the following synthesized instructions (pseudo instructions, which correspond to two or more actual machine instructions).

.arm The following code uses the ARM instruction set.
.thumb The following code uses the THUMB instruction set.

This synthetic instruction is not supported for use with eCos.
.code 16 An alias for .thumb

This synthetic instruction is not supported for use with eCos.
.code 32 An alias for .arm
.force_thumb The following code uses the THUMB instruction set, and should be assembled even if the target processor does not support THUMB instructions.

This synthetic instruction is not supported for use with eCos.
.thumb_func The following label is the name of function which has been encoded using THUMB instructions, rather than ARM instructions.

This synthetic instruction is not supported for use with eCos.
.ltorg Start a literal pool.

Linker

eCos generates linker scripts appropriate for the exact eCos configuration you have chosen. Instructions on how to use this linker script are provided in the manual Getting Started with eCos. ARM7-specific command-line options For a list of available generic linker options, refer to ld command line options in Using LD in GNUPro Utilities. There are no ARM7-specific command-line linker options.
Debugger

This section describes ARM7-specific features of the GNUPro Debugger.

Remote target board:
To load your program onto the standard evaluation board, build eCos for the hardware with RAM startup. Provided the board is fitted with CygMon ROMs, you may connect to the target board in GDB using the command target remote <devicename> where <devicename> will be a serial device such as com2 (Windows NT) or /dev/ttyS1 (Linux). Then load the code onto the target board by typing load. After being downloaded, the program can be executed.

Note:
When using the remote target, GDB does not accept the run command. However, since downloading the program has the side effect of setting the PC to the start address, you can start your program by typing continue (the letter c works as a shortcut for the continue command).

ARM7-specific command-line options

For the available generic debugger options, see Debugging with GDB in GNUPro Debugging Tools. There are no ARM7-specific debugger command-line options

.
Debugging programs with multiple threads

Programs with multiple threads can be debugged using either the graphic user interface to GDB, GDBTk or the GDB command line interface. The following describes how to debug multiple threads using the GDB command line.

In some operating systems, such as eCos, a single program may have more than one thread of execution. The precise semantics of threads differ from one operating system to another, but in general the threads of a single program are akin to multiple processes, except that they share one address space (that is, they can all examine and modify the same variables). On the other hand, each thread has its own registers and execution stack, and perhaps private memory.

GDB provides the following functions for debugging multi-thread programs

- thread threadno, a command to switch among threads
- info threads, a command to inquire about existing threads
- thread apply [threadno][all] args , a command to apply a command to a list of threads
- thread-specific breakpoints
The GDB thread-debugging facility allows you to observe all threads while your program runs, but whenever GDB takes control, one thread in particular is always the focus of debugging. This thread is called the current thread. Debugging commands show program information from the perspective of the current thread.

For debugging purposes, GDB associates its own thread number, always a single integer, with each thread in your program.
info threads Display a summary of all threads currently in your program. GDB displays for each thread (in the following order):

- The thread number assigned by GDB
- The target systems thread I.D.
- The current stack frame summary for that thread
An asterisk * to the left of the GDB thread number indicates the current thread. Use the following example for clarity.

(gdb) info threads
* 2 thread 2 breakme ()
at /eCos/packages/kernel/v1_2_1/tests/thread_gdb.c:91
Name: controller, State: running, Priority: 0, More: <none>
1 thread 1 Cyg_HardwareThread::thread_entry (thread=0x1111aaa2)
at /eCos/packages/kernel/v1_2_1/src/common/thread.cxx:68
Name: Idle Thread, State: running, Priority: 31, More: <none>

thread <threadno> Make thread number <threadno>the current thread. The command argument, <threadno>, is the internal GDB thread number, as shown in the first field of the info threads display. GDB responds by displaying the system identifier of the thread you selected, and its current stack frame summary, as in the following output. (gdb) thread 2
[Switching to thread 2]
#0 change_state (id=0, newstate=0 '\000')
at /eCos/kernel/current/tests/bin_sem2.cxx:93
93 if (PHILO_LOOPS == state_changes++)
Current language: auto; currently c++
thread apply [<threadno>][<all>] <args> The thread apply command allows you to apply a command to one or more threads. Specify the numbers of the threads that you want affected with the command argument <threadno>, where <threadno> is the internal GDB thread number, as shown in the first field of the info threads display. To apply a command to all threads, use thread apply all args. Whenever GDB stops your program, due to a breakpoint or a signal, it automatically selects the thread where that breakpoint or signal happened.

When your program has multiple threads, you can choose whether to set breakpoints on all threads, or on a particular thread.
break <linespec> thread <threadno>
If <linespec> specifies source lines, then there are several ways of writing them. Use the qualifier thread <threadno> with a breakpoint command to specify that you only want GDB to stop the program when a particular thread reaches this breakpoint. <threadno> is one of the numeric thread identifiers assigned by GDB, shown in the first column of the info threads display.

If you do not specify thread <threadno> when you set a breakpoint, the breakpoint applies to all threads of your program.

You can use the thread qualifier on conditional breakpoints as well; in this case, place thread <threadno> before the breakpoint condition, as the following example shows.
(gdb) break frik.c:13 thread 28 if bartab > lim
Whenever your program stops under GDB for any reason, all threads of execution stop; not just the current thread. This allows you to examine the overall state of the program, including switching between threads, without worrying that things may change.

Conversely, whenever you restart the program, all threads start executing. This is true even when single stepping with commands like step or next. In particular, GDB cannot single-step all threads in lockstep. Since thread scheduling is up to your debugging targets operating system (not controlled by GDB), other threads may execute more than one statement while the current thread completes a single step. In general other threads stop in the middle of a statement, rather than at a clean statement boundary, when the program stops.

You might even find your program stopped in another thread after continuing or even single stepping. This happens whenever some other thread runs into a breakpoint, a signal, or an exception before the first thread completes whatever you requested.

SET SCHEDULER-LOCKING
For targets that support it, GDB has a new command that helps to debug
multi-threaded programs. The set scheduler-locking [on off step] command allows the GDB user to exert some control over how threads are scheduled while debugging.

Normally GDB does not attempt to interfere with thread scheduling. This means that in the default mode (scheduler-locking off), the current thread may be scheduled out, and a different thread may begin running, at any time (as determined by the native scheduler). For instance, you may give a GDB command such as step or finish, and when the command completes, you may be looking at a different thread.

If you set the scheduler-locking mode to step, then GDB will try to interfere with the native scheduler just enough to prevent another thread from popping up while you debug. Other threads may get to run sometimes, but whenever a command such as step or finish completes, you should be looking at the same thread that was running before the command. Of course, if another thread gets to run and hits a breakpoint, GDB will still switch you to that thread (so if you dont want that to happen, then disable your breakpoints).

For even greater (and more intrusive) control over the thread scheduler, GDB provides the mode scheduler-locking on. In this mode, the native scheduler is completely locked, and no thread may run except the current one. Obviously this will radically change the behavior of your program, and may lead to deadlock or other unpleasant consequences, so use it with caution.

Syntax:

set scheduler-locking [off on step] Set mode for locking scheduler during target execution. off No locking (threads may preempt at any time). on Full locking (no thread except the current thread may run). step The scheduler is locked during every single-step operation. In this mode, no other thread may run during a step command. However, other threads may run while stepping over a function call (next).

Appendix A: ARM7-specific Assembler Error Messages

Error: Unrecognized opcode This instruction is misspelled or there is a syntax error somewhere.
Warning: operand out of range An immediate value was specified that is too large for the instruction Appendix B: Bibliography

ARM7TDMI Data Sheet
(ARMDDI0029E, Advanced RISC Machines Ltd. (ARM), August, 1995)

Getting Started with eCos version 1.2.1
(Sunnyvale: Cygnus Solutions, 1999)

eCos User Guides version 1.2.1
(Sunnyvale: Cygnus Solutions, 1999)

eCos Reference Manual version 1.2.1
(Sunnyvale: Cygnus Solutions, 1999)

Getting Started with GNUPro Toolkit
(Sunnyvale: Cygnus Solutions, 1999)

GNUPro Compiler Tools
(Sunnyvale: Cygnus Solutions, 1999)

GNUPro Debugging Tools
(Sunnyvale: Cygnus Solutions, 1999)

GNUPro Libraries
(Sunnyvale: Cygnus Solutions, 1999)

GNUPro Utilities
(Sunnyvale: Cygnus Solutions, 1999)

GNUPro Advanced Topics
(Sunnyvale: Cygnus Solutions, 1999)

GNUPro Tools for Embedded Systems
(Sunnyvale: Cygnus Solutions, 1999)

System V Application Binary Interface
(Prentice Hall, 1990)