0% found this document useful (0 votes)
441 views761 pages

Multi Building Applications For Embedded Cmpe490documentsghsbuildarmpdfmulti

Uploaded by

fl0rin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
441 views761 pages

Multi Building Applications For Embedded Cmpe490documentsghsbuildarmpdfmulti

Uploaded by

fl0rin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 761

MULTI: Building Applications for

Embedded ARM

Green Hills Software, Inc.

30 West Sola Street


Santa Barbara, California 93101
USA
Tel: 805-965-6044
Fax: 805-965-6343
www.ghs.com
DISCLAIMER
GREEN HILLS SOFTWARE, INC., MAKES NO REPRESENTATIONS OR WARRANTIES WITH RESPECT
TO THE CONTENTS HEREOF AND SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Further, Green Hills Software, Inc.,
reserves the right to revise this publication and to make changes from time to time in the content hereof without obligation
of Green Hills Software, Inc., to notify any person of such revision or changes.
Copyright © 1983-2005 by Green Hills Software, Inc. All rights reserved. No part of this publication may be reproduced,
stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording,
or otherwise, without prior written permission from Green Hills Software, Inc.
Green Hills, the Green Hills logo, CodeBalance, GMART, GSTART, INTEGRITY, and MULTI are registered
trademarks of Green Hills Software, Inc. AdaMULTI, EventAnalyzer, G-Cover, GHnet, GHnetLite, Green Hills Probe,
Integrate, ISIM, PathAnalyzer, Quick Start, ResourceAnalyzer, Safety Critical Products, Slingshot, SuperTrace Probe,
TimeMachine, and TotalDeveloper are trademarks of Green Hills Software, Inc.
All other company, product, or service names mentioned in this book may be trademarks or service marks of their
respective owners.

PubID: 10379
October 24, 2005
Contents

1 Introduction 1
The MULTI Integrated Development Environment 2
The MULTI Launcher 4
MULTI Workspaces 5
The MULTI 4.0 Document Set 6
About This Book 7
The MULTI Builder 8
The C and C++ Compiler Driver 9
The Optimizing Compilers 9
The asarm Assembler 10
The ax Librarian 10
The elxr Linker 11
Optimized Libraries and Header Files 11
Utility Programs 11
The CodeBalance Optimization Wizard 11
ARM Recommended Reading 12
Online Help 13
Viewing Help on Windows Systems 13
Viewing Help on UNIX Systems 14
Conventions Used in This Book 15

Part I Using the MULTI Builder and


Compiler Drivers
2 The MULTI Builder 19
Starting the Builder 22
The Build Cycle 23
Creating a New Project: The New Project Wizard 24
Selecting a Target 24
Selecting a Project 25
Setting Link Options 26
Setting C Language Options 27
Setting C++ Language Options 28
Setting Optimizations and Run-Time Checks 29

Green Hills Software, Inc. i


Contents
Opening the New Project in the MULTI Debugger 30
Working with Project Files 31
Green Hills Project Files 31
Builder File Types 32
Creating New Project Files 34
Adding Existing Source Files To Your Project 35
Creating New Source Files For Your Project 35
Linking with a Library that is Built with Your Project 36
Linking with a Pre-Built Library 37
Adding Header Files 37
Changing File Types 38
Editing the Project Hierarchy 38
Editing Project Files 39
Searching for Project Files 40
Searching in Files 40
Working with Linker Directives Files 43
Setting Builder Options 50
The Options Window 50
Setting Build Option Macros 58
Importing Environment Variables 60
Inheriting Options from Parent Build Files 61
Setting Options for Projects and Subprojects 61
Setting Options for Source Files 61
Building Your Project 62
Using the File Shortcut Bar 63
Building Platform-Specific Programs from the
Same Source Files 64

3 The Compiler Driver 65


The Compiler Driver Syntax 67
Building an Executable from C or C++ Source Files 68
Working with Input Files 69
Recognized Input File Types 69
Passing Multiple Input File Types to the Driver 70
Passing Linker Directives Files to the Driver 70
Generating Other Output File Types 71
Creating Libraries 72
Adding and Updating Files in Libraries 72
Driver Options for Intermediate Forms of Output 73

ii MULTI: Building Applications for Embedded ARM


Contents
Recognized Output File Types 74
Controlling Driver Information 75
Using a Driver Options File 76
Using makefiles 78
Generating Dependency and Header File Information 81

4 Developing for ARM 83


ARM Characteristics 84
Register Usage 85
Structure Packing 86
Specifying an ARM Target 89
ARM Processor Variants 90
Generating Debugging Information 91
Obtaining Profiling Information 93
Optimizing Your Executable 95
Reducing Program Size 95
Increasing Program Speed 95
Using Your Own Header Files and Libraries 96
Instructing the Compiler to Search for Your Headers 96
Instructing the Compiler to Link Against Your
Libraries 99
Controlling the Assembler 99
Controlling the Linker 100
Thumb Mode 101
Mixed ARM/Thumb 102
Working with Memory Models 106
Program Sections 106
Position Independent Code (PIC) 112
Position Independent Data (PID) 114
Near and Far Function Calls 115
Storing Global Variables in Registers 118
Customizing the Green Hills Run-Time Environment 119
Other Topics 120
Renaming the Output Executable 120
Specifying an Alternate Program Start Address 120
Writing Interrupt Routines 120
Symbolic Memory-Mapped I/O 122

Green Hills Software, Inc. iii


Contents
Viewpathing: Setting Relative Workspace Paths 123
Advanced Optimization Strategies 127

5 Builder and Driver Options 129


Target Options 131
Floating-Point 132
Memory Models 133
Instruction Set 135
Operating System 135
Project Options 140
Optimization Options 143
Optimization Scope 144
Individual Functions 146
Debugging Options 147
Preprocessor Options 150
C/C++ Compiler Options 151
MISRA C 154
Data Types 163
Alignment & Packing 165
C/C++ Data Allocation 166
Special Tokens 167
C++ 169
Assembler Options 180
Linker Options 183
Linker Optimizations 186
Start and End Files 187
Symbols 188
Linker Output Analysis 189
Link-Time Checking 190
Compiler Diagnostics Options 191
Varying Message Format 192
C/C++ Messages 192
Advanced Options 197
Advanced Target Options 197
Advanced Project Options 198
Advanced Optimization Options 203
Advanced Debugging Options 206
Advanced Preprocessor Options 210

iv MULTI: Building Applications for Embedded ARM


Contents
Advanced C/C++ Compiler Options 212
Advanced Assembler Options 216
Advanced Linker Options 216
Advanced Support Diagnostics Options 219
Driver Option Synonyms 220

6 The Builder GUI Reference 223


The File Menu 224
The Edit Menu 225
The Target Selector Dialog Box 228
The Build Menu 229
The Advanced Build Dialog Box 230
The Build Settings Dialog Box 231
The Connect Menu 232
The Debug Menu 233
The Tools Menu 234
The Utility Program Launcher Dialog Box 236
The Windows Menu 236
The Help Menu 237

Part II Using Advanced Tools


7 The asarm Assembler 241
Running the Assembler from the Builder or Driver 242
Generating Assembly Language Files 243
Running the Assembler Directly 243
Assembler Options 244
General Assembler Options 244
Assembler Syntax 245
Character Set 245
Identifiers 245
Reserved Symbols 246
Source Statements 249
Expressions 250
Assignment Statements 250
Scalar Expression Operators 251
Expression Types 252

Green Hills Software, Inc. v


Contents
Type Combinations 252
Labels 253
Current Location 253
Reading the Compiler’s Assembly Output 254
Header Comment File 254
Function Comment Section 255
File Comment Section 255
Source Line Comments 255
Porting Guide for ARM Limited Assembly 256
Driver and Builder Options 256
Assembler Options 256
Support for ARM Ltd. Syntax 257
Support for ARM Ltd. Variables 258
Support for ARM Ltd. Expressions 258
Support for ARM Ltd. Directives 259
ARM Address Operators 263

8 Assembler Directives 265


Alignment Directives 266
Conditional Assembly Directives 267
Data Initialization Directives 268
File Inclusion Directives 269
Macro Definition Directives 269
Repeat Block Directives 271
Section Control Directives 272
Symbol Definition Directives 273
Symbolic Debugging Directives 275
Miscellaneous Directives 276

9 The elxr Linker 277


Running the Linker from the Builder or Driver 278
Running the Linker Directly 279
Linker Options 280
Specifying the Program Entry Point 284
Linker Directives Files 285
The OPTION Directive 287
The CONSTANTS Directive 287

vi MULTI: Building Applications for Embedded ARM


Contents
Memory Maps (the MEMORY Directive) 288
Section Maps (the SECTIONS Directive) 289
Expressions 295
Modifying your Section Map for Speed or Size 297
Customizing the Run-Time Environment Program
Sections 299
Symbol Definitions 302
Beginning, End, and Size of Section Symbols 302
End of Function Symbols 303
Linker Generated Tables 304
Deleting Unused Functions 305
Advanced Linker Features 307
Code Factoring 307
Compressed ROM 309
Section-information Section (.secinfo) 310
Obtaining Run-Time Section Information 310
Run-Time Clear and Copy Tables 310
Porting to the elxr Linker from the old lx Linker 311
Working with ARM ADS Object Files 312

10 The ax Librarian 313


Creating a Library from the Builder 314
Creating a Library from the Compiler Driver 314
Modifying Libraries 315
Librarian Commands 315
Creating and Updating Tables of Contents 317

11 Utility Programs 319


The gasmlist Utility Program 321
The gbin2c Utility Program 325
Global Options 325
Module Inclusion Options 327
Local Options 327
The gbincmp Utility Program 333
The gbldconvert Utility Program 335
The gbuild Utility Program 336
Using gbuild 339
The gcolor Utility Program 342

Green Hills Software, Inc. vii


Contents
Color Configuration Files 343
Rules Files 344
The gcompare Utility Program 346
The gdump Utility Program 349
Debugging File Options 349
ELF File Options 350
COFF File Options 353
BSD File Options 355
The gfile Utility Program 356
The gfunsize Utility Program 357
The ghexfile Utility Program 358
Address Space 359
Data Splitting 360
The ghide Utility Program 362
The gmemfile Utility Program 363
Data Splitting 365
The gnm Utility Program 370
General Options 370
ELF File Options 370
BSD File Options 371
Output Formats 372
The gpjmodify Utility Program 375
Editing Existing .gpj Files 375
Creating a New .gpj File 376
Generating a makefile 377
The grun Utility Program 378
The gsize Utility Program 380
The gsrec Utility Program 382
S-Record Output Format 384
Data and Termination Records 384
Data Splitting 385
The gstack Utility Program 387
Caveats 388
The gstrip Utility Program 389
The gversion Utility Program 390
The gwhat Utility Program 392
Version Extract Mode 392

viii MULTI: Building Applications for Embedded ARM


Contents
Version Update Mode 393

12 The CodeBalance Optimization


Wizard 395
Completing the Setup Tab 397
Completing the Build Tab 398
Completing the Profile Tab 399
Completing the Optimize Tab 400
Advanced Options 402

Part III Language Reference


13 Green Hills C 405
Specifying a C Language Dialect 406
ANSI C 407
ANSI C Extensions 407
GNU C 413
GNU C only Extensions 413
GNU C/C++ Extensions 416
K&R C 420
K&R Mode Extensions to ANSI C 421
Motor Industry Software Reliability Association
(MISRA) Rules 426
Japanese Automotive C Extensions 426
Type Qualifiers 427
volatile 427
const 428
Assignment and Comparisons on struct and union
Types 428
Bitfields 429
ANSI C Limitations 429
Signedness of Bitfields 429
Size and Alignment of Bitfields 430
Enumerated Types 431
Functions with Variable Arguments 432
The <varargs.h> Facility 432

Green Hills Software, Inc. ix


Contents
The <stdarg.h> Facility 433
The asm Statement 434
The Preprocessor 435
Preprocessor Output File 435
C Run-Time Library 436
Extended Characters 436
Compiler Support for Extended Characters 437
Kanji Character Support 438
Compiler Limitations 440
ANSI C Implementation Defined Features 441
Translation F.3.1 442
Environment F.3.2 443
Identifiers F.3.3 443
Characters F.3.4 443
Integers F.3.5 444
Floating-Point F.3.6 445
Arrays and Pointers F.3.7 446
Registers F.3.8 447
Structures, Unions, Enumerations and Bit-fields
F.3.9 447
Qualifiers F.3.10 450
Declarators F.3.11 450
Statements F.3.12 451
Preprocessing Directives F.3.13 451
Library Functions F.3.14 451
Additional Features 452
Amendment 1 Compliance 458
Header File iso646.h 458
Header File wchar.h 458
Header File wctype.h 459
The EILSEQ macro 459
ISO C99 Compliance 460
The long long Data Type 460
// Comments 461
Header File math.h 461
Header File stdio.h 462
The va_copy macro 462
Header File stdbool.h 462
Header File stdint.h 462

x MULTI: Building Applications for Embedded ARM


Contents
14 Green Hills C++ 463
Specifying a C++ Language Dialect 464
Standard C++ 465
Standard C++ Extensions 465
Accepted Anachronisms 468
Extensions Accepted in Normal C++ Mode 469
Standard C++ with ARM Extensions 472
GNU C++ 473
GNU C++ Extensions 473
Extended Embedded C++ 477
EEC++ Library Features 477
Embedded C++ 478
EC++ Library Features 480
Template Instantiation 481
Automatic Instantiation 482
Instantiation Modes 486
Instantiation #pragma Directives 487
Implicit Inclusion 488
Exported Templates 490
Using Clearmake with Green Hills C++ 491
Automatic Instantiation 491
Compile-Time Demand Instantiation 492
Explicit Instantiation 492
Multiple and Virtual Inheritance 493
Namespace Support 495
Precompiled Header Files 497
Automatic PCH Processing 497
Manual PCH Processing 501
Other Ways to Control PCHs 501
Performance Issues 502
Linkage 503
Post Processing in C++ 503
The C++ decode Utility 504
C++ Implementation-Defined Features 505

15 Macros, #pragmas, and Intrinsics 511


Predefined Macro Names 512

Green Hills Software, Inc. xi


Contents
Macro Formats 512
Macro Names Required by ANSI C and C++ 512
Language Identifier Macros 513
Green Hills Toolchain Identification Macros 515
ARM-Specific Predefined Macro Names 516
Endianness Macros 516
Data Type Macros 517
Floating-Point Macros 518
MISRA Macros 519
Memory Model Macros 519
Alignment and Packing Macros 520
Current File and Function Macros 520
Object Format Macros 521
Optimization Predefined Macro Names 521
GNU Compatibility Macros 522
C++ Macros 522
Operating System-Specific Macros 523
Deprecated Macros 524
#pragma Directives 526
General #pragma Directives 527
Green Hills Extension #pragmas 531
Intrinsic Functions 536
Arithmetic Operation Instructions 537
Enhanced DSP Intrinsic Functions 538
XScale Intrinsic Functions 539
v6 Instruction Set Intrinsics 540

16 Libraries and Header Files 547


The Green Hills Header Files and Standard Libraries 549
C and C++ Header File Directories 549
Library Directories 549
Libraries 550
Choosing a C++ Library 553
Automatic Searching of Libraries 554
Advanced Library Topics 555
Linking Alternate Startup Files and Libraries 555
Less Buffered I/O 555
Division by Zero 557
64-bit Integer Arguments and printf 557
Thread-Safe Library Functions 557

xii MULTI: Building Applications for Embedded ARM


Contents
libansi.a Data Structures and Functions 561
libsys.a Functions Provided through MULTI
System Calls 576
libind.a Functions 577
Customizing the Run-Time Environment Libraries and
Object Modules 580
Startup Module crt0.o 581
Low-Level Startup Library libstartup.a 583
Low-Level System Library libsys.a 584

17 Mixing Languages and Writing Portable


Code 589
Mixing Languages 590
Initialization of Libraries 591
Examples of main() Programs 591
Performing I/O on a Single File in Multiple
Languages 592
C Routines and Header Files In C++ 592
Using C++ in C Programs 593
Function Prototyping in C vs. C++ 594
Writing Portable Code 595
Compatibility Between Green Hills Compilers 596
Word Size Differences 596
Endianness Problems 597
Alignment Requirements 597
Structures, Unions, Classes, and Bitfields 599
Assumptions About Function Calling Conventions 600
Pointer Issues 601
NULL Pointer 601
Character Set Dependencies 601
Floating Point Range and Accuracy 602
Operating System Dependencies 602
Assembly Language Interfaces 602
Evaluation Order 603
Machine-Specific Arithmetic 604
Illegal Assumptions About Compiler Optimizations 605
Memory Optimization Restrictions 606
Problems with Source Level Debuggers 607
Problems with Compiler Memory Size 608
Detection of Portability Problems 608

Green Hills Software, Inc. xiii


Contents
18 Enhanced asm Macro Facility for C and
C++ 611
Definition of Terms 613
Example 613
Definition 614
Use 614
Using asm Macros 615
Definition 616
Storage Modes 617
asm Body 618
ARM asm Macros 619
Writing asm Macros 620

19 Optimization Descriptions 623


Inlining Optimizations 625
What Can Be Inlined 625
Automatic Inlining 625
Manual Inlining 626
Single-pass Inlining 626
Two-Pass Inlining (Intermodule Inlining) 627
Varying Inlining Thresholds 630
Advantages of Inlining 631
Limitations of Inlining 632
Inlining of C Memory Functions 632
Inlining of C String Functions 633
Additional C++ Inlining Information 634
Loop Optimizations 636
Automatic Loop Optimization 636
Loop Optimizing Specific Functions 636
Strength Reduction 637
Loop Invariant Analysis 638
Loop Unrolling 639
General Optimizations 641
Peephole Optimization 641
Pipeline Instruction Scheduling 642
Conditional Instructions 644
Data Definition Movement 646
Common Subexpression Elimination/Partial
Redundancy Elimination 647

xiv MULTI: Building Applications for Embedded ARM


Contents
Tail Recursion 648
Constant Propagation 649
C/C++ Minimum/Maximum Optimization 650
Memory Optimization 650
Dead Code Elimination 651
Static Address Elimination 652
Default Optimizations 653
Register Allocation by Coloring 653
Automatic Register Allocation 654
Register Coalescing 654
Constant Folding 655
Loop Rotation 655

20 The ELF File Format 657


Formats of Relocatable and Executable Files 658
32-Bit ELF Data Types 659
ELF Headers 660
ELF Identification 663
ELF Sections 664
Section Headers 664
Symbol Tables 674
Symbol Binding 675
Symbol Type 675
Symbol Values 676
String Tables 677
Program Headers 678
Program Types 679
Program Attribute Flags 680

Index 683

Green Hills Software, Inc. xv


Contents

xvi MULTI: Building Applications for Embedded ARM


Chapter 1

Introduction

This Chapter Contains:


• The MULTI Integrated Development Environment
• The MULTI Launcher
• The MULTI 4.0 Document Set
• About This Book
• ARM Recommended Reading
• Online Help
• Conventions Used in This Book
1. Introduction

This chapter provides an overview of the MULTI Integrated Development


Environment and its documentation set, and then gives a brief introduction to
the tools that are used to compile, assemble, and link code.

The MULTI Integrated Development Environment


MULTI is a complete Integrated Development Environment (IDE) designed
especially for embedded systems engineers to assist them in analyzing, editing,
compiling, optimizing, and debugging embedded applications.

The MULTI IDE includes graphical tools for each part of the software
development process. The following tools can be launched from within the IDE
or as separate stand-alone programs:

• IDE launcher
MULTI Launcher (mstart) — The gateway to the MULTI IDE, which
allows you to quickly launch any of the primary MULTI tools, access
open windows, and manage MULTI workspaces
• Editing tools
MULTI Editor (me) — A graphical editor for modifying text files
Checkout Browser (mcobrowse) — A graphical viewer for files
managed under a version control system
Diff Viewer (diffview) — A graphical viewer that displays differences
between two text files
Hex Editor (mhexedit) — A graphical editor for modifying binary files
• Building tools
MULTI Builder (mbuild) — A graphical interface for managing and
building projects
CodeBalance (codebalance) — A graphical interface for automating the
process of optimizing an executable for size or speed
INTEGRATE (integrate) — A graphical utility for configuring tasks,
connections, and kernel objects across multiple address spaces when
using the INTEGRITY RTOS
Linker Directives File Editor (mldedit) — A graphical editor for
creating and modifying linker directives files

2 MULTI: Building Applications for Embedded ARM


The MULTI Integrated Development Environment

• Debugging tools
MULTI Debugger (multi) — A graphical source-level debugger
EventAnalyzer (mevgui) — A graphical viewer for monitoring
the complex real-time interactions of an embedded RTOS such as
INTEGRITY or ThreadX
ResourceAnalyzer (wperf) — A graphical viewer for monitoring
the CPU and memory usage of an embedded system running the
INTEGRITY RTOS
Script Debugger (mscriptdbg) — A graphical debugger for writing,
recording, and debugging scripts containing MULTI commands
Serial Terminal (mterminal) — A serial terminal emulator for
connecting to serial ports on embedded devices
• Miscellaneous and administrative tools
Bug Report (gbugrpt) — A utility for providing system configuration
and tool version information to the Green Hills support staff
Green Hills Probe Administrator (gpadmin) — A graphical interface
for configuring and managing Green Hills Debug Probes (Slingshots,
Green Hills Probes, and/or SuperTrace Probes)
Graphical Utilities (wgutils) — A collection of utilities for analyzing
and performing various operations on object files, libraries, and
executables produced with the Green Hills toolchain
MULTI License Administrator (mlmadmin) — A graphical utility for
managing Green Hills tools licenses

Green Hills Software, Inc. 3


1. Introduction

The MULTI Launcher

The MULTI Launcher (mstart) provides a convenient way to launch frequently


used tools, to create new or access recently used files and projects, and to
manage MULTI workspaces. All of the main MULTI components can be
accessed using the following buttons:

• — Runs a shortcut or an action sequence in the current workspace. Also


allows you to create a new workspace or create or edit a shortcut.
• — Opens the Builder on a recent or new project.
• — Opens the Debugger on a recent or new executable.
• — Opens the Editor on a recent or new file.
• — Opens the Checkout Browser on a recent or new checkout.
• — Opens the Connection Organizer or a recent or new target connection.
• — Opens a Serial Terminal using a recent or new connection.
• — Opens the EventAnalyzer (licensed separately).
• — Opens the ResourceAnalyzer (licensed separately).
• — Closes the MULTI Launcher (UNIX only by default).
• — Shows/hides the detail pane of the Launcher.

You can also launch the Green Hills License Administrator and (if installed) the
Green Hills Probe Administrator from the Utilities menu.

During development, you can use the MULTI Launcher as a convenient


centralized window manager. You can access any of your open MULTI
windows from the Windows menu of the Launcher.

4 MULTI: Building Applications for Embedded ARM


The MULTI Launcher

MULTI Workspaces
The MULTI Launcher allows you to create and use workspaces. A MULTI
workspace is a virtual area where the tools, files, and actions required for a
particular project can be organized, accessed, and executed.

A workspace is typically created for each top-level project and includes a


working directory and a group of related actions — for example, opening a
project in the MULTI Builder, connecting to a target, or performing a shell
command. Actions are grouped into action sequences, so that a single mouse
click can perform all the actions in the specified action sequence.

For more information, see Chapter 5, “Using MULTI Workspaces and


Shortcuts” in the MULTI: Editing Files and Configuring the IDE book.

Green Hills Software, Inc. 5


1. Introduction

The MULTI 4.0 Document Set


The primary documentation for using MULTI is provided in the following
books:

• MULTI: Getting Started — Describes how to install MULTI and obtain a


license, and takes you through creating, building, and debugging an example
project.
• MULTI: Editing Files and Configuring the IDE — Describes how to use the
MULTI Editor, how to use a version control system with MULTI, how to use
the MULTI Launcher, and how to configure and license the MULTI IDE.
• MULTI: Building Applications — Describes how to use the MULTI Builder
and compiler drivers and the tools that compile, assemble, and link your
code. Also describes the Green Hills implementation of supported high-level
languages.
• MULTI: Configuring Connections — Describes how to set up your target
debugging interface for use with MULTI and how to configure connections
to your target.
• MULTI: Debugging — Describes how to use the MULTI Debugger and
its associated tools.

These books, and any others you may have received (for example, for the
INTEGRITY or ThreadX operating system, or for the Green Hills Debug
Probes) are available in the following formats:

• A printed book
• Online help, accessible from most MULTI windows via the Help →
Manuals menu (see “Online Help” on page 13)
• An electronic PDF, available in the manuals subdirectory of your installation

Note New or updated information may have become available while this
book was in production. For additional material that was not available at press
time, or for revisions that may have become necessary since this book was
printed, please check your CD-ROM for Release Notes, README files, and
other supplementary documentation.

6 MULTI: Building Applications for Embedded ARM


About This Book

About This Book


This book provides comprehensive documentation of the components that make
up the MULTI toolchain. It is divided into the following parts:

• Part I: Using the MULTI Builder and Compiler Drivers — documents how
to use the MULTI Builder or compiler drivers to control the toolchain.
Includes an introduction to the Builder and compiler drivers, discussions of
commonly-used features of the compiler for your target environment, and
descriptions of all the Builder and driver options.
• Part II: Using Advanced Tools — documents the other elements of the
toolchain — the assembler, linker, librarian, and utility programs.
• Part III: Language Reference — documents the Green Hills implementation
of high level languages, including macros, #pragmas, libraries, headers,
and optimizations.

Green Hills Software, Inc. 7


1. Introduction

The MULTI Builder


The MULTI Builder provides a convenient GUI interface for:

• creating and organizing high-level and assembly language source files, object
files, libraries, and supplementary files, and for setting file dependencies.
• specifying build options to control how code will be processed by the
toolchain.
• invoking the Green Hills compilers, assembler, linker, and other utilities to
build an executable.

To get started using the Builder, see Chapter 2, “The MULTI Builder”.

8 MULTI: Building Applications for Embedded ARM


About This Book

The C and C++ Compiler Driver


The compiler driver is the command line interface for invoking the components
of the toolchain. It takes high-level source and other files as input, and invokes
a compiler, the assembler, and the linker, to generate an executable.

To get started using the driver, see Chapter 3, “The Compiler Driver”.

The Optimizing Compilers


The Green Hills compilers are an integrated family of optimizing compilers that
translate high-level language files into assembly language or object files.

There is a compiler for each of, C and C++, which is composed of a


language-specific front end, a global optimizer, and a target-specific code
generator. Compatible subroutine calling conventions allow modules written in
different languages to be combined. The compilers are invoked by the Builder
or the appropriate compiler driver.

Green Hills Software, Inc. 9


1. Introduction

The asarm Assembler


The Green Hills assembler, asarm, translates ARM assembly language
statements and directives into ARM machine code and data formats. The
resulting file produced is an object file.

The assembler is ordinarily called by the Builder or compiler driver, when


required, as part of the compilation process (see “Controlling the Assembler”
on page 99). For information about invoking the assembler directly, and for a
detailed description of its operations, see Chapter 7, “The asarm Assembler”.

Note The ARM compiler defaults to binary code generation, which allows the
compiler to produce object files directly, without invoking the assembler, and
results in reduced compilation times.

The ax Librarian
The Green Hills librarian, ax, combines object files into a library file.

Libraries can be searched by the linker for object files to resolve external
references. A module from a library is included in a program only if it is
referenced in the program.

The librarian is ordinarily invoked from the Builder or compiler driver (see
“Creating Libraries” on page 72). For information about invoking the librarian
directly, and for a detailed description of its operations, see Chapter 10, “The
ax Librarian”.

10 MULTI: Building Applications for Embedded ARM


About This Book

The elxr Linker


The Green Hills linker, elxr, combines object files into an executable.

During linking, the relocation section of each input file resolves its external text
and data references with files containing the required text and data.

The linker is ordinarily called by the Builder or compiler driver as part of


the compilation process (see “Controlling the Linker” on page 100). For
information about invoking the linker directly, and for a detailed description
of its operations, see Chapter 9, “The elxr Linker”.

Optimized Libraries and Header Files


Green Hills provides optimized libraries and header files that support the
standard libraries specified by each language. These header files and libraries
are selected automatically by the compiler driver when compiling and linking,
respectively. For more information, see Chapter 16, “Libraries and Header
Files”.

Utility Programs
The Green Hills Utility Programs allow you to analyze and perform various
operations on object files, libraries, and executables produced with the Green
Hills toolchain. For more information, see Chapter 11, “Utility Programs”.

The CodeBalance Optimization Wizard


The CodeBalance optimization wizard uses profiling information to analyze
individual functions within an executable and to suggest the most appropriate
optimizations for each. You can optimize for size, for speed, or for speed
within a specified size. CodeBalance generates a wizard file, which is used to
recompile your executable in accordance with its recommendations. For more
information, see Chapter 12, “The CodeBalance Optimization Wizard”.

Green Hills Software, Inc. 11


1. Introduction

ARM Recommended Reading


• Seal, David (ed.) ARM Architecture Reference Manual Second Edition
(Addison-Wesley: ISBN: 0-201-73719-1, ARM Document No.:DDI-0100

12 MULTI: Building Applications for Embedded ARM


Online Help

Online Help
The MULTI online help system provides three different types of online help:

• Full online manuals — You can access an indexed hypertext version of


any MULTI manual by selecting it from the list that appears in the Help
→ Manuals menu.
• Context-sensitive help — Many MULTI windows and dialog boxes are
linked to specific sections of the online manuals. To view the page in online
help that documents an active window or dialog box:

(Windows) Press F1.


(UNIX) Press F1 or Help.

If you are using the MULTI Editor, you can also open context-sensitive
help about a button or a menu item by selecting Help → Identify and then
clicking the button or selecting the menu item.
• Debugger command help — You can obtain help information about a
specific MULTI Debugger command by typing help command_name
in the Debugger command pane. This will open the online version of the
MULTI: Debugging book on the section that documents the specified
command. You can also type usage command_name to print to the
command pane the basic syntax of the specified command.

Viewing Help on Windows Systems


Windows systems display online help via the Microsoft HTML Help viewer.
You can view only one manual at a time with the HTML Help viewer.

There are two panes in the HTML Help viewer. The right-hand pane displays
the contents of a selected help page. You can click any underlined link that
appears in right-hand pane to jump to pages about other related topics. The
left-hand pane provides the following three navigation tabs:

• Contents — Displays the chapter and section headings for the manual
being viewed. Click a plus or minus icon to show or hide headings for
embedded sections. Click a heading to display the associated help page in
the right-hand pane.
• Index — Displays index entries for the manual. Double-click an index entry
to display its help page in the right-hand pane.

Green Hills Software, Inc. 13


1. Introduction

• Search — Provides an interface that allows you to search for specific words
in the manual. Enter a word or phrase in the text box and click List Topics
to display a list of pages related to your search string. Double-click any
entry in the list to display the entry’s help page in the right-hand pane.

Viewing Help on UNIX Systems


Depending on your specific UNIX system, MULTI will automatically choose
one of the following two methods for viewing online help:

• Oracle Help for Java — Displays hypertext version of manuals, including


tables of contents and index entries, and provides full text searching across
multiple manuals, with the ability to sort and rank search results.

This viewer may take up to 30 seconds to initialize and is only available


on systems running Red Hat Linux 7.1 or higher, Solaris 2.6 or higher, or
HP-UX 10.20 or 11.x. Other UNIX systems must use browser-based online
help. If problems occur when MULTI is attempting to start the Oracle
Help for Java application, you will see a message prompting you to use
browser-based help (see below).

The Java Runtime Environment that is included with MULTI has been
configured to use fonts common to most X Window servers. However,
some X Window servers may not display Oracle Help for Java properly. To
configure fonts for the Java Runtime Environment, edit the font.properties
file that is located in the jre/lib directory of your MULTI installation (for
more information, see the Sun Microsystems Java web site).
• Web Browser Help — Displays hypertext version of manuals, including
tables of contents and index entries. In GUI mode, netscape is the default
browser. If netscape is installed on your system and the executable is in
your path, no further configuration should be necessary. In non-GUI mode, a
copy of lynx running inside of an xterm will be used as the default browser.
If you have xterm in your path, no further configuration should be necessary.

For information about using an alternate web browser, see “Using a Custom
Web Browser with UNIX” in Chapter 8, “Configuring and Customizing
MULTI” in the MULTI: Editing Files and Configuring the IDE book.

Note To change your online help settings, choose Config → Options →


General tab, then click Help.

14 MULTI: Building Applications for Embedded ARM


Conventions Used in This Book

Conventions Used in This Book


All Green Hills documentation assumes that you have a working knowledge
of your host operating system and its conventions, including its command line
and graphical user interface (GUI) modes. For example, you should know how
to use basic commands, how to open, save, and close files, and how to use a
mouse and standard menus.

Green Hills documentation uses a variety of notational conventions to present


information and describe procedures. These conventions are described below.
Convention Meaning Examples
bold type Indicates a:
• Filename or pathname • C:\MyProjects
• Command • setup command
• Option • -G option
• Window title • the Task window
• Button name • the Browse button
• Menu name or menu choice • the File menu
italic type Indicates that the user should -o filename
replace the text in italics with
an appropriate argument,
command, filename, or other
value.
ellipsis (...) Indicates that the preceding debugbutton [name]…
argument or option can be
(in command line
repeated zero or more times.
instructions)
greater than sign ( > ) Represents a prompt. Your
actual prompt may be a different > print Test
symbol or string. The > prompt Test
helps to distinguish input from
output in examples of screen
displays.

Green Hills Software, Inc. 15


1. Introduction

Convention Meaning Examples


pipe ( | ) Indicates that one (and only help [command | group]
one) of the parameters or
(in command line (The square brackets
options separated by the pipe
instructions) indicate that an argument
or pipes should be specified.
is optional. If an
argument is specified,
however, it must be either
a command or a group.)
square brackets ( [ ] ) Indicate optional arguments, .macro name [list]
commands, options, and so
(in command line
on. You can either include or
instructions)
omit the enclosed elements.
The square brackets should
not appear in your actual
command.

The following command description demonstrates the use of some of these


typographical conventions.

gxyz [-option]… filename

The formatting of this command indicates that:

• The command gxyz should be entered as shown.


• The option -option should either be replaced with one or more appropriate
options or be omitted.
• The word filename should be replaced with the actual filename of an
appropriate file.

The square brackets and the ellipsis should not appear in the actual command
you enter.

16 MULTI: Building Applications for Embedded ARM


Part I

Using the MULTI Builder


and Compiler Drivers
Chapter 2

The MULTI Builder

This Chapter Contains:


• Starting the Builder
• The Build Cycle
• Creating a New Project: The New Project Wizard
• Working with Project Files
• Setting Builder Options
• Building Your Project
2. The MULTI Builder

The MULTI Builder is a graphical tool that organizes your source and other
input files, and controls the tools needed to compile your software project.

The term project is used to encompass all of the files which are used to build
your application. Projects are controlled using Green Hills project files (*.gpj),
which are similar to makefiles, and which maintain file dependencies and set
the options used in building.

To start the Builder, do one of the following:

• From the MULTI Launcher, click the Builder button ( ) and select either
an existing project or Create Project.
• (Windows) Double-click the MULTI Builder icon.
• Enter multi filename.gpj on the command line if the MULTI Builder is
in your path.

Note This chapter describes the new default interface to the MULTI Builder.
For information about the legacy Builder interface, see MULTI: Legacy
Building Tools.

20 MULTI: Building Applications for Embedded ARM


2. The MULTI Builder

The primary components of the main Builder window are as follows:

• Title Bar — Displays the location of the current project. In the screen above,
the project is default.gpj, which is the default project name when you first
run the Builder.
• Menu Bar — For a complete list of all the menu items, see Chapter 6, “The
Builder GUI Reference”.
• Toolbar — The buttons on the Builder toolbar are documented along with
their menu equivalents in Chapter 6, “The Builder GUI Reference”.
• File Shortcut Bar — Allows you to quickly locate or build files and projects.
For more information, see “Using the File Shortcut Bar” on page 63.
• Source Pane — Displays the files and subprojects of the current project. The
name of each file, its type, and any Builder options set in it are shown.
Projects (*.gpj) have a small plus or minus sign to their left, which allows
you to expand or contract their contents.
• Shortcut Menu — You can access the shortcut menu by right-clicking
anywhere in the source pane. This context-sensitive menu allows you to
perform several Builder operations.
• Output Pane — Displays information about the current status of the build
process.
• Status Bar — Displays status information, which includes a description of
the button which the mouse is presently over.
• Target Indicator — Displays the currently selected build target architecture.

Green Hills Software, Inc. 21


2. The MULTI Builder

Starting the Builder


You can open the Builder from the MULTI Launcher, the MULTI Debugger, the
command line or a Windows shortcut. We recommend that you add multi to
your path for easy command line access.

To start the Builder from the command line on a specific project file, cd to the
directory where your project files are located, and enter:
multi filename.gpj

where filename is the project file (*.gpj) of your project’s program, subproject,
or library that you want to open. For more information about project files, see
“Working with Project Files” on page 31.

If you start the Builder without specifying any parameters, the Launcher is
started.

On Windows, you can drag and drop a top-level project file (usually called
default.gpj) to a MULTI icon to open it.

22 MULTI: Building Applications for Embedded ARM


The Build Cycle

The Build Cycle


• Before beginning development, you must create a project with the New
Project Wizard, a simple interface that allows you to:

Specify your target board or processor and operating system


Specify the intended layout of your program in ROM and RAM
Set some of the most important compiler options

The New Project Wizard automatically generates all the project files
necessary to compile an example application. This project can be built,
downloaded to your target or simulator, and opened in the Debugger so that
you can explore many of the features of MULTI.

To get started, see “Creating a New Project: The New Project Wizard”
on page 24.
• Once you have created an example project and are comfortable with the
Builder you can begin adding your own files to the skeleton project structure
generated by the New Project Wizard. For more information about adding
files to your project, and organizing your project structure, see “Working
with Project Files” on page 31.
• You may want to set various Builder options to control exactly how your
project will be built. Builder options are set through the Options window.
For more information, see:

“Setting Builder Options” on page 50 — for an overview of the Options


window.
Chapter 4, “Developing for ARM” — for information about the main
ARM features that can be accessed or controlled with options.
Chapter 5, “Builder and Driver Options” — for a complete list of
available options.
• When your file dependencies and options are set, you can build your project
by clicking the Build button ( ). You can instruct the Builder to build your
entire project, one or more subprojects, or individual source files. For more
information, see “Building Your Project” on page 62.

Green Hills Software, Inc. 23


2. The MULTI Builder

Creating a New Project: The New Project Wizard


To open the New Project Wizard and create a new project, click the button.
The following screen will appear:

Selecting a Target

On this screen, you can specify:

• the processor family to which your target belongs.


• the operating system running on your target. This book focuses on
development for stand-alone targets, those which do not have a Real-Time
Operating System (RTOS) running on them.
• the endianness of your target. This option is only used for targets where the
endianness is configurable.
• your target board. If your exact target combination is not listed, select the
processor-board combination that is most similar to yours. You may need
to modify some of the files created by the wizard before you can test your
configuration and begin debugging.
• the location of your RTOS installation. This option is only available for
certain operating system selections.

Click Next, and the following screen will appear:

24 MULTI: Building Applications for Embedded ARM


Creating a New Project: The New Project Wizard

Selecting a Project

On this screen, you can specify:

• the primary language of your source code.


• the type of project that you want to create (not all example projects are
available for all languages).
• the directory to create the new project in. This must be an empty directory.
• the name of your program or library (no extension is necessary).
From this point on, you can click Finish to accept the remaining default driver
option settings . If you want to continue to the next screen, click Next. The next
screen will vary (or may not appear), depending on which operating system
you chose on the first screen. Here, we will assume that you have chosen a
stand-alone project with no operating system.

Green Hills Software, Inc. 25


2. The MULTI Builder

Setting Link Options

On this screen, you can specify:

• whether to use the standard pre-built startup code, or to customize it.


The default is to use the pre-built code. If you choose to customize, the
New Project Wizard will add an additional project file to your project,
containing the source code to the Green Hills startup library, libstartup.a.
• whether to use the standard pre-built low-level system code, or to customize
it. The default is to use the pre-built code. If you choose to customize, the
New Project Wizard will add an additional project file to your project,
containing the source code to the Green Hills system library, libsys.a.
• a standard board layout for your program. The different layouts correspond
to different linker directives files (*.ld), each of which provides an
appropriate memory map of your target board. The default is to link to and
execute out of RAM.

Note The layout that you choose is the one that will be used during linking,
but the New Project Wizard provides a number of linker directives files (in
subproject resource.gpj), so that you can change the layout conveniently
at later stages of development. For more information, see “Working with
Linker Directives Files” on page 43.

Once you have completed this screen, click Next, and the following screen
will appear:

26 MULTI: Building Applications for Embedded ARM


Creating a New Project: The New Project Wizard

Setting C Language Options

On this screen, you can specify:

• which dialect of the C language to use. The default is ANSI.


• if the compiler will generate warnings or errors when it encounters a C
function without a prototype. The default is to accept functions without
prototypes silently.
• if the compiler will accept C++-style slash comments in C files. The default
is to accept them.

Once you have completed this screen, click Next. If you have selected a project
that includes both C and C++ code, then the following screen will appear
(otherwise, go to “Setting Optimizations and Run-Time Checks” on page 29):

Green Hills Software, Inc. 27


2. The MULTI Builder

Setting C++ Language Options

On this screen, you can specify:

• which dialect of the C++ language to use. The default is Standard C++.
• how the compiler will process template instantiations. The default is never
to force instantiations.
• if C++ exception handling is enabled. The default is to disable exceptions.
• if the compiler will treat for-loop initialization variables as existing beyond
the end of the loop’s scope. The default is for these variables to go out of
scope at the end of the loop.
• if the compiler will instantiate templates automatically. The default is to
enable this feature.
• if the compiler will implicitly include templates. The default is to enable
this feature.

Once you have completed this screen, click Next, and the following screen
will appear:

28 MULTI: Building Applications for Embedded ARM


Creating a New Project: The New Project Wizard

Setting Optimizations and Run-Time Checks

On this screen, you can specify:

• how your project will be optimized. You can instruct the compiler to optimize
generally (making your program both smaller and faster), or specifically for
size or speed. The default is to not perform any optimizations.
• if run-time error checking will be enabled. The default is to disable this
feature.
• if run-time memory checking will be enabled. The default is to disable
this feature
• if performance analysis information (for use with the MULTI Profiler) is
enabled. The default is to disable this feature.

Once you have completed this screen, click Finish, and the New Project
Wizard will exit and return you to the Builder opened on the new project.

Green Hills Software, Inc. 29


2. The MULTI Builder

Opening the New Project in the MULTI Debugger


Once the New Project Wizard exits you can, without further modifications,
build your new application, connect to the Green Hills ARM simulator, and
open it in the Debugger:

• Click the Build button ( ), to build your project. You can follow the
progress of the build in the Output pane at the bottom of the main Builder
window.
• Click the Connect button ( ), to open the Connection Chooser. The New
Project Wizard has created a connection type called:

Target Board with Simulator for ARM

which will be selected. Click Connect to connect to the simulator.


• Click the Debug button ( ), to open the application in the Debugger (if the
Debug button is not already enabled, select the Program project to enable it).

Note For more information see:

• “Building Your Project” on page 62.


• Chapter 3, “Connecting to Your Target” in the MULTI: Debugging book.
• Chapter 5, “Executing and Controlling Your Program from the Debugger” in
the MULTI: Debugging book

30 MULTI: Building Applications for Embedded ARM


Working with Project Files

Working with Project Files


The Source pane of the Builder window provides a graphical representation of
the hierarchy of your project files. It contains three columns:

• Name: the name of each file, and its position in the project hierarchy.
• Type: the type of file, usually determined from its extension.
• Options: the compiler options that are set at this level of the hierarchy.
The Source pane pictured below shows the files generated by the New Project
Wizard for the example project Hello World:

Green Hills Project Files


The Green Hills Project (.gpj) file format used by the Builder differs from the
format of build files (.bld) used by previous tools releases.

Project files are text files that list program source files, subprojects, and other
files that make up a program or a project. Each source file is listed along with
its type in brackets ([]), if that type cannot be discerned by the Builder from
the file’s extension. Source files and other project file entries can be followed
by the project options used when building that file. Project options appear on
subsequent lines and indented in the project file.

Various special options can only be set in the top-level project file. These
include, but are not limited to, primaryTarget, customization, gbuildDir,
defaultBuildOptions, and macro. These options should only be set or modified
from the Builder, as they are not documented.

Green Hills Software, Inc. 31


2. The MULTI Builder

Lines whose first non-whitespace character is # are treated as comments


and ignored, except for the first line of the file, which must exactly match
#!gbuild.

Builder File Types


You may encounter the following file types in the Builder Source pane:

• Project Files (.gpj):


Project — General project file. The New Project Wizard always
creates a project file called default.gpj as the top-level file in the project
hierarchy, but these general purpose containers can also be used to group
programs and libraries.
Library — Project file to output a compiled library.
Program — Project file to output an executable.
Relocatable Object Entry — Project file to output a relocatable object
containing the compiled code from one or more source files.
Select One — Project file that contains multiple source files, only one of
which will be used in the build. These projects are generally used for
multiple architecture hierarchies.
Shared Object — Project file to output a shared library. These projects
are only available for some target operating systems.
Singleton Library — Project file to output a library containing a single
object file. The library will be forced into the final executable.
Subproject — Project file to group files within a project, but which does
not output anything itself. Subprojects differ from Projects in that files
contained within them are included in the link of their parent project.
• Source and Object Files:
C (.c) — C source files.
C++ (.cc, .cpp, .cxx, .c++, .C) — C++ source files.
Assembly (.s, .asm, .arm, .thm) — Assembly language source files.
Object (.o) — Object files.
Prebuilt Library (.a) — Library file of object modules. These are
usually used to specify binary libraries for which there is no source
available.

32 MULTI: Building Applications for Embedded ARM


Working with Project Files

• Resource Files:
Linker Directives (.ld, .lnk) — Linker directives file that contains a
memory map for the target board and a section map for the program.
For more information, see “Working with Linker Directives Files” on
page 43.
Board Setup (.mbs,.dbs) — Setup script file for initializing your target
board.
Memory Layout (.mdf) — Memory layout for your target board for
use by the Debugger.
Target Connections (.con) — Target configuration information for
connecting to a simulator or to your board via appropriate debug servers.
Double-click this file to open the Connection Organizer (see Chapter 3,
“Connecting to Your Target” in the MULTI: Debugging book).
Text (.txt) — Generic text files. This type is used by default for
unclassified file extensions.
Header (.h, .hh, .H, .h++, .hxx, .hpp) — C and C++ header files.
Portable Document Format (.pdf) — Adobe PDF files.
Script (.rc) — MULTI command scripts.

Green Hills Software, Inc. 33


2. The MULTI Builder

Creating New Project Files


The projects generated by the New Project Wizard are intended to provide you
with a skeletal structure into which you can insert your own source and other
project files.

You should start by adding a Program project file (*.gpj) for each program in
your project. You may also add other project files. These include Library
projects for building libraries, Subproject projects for conceptually grouping
source files, and even additional Project projects for more complex groupings.

To create a new program which is a direct child of the top-level project (usually
named default.gpj):

1. Click default.gpj in the source pane to select it.


2. Click the Add button ( ), to open a file chooser.
3. Navigate to the directory where you want to create the project file, enter
an appropriate name (with a .gpj extension) in the Filename text box, and
click Add. A new project file of type Program is created.
4. If you want to change the project’s type, right-click the new project file and
select Change Type. Choose a project type from the Set Type dialog box,
and click OK. For example, if the files in this project are a conceptual unit
inside a Program or Library, you should select Subproject from the list.
5. Click the Save button ( ), to save the project and create the new project
file on disk.

The four main types of project file that you may want to create are:

• Program — Create a project file of this type when the source files it will
contain are intended to be compiled into an executable.
• Subproject — Create a project file of this type inside a Program, Library
or Subproject when you want to organize your source files into conceptual
units. If your source code is organized into subdirectories, we recommend
that you create a subproject in each subdirectory, so that the program
hierarchy displayed in the Builder reflects the organization of your source
file structure.

This type of project does not generate any output in its own right. Instead,
its source files are compiled and then either added to the containing Library
or linked into the containing Program.

34 MULTI: Building Applications for Embedded ARM


Working with Project Files

• Library — Create a project file of this type when you want to produce a
library file. A Program will be linked against all the Library projects
it contains.
• Project — Create a project file of this type to contain a project inside
another project. This allows you to create quite complex hierarchies. Files
contained within a Project do not affect its parents.

For a complete list of project and other file types, see “Builder File Types”
on page 32.

When creating your project hierarchy, be aware that files inherit compiler
options from parent project files. For example, if a program, masterfoo.gpj,
contains a subproject, subfoo.gpj, then subfoo.gpj is a child that inherits
options from the parent, masterfoo.gpj. If subfoo.gpj contains a source file,
foo.c, then foo.c inherits options from masterfoo.gpj and from subfoo.gpj. For
information about setting options, see “Setting Builder Options” on page 50.

Adding Existing Source Files To Your Project


(Windows) You can quickly add existing source files to your project hierarchy
by dragging the files from Windows Explorer into the Builder’s Source pane.
Alternatively, you can:

1. Select the location within the hierarchy where you want to add the file.
2. Click the Add button ( ) or right-click and select the appropriate Add
File action.
3. In the file chooser, browse to the source file and click Add.

(UNIX) To add multiple files quickly, you can specify a file pattern using the
wildcard characters asterisk (*) and question mark (?) in the file chooser.

Creating New Source Files For Your Project


1. Select the location within the hierarchy where you want to add the file.
2. Click the Add button ( ) or right-click and select the appropriate Add
File action.
3. In the file chooser, select a directory and enter the name of the new source
file with an appropriate extension (e.g. .c for C files, or .cc for C++). Click

Green Hills Software, Inc. 35


2. The MULTI Builder

Add. The name of the file appears in the Source pane, but the actual file
does not yet exist.
4. Double-click the name of the new source file to open it in the MULTI
Editor.
5. Edit and save the new file.

Linking with a Library that is Built with Your Project


You can add a library and its source files so that the library gets rebuilt as
needed every time you build your project. If the library is the child of a program
or subproject, then the library will inherit settings from the parent program
or subproject. However, the library’s source files are built into the library,
not into the parent program.

To create such a library:

1. Select the location within the hierarchy where you want to add the library.
2. Click the Add button ( ) or right-click and select the appropriate Add
File action.
3. In the file chooser, select a directory and enter the name of the project
file for the new library (with a .gpj extension). We recommend that your
library’s project file is located in the same directory as its source files
and that the name of the project file is the same name as the library (but
with a .gpj extension).
4. Click the Add button.
5. Right-click the newly created project file and select Set Type from the
context-sensitive menu.
6. Choose Library from the drop-down list, and click OK.
7. Add any appropriate source files to the new library project, and click the
Save button ( ) to save your changes.

! Warning When including the same Library project in multiple programs


be sure that they do not inherit different options. For example, if one
program is built with optimizations, and the other is not, then your library
will contain inconsistently built objects depending on which program was
being built. One way to avoid this is to only set options in your top-level
project and explicitly override any inherited options in the Library project.

36 MULTI: Building Applications for Embedded ARM


Working with Project Files

Linking with a Pre-Built Library


To link a pre-built library into a program, add the library file to the program
project file.

1. Double-click the project file of the appropriate program.


2. Click the Add button ( ) or right-click and select the appropriate Add
File action.
3. In the file chooser, browse to the library file, and click Add.

Note This method should primarily be used for libraries for which source code
is unavailable. Library projects should usually be used instead since the source
files will be rebuilt as necessary.

! Warning Never manually add Green Hills provided target libraries to your
project (e.g. libind.a). The compiler will link in the correct target libraries
for your configuration when the appropriate Builder options are set.

Adding Header Files


You can add header files to your project hierarchy to quickly access the header
files for editing. However, adding a header file to the hierarchy does not affect
how the compiler locates the header file when it is compiling your source files.

To add a header file in your project hierarchy, add the file in the same manner
as adding a source file.

If your header files are located in separate directories, you can add explicit
include directories; however, this is often not necessary:

1. Right-click the project file for the program or library you are building and
select Set Options from the context-sensitive menu.
2. Select the Project category, and double-click the Include Directories
option.
3. Enter the path to the header file, and click OK.

Green Hills Software, Inc. 37


2. The MULTI Builder

Changing File Types


The Builder categorizes each file that you add to a project by assigning it a type
in the Type column of the source pane. The type, initially set based on the file’s
extension, determines the actions that the Builder will perform upon it.

We recommend that you retain the default classifications, and use file extensions
as specified in “Builder File Types” on page 32. However, if you need to
manually override the Builder’s choice of type, you can:

1. Right-click the file and select Set Type from the context-sensitive menu.
2. Choose the appropriate type from the drop-down list and click OK. The
entry in the type column will change accordingly.

Editing the Project Hierarchy


The files at each level of your project’s hierarchy are displayed in the order in
which you added them to the Builder. This is also the order in which the files
will be built. You can rearrange the order in which the files are displayed to
change the compilation order or to help visualize your hierarchy.

You can cut and paste files within the source pane using Ctrl + X and Ctrl + V or
the Cut ( ) and Paste ( ) buttons.

To paste files, select the file immediately above where you want the files to be
added and click the Paste ( ) button.

Note You can select multiple files to cut as long as they are all contained within
the same project.

38 MULTI: Building Applications for Embedded ARM


Working with Project Files

Editing Project Files


You can edit any of the files contained within a project in the MULTI Editor by
selecting it and pressing Ctrl + E, or right-clicking it and selecting Edit from
the context-sensitive menu. You can also open source files and text files in the
Editor by double-clicking their name.

You can access graphical interfaces to assist you in editing certain file types, by
right-clicking them and selecting Grahically Edit:

• Double-click a Target Connections file (.con) to open the Connection


Organizer, which allows you to edit or add a way of connecting to your
target. For more information, see Chapter 3, “Connecting to Your Target” in
the MULTI: Debugging book.
• Right-click a Linker Directives file (.ld) to open the Linker Directives
File Editor, which allows you to edit the allocation of program sections to
memory regions on your target. For more information, see “Working with
Linker Directives Files” on page 43.
• (Windows) Files with registered file extensions can be opened with their
open action.
• (UNIX) Several standard third-party file types have been added including
.pdf.

Green Hills Software, Inc. 39


2. The MULTI Builder

Searching for Project Files


If your project has many files, it may be difficult to locate a particular file
within the hierarchy. To search for a file:

• Use the File Shortcut Bar by selecting either Find: or Next:, then enter the
name of an input (e.g. hello.c) or output (e.g. hello.o) file in your project
and press Enter.

Find: — does a fast search though the project, so it is the best choice
when there is only one match or when any match is sufficient.
Next: — performs a slower, depth-first search through the project
starting at your current selection to find the next occurrence, so it is
good for more complex projects.

For more information, see “Using the File Shortcut Bar” on page 63.
• You can also search the visually expanded portion of the Source pane for
options and files. Press Ctrl + F and type a search string to search forwards,
or Ctrl + B and type a search string to search backwards. The Builder
searches incrementally as you type. Press Ctrl + F or Ctrl + B to look at the
next or previous instance of a string. To exit the search mode, press Esc.

Searching in Files
The Builder supports searching for a text string in all the searchable files in
a program. If you select an individual source file, then only that file will be
searched. If you select a .gpj file, then all the files referenced by that file will
be searched.

To begin a search, select Edit → Search in ... to open the Search in Selected
Files dialog box.

40 MULTI: Building Applications for Embedded ARM


Working with Project Files

Enter the search string in the text box (or use the drop-down list to select recent
search strings) and select any of the following searching options, if desired:

• Case sensitive — The search will only find text that matches the case of the
search string exactly. If this box is not selected, the search will ignore case
when searching for a match. This box is selected by default.
• Whole word — The search will only find text that matches as a whole word.
For example, if this box is selected, a search for word would not match
sword. This box is cleared by default.
• Use Regular Expressions — The search treats the text you enter in the text
box as a regular expression. If this box is not selected, the search treats the
text you enter as a fixed string. This box is selected by default.

After you have entered the search string and set your searching options, click
Search to perform the search. A Search in Files Results window will open
when the search is complete. See the next section for a description of this
window.

Note The Search in Files capability works by running the GNU grep utility.
A copy of GNU grep is installed along with MULTI. However, GNU grep is
not part of MULTI and is not distributed under the same license as MULTI.
For more information about the GNU General Public License, under which
GNU grep is distributed, refer to the file gnugrep.txt, which is located in the
copyright directory of the MULTI installation.

Viewing Search in Files Results


The results of a Search in Files operation are displayed in the Search in Files
Results window.

Green Hills Software, Inc. 41


2. The MULTI Builder

The main components of this window include:

• Results Pane — Contains three columns that display information about the
matching lines in the files searched.
File column — Displays the filename of the matching line. Place your
mouse pointer over this field to display the path to the file, if available,
in a tooltip.
Line column — Displays the line number of the matching line.
Text column — Displays the text of the matching line.
• Status Pane — Contains a description of the search and displays any errors
printed by the GNU grep utility.
• Stop Search button — Stops the current search. This does not dismiss the
results window; the results collected before the search was stopped will
continue to be displayed. This button becomes unavailable when the search
is complete.
• Close button — Dismisses the results window.
• Status Bar — Displays the progress of the search. Located at the bottom
of the window, this bar will display either Searching, Search completed,
or Search stopped.

You can double-click any line in the search results window to open an Editor
on the specified file and line.

Note Although Search in Files is available from the Builder, the Debugger, and
the Editor, the functionality differs slightly across these tools. The descriptions
above apply to searches performed from the Builder. See the MULTI:
Debugging book and the MULTI: Editing Files and Configuring the IDE book
for more information about searching from the Debugger and the Editor.

42 MULTI: Building Applications for Embedded ARM


Working with Project Files

Working with Linker Directives Files


A linker directives file has a .ld extension, and controls how the linker links your
executable, and loads it into memory. A typical linker directives file contains:

• a memory map — which lists the starting address and size of each region of
memory that will be used to contain program code.
• a section map — which lists the program sections, and specifies the memory
regions that they will be loaded into.

Linker directives files may also define constants and special symbols, which the
linker will use when linking and loading your executable. For more information
about the file format, see “Linker Directives Files” on page 285.

The following default linker directives files are generated automatically when
you create a new project for the Standalone operating system and are placed
within the resource.gpj project file:

• standalone_ram.ld — The program is linked so that it is loaded into, and


executes out of RAM. Such programs are usually downloaded and started
running by the Debugger and a debug server. This layout is generally used
in the early stages of development.
• standalone_romrun.ld — The program is linked so that it can be loaded
into, and executes out of ROM/FLASH. Such programs must be burned into
flash (e.g. by gflash) and connected to using the Debugger and a debug
server. This layout may be used for producing a final executable. It requires
the least amount of RAM, but is typically slower, and cannot be debugged
using software breakpoints.
• standalone_romcopy.ld — The program is linked so that it can be loaded
into ROM/FLASH, but then copies itself to RAM and executes out of
RAM. Such programs are burned into flash and connected to using the
Debugger and a debug server. This layout may be used for producing a
final executable. It is faster than the romrun layout and offers software
breakpoint debugging, but takes longer to initialize and requires more RAM.
• standalone_pic.ld — A special linker directives file for projects built with
Position Independent Code (see “Position Independent Code (PIC)” on
page 112).
• standalone_pid.ld — A special linker directives file for projects built with
Position Independent Data (see “Position Independent Data (PID)” on page
114).

Green Hills Software, Inc. 43


2. The MULTI Builder

• standalone_picpid.ld — A special linker directives file for projects with


Position Independent Code and Data.

Depending on how you set the Program Layout field on the Link Options
screen of the New Project Wizard (see “Setting Link Options” on page 26),
one of these files will have been copied to your program project file (e.g.
hello.gpj) for use at link-time. To change the .ld file used for linking, remove
the current linker directives file from the project and insert the new one.

Note These default files are automatically generated by the New Project
Wizard by combining the generic section maps in the install_dir/target/arm
directory together with a board-specific memory map taken from
install_dir/target/arm/target_dir.

You may need to edit these default files to add new memory regions or sections
or to change their attributes. To edit a file:

• Right-click it and select Graphically Edit to open it in the Linker


Directives File Editor graphical interface.
• Double-click it (or right-click it and select Edit) to open it in a text editor.
The remainder of this section will describe editing an .ld file with the Linker
Directives File Editor. For more information about the file format, see “Linker
Directives Files” on page 285.

44 MULTI: Building Applications for Embedded ARM


Working with Project Files

Using the Linker Directives File Editor


The Linker Directives File Editor window provides two ways of viewing
a linker directive file:

• The left-hand Hierarchy pane displays memory regions and sections and
their attributes in a tree structure. Memory regions are at the root of the tree,
and the sections they contain (together with any appropriate expressions) are
displayed as their children. Section attributes are shown as children of the
sections. Sections which are not located in a memory region are grouped in
a Global Memory Region for display purposes.
• The right-hand Layout pane displays memory regions and sections as visual
objects. Memory regions are laid out in order as colored rectangles, with
the region at the lowest address in memory shown at the top. The display
attempts to scale them to an appropriate length, but they may be stretched in
order to accommodate the display of sections. Sections are shown as white
rectangles inside their appropriate regions.

Green Hills Software, Inc. 45


2. The MULTI Builder

Editing a Memory Region


Double-click a memory region in the left or right pane to open it in the Memory
Region dialog box for editing. You may also right click and select Edit to
open this dialog box.

This dialog box allows you to specify:

• The Name of the region, which is often used to describe the type of memory
(DRAM, Flash, etc)
• Its Origin or start address, which may be specified in hex or decimal form.
The dot symbol (“.”) specifies that this region will begin at the first address
available after the end of the previous memory region.
• Its Length, which may be specified in hex, decimal or as an expression.
• Whether the region is the Global Memory Region. This optional feature
provides backwards compatibility with old linker directives files in which
sections were allocated to specific addresses in memory rather than to
named memory regions. Such directly-allocated sections will be displayed
by the Linker Directives File Editor in a region called the Global Memory
Region. This is for display purposes only — these sections will not have an
associated memory region in the .ld file viewed in a text editor.
• The list of Sections that will be loaded into the region. The buttons to the
right of the section list allow you to:

Add a Section to the region.


Add an Expression to the region.

46 MULTI: Building Applications for Embedded ARM


Working with Project Files

Remove a selected section from the region.


Edit a selected section in the Section dialog box (see “Editing a Section”
on page 47).
Move Up a selected section in the list of sections.
Move Down a selected section in the list of sections.

Editing a Section
Double-click a section in the left or right pane to open it in the Section dialog
box for editing:

This dialog box allows you to specify:

• The Name of the section, which conventionally begins with a dot and is
lowercase.
• Its Start Addr. If no start address is given, or if it is specified as a dot (“.”),
then the section will begin at the next available address in its memory region.

Green Hills Software, Inc. 47


2. The MULTI Builder

• The Section Attributes portion of the dialog box allows you to specify
various attributes to the section (for full documentation of these attributes,
see “Section Attributes” on page 292):

Selecting one of Clear, No Clear, and Default specifies how the section
will be treated by the run-time clear table, which can be used to initialize
a section to a particular value at startup.
Selecting Absolute specifies that the section start address is absolute and
must not be moved.
Selecting No Load specifies that the section will be linked to in order to
resolve symbols, but that its data will not be loaded into memory.
Load Addr specifies an address to load the section into (necessary only
if this is different from the address it is linked to).
Pad specifies a number of bytes of padding to be inserted at the start
of the section.
Max Size will generate an error if the section is larger than the specified
size.
Max End Addr will generate an error if the end of the section is at an
address higher than the specified address.
Min Size will generate an error if the section is smaller than the specified
size.
Min End Addr instructs the linker to pad the end of the section if it does
not reach the specified address.
• Selecting ROM Copy specifies that this section is to be loaded into ROM,
but will be copied to RAM at startup for execution. You must additionally
specify:

Whether the section is ordinary ROM or CROM (compressed ROM).


The name of the corresponding RAM section (this section must be
created separately).
• The list of Section Contents allows you to have greater control over the way
that sections from individual modules are allocated to link-time sections.
For example, if you were editing a section called .newtext and wanted to
allocate the .text section from the crt0.o module to it, you would enter
crt0.o(.text) in this box. For more information and examples, see
Chapter 9, “The elxr Linker”.

48 MULTI: Building Applications for Embedded ARM


Working with Project Files

• The Additional Attributes text box allows you to specify other attributes
not available elsewhere in the interface.

Once you have made all your necessary changes, click to save and exit.

Editing an Expression
Double-click an expression in the left pane to open it in the Expression dialog
box for editing:

Enter or edit the expression as appropriate, and click OK to save your changes.

Green Hills Software, Inc. 49


2. The MULTI Builder

Setting Builder Options


The Builder provides many options to control such features as:

• extensions or restrictions to C or C++


• the location of your libraries and header files
• the level of debugging information to be generated
• how your project will be optimized
• run-time error checking
• program data allocation
• generation of Position Independent Code (PIC) or Data (PID)
Each of the Build options corresponds directly to one or more of the command
line compiler driver options. There are four different types of Build options:

• Switches — which have two or more settings from which you choose only
one (for example Optimization Strategy and Debugging Level).
• Combination Switches — which have multiple settings from which you
choose all, none, or any combination (for example Run-Time Error
Checking and MISRA C).
• Strings — which accept a single string value (for example Output File
Name and Start Address Symbol).
• Lists — which accept multiple string values (for example Include
Directories and Library Directories).

Detailed descriptions of all the Builder options, together with their compiler
driver equivalents are provided in Chapter 5, “Builder and Driver Options”. The
following sections provide a general guide to setting options.

The Options Window


To open the Options window, right-click the file that you want to set the
options in, and select Set Options. This window has three tabs, which allow
you different ways of viewing Builder options, and will open on the last tab
you viewed.

To set or edit an option on any of the tabs, double-click it and select a setting
or enter a value in the dialog.

50 MULTI: Building Applications for Embedded ARM


Setting Builder Options

The present value or setting of the option is displayed in the Value column.
Options can be set at different levels of the Build hierarchy, and an option
set in a *.gpj file is inherited by all the files contained in that *.gpj file (see
“Inheriting Options from Parent Build Files” on page 61). Each value appears
in one of three colors:

• Values in printed in gray and which appear in parentheses are default values
that have not been explicitly set anywhere in the project. Note that not all
options have default values, and that some defaults may change depending
upon other option settings.
• Values printed in black are inherited from a parent file. You can override
inherited values by setting the option to a new value in the present file.
• Values printed in blue are set in the present file.

The Basic Options Tab

This tab lists only the common options that most users will need to control.
Categories can be expanded or contracted by clicking the plus or minus sign to
their left. Double-click an option to edit it.

Green Hills Software, Inc. 51


2. The MULTI Builder

The All Options Tab

This tab lists all of the Builder Options, categorized by type or associated tool.
The pane on the left displays the category structure. Click a category in order to
display the options it contains in the pane on the right.

The Modified Options Tab

This tab displays those options that have been set in, or are inherited by, this
file, together with their current settings.

52 MULTI: Building Applications for Embedded ARM


Setting Builder Options

Setting a Switch Option


When you double-click a switch option, a dialog box like this appears.

If the option has already been set at this or a higher level of the project
hierarchy, its present setting is displayed in the Value field, and the file in which
it was set is displayed in the Set In field.

To set (or override a previous setting for) the option:

1. Select a value from the drop-down list. The Set In field will change to
display the current file’s name.
2. Click OK to complete setting the option and return to the Options window.

Green Hills Software, Inc. 53


2. The MULTI Builder

Setting a Combination Switch Option


When you double-click a combination switch option, a dialog box like this
appears, in which all of the available sub-options are displayed.

If a sub-option has already been set at this or a higher level of the project
hierarchy, its present setting is displayed in the left-hand column, and the file in
which it was set is displayed in the Set In column. Sub-options set higher in the
project hierarchy, are printed in black and have an arrow pointing up and to the
left in the left-hand column. Those set in the present file, are printed in blue,
and those that have not been set are printed in gray.

To set (or override a previous setting for) a sub-option:

1. Click the symbol in the left-hand column. These symbols toggle between:

• — not set
• — enabled
• — disabled

The line for the sub-option will turn blue, and the Set In field will change
to display the current file’s name.

54 MULTI: Building Applications for Embedded ARM


Setting Builder Options

You can enable or disable all of the sub-options with the All toggle
( )
2. Edit other sub-options as appropriate, and then click OK to return to the
Options window.

Setting a String Option


When you double-click a string option, a dialog box like this appears.

If the option has already been set at this or a higher level of the project
hierarchy, its present setting is displayed in the Value field, the file in which
it was set is displayed in the Set In field, and the Override Inherited check
box is displayed.

To set the option:

1. Enter an appropriate string in the Value field (if the option has already
been set, you must select the Override Inherited check box before you
can access the Value field). If the option requires a directory or filename as
a value, then a folder icon ( ) is displayed, which you can use to navigate
to the appropriate file or directory.
2. The Set In field will change to display the current file’s name. Click OK
to complete setting the option and return to the Options window.

Green Hills Software, Inc. 55


2. The MULTI Builder

Setting a List Option


When you double-click a list option, a dialog box like this appears.

If the option has already had values assigned to it at this or a higher level of the
project hierarchy, its present settings are displayed in the Value field, and the
file in which each was set is displayed in the Set In field.

To delete a value from the list:

1. Click the value you want to delete to select it, and then click the delete
button ( ).

To add a value to the list:

1. Click the Add button ( ) and enter an appropriate string in the text box.
If the option requires a directory or filename as a value, then a folder
button ( ) is displayed, which you can use to navigate to the appropriate
file or directory.
2. The new value is appended to the bottom of the list and the current file’s
name appears in its Set In field. Click OK to complete setting the option
and return to the Options window.

56 MULTI: Building Applications for Embedded ARM


Setting Builder Options

The Options Window Toolbar


The following buttons are available on the Options window:

• (Show Driver Options) — Toggles the display of driver option names.


• (Show Option Names) — Toggles the display of Builder option names.
• (Edit) — Opens the present project file in the MULTI Editor.
• (Expand All) — Displays all sub-categories.
• (Contract All) — Hides all sub-categories.
• (Goto Parent) — Goes to the options for the parent of the current file.
• (Goto Child) — Goes to the options for the child of the current file.
• (Search for Options) — Opens the Search dialog box, which allows
you to perform text searches on the option category tree.
• (Close) — Closes the Options window.

The Options Window Lower Tabs


Two tabs are available from the lower portion of the Options window:

• The Command Line tab, which shows the driver options that will be passed
to the compiler when you build the selected file:

• The Documentation tab, which provides documentation for whichever


build option is currently selected:

Green Hills Software, Inc. 57


2. The MULTI Builder

Searching For Options


If you are unable to find the option you want to set, then click the search button
( ) to open the Search Build Options dialog box:

Enter an option name or part of a name in the Option to search for text box,
and click the Search button. By default, the Builder will search all three of:

• Build Option Names


• Compiler Driver Option Names
• Settings
Search results appear in the right-hand Results pane. Double-click a result
to go to its entry in the category tree.

Setting Build Option Macros


You can define macros to stand in for commonly used strings in option settings.
This feature is especially useful on Windows hosts to specify the root of the
project.

To set a macro, from the main Builder window select Edit → Set Build Macros
to open the Set Build Macros dialog box:

58 MULTI: Building Applications for Embedded ARM


Setting Builder Options

To define a macro, enter macro_name=value in the text field.

Example 1.

The root directory of the project in this example is C:\src. To define a macro
called top to represent the root directory:

1. Open the Set Build Macros dialog box.


2. Enter: top=C:\src and click OK.

The include files for the project are located in C:\src\include. To specify this
include directory to the Builder using the top macro:

1. Click Edit → Set Options to open the Build Options Window.


2. Navigate to the Project→Include Directories option and open it.
3. Enter $top\include and click OK.

Green Hills Software, Inc. 59


2. The MULTI Builder

Importing Environment Variables


You can import variables from your environment to stand in for strings used in
your option settings.

To import a variable:

1. Click Edit → Advanced → Set Imported Environment Variables to


open the Import Environment Variables dialog box.
2. Enter the name of the environment variable you want to import. The
current value from the environment is displayed in the Value column of
the dialog box.
3. Click OK to import the variable.

After a variable is imported, you can use the variable’s name to stand in for its
string value by using $VARNAME anywhere in a builder option where you want
to have the value of VARNAME substituted.

The Builder tracks changes to the environment variables you import so that
your entire project is rebuilt whenever you modify the value of an imported
environment variable.

Example 2.

To include header files in the headers subdirectory of a third-party SDK


installed in a directory specified by the environment variable SDK_DIR:

1. Open the Set Imported Environment Variables dialog box.


2. Enter SDK_DIR and click OK.
3. Click Edit → Set Options to open the Build Options Window.
4. Navigate to the Project → Include Directories option and open it.
5. Enter $SDK_DIR\headers and click OK.

Note Macros and imports are only valid if they are set in the top-level project.
If you use the GUI for setting builder option macros or importing environment
variables, then the macros and imports are always saved in the top-level project.
This behavior is different from the Set Options dialog box where the options
are set on whichever file is selected.

60 MULTI: Building Applications for Embedded ARM


Setting Builder Options

Inheriting Options from Parent Build Files


A file inherits its options from all of the project files (*.gpj) to which it belongs
in the project hierarchy. You can override these inherited options by setting
options in the file itself. When the Builder compiles your project, the top-level
project options are applied first, with each subsequent child project adding its
options to the existing ones, overriding or appending where specified, until
finally the individual file options are added for each file.

Setting Options for Projects and Subprojects


Since you can reuse project files for programs, subprojects, and libraries in
multiple projects, it is important to specify whether the options for a project file
are specific to the current project, or whether the options are specific to the
project file itself regardless of the project to which it belongs.

• If the options are specific to the current project, select the parent’s project
file, and then set the options. For example, if child.gpj is a subproject of
master.gpj, select master.gpj, and then set the options. These options are
written to the parent project file. If you reuse the child’s project file in a
different project, the options will not be carried over into the new project.
• If the options are specific to the subproject file itself, select the subproject
(child.gpj), and then set the options. These options are written to the child
project file, and therefore will be set for that project file regardless of what
parent it currently belongs to.

Setting Options for Source Files


You can set options for an individual file or for a list of files.

• To set an option for an individual file, select the file and set the options.
• To set an option for a group of files, select the project file that contains the
files in the Builder’s hierarchy of your project, then set the options. The
options are set in the project file; all files below the project file, including its
source files, will inherit these options.

Green Hills Software, Inc. 61


2. The MULTI Builder

Building Your Project


You can instruct the Builder to build your entire project, a specific subproject,
executable, or library, or an individual source file:

• To build your entire project, select the top-level project (usually named
default.gpj), in the Source pane, and click the Build button ( ).
• To build a specific subproject, executable, or library, select the appropriate
project file, right-click it, and select Build selected file.
• To build an individual source, select it, right-click it, and select Compile
selected file.

In each case, the Builder will invoke all the appropriate tools. You can follow
the progress of the build in the Output pane at the bottom of the Builder
window. If the build is successful, then its completion will be reported here. If
errors occur, then a Build Progress window will open:

You can modify or obtain extra information about the build process, by selecting
Build → Advanced Build to open the Advanced Build dialog box (for full
documentation, see “The Advanced Build Dialog Box” on page 230):

• To remove any previous output files before beginning the build, select the
Clean all output before building check box, and click the Build button.
• To see a dry-run of the build, without actually executing any commands or
modifying any files, select the Show build without execution check box,
and click the Build button.

62 MULTI: Building Applications for Embedded ARM


Building Your Project

• To see the commands that the Builder executes as it builds, select the Show
tool commands check box, and click the Build button.

Using the File Shortcut Bar


The File Shortcut Bar is located directly above the Source Pane in the main
Builder window.

The bar has two components, a drop-down list that enables you to specify
whether you want to Build, Find, or [Find] Next, and a text field in which
you can enter parameters as follows:
Build: options files
Builds any files specified. You may also specify gbuild options (see “The gbuild
Utility Program” on page 336).
For example, to delete all previous output files, and then build the projects foo.gpj
and bar.gpj, you would select the Build: setting and enter the following:

-cleanfirst foo.gpj bar.gpj


Find: file
Locates an instance of the specified file in the Source Pane. This option is best
suited to finding .gpj files or uniquely named files quickly.
Next: file
Locates the next instance of the specified file in the Source Pane. This option is
best suited to finding files with commonly-used names.

Note The file specified must be the complete base name (including any
extension but excluding any path), and may be any one of:

• A project file (for example, foo.gpj)


• The executable output of a project file (for example, foo)
• A C (or other source) language input file (for example, foo.c)
• The object file output of a source language file (for example, foo.o)

Green Hills Software, Inc. 63


2. The MULTI Builder

Building Platform-Specific Programs from the Same Source Files


When a program needs to work on multiple hardware platforms, the source files
are often identical except for one or more assembly language routines that
vary from processor to processor. In cases like this, you can create Select One
projects that contain the processor-specific files so you can build the same
program for multiple target processors.

Consider the following example:

The Select One project, traps.gpj, can build a program that uses only the
processor-specific file, traps.ppc or traps.mip, for the specified target
processor.

If you have multiple files that are specific to a single processor, create multiple
Select One projects. Suppose the program in the above example also uses
bdriver.ppc and bdriver.mip. In this case, you would need another Select One
project, bdriver.gpj.

Creating Your Project For Multiple Platforms


1. Create the program that is compiled and linked.
2. Add to the program all of the source files except the processor-specific
assembly files.
3. Add a Select One subproject to the program to contain the
processor-specific assembly files (for example, traps.gpj). For information
about creating a project, see “Creating New Project Files” on page 34.
4. In the Source pane, add the various processor-specific assembly files for
the program to the new project . In the example above, traps.gpj contains
two files: traps.ppc and traps.mip.

64 MULTI: Building Applications for Embedded ARM


Chapter 3

The Compiler Driver

This Chapter Contains:


• The Compiler Driver Syntax
• Building an Executable from C or C++ Source Files
• Working with Input Files
• Generating Other Output File Types
• Controlling Driver Information
• Using a Driver Options File
• Using makefiles
3. The Compiler Driver

The driver is the command line wrapper for various toolchain components.
The driver enables you to manually specify which source files you want to
compile and/or all of the source files that are necessary to link your program.
This chapter explains how to use the driver and introduces some of the
most important tasks it can perform. Like the Builder, it can control all the
components of the Green Hills toolchain necessary to produce an executable
from high-level source files:

• The optimizing compilers for C and C++, which compile high-level source
files into ARM assembly language files.
• The asarm assembler, which translates ARM assembly files into object files.
• The elxr linker, which links object files (including object files in libraries)
together to generate an executable.

In addition, the driver accepts many other forms of input files (see “Working
with Input Files” on page 69) and can produce many different forms of output,
including using the ax librarian to combine object files together into libraries
(see “Generating Other Output File Types” on page 71).

66 MULTI: Building Applications for Embedded ARM


The Compiler Driver Syntax

The Compiler Driver Syntax


The syntax for using the compiler driver is:
driver [file]… [-option]…

where:

• driver is one of the following:


ccarm: for C files. Generates ARM code and ARM libraries.
ccthumb: for C files. Generates Thumb code and Thumb libraries.
cxarm: for C++ files. Generates ARM code and ARM libraries.
cxthumb: for C++ files. Generates Thumb code and Thumb libraries.

If your source files contain mixed ARM/Thumb code, you can invoke either
an ARM, or a Thumb compiler driver.
• file is one or more of the following:
C or C++ source file
Assembly source file
Object file or library of object files
Linker directives file (see “Passing Linker Directives Files to the Driver”
on page 70)
• -option is one or more compiler driver options. All the options are
case-sensitive (for example -o renames the output file, while -O enables
general optimizations), and most are host-independent. Many of the most
commonly used options are discussed in this chapter. All of the driver
options are listed and explained in Chapter 5, “Builder and Driver Options”.

Files and options are listed on the command line, separated by spaces.

The driver reads all options before processing any files. When two options
represent different choices for the same feature, the later choice overrides the
earlier one. If it encounters an unrecognized or invalid option, the driver will
ignore it and issue a warning.

After reading the options, the driver processes files in the order they appear
on the command line. If an error occurs in one file, processing will continue
with the next file. If no errors occur, all object files and libraries will be linked
together according to the order specified on the command line.

Green Hills Software, Inc. 67


3. The Compiler Driver

Building an Executable from C or C++ Source Files


When the driver receives source language files as input, it invokes the
appropriate compiler, assembler, and linker to produce an executable.

To build an executable from a C source file called hello.c, use the C driver,
ccarm, and enter the following:
ccarm hello.c

To build an executable from a C++ source file called hello.cxx, use the C++
driver, cxarm, and enter the following:
cxarm hello.cxx

In each case, an executable file called a.out is generated, together with the
following additional files: hello.o, a.map, a.dnm and a.dla

The hello.o file is the object file which results from passing hello.c to the
compiler and assembler. Whenever the driver generates an executable from a C
or C++ file, or from an assembly language file, it retains the intermediate object
files for future re-use. The a.map file is a map file produced by the linker. The
a.dnm and a.dla files contain basic debugging information for use with the
MULTI Debugger. For instructions on generating full debugging information
for MULTI, see “Generating Debugging Information” on page 91.

To build an executable from multiple source files, list the files on the command
line, separated by spaces, as follows:
ccarm hello.c foo.c bar.c

This command generates an executable called a.out, the debugging files a.dnm
and a.dla, a map file a.map, and three object files, hello.o, foo.o, and bar.o.

68 MULTI: Building Applications for Embedded ARM


Working with Input Files

Working with Input Files

Note The example command lines in this section, and in the remainder of
this chapter, are shown using the C driver, ccarm. They will also work with
the other drivers.

In addition to high-level language source files, the driver can also process
assembly language files, object files, and libraries. The diagram below shows
how these files are passed to the various tools in the toolchain.

Recognized Input File Types


The compiler driver determines the type of a file (and hence the compilation
steps to perform on it) by reading its extension. For example, a file with
a .c extension is a C source file and (unless options to the contrary have
been passed) needs to be compiled with the appropriate language compiler,
assembled, and then linked.

The following is a partial list of file extensions which the driver recognizes:

• C source files: .c, .i,

Green Hills Software, Inc. 69


3. The Compiler Driver

• C++ source files: .C, .cc, .cpp, .cxx


• Assembly language files: .s, .asm, .mar
• Assembly language files with C preprocessor directives: .arm
• Thumb assembly language files with C preprocessor directives: .thm
• Object files: .o
• Library files: .a
• Linker directives files: .ld

Note On a command line, you can use the -filetype option to override the
default type associated with the filename. For example:
ccarm -filetype.cc hello.i

Passing Multiple Input File Types to the Driver


To pass assembly files, object files, and libraries to the driver, add them to the
command line, separated by spaces. For example:
ccarm hello.c foo.c bar.s baz.o libfoo.a

Source files of different languages can be included within the same executable
by using the Advanced→Advanced Project Options→Input Languages or
-language options. For more information, see “Advanced Project Options”
on page 198.

Passing Linker Directives Files to the Driver


Linker Directives (.ld) files define the program sections of the executable
and assign them to specific regions of memory. Several default .ld files are
provided (see “Working with Linker Directives Files” on page 43) and the most
appropriate one is used automatically.

You can edit the default files to specify your own layout. For full documentation
of the syntax, see “Linker Directives Files” on page 285).

To pass a .ld file to the driver, add it to the command line as follows (no option
is required; the file is recognized by its extension):
ccarm hello.c mylinkfile.ld

70 MULTI: Building Applications for Embedded ARM


Generating Other Output File Types

Generating Other Output File Types


The driver can be instructed to halt the compilation process at various stages in
order to produce assembly files, object files, libraries, or other forms of output.

To instruct the compiler to halt the build process after the compiler has
generated assembly files, use the -S option as follows:
ccarm hello.c -S

This command produces an assembly language file called hello.s.

To instruct the compiler to halt the build process after the compiler has
generated assembly files and the assembler has translated them to object files,
use the -c option as follows:
ccarm hello.c -c

This produces an object file called hello.o.

Green Hills Software, Inc. 71


3. The Compiler Driver

Creating Libraries
You can pass high-level source files, assembly language files, and object files
to the driver, and instruct it to collect them into a library. The driver invokes
the compiler and/or the assembler (if required) to produce object files, and then
invokes the librarian to combine these object files into a library.

To instruct the driver to create a library from the C source file hello.c and the
object file foo.o, use the -archive option as follows:
ccarm hello.c foo.o -archive -o libfoo.a -G

This command produces a library of object files called libfoo.a, which contains
two object files, hello.o and foo.o.

Note When using the -archive option to create a library, you must use the -o
option to specify a name for it. The name must be in the form libfile.a. The
-G option is optional, but should be passed if you intend to use the MULTI
Debugger.

Adding and Updating Files in Libraries


To add an object file to an existing library, use the -archive option and specify
the library name using the -o option. For example, to generate an object file
from the C source file hello.c and add this object file to library libfoo.a, enter
the following:
ccarm hello.c -archive -o libfoo.a

To update an object file already included in a library, pass the new version to
the driver with the -archive option, as follows:
ccarm hello.c -archive -o libfoo.a

To perform other operations on libraries, you must invoke ax directly. For more
information, see Chapter 10, “The ax Librarian”.

72 MULTI: Building Applications for Embedded ARM


Generating Other Output File Types

Driver Options for Intermediate Forms of Output


The following table lists all of the driver options that instruct the driver to stop
at particular stages of the compilation process.

Note These options only apply to the compiler driver and cannot be set from
the Builder.

-archive
Runs the ax librarian to generate a library (instead of running the linker to
generate an executable program). For more information, see “Creating Libraries”
on page 72.
-c
Produces an object file (called input-file.o) for each source file.
-E
Runs the preprocessor and writes the preprocessed file output to stdout. This
option can be useful when debugging preprocessor macros and #include files.
-Q
Produces only an inline file (called input-file.inf) for each source file. These files
contain partially compiled code for functions generated during the first pass of the
inliner, together with the list of the include files that the source file depends on
(and are used by automatic dependency checking).
-S
Produces an assembly file (called input-file.s) for each source file.
-syntax
Checks the syntax without generating code.

Note See also the driver options associated with the Linker→Generate
Additional Output option in “Linker Options” on page 183.

Green Hills Software, Inc. 73


3. The Compiler Driver

Recognized Output File Types


The following is a listing of output files types that are generated by builder.
Additionally, input file types can be produced with the toolchain when executed
with options. See “Recognized Input File Types” on page 69 for more
information.
bmon.out
gmon.out
mon.out
Profiling data files that are read and written only by the toolchain.
.dba
.dbo
.dla
.dlo
.dnm
Debugging information files that are read and written only by the toolchain. See
“Debugging Options” on page 147.
.graph
Call graph information that is written only by the toolchain, and read by the user.
See “Linker Output Analysis” on page 189.
.idep
Dependency files generated by Intex.
.ii
.ti
C++ template information files that are read and written only by the toolchain.
.inf
Database file used for intermodule inlining, which is read and written only by
the toolchain.
.lcp
INTEGRITY-only files that are generated by the driver for Intex. It contains the
command line used when building with -kernal so that Intex is able to relink the
executable itself.

74 MULTI: Building Applications for Embedded ARM


Controlling Driver Information

.lst
An assembler source listing that is written by the toolchain, and read only by the
user. See “Assembler Options” on page 180.

.map
A map file generated by the linker that contains information about how the program
is laid out in memory. .map is written by the toolchain, and only read by the user.
See “Linker Output Analysis” on page 189.
.mem
An additional copy of the executable image that has been translated by the
gmemfile utility. .mem is written by the toolchain, and read by non-GHS utility
programs. See “Linker Options” on page 183.
.run
An additional copy of the executable image that has been translated by the gsrec
utility. .run is written by the toolchain, and read by non-GHS utility programs. See
“Linker Options” on page 183.
.time
Files that are generated by the builder when the file being processed does not
generate an output file. This allows the builder to track if and when the item was
last processed for dependency tracking. .time is read and written only by the
toolchain.

Controlling Driver Information


The following options control the display of information about the driver itself.

Note These options only apply to the compiler driver and cannot be set from
the Builder.

@file
Instructs the driver to read command line arguments from file.

Green Hills Software, Inc. 75


3. The Compiler Driver

-#
Displays the command lines generated by the driver (which are used to call the
compiler, assembler, and/or linker for processing the input files) without executing
them. For compatibility purposes, this option can also be entered as -dryrun or
--driver_debug.
-help
Displays a list of some of the more commonly-used options with brief descriptions.
-v
Displays the command lines generated by the driver as it calls the compiler,
assembler, and/or linker for processing the input files.

Using a Driver Options File


When using multiple driver options, you may find that your command lines
become overly long and hard to read. You can, instead, enter your options into a
plain text file, which you pass to the driver using the @file option.

All characters in the file other than spaces, tabs, newline characters, and double
quotes are literal.

Arguments must be separated by spaces, tabs, or newline characters. The double


quote (“) may be used to include spaces or tabs in a single argument as follows:

• If the argument begins with a ", then everything on the line up to the next "
will be part of the argument, and those quotes will be discarded.
• Otherwise, if a " is in the middle of an argument, the " will NOT be
discarded, but will cause any whitespace on the line up to the next " to
be included in the argument.

Note Due to limitations in the command line parser, the -bsp and -layout
options cannot be entered in a driver options file and must be placed directly on
the driver command line, either before or after any @file.

Example 1.

The plain text file myoptfile contains the following information:

76 MULTI: Building Applications for Embedded ARM


Using a Driver Options File

hello.c foo.c bar.c


-G
-Ospeed -OI
-o foo

To instruct the driver with the options file myoptfile, enter:


ccarm @myoptfile -bsp=iq80310 -layout=romrun

This command instructs the driver to read myoptfile and to:

• pass files hello.c, foo.c, and bar.c to the compiler, assembler, and linker
• generate MULTI debugging information (-G)
• compile the files in such a way as to maximize the speed of the final
executable, including using two-pass inlining (-Ospeed -OI)
• name the output executable foo (-o foo)
• generate code tailored to the instruction set associated with the Intel
IQ80310 board, and assign the program to memory regions of that
board using a board-specific linker directives files (-bsp=iq80310
-layout=romrun)

Note You cannot include comments in a command file that you pass to the
compiler driver with this option. Do not use this option to read a file containing
assembler or linker options. Instead, use -asmcmd=file (see “Assembler
Options” on page 180) or -lnkcmd=file (“Linker Options” on page 183) to pass
the file directly to the assembler or the linker, respectively. Note that linker
directive files should be passed to the linker by using a known suffix, such as
.ld or .lnk, rather than using this option.

Green Hills Software, Inc. 77


3. The Compiler Driver

Using makefiles
The Green Hills compiler drivers are completely compatible with makefiles.
This section discusses the basic issues involved in porting existing makefiles
for use with Green Hills projects.

In each of the following examples, we port a makefile from the fictional


compiler qcc to the Green Hills compiler ccarm. We assume that qcc uses
fairly standard command line syntax.

Example 1. A Very Simple Build

The following is an example of a very simple qcc makefile:


scanprog: scanprog.c
qcc -O2 scanprog.c -o scanprog

To convert this makefile for use with ccarm, you would need to make the
following changes:

• Change the invocation of qcc to ccarm.


• Change the optimization option -O2 to a Green Hills option, such as -O
(which enables general optimizations).

The resulting ccarm makefile will look like the following:


scanprog: scanprog.c
ccarm -O scanprog.c -o scanprog

78 MULTI: Building Applications for Embedded ARM


Using makefiles

Example 2. makefile Macros, Incremental Build

The following is a common format for a makefile. It uses an incremental


build process (building .c files to .o files, and then linking them). It also uses
makefile macros (such as CC and CFLAGS) to gather commonly-modified
parts of the makefile in one place:
CC=qcc
CFLAGS=-g -I../include -DITERATIONS=3 -O3 -fprocessor=A
LFLAGS=-L../lib -lxyzlib -fprocessor=A
OFILES=bigprog.o main.o utils.o

bigprog: $(OFILES)
$(CC) $(LFLAGS) $(OFILES) -o $@

bigprog.o: bigprog.c bigprog.h utils.h


main.o: main.c bigprog.h
utils.o: utils.c utils.h

To convert this makefile for use with ccarm, you would need to change the
macros as follows:

• Change:
CC=qcc

to:
CC=ccarm

• Change:
CFLAGS=-g -I../include -DITERATIONS=3 -O3

to:
CFLAGS=-G -I../include -DITERATIONS=3 -Ospeed -OI

Green Hills Software, Inc. 79


3. The Compiler Driver

Example 3. Mixing Languages

In this example, two C files, one ARM assembly file, and one C++ file are
linked together into a single executable:
OFILES=myprog.o utils1.o utils2.o interface.o

myprog: $(OFILES)
qcc $(OFILES) -o myprog

myprog.o: myprog.c utils.h


qcc -c myprog.c

utils1.o: utils1.c utils.h


qcc -c utils1.c

utils2.o: utils1.s
qasm -c utils1.s

interface.o: interface.cpp
qc++ -c interface.cpp

Porting this example to use cxarm is easy because the Green Hills drivers
recognize filename extensions and invoke the correct compiler or assembler
automatically. Consequently, you would simply need to change all references to
qcc, qasm, and qc++ to cxarm, so that the makefile would read as follows:
OFILES=myprog.o utils1.o utils2.o interface.o

myprog: $(OFILES)
cxarm $(OFILES) -o myprog

myprog.o: myprog.c utils.h


cxarm -c myprog.c

utils1.o: utils1.c utils.h


cxarm -c utils1.c

utils2.o: utils1.s
cxarm -c utils1.s

interface.o: interface.cpp
cxarm -c interface.cpp

80 MULTI: Building Applications for Embedded ARM


Using makefiles

Generating Dependency and Header File Information


These options provide information about your makefile structure:
-H
Prints to stderr a list of files opened by #include directives during normal
compilation. Files are compiled and linked normally. This option can be used
together with -syntax to print the names of header files without producing any
other output.
This option has no effect if -MD or -Make is passed.
-MD
Produces a makefile dependency file (called input-file.d) for each source file.
Duplicate dependencies are eliminated and only one rule is output for a single
object file. The backslash (\) character is used to form continuation lines.
Unlike the -Make option (see “Driver Options for Intermediate Forms of Output” on
page 73), compilation will continue normally.
This option has no effect if -syntax or -Make is passed.
This option only applies to the compiler driver and cannot be set from the Builder.

Green Hills Software, Inc. 81


3. The Compiler Driver

82 MULTI: Building Applications for Embedded ARM


Chapter 4

Developing for ARM

This Chapter Contains:


• ARM Characteristics
• Register Usage
• Structure Packing
• Specifying an ARM Target
• Generating Debugging Information
• Optimizing Your Executable
• Using Your Own Header Files and Libraries
• Controlling the Assembler
• Controlling the Linker
• Thumb Mode
• Working with Memory Models
• Customizing the Green Hills Run-Time Environment
• Other Topics
4. Developing for ARM

This chapter describes the ARM target environment, and provides information
about some of the more commonly used Builder and driver options used to
access and control features of that environment.

The Green Hills ARM compiler, assembler, and linker comply with the ARM
Embedded Application Binary Interface specification (ARM EABI).

ARM Characteristics
The ARM memory is byte-addressed with 32-bit addresses. Bits are numbered
with bit zero as the least significant bit.

By default, the ARM compiler uses little endian byte ordering, in which the
least significant byte of a multiple-byte value is stored at the lowest address.
The reverse byte order, big endian, is also supported.

Floating-point values use IEEE-754 format (32 and 64 bits) and are in the same
byte order as other values, except when an FPA hardware floating-point unit
is used. In that case, all floating-point values are represented in big endian
byte order.

Note Although we follow the IEEE-754 floating-point format, floating-point


operations might not generate the exact values required by the specification.

On systems where the compiler generates code for a floating-point unit,


the floating-point computation is as accurate as the underlying hardware
(Green Hills does not supply software libraries to handle cases that the
hardware may ignore or signal an exception on). On systems where the Green
Hills floating-point emulation routines are used instead of hardware, the
floating-point emulation routines are designed for speed, and the results may
differ from the IEEE specification, particularly in exceptional cases such as
NANs and denormals.

By default, the ARM chip uses software floating point, which means the
compiler emits library calls to perform most floating-point arithmetic operations.

Character encoding is ASCII.

The stack is always 4-byte aligned.

84 MULTI: Building Applications for Embedded ARM


Register Usage

In C and C++, bitfields are allocated starting at the lowest memory address.
Bitfields begin at the least significant bit in little endian mode and at the most
significant bit in big endian mode.Each structure, union, and array is aligned to
the maximum alignment requirement of any of its components.

Data types long long and unsigned long long are 64 bits, aligned
to 4 bytes, and are held in pairs of 32-bit registers.

The following table describes data type alignments for C and C++.
C/C++ data type Size Alignment
char 8 8
short 16 16
int 32 32
long 32 32
long long 64 32
float 32 32
double 64 32
long double 64 32
* (pointer) 32 32
enum (default) 32 32

Note To reduce the size and alignment of the enum type to 8 or 16 bits where
possible:

Set the C/C++ Compiler→Data Types→Use Smallest Type Possible


for Enum option to On (--short_enum).

Register Usage
The ARM processor has sixteen 32-bit registers accessible for integer values.

Some ARM systems have a Floating-Point Accelerator (FPA) hardware


floating-point coprocessor and eight hardware floating-point registers used for
floating-point values in hardware floating-point mode. These registers can store
either single-precision or double-precision values in a single register.

Green Hills Software, Inc. 85


4. Developing for ARM

Other processors have a Vector Floating-Point (VFP) hardware floating-point


coprocessor, with thirty-two single-precision floating-point registers,
overlapping sixteen double-precision floating-point registers.

In software floating-point mode, a single-precision floating-point value is


contained in a single integer register and a double-precision floating-point value
is contained in two consecutive integer registers. There is no requirement that
the lower register number for a double-precision floating-point value be even.

The general registers are as follows:


General Alternate
Register Name Use
r0-r3 Argument registers, not saved across calls
r4-r7 Permanent registers, saved across calls
r8-r10 Permanent registers, not allocated by the compiler in
Thumb mode. In PID mode, r9 is the PID base register.
r11 FP Either a permanent register or the frame pointer
r12 IP Scratch register, not saved across calls
r13 SP Stack pointer
r14 LR Link register
r15 PC Program counter

The floating-point registers are as follows:


VFP Hardware
FPA
Floating-Point
Hardware
Register
Floating-
Point Single- Double-
Register Precision Precision Use
f0-f3 s0-s15 d0-d7 Argument registers, not saved across calls
f4-f7 s16-s31 d8-d15 Permanent registers, saved across calls

Structure Packing
The Green Hills compilers always allocate fields of a structure in the order
specified in the declaration. It may be necessary for the compiler to insert one
or more bytes of padding to ensure that a field begins at an offset from the

86 MULTI: Building Applications for Embedded ARM


Structure Packing

beginning of the structure that is a multiple of the alignment of that field. The
alignment of a field is determined by its type. The maximum alignment of a field
is 4 bytes. This alignment applies to fields of type float, int, long, long
long, and double, as well as all fields with pointer types. Fields of type
short have 2-byte alignment and fields of type char have 1-byte alignment.

Packing is a feature that reduces the maximum padding the compiler will
insert between fields. If a structure is packed to 2 bytes, then each field has
a maximum alignment of 2 bytes, and at most 1 byte of padding will ever
be inserted between fields. The structure itself will also have a maximum
alignment of 2 bytes.

Use the C/C++ Compiler→Alignment & Packing→Packing


(Maximum Structure Alignment) option (-pack=n), where n is 1,
2, or 4.

In addition, the #pragma pack() directive controls the packing of an


individual structure. The directive must appear before the beginning of the
declaration, listing the fields of the structure. The directive should not be used
inside of a structure declaration. If 1, 2, or 4 appears inside the parentheses
(), that changes the packing until the next #pragma pack() directive. If
there is no number inside the parentheses (), then packing resets to the default
level of 4 bytes.

Example 1.
struct s {
char c;
int i, j;
} a;
#pragma pack(2)
struct s x;
struct s2 {
char c;
int i, j;
} b;
#pragma pack()
struct s2 y;

The size of a and the size of x are both 12. Three bytes of padding appear
between field c and field i. Since struct s was already declared, the
directive #pragma pack(2) does not affect the declaration of x.

Green Hills Software, Inc. 87


4. Developing for ARM

The size of b and the size of y are both 10. One byte of padding appears
between field c and field i. Since struct s2 was already declared,
#pragma pack() does not affect the declaration of y.

Note The use of the #pragma pack() directive may generate structures in
which some of the fields are not fully aligned. The compiler can automatically
generate code to access unaligned fields correctly, but such accesses may be
inefficient. Furthermore, it is not legal to access the address of an unaligned
field. This problem may come up more frequently in Thumb mode.

88 MULTI: Building Applications for Embedded ARM


Specifying an ARM Target

Specifying an ARM Target


The Builder and compiler drivers support many of the most popular ARM
boards and the entire ARM family of microprocessors. The compilers can
produce more efficient code if you specify the target on which you intend to
run the finished executable. Options are provided to specify the exact processor
configuration desired. These options may affect the predefined preprocessor
symbols, the compiler, the assembler, and the selection of header files and
libraries used by the linker.

Many of the most popular ARM boards are supported through tailored linker
directives files that greatly simplify the process of linking and loading an
executable. To specify a particular target board:
When creating a new project with the New Project Wizard (see
“Creating a New Project: The New Project Wizard” on page 24),
choose the appropriate target board. To subsequently change your
target in the Builder, click Edit → Set Build Target, and choose a
target from the Target Selector dialog box.
To specify a target board with the driver, pass the -bsp board option.
To obtain a list of supported boards, enter -bsp=? (or -bsp=\? in many
shells).

If your board is not supported, you should specify your target processor instead.
Specifying a target processor enables the driver to determine the most efficient
instruction set to use in code generation.

All major ARM processors are supported. To specify a target processor:


When creating a project with the New Project Wizard (see “Creating
a New Project: The New Project Wizard” on page 24), expand the
Generic option in the Board Name box, and choose the appropriate
processor. To subsequently change your target in the Builder, click Edit
→ Set Build Target, and choose a target from the Target Selector
dialog box.
To specify a target processor with the driver, pass the -cpu=cpu
option. To obtain a list of supported processors, enter -cpu ? (or
-cpu=\? in many shells).

Green Hills Software, Inc. 89


4. Developing for ARM

ARM Processor Variants


The following ARM processor variants are supported:
Defaults
Driver
Option Predefined Library Floating Point
Processor -cpu= Macro Name Directory
ARM6 arm6 __ARM6 arm3 Software
ARM7 (default) arm7 __ARM7 arm3 Software
ARM7 with v3M arm7m __ARM7m arm3 Software
ARM7TM arm7tm __ARM7tm arm4 Software
ARM8 arm8 __ARM8 arm4 Software
ARM9 arm9 __ARM9 arm4 Software
ARM9E arm9e __ARM9E arm5 Software
ARM10 arm10 __ARM10 arm5 Software
microRad microRAD __MicroRAD armfp Hardware
StrongARM strongarm __StrongARM arm4 Software
XScale xscale __XScale arm5 Software
ARM11 arm11 __ARM11 arm5 Software

For more information about controlling floating-point support, see


“Floating-Point” on page 132.

90 MULTI: Building Applications for Embedded ARM


Generating Debugging Information

Generating Debugging Information


Green Hills incremental debugging technology is a state-of-the-art system for
producing, processing, and storing debugging information that is much faster
than, and requires a fraction of the memory of, traditional solutions.

To generate debugging information for use with the MULTI Debugger:

Set the Debugging→Debugging Level option to MULTI (-G).

The diagram below illustrates the creation of debugging information:

Green Hills Software, Inc. 91


4. Developing for ARM

As the compiler and assembler translate each C or other high-level language file
into an object file, they also generate associated debugging information. For
each object file created, a separate file with the same name but a .dbo extension
is produced to hold this information. After the executable is linked together,
these individual debugging information files are combined into a structure that
can be quickly searched and incrementally loaded.

In the diagram, the files foo.c and bar.c are passed to the toolchain, which
generates files foo.o and bar.o and links them together to generate an executable,
baz. In addition, the debugging information files foo.dbo and bar.dbo are
generated and passed to the dblink utility, which also extracts the executable’s
namelist information (via the gnm utility), and generates the following two files:

• baz.dnm — the debug symbol table for baz.


• baz.dla — an archive of the .dbo files associated with baz
When the executable is opened in the MULTI Debugger, baz.dnm controls the
loading of debugging information from baz.dla as necessary.

Note

• The creation of debugging information for libraries is performed in the same


way as for object files, except that an additional file with a .dba extension is
generated to combine the debugging information for all of the members of
the library.
• Debugging information is only created or updated when you create an
executable or a library with the Builder or driver, and not when the linker
or librarian are invoked separately.
• If you move an executable, library, or object file, you should also move the
associated debugging information files. Otherwise, it may be necessary to
rebuild or relink your program before you can use the MULTI Debugger.
• The files foo.dnm and foo.dla are generated even if the
Debugging→Debugging Level option is not set to MULTI (-G), so that
MULTI can obtain skeletal debugging information for the executable.
However, you must enable this option in order to perform source-level
debugging and to view assembly language interlaced with your source.

For more information about debugging options, see “Debugging Options” on


page 147. For information about using the MULTI Debugger, see MULTI:
Debugging.

92 MULTI: Building Applications for Embedded ARM


Generating Debugging Information

Obtaining Profiling Information


The MULTI Debugger can analyze various forms of profiling information,
to help you make your program run more efficiently. This section describes
how to compile your program so that profiling information is available to the
Debugger. For information about the various forms of profiling, and how to use
them, see Chapter 15, “Using the Profiler” in the MULTI: Debugging book.

Call Count Profiling


To obtain Call Count profiling information:

Set the Debugging→Profiling - Call Count option to:


• On (-p), or
• On with Call graph (-pg).

Coverage Profiling
To obtain Coverage (also known as Block Count) profiling information:

Set the Debugging→Profiling - Coverage option to On (-a).

Green Hills Software, Inc. 93


4. Developing for ARM

Target-Based Timing Profiling


This section describes how to obtain Timing information for stand-alone targets
and some real-time operating system targets.

Target-Driven Timing Profiling is supported by ind_manprf.c and


arm_manprf.h in the source of libsys.a. This form of profiling, which is
generated by the target periodically sampling its own PC, is faster and more
accurate than host-driven profiling.

The Target-Driven Timer Profiling library module, ind_manprf.o, is not linked


into your program by default. To link with it and enable this form of profiling,
follow these steps:

1. Review ind_manprf.c for instructions. If an example header file is


provided with board-specific code for implementing the necessary
interrupts, then make and save any appropriate edits. Otherwise create a
new header file, using the example files as a template.
2. Rebuild libsys.a. For information about rebuilding Green Hills libraries,
see “Customizing the Run-Time Environment Libraries and Object
Modules” on page 580.
3. To link in the ind_manprf.o module:

Set the Debugging→Profiling - Target-Based Timing option to On


(-timer_profile).

Rebuild your application. If linker errors result, you may need to review
the settings for your board in the Target-Driven Timing Profiling source
files mentioned in the preceding.
4. Open your application in the debugger, enable profiling and run your
program in the usual way. For more information about profiling, see
Chapter 15, “Using the Profiler” in the MULTI: Debugging book.

94 MULTI: Building Applications for Embedded ARM


Optimizing Your Executable

Optimizing Your Executable


Green Hills provides many different ways of optimizing code, both to reduce the
size and to increase the speed of your program. To enable general optimizations
that improve both size and speed:

Set the Optimization→Optimization Strategy option to Optimize for


General Use (-O).

Reducing Program Size


To enable optimizations that emphasize the reduction of program size over
performance speed:

Set the Optimization→Optimization Strategy option to Optimize


for Size (-Ospace).

Increasing Program Speed


To enable optimizations that emphasize the increase of performance speed
over program size:
Set the Optimization→Optimization Strategy option to Optimize for
Speed (-Ospeed).
To further increase your program speed (at the cost of a substantial
increase in compilation time), set the Optimization→Intermodule
Inlining option to On (-OI)

For information about these and other optimization options, see “Optimization
Options” on page 143. For detailed descriptions of the various optimizations,
see Chapter 19, “Optimization Descriptions”.

Green Hills Software, Inc. 95


4. Developing for ARM

Using Your Own Header Files and Libraries

Note For information about the headers and libraries provided with your
distribution, see Chapter 16, “Libraries and Header Files”.

If your project is of any size or complexity, you will probably want to create
your own libraries of frequently used functions, and to instruct the compiler
to link against them. While the compiler knows where to find the standard
libraries and header files provided with your distribution and automates linking
against them, you must tell it where it should search for your own headers and
libraries. At link-time, the linker will attempt to resolve external references in
the source files you pass to it by linking against your libraries before searching
the standard libraries.

Instructing the Compiler to Search for Your Headers


To instruct the compiler to look for header files in a new directory:

Enter the directory in the Project→Include Directories option


(-Idirectory).

You can specify multiple directories. The compiler searches the directories in
the order in which they are specified.

#include <header> vs. #include "header"


The compiler recognizes both standard forms of the #include directive.
These forms can specify either a full path or only a filename, so the full range of
possible types of #include directives is as follows:
UNIX host Windows host
A #include "/src/h/header.h" #include "f:\src\h\header.h"
B #include </src/h/header.h> #include <f:\src\h\header.h>
C #include "header.h" #include "header.h"
D #include <header.h> #include <header.h>

96 MULTI: Building Applications for Embedded ARM


Using Your Own Header Files and Libraries

The compiler searches for header files included with the various types of
#include directive in the following ways:

• If the #include directive specifies a full path to the header file (cases A
and B above), the compiler searches:
in that location only. It does not search for another version of the file in
any other directory.
• If the #include directive specifies only a filename or a partial path for the
header file, and uses quotes (case C above), the compiler searches:
in the directory of the source file that contains the #include directive,
and then
in any directories specified with the Project→Include Directories
option (-Idirectory), in the order in which they appear on the command
line, and then
in the default directories (see “C and C++ Header File Directories” on
page 549).
• If the #include directive specifies only a filename or a partial path for the
header file, and uses angle brackets (case D above), the compiler searches:
in any directories specified with the Project→Include Directories
option (-Idirectory), in the order in which they appear on the command
line, and then
in the default directories (see “C and C++ Header File Directories” on
page 549).

Modifying Header File Searches


Specifying a dash (-) in the Project→Include Directories list (-I- ) changes
the rules for searching for header files where only a filename or partial path is
given (cases C and D):

• For #include “header” directives, this prevents the compiler from


searching for header in the directory containing the source file. In other
words, it forces the compiler to process the #include “header” directive
in the same way it normally processes the #include <header> directive.
• For #include <header> directives, it instructs the compiler to search for
header only in the directories listed with -Iinclude_directory that appear
after it on the command line. For example, suppose the command line

Green Hills Software, Inc. 97


4. Developing for ARM

includes -Isys -I- -Iinc. In this case, the compiler searches for
include files in the inc directory, but not in the sys directory.

Note Using #include "header" can create problems if you keep source
files and header files in the same directory and then make local copies of either
source files or header files. For example, suppose you are working with a local
copy of a header file but do not have local copies of all source files. When
the compiler processes a non-local source file with a #include "header"
directive, it finds the non-local header file in the directory of the non-local
source file before it finds the local copy of the header file.

The simplest way to avoid this problem is to always keep your source files
and header files in different directories. If your source files and header files
must share a directory, you can avoid problems by always using #include
<header> instead of #include "header".

If you must use #include "header", you can specify a dash (-) in the
Project→Include Directories list (-I- ) to force the compiler to process the
directive as it does the #include <header> directive. When this appears
anywhere on the command line, the compiler does not look in the directory
containing the source files, regardless of which #include directive is used in
the source files.

Modifying C++ Header File Searches


Since C++ headers do not necessarily have a .h extension, there may be
confusion between the legitimate headers and other files or subdirectories
with the same name. To limit such confusion, you can create a new directory,
dedicated to C++ headers without extensions, and specify this directory to the
compiler for searching as follows:
Specify the appropriate directory in the Advanced→Advanced
Preprocessor Options→Advanced Include Directories→C++
Include Directories option (--cxx_include_directory directory).
When searching for C++ headers without extensions, the driver will
ignore any directories specified with the Project→Include Directories
option (-Iinclude_directory), and will search only in the directory
specified with this option.

98 MULTI: Building Applications for Embedded ARM


Controlling the Assembler

Instructing the Compiler to Link Against Your Libraries


To instruct the compiler to link against your libraries:
• Specify the directories to search in the Project→Library
Directories option (-Llibrary_directory).
• Specify the library names to link against in the Project→Libraries
option (-llibrary). Note that the names of libraries must be specified
in their abbreviated form. For example, a library called libfoo.a
would be specified as foo.

Controlling the Assembler


Unless you instruct them otherwise, the Builder or driver automatically invokes
the assembler, asarm, to process the assembly file output of the compiler.

You can control the most commonly used features of the assembler with Builder
and driver options. For example, to instruct the assembler to produce a source
listing file:

Specify a filename in the Assembler→Source Listing Generation


option (-list[=file]).

For a list of all the assembler-specific Builder and driver options, see
“Assembler Options” on page 180. For detailed documentation of the
assembler, see Chapter 7, “The asarm Assembler”.

Green Hills Software, Inc. 99


4. Developing for ARM

Controlling the Linker


Unless you instruct them otherwise, the Builder or driver automatically invokes
the linker, elxr, to combine the object file output of the assembler.

You can control the most commonly used features of the linker with Builder
and driver options. For example, to instruct the linker to strip the executable
after linking:

Set the Linker→Executable Stripping option to On (-strip).

For a list of all the linker-specific Builder and driver options, see “Linker
Options” on page 183. For detailed documentation of the linker, see Chapter
9, “The elxr Linker”.

100 MULTI: Building Applications for Embedded ARM


Thumb Mode

Thumb Mode
Certain ARM processors support the execution of Thumb code, which is a 16
bit restricted interface to the 32-bit ARM processor. Every Thumb instruction
maps to an equivalent ARM instruction, with identical behavior. Choosing to
do so can decrease code size by sacrificing execution time. Since Thumb code
is more compact, switching from ARM to Thumb typically reduces overall
code size (by up to 35 percent), and increases the total number of instructions
required. Consequently, execution time may increase by up to 30 percent.
When both size and speed are important, we recommend that you selectively
use the smaller, slower Thumb code only for those sections of code which
are executed infrequently.It is possible to mix ARM and Thumb encodings in
the same application.

The following version 4 and higher architectures currently support Thumb


operation:

• ARM7TM
• ARM9
• ARM9E
• ARM10
• XScale
• ARM11
ARM6, ARM7, ARM8, and StrongARM do not support Thumb mode.
Attempting to use Thumb mode on CPU’s that lack Thumb support results
in a build error.

To enable the generation of Thumb code:


Set the Target→Instruction Set→Thumb Code Generation option
to On (-thumb).
To enable linking with Thumb libraries:
Set the Target→Instruction Set→Thumb Libraries option to On
(-thumb_lib) — this option automatically enables Target→Instruction
Set→Thumb Code Generation (-thumb)
Note that if you are using the ccthumb or cxthumb compiler driver
then Thumb code will automatically be generated and linked to Thumb
libraries

Green Hills Software, Inc. 101


4. Developing for ARM

Mixed ARM/Thumb

Switching Between Thumb and ARM in Assembly Files


In Assembly, use the .thumb and .nothumb directives to switch between
Thumb and ARM. For example:
.thumb
.globl thumbcode
thumbcode:
mov r0,r1
bx lr

.nothumb
.globl armcode
armcode:
stmfd sp!,{r0}

For correct disassembly, a global label must appear at every mode change. This
restriction may be removed in the future.

If you are programming in mixed ARM/Thumb assembly language for a version


4 architecture, you must:

• Ensure that each assembly routine that may be called from a mixed mode
has only one return instruction located at the end of the routine, or that
the routine returns with the bx instruction. If a routine has multiple return
points, the linker can patch only the last return point. The routine must end
in one of the following instructions:
ldmfd sp!, {..., pc} (ARM)
pop {..., pc} (Thumb)
bx reg
mov pc, lr
• Explicitly specify the symbol size using a .size directive in the assembly
source, and tag it as a function with .type.

102 MULTI: Building Applications for Embedded ARM


Thumb Mode

Example 1.
.text
.align 4
.globl sample_func
sample_func:
...
...
.type sample_func,$function
.size sample_func,.-sample_func

Switching Between Thumb and ARM in C and C++ Files


To switch between Thumb and ARM in C and C++ files, use #pragma ghs
thumb and #pragma ghs nothumb. For example:
#pragma ghs thumb
int ThumbFunction()
{
return 0;
}
#pragma ghs nothumb
int ArmFunction()
{
return ThumbFunction();
}
#pragma ghs thumb
int main()
{
return ArmFunction();
}

ret Pseudo Instruction


The assembler assembles the pseudo instruction ret differently depending on
whether the target processor supports and uses 16-bit mode or not.

If Thumb mode is supported and used, ret is assembled as:


bx lr

If Thumb mode is not supported, ret is assembled as:


mov pc,lr

Green Hills Software, Inc. 103


4. Developing for ARM

Linker Behavior
The linker has built-in support for mixed-mode application development.

If the linker determines that there are calls between functions of different types
(16-bit versus 32-bit) within the application, it will modify the program to
switch modes appropriately.

Version 4 architectures (ARM7TM, MICRORAD, ARM9) will transfer mixed


mode calls to a veneer stub inserted before the destination function, which will
transfer from 32-bit to 16-bit modes or vice versa. The final instruction of the
callee may also be patched. For example, a load instruction to the Program
Counter will be replaced with a load instruction to another register, followed
by a bx through that register.

In order to determine the exit instruction of a called function that may require
patching, the linker depends on two restrictions:

• The function has only one exit point, which is contained in the last
instructions of the function.
• The size of the function is known at link time.
For code written in high-level languages, the Green Hills ARM compiler
enforces these two restrictions. If you are hand-coding mixed ARM/Thumb
assembly code, see “Switching Between Thumb and ARM in Assembly Files”
on page 102 to ensure that your code meets the linker’s criteria.

Version 5 and higher architectures (ARM9E, ARM10, XSCALE, ARM11)


simply replace bl instructions with blx instructions to implement mixed
mode calls. A load multiple instruction to the Program Counter on version 5
processors will switch modes appropriately, so no patching of the callee is
necessary.

The caller-callee relationship is determined by examining the relocations in the


linked files. Functions called through pointers are automatically patched in
the presence of mixed code.

Limitations in the Thumb Code Generator


To produce the tightest code, the Thumb function entry and exit code does
not contain the extra information that allows stack traces on the target. This

104 MULTI: Building Applications for Embedded ARM


Thumb Mode

prevents the following debugging/profiling features from functioning while in


Thumb mode or while Thumb functions are on the call stack:

• Call analysis
• Coverage analysis
• Memory leak reporting
• Hardware Floating-Point — Only software floating point is supported. Since
the calling convention differs between hardware and software floating
point with regard to floating point parameters, intercalls from arm code
compiled for hardware floating point to thumb functions requiring floating
point parameters and vice versa are not permitted. When mixing hardware
floating point arm code with software floating point thumb code, you should
avoid directly passing floating point parameters for intercalled functions.
You can pass VFP floating point values by reference to software floating
point functions, as the representation in memory is identical.

Green Hills Software, Inc. 105


4. Developing for ARM

Working with Memory Models

Program Sections
Program sections are labeled collections of program objects. The compiler
assigns all data and text objects to the appropriate sections at compile time.
The standard program sections are:

• .text — which holds program code.


• .data — which holds external variables with explicitly initialized values
(e.g. int i=1;).
• .bss — which holds variables that are not explicitly initialized (e.g. int
j;). The Green Hills startup code automatically initializes the .bss section
to all zeros, as required by the C and C++ languages.
• .rodata — which holds read-only data

Note The compiler will, by default, place variables that are explicitly
initialized to zero into .bss. To place such objects in .data instead, set
the Target→Memory Models→Placement of Zero-Initialized Data option
to Place Zero-Initialized Data in .data (-no_discard_zero_initializers) (see
“Memory Models” on page 133). In contrast, the optimizer may reallocate
certain uninitialized variables from .bss into .data. For information about
this optimization and how to control it, see “Data Definition Movement” on
page 646. Variables placed in user-defined sections with the #pragma ghs
section directive are not affected.

The linker collects all data for each named section and locates that section in
memory, guided by a section map that is defined in a user-supplied or default
linker directives file. The section map specifies the desired location of each
section and the order of the sections in the final output file.

You can also create sections, assign them to specific regions of memory, and
assign variables to them.

The linker provides definitions for several symbols that, if referenced and
not defined, are given certain addresses corresponding to the final image.
These symbols are constructed by prepending the strings __ghsbegin and
__ghsend to the name of each section in the final image, and changing the
periods (“.”) in the section names to underscores (_). For example, for a section

106 MULTI: Building Applications for Embedded ARM


Working with Memory Models

named .text, the symbols __ghsbegin_text and __ghsend_text


refer to the virtual start and end addresses of that section. For more information,
see “Beginning, End, and Size of Section Symbols” on page 302.

Controlling Code Placement with #pragma ghs section


In embedded programming, you must sometimes place certain variables in
specific memory regions. For example, there may be different kinds of RAM
memory available, some fast and some slow, and selected variables need to
be placed into the fast RAM. Use the Green Hills compiler and linker to
achieve this and similar goals by grouping variables into program sections and
positioning them as desired in memory.

To group program variables and position them in memory:

• Create named sections, and assign them to memory regions using a linker
directives file.
• Assign variables to specific sections using the #pragma ghs section
directive, which has the following syntax:
#pragma ghs section[secttype="sectname"[,secttype="sectname"]...]

sectname is the user-defined section name, 30 letters or fewer in length, and


by convention starts with a period (.). The word default may be used
in place of any sectname. While normal section names are specified in
quotes, the word default is not.

secttype specifies which kind of data item is affected by the #pragma


directive and may be any of those listed in “Program Sections” on page 106
(without the leading period).

Each occurrence of the #pragma ghs section directive specifies a


mapping of data types to section names. It leaves mappings from earlier
#pragma directives in place, except for those that it explicitly overrides.
Specifying default in place of a quoted section name removes any mapping
for that particular secttype.

The following statement removes all mappings and restores the section
assignment rules to their initial state:
#pragma ghs section

Green Hills Software, Inc. 107


4. Developing for ARM

Mappings affect variables at the point at which they are defined. The section in
which each variable is placed is determined by the mapping in the source file.
One can place different variables in different sections by interspersing section
#pragma directives among the variable declarations. The compiler determines
which section each variable would normally fall into and then checks whether
variables of that type have a mapping. If so, the section specified in the mapping
is used in place of the default.

For example, consider the following line of C code:


int foo=3;

The variable foo is normally placed into the .data section because it is
initialized to an explicit value. However, if this line of code were preceded
by the following:
#pragma ghs section data=".mydata"

then the variable foo would be placed in the section .mydata instead.

You can also specify user-defined sections for .bss variables.

Specifying a user-defined section for the .rodata section type places certain
read-only (const) variables into the specified section. The eligible objects
depend on the specific target system and compile-time options. Typically, these
include const variables and string literals.

108 MULTI: Building Applications for Embedded ARM


Working with Memory Models

Example 1.

Three different variables might be assigned to three different sections the


following way:
/* Assign x1 to section .data1 */
#pragma ghs section data=".data1"
int x1 = 1;

/* Assign x2 to section .data2 */


#pragma ghs section data=".data2"
int x2 = 2;

/* Assign x3 to section .data3 */


#pragma ghs section data=".data3"
int x3 = 3;

/* Now go back to default rules */


#pragma ghs section data=default

Note In some environments, only one text section is allowed. This means
that #pragma ghs section text="text1" must appear in the
file before any functions. It also means that #pragma ghs section
text=default and #pragma ghs section should not be used after the
text section has been renamed.

This #pragma directive should be used outside of any function.

Run-Time Environment Sections


The Green Hills run-time environment uses some special program sections. The
sections are defined in linker directives files and are used by the run-time object
files libsys.a, libstartup.a, and crt0.o to set up the run-time environment. If
you are creating user-defined sections, do not duplicate the names of these
special sections. For more information about these special sections, see
“Customizing the Run-Time Environment Program Sections” on page 299.

Green Hills Software, Inc. 109


4. Developing for ARM

Locating Program Sections in ROM and RAM


In embedded programming, it is generally the case that all program sections
must be initially located in ROM to prevent their loss upon reset, and that
any program sections that contain data which may change at run-time must
be copied into RAM at startup. Working within these restrictions, embedded
programmers must decide how much of their other program code will be copied
into RAM at startup. There are two factors which influence this decision: the
amount of available RAM and the emphasis on speed of execution. In general:

• Programs that copy all of their sections from ROM to RAM at startup will
execute more quickly, but will require more RAM.
• Programs that copy as few sections as possible from ROM to RAM at startup
will require less RAM, but will execute more slowly.

Default linker directives files and options are provided to manage the location
of program sections. To specify a particular layout when creating a project
with the New Project Wizard (see “Creating a New Project: The New Project
Wizard” on page 24), set the Program Layout option (on the Link Options
screen) to one of the following settings:

• Link to ROM and execute out of RAM — Uses the standalone_romcopy.ld


linker directives file, which maximizes execution speed by copying all the
program sections from ROM to RAM at startup.
• Link to and execute out of ROM — Uses the standalone_romrun.ld
linker directives file, which minimizes RAM usage by copying as few
program sections as possible from ROM to RAM at startup.
• Link to and execute out of RAM — Uses the standalone_ram.ld linker
directives file, which loads the program directly into RAM. This layout is
often used in the early stages of debugging, when you may prefer to have
the MULTI Debugger download your program to RAM and start it running.

Whichever layout you choose, the New Project Wizard will create all three
.ld files and place them in the src/resource.gpj subproject. To change your
program layout, simply copy the relevant file into your project, and delete
whatever other .ld file was previously there.

110 MULTI: Building Applications for Embedded ARM


Working with Memory Models

Note For information about manually editing linker directives files to control
this feature, see “Modifying your Section Map for Speed or Size” on page 297.

Verifying Program Integrity

You can use the __secinfo structure to checksum sections in memory to


verify that they have not changed from the state in which they were created by
the linker. To do this, set the Linker→Link-Time Checking→Checksum
option to On (-checksum) (see “Link-Time Checking” on page 190) to instruct
the linker to calculate a Cyclic Redundancy Check (“CRC”) checksum for
each SECINFO_TEXT or SECINFO_DATA section of non-zero length and
store it as the last 4 bytes of the section. Upon initialization, you can scan the
__secinfo table, calculate the same CRC on all but the last 4 bytes of .text
and .data sections, and then compare the result to the stored CRC. A match
indicates that the program has the same byte values in memory that it had when
the linker created the executable file. For more information about performing
checksums, see install_dir/src/libstartup/cksum.c. For more information
about the __secinfo structure, see install_dir/src/libsys/indsecinfo.h.

Green Hills Software, Inc. 111


4. Developing for ARM

Position Independent Code (PIC)


Position independent code (PIC) is code that can be run at an address that was
not known at the time the code was linked. You can use PIC to create executable
files that can be placed anywhere in memory.

PIC involves the calculation of the address of any object in a .text section,
typically a function label. Addresses in C can appear as:

• Local branches
• Normal function calls
• Far function calls
• Switch statements
• Function pointers
Instructions that implement local branches and normal function calls are relative
to the program counter (PC) and therefore are inherently position-independent;
no additional code is needed to achieve position independent code. To achieve
position independent code for far function calls, switch statements, and function
pointers, the compiler must generate additional code.

To compile a program with position independent code:

Set the Target→Memory Models→Position Independent Code


option to On (-pic).

When you enable PIC, the linker suppresses errors that identify overlapping
sections.

Running a PIC Program with the Simulator


When running a PIC program on the simulator without the MULTI Debugger,
you should pass the -text offset option in order to specify the PIC offset. For
example, to run the PIC program myprog on the simulator and to load the
program code at address 0x100000, enter:
simarm -text 0x200000 myprog

112 MULTI: Building Applications for Embedded ARM


Working with Memory Models

Alternatively, you can use the grun utility with the -text offset option to run the
simulator. For example, to run myprog as above, enter:
grun -text 0x100000 simarm -- myprog

For more information about the grun utility, see “The grun Utility Program”
on page 378.

Debugging a PIC Program


When debugging a PIC program in the MULTI Debugger, you must specify the
PIC base address so that the Debugger can properly offset the addresses of code.
You can specify the PIC base address in two ways:

• Use the -text option when starting the MULTI Debugger from the command
line. For example, to start debugging a PIC program myprog with the PIC
base address set to 0x100000, enter:
multi -text 0x100000 myprog

• Set the _TEXT variable while the Debugger is running. For example,
suppose you open a PIC program myprog in the Debugger and want to set
the PIC base address to 0x100000. In the Debugger command pane, enter:
_TEXT=0x100000

Combining PIC with Other Modules


You can link modules that were compiled with PIC with modules that were not,
as long as the resulting program does not run as a PIC program. Any program
that is running as PIC must have all its source modules compiled with PIC.

To reduce the number of library variants, Green Hills embedded system libraries
are built with PIC enabled. Therefore, the same libraries can build both PIC
and non-PIC executables. PIC addressing calculations are made relative to the
PC register.

Green Hills Software, Inc. 113


4. Developing for ARM

Position Independent Data (PID)


If you enable Position Independent Data (PID), the executable file is built so
that the program’s data can be located at any position in memory.

Because data accesses are not inherently position-independent, PID requires


a base register that is initialized by the operating system, monitor, or program
loader to pinpoint the location of the data segment in the memory.

To compile a program with position independent data:

Set the Target→Memory Models→Position Independent Data


option to On (-pid).

When you enable PID, the linker suppresses errors that identify overlapping
sections.

Running a PID Program with the Simulator


When running a PID program on the simulator without the MULTI Debugger,
you should pass the -data offset option in order to specify the PID offset. For
example, to run the PID program myprog on the simulator and to load the
program data at address 0x200000, enter:
simarm -data 0x100000 myprog

Alternatively, you can use the grun utility with the -data offset option to run the
simulator. For example, to run myprog as above, enter:
grun -data 0x200000 simarm -- myprog

For more information about the grun utility, see “The grun Utility Program”
on page 378.

Debugging a PID Program


When debugging a PID program in the MULTI Debugger, you must specify the
PID base address so that the Debugger can properly offset the addresses of data.
You can specify the PID base address in two ways:

114 MULTI: Building Applications for Embedded ARM


Working with Memory Models

• Use the -data option when starting the Debugger from the command line.
For example, to start debugging a PID program myprog with the PID base
address set to 0x200000, enter:
multi -data 0x200000 myprog

• Set the _DATA variable while the Debugger is running. For example, to set
the PID base address to 0x200000, enter the following in the Debugger
command pane, enter:
_DATA=0x200000

Initializing the PID Base Register


The PID base register, by convention r9, must be initialized with the starting
address of the data segment. One way of doing this is to have the loader,
monitor, or operating system initialize the base register when loading the
program on the target. Alternatively, the program’s startup code can initialize
the base register each time it runs. If the data segment of the program is loaded
into ROM and then copied from ROM to RAM at startup, be sure that the base
register is initialized properly by the operating system or startup code.

Combining PID with Other Modules


You cannot link libraries or modules compiled with PID with libraries or
modules that were not. Two sets of libraries are included, one set supporting
PID and one set without PID. To use the PID-enabled libraries, link your
program with the PID option selected.

Near and Far Function Calls


A function call is normally performed with an instruction that contains a
24-bit value that is shifted left by 2 and is added to the address of the current
instruction to yield the address of the called function. If the offset of the called
function is greater than 26 bits, an error will occur at link time.

To avoid this problem, the compiler provides support for far function calls. The
compiler generates a series of instructions to place the address of the called
function into a register before using an instruction to call the function. This

Green Hills Software, Inc. 115


4. Developing for ARM

method allows you to reach a function anywhere in the address space of the
processor, but it requires additional code size and processor time.

Call Patching
In most cases, the linker is able to detect out of range calls, and inserts veneers
to the far function as necessary. This method is the default behavior of the
linker and does not require the setting of options or modification of source code.
A far call using this method requires two branches, one to the veneer and one to
the function itself, which may reduce execution speed for the call. Nonetheless,
this is generally the recommended method for making far function calls on
the ARM architecture. This method impacts code size and run time less than
using the Target→Memory Models→Far Calls option, because only those
calls that are out-of-range are affected.

Note Functions declared with the static keyword cannot be patched in


this way, but far calls will be generated for them if you use a #pragma (see
“Function Call #pragma Directives” on page 116).

Far Function Call Build Option


To enable far function calls for every function:

Set the Target→Memory Models→Far Calls option to On (-farcalls).

This option instructs the compiler to generate a far function call for every
call (with no need for modifications to the source code), unless the option is
overridden by one of the other methods specified below. This method should
only be used when far call patching is not an effective solution.

Function Call #pragma Directives


The following #pragma directives govern the declaration of functions. When
you use one of these directives, all function declarations after it will be modified
until another #pragma directive occurs.

116 MULTI: Building Applications for Embedded ARM


Working with Memory Models

#pragma ghs near


#pragma ghs callmode=near
Any function declared after this directive will be called using a near function call.
#pragma ghs far
#pragma ghs callmode=far
Any function declared after this directive will be called using a far function call.
#pragma ghs callmode=default
Any function declared after this directive will be called as directed by the build
option.

Note that in certain cases, such as when both the caller and callee are located in
the same file, the compiler may be able to determine that a far function call is
unnecessary, and so perform a near call regardless of the #pragma directive.

Function Declaration
The keywords __nearcall and __farcall may be placed in the
declaration of a function to specify the type of function call to be used for that
function. These keywords override the setting implied by either the #pragma
directive or the command line option. For example:
__nearcall int nearfunc();
__farcall int farfunc();

The syntax requires that __nearcall and __farcall be placed before the
function return type. If the function returns a pointer, then the __nearcall or
__farcall keyword must be placed before the first asterisk (*).

The __nearcall and __farcall keywords cannot be used for function


pointers, but only for functions themselves. They cannot be used in typedef
statements, casts, or in the type of a function parameter.

Green Hills Software, Inc. 117


4. Developing for ARM

Storing Global Variables in Registers


Machine registers are primarily used by the compiler to store local variables
or working values. This will generally produce smaller and faster code than if
most variables were on the stack. However, in certain circumstances, allocating
critical global data to registers can decrease performance. To reserve up to 3
registers (r4, r5, and r6 in that order):

Specify the number of registers you want to reserve with the


Target→Memory Models→Global Registers (-globalreg=n) option.

This allows the use of the (otherwise illegal) C/C++ register keyword to
place global variables in registers using the following syntax:
register int i; /* file scope implies global */

Note The syntax register static int i is still illegal, because it can
cause a possible register numbering problem when compiling multiple files.

These registers are initialized to zero by the startup module. The data type of the
variable can be any integral or pointer type where a local variable of that type
would be eligible for allocation to a register. It must not be explicitly initialized,
and its address should never be taken. The program must be compiled with
the Green Hills startup code.

Global registers are permanent registers, so functions compiled with this option
can call (but not be called by) functions compiled without it, including third
party object files and libraries. A function may not access variables allocated to
global registers unless all functions in the call chain before it were compiled
with the global registers reserved. The easiest way to guarantee this is to
compile all files with this option. However, since the Green Hills libraries are
not compiled with this option, it is not safe to use variables allocated to global
registers in library callback routines (such as the user-supplied comparison
function called by the stdlib.h functions bsearch() and qsort()). It is
also generally not safe to use variables allocated to global registers in interrupt
functions, as such interrupts may be triggered asynchronously.

If you want to share the same global registers across compilations, consider
placing them into a single #include file, which is always included first in all
compilations to ensure consistency.

118 MULTI: Building Applications for Embedded ARM


Customizing the Green Hills Run-Time Environment

Customizing the Green Hills Run-Time Environment


You can customize the Green Hills run-time environment to implement or
enhance the environment for a particular hardware system by:

• Modifying the source code of the run-time object modules libsys.a,


libstartup.a, and crt0.o, and then rebuilding these object modules (see
“Customizing the Run-Time Environment Libraries and Object Modules”
on page 580). Each source file, including files with only assembly language,
is fully commented. These source files are located in the src/libsys and
src/libstartup directories of your installation.
• Modifying the linker directives file for special program sections that
libsys.a, libstartup.a, and crt0.o use to set up the run-time environment (see
“Customizing the Run-Time Environment Program Sections” on page 299).

Green Hills Software, Inc. 119


4. Developing for ARM

Other Topics

Renaming the Output Executable


To change the name of the output file:

Enter the desired name in the Project→Output Filename (-o name)


option.

Specifying an Alternate Program Start Address


The linker normally uses the address of the global symbol _start as the start
address for the user program. To specify an alternate start address:
Specify a new symbol in the Linker→Start Address Symbol (-e
symbol_name) option.
For example, to use the symbol newstart as the program start
address, enter the following from the command line:

ccarm -e=newstart file.s

Writing Interrupt Routines


In C and C++, you can declare a function as an interrupt routine. The compiler
will generate code for this function that will save all the registers this function
uses, including the registers that normally can be destroyed across function
calls. Interrupt routines are always compiled in ARM rather than Thumb mode.

Use interrupt functions to handle hardware interrupt and exception conditions.


These functions should be of void type and should take no arguments.

You can use either of the following methods to declare a function as an interrupt
routine:

• Place #pragma ghs interrupt immediately before the function.


• Prepend the __interrupt keyword to the function definition.

120 MULTI: Building Applications for Embedded ARM


Other Topics

Establishing Interrupt Vectors


All ARM interrupt functions must specify a particular interrupt vector entry
using the following directive, which is placed between the function prototype,
and its body:
#pragma intvect function constant_integer

where function is the name of your exception handler, and constant_integer


represents one of the seven exception types defined by the ARM processor.

The compiler uses a .org assembler directive to place the address of the
named function in the memory location that the ARM processor reserves for
the exception type represented by constant_integer.

Example 1.

In this example, the function handler is declared as an interrupt routine


by prepending it with __interrupt, and its interrupt vector is defined by
#pragma intvect as 0x8.
int tick;

__interrupt void handler();


#pragma intvect handler 0x8

__interrupt void handler()


{
tick ++;
}

Note This feature is supported only when using a Green Hills assembler and
is not available in binary code generation mode. You must ensure that the call
destination is within range of the vector or unpredictable behavior may result.

Writing Custom Interrupt Tables


If you want to compile interrupt routines but do not want to use the interrupt
table generated by the compiler, use the -no_auto_interrupt_table option.
This option assumes that you are writing a custom interrupt table to handle
the compiled interrupt routines. This option may be required for hardware
vectoring, for example, with the Atmel AT91.

Green Hills Software, Inc. 121


4. Developing for ARM

SWI Exception Functions


You can place the __swi(value) keyword in the declaration of a function to
indicate that it should be called by an exception rather than a branch, using the
SWI instruction. This syntax may be used in either ARM mode (with a range
of 24 bits) or Thumb mode (with a range of 8 bits).

A function declared with the __swi keyword is not itself a top level interrupt
handler; it is a function that is expected to be called by a separate SWI interrupt
handler when the matching value field is detected. A top level SWI interrupt
handler intended to dispatch different exception values can be declared with
#pragma intvect or it may already be initialized outside the program.

Symbolic Memory-Mapped I/O


Embedded systems may have memory locations reserved for I/O, with the
registers of a hardware device mapped in these locations. Several techniques
access such memory-mapped I/O devices, but using specially named sections
has some advantages.

For memory-mapped I/O, the variables that correspond to the memory locations
should be kept in one or more sections that contain only memory-mapped
locations. These sections should not be initialized during program startup.

This approach creates a C language structure definition that matches the


allocation of the I/O registers in the memory space. Named structure fields are
assigned to correspond to the I/O registers. Next, the #pragma directive is
used to define a variable of the struct type within a named .data section
that holds only this variable. A linker section map places this named section at
the position in memory of the I/O device. The I/O registers are now structure
fields of the variable in the named section.

With this approach, the variable definition can be placed in a source file of
its own. This file is compiled to an object file that is shared among different
projects that need to refer to this I/O device. Each project needs the object file,
an entry in the section map to position the section, and a header file to define
the struct type.

In addition, you can then display the named variable in a MULTI Debugger data
explorer to provide ongoing displays of the state of the I/O registers, and edit
the fields of the data explorer to cause writes to the I/O registers. This displays

122 MULTI: Building Applications for Embedded ARM


Other Topics

and manipulates memory-mapped I/O registers by MULTI view windows,


similar to built-in registers.

For example, consider a simplified universal asynchronous receiver-transmitter


(“UART”) that has three 16-bit registers: an output register, an input register,
and a control/status register, mapped at locations 0x1000, 0x1002, and
0x1004 respectively. With code containing the following lines:
struct uart {
short Tx; /* Transmit Register */
short Rx; /* Receive Register */
short CSR; /* Control/ Status Register */
};
#pragma ghs section bss=".uartsec"
struct uart uart;
#pragma ghs section bss=default

and a section map entry in the linker directives file such as:
SECTIONS {
...
.uartsec NOCLEAR 0x1000 :
...
}

Note The NOCLEAR attribute in the linker directives file prevents the
.uartsec section from being cleared to zeros at startup.

Code can then refer to the registers as uart.Tx, uart.Rx, and uart.CSR.
Within MULTI, the command view uart views a window showing the
contents of the UART registers.

Since MULTI must perform read operations to display this data, this approach
is not suitable for registers that are sensitive to read and write operations (that
is, registers for which accessing a register triggers an activity or referencing a
data location near the register causes problems). Such registers or data locations
are often declared in C/C++ with the volatile qualifier.

Viewpathing: Setting Relative Workspace Paths


Viewpathing is an advanced method of setting a workspace path. It provides
tools with a list of directories to search for requested input files. For example,
with this feature the compiler could first look in the current developer’s local

Green Hills Software, Inc. 123


4. Developing for ARM

source directory for a source file, then in the development group’s group source
directory, and finally in a multi-group global source directory. Viewpathing is
available on UNIX only.

The Viewpath Workspace


When a viewpath is specified (by means of a selected environment variable),
all input filenames become viewpath-relative. To create a viewpath-relative
filename, the tools first determine the difference between the first element of
the viewpath variable and the current working directory. For example, if the
viewpath directories are /1, /2, and /3 and your current working directory is
/1/subdir/, then the difference is subdir/.

This difference is appended to each node in the viewpath, in order to generate


the path prefix to append to the relative filename provided to the tool. In the
previous example, if the tool is given src/file.c, then the searched locations
will be, in order:
/1/subdir/src/file.c
/2/subdir/src/file.c
/3/subdir/src/file.c

Working from a Root Node

You must run all tools from your root node, the current working directory that is
a subdirectory of the first element in the viewpath.

Undesirable behavior may result if . (dot) is specified as the root node.

Viewpathing does not affect the locations of output files. All temporary files
will be unaffected and all other output files (such as executables, object files,
etc.) will be created relative to the root node.

If a file located in a directory down the viewpath (for example, in the second
or third node) is to be opened for modification (for example, to add files to
an archive or to edit a text file), then the original file will first be copied into
a location relative to the root node. Then the new copy will be opened for
modification. Hence, your modification will not affect the development group’s
files.

124 MULTI: Building Applications for Embedded ARM


Other Topics

Note When you create a file for output in your root node, the intermediate
directories are not created in the root node, even if the corresponding directory
path exists in the viewpath.

Usage
To enable viewpathing, set the NVPATH environment variable and do not set the
GHS_VP_NONE environment variable.
Environment Variable Meaning
NVPATH Enables viewpathing. Use colons to separate the
pathnames.
GHS_VP_NONE Disables viewpathing.
GHS_VP_DEBUG Enables the diagnostic output.
GHS_VP_SLOW Disables a performance optimization where files that
are opened for creation and not updating are not
copied down the viewpath if they already exist.

Example
This example requires three existing directories (/test/local, /test/group, and
/test/global) and three non-empty files (/test/local/file3.c, /test/group/file2.c,
and /test/global/file1.c):

Green Hills Software, Inc. 125


4. Developing for ARM

</test>: pwd
/test
</test>: ls -Agd */*
-rw-rw-r-- 1 green 7 Feb 11 15:56 global/file1.c
-rw-rw-r-- 1 green 15 Feb 11 15:58 group/file2.c
-rw-rw-r-- 1 green 34 Feb 11 15:55 local/file3.c
</test>: cd local
</test/local>: setenv NVPATH "/test/local:/test/group:/test/global"
</test/local>: setenv GHS_VP_DEBUG 1
</test/local>: ax crv archive.a file1.c file2.c file3.c
ax: info: Viewpathing support is ON (FAST).
ax: info: Adding viewpath node 1: /test/local
ax: info: Adding viewpath node 2: /test/group
ax: info: Adding viewpath node 3: /test/global
a - file1.c
ax: info: Located file: /test/global/file1.c
a - file2.c
ax: info: Located file: /test/group/file2.c
a - file3.c
</test>: cd ..
</test>: ls -Agd */*
-rw-rw-r-- 1 green 7 Feb 11 15:56 global/file1.
-rw-rw-r-- 1 green 15 Feb 11 15:58 group/file2.c
-rw-rw-r-- 1 green 246 Feb 11 16:05 local/archive.a
-rw-rw-r-- 1 green 34 Feb 11 15:55 local/file3.c
</test>: cd local
</test/local>: ax tv archive.a
ax: info: Viewpathing support is ON (FAST).
ax: info: Adding viewpath node 1: /test/local
ax: info: Adding viewpath node 2: /test/group
ax: info: Adding viewpath node 3: /test/global
rw-rw-r-- 4025/28 7 Feb 11 15:56 1998 file1.c
rw-rw-r-- 4025/28 15 Feb 11 15:58 1998 file2.c
rw-rw-r-- 4025/28 34 Feb 11 15:55 1998 file3.c
</test/local>: echo "Completely new and larger file 1" > file1.c
</test/local>: ls -Ag
total 6
-rw-rw-r-- 1 green 246 Feb 11 16:05 archive.a
-rw-rw-r-- 1 green 32 Feb 11 16:09 file1.c
-rw-rw-r-- 1 green 34 Feb 11 15:55 file3.c
</test/local>: ax r archive.a file1.c
ax: info: Viewpathing support is ON (FAST).
ax: info: Adding viewpath node 1: /test/local
ax: info: Adding viewpath node 2: /test/group
ax: info: Adding viewpath node 3: /test/global
</test/local>: ax tv archive.a
ax: info: Viewpathing support is ON (FAST).
ax: info: Adding viewpath node 1: /test/local
ax: info: Adding viewpath node 2: /test/group
ax: info: Adding viewpath node 3: /test/global
rw-rw-r-- 4025/28 32 Feb 11 16:09 1998 file1.c
rw-rw-r-- 4025/28 15 Feb 11 15:58 1998 file2.c
rw-rw-r-- 4025/28 34 Feb 11 15:55 1998 file3.c

126 MULTI: Building Applications for Embedded ARM


Other Topics

Advanced Optimization Strategies


Given the limitations on the amount of ROM available in typical embedded
systems, you will often need to make programs as small as possible. For
a description of the optimizing compiler options geared towards reducing
program size, see “Optimization Options” on page 143. The following sections
describe other ways to reduce the size of executables.

Removing Floating-Point Libraries


Large executable files can result from library routines that cause code related
to floating-point operations to be linked in, even if your program does not use
floating-point variables. For example, the printf function contains formatting
options for floating-point values, such as %f, %e, and %g, which cause
floating-point handling code to be loaded even if these particular options are
not used.

If your program does not use floating-point operations, you can reduce the size
of your program by building it with special versions of certain library functions,
such as printf, that do not use any floating-point code.

To specify that your program does not use floating-point operations:

Set the Target→Floating-Point→Floating-Point Coprocessor option


to No Floating-Point (-fnone).

Specifying that your program does not use floating-point operations has two
effects:

• The compiler gives a fatal error for any floating-point constants and for
any use of the reserved words float and double. This prevents any
floating-point value or operation from appearing in the C source code.
• The linker searches a special library that has non-floating-point versions
of library functions before searching the regular libraries. If any of these
functions are used, the non-floating-point versions are loaded in place of
the floating-point versions.

Green Hills Software, Inc. 127


4. Developing for ARM

128 MULTI: Building Applications for Embedded ARM


Chapter 5

Builder and Driver Options

This Chapter Contains:


• Target Options
• Project Options
• Optimization Options
• Debugging Options
• Preprocessor Options
• C/C++ Compiler Options
• Assembler Options
• Linker Options
• Compiler Diagnostics Options
• Advanced Options
• Driver Option Synonyms
5. Builder and Driver Options

This chapter lists all of the Builder and driver options.

These options control various aspects of the compilation, assembly, and linking
of your project, and are presented in the following format in this chapter:
Builder Option
Description of option.
• Setting (Equivalent Driver Option) — Description of setting.

To set options in the Builder, click Edit → Set Options to open the Options
window (see “Setting Builder Options” on page 50).

Note The information in this chapter is available directly in the Options


window on the lower Documentation tab (see “The Options Window Lower
Tabs” on page 57).

To search for options in the Options window, click the Search button ( ) and
enter a text string to search for (see “Searching For Options” on page 58).

To pass options to the compiler driver, add them to your command line or
makefile. For more information about using the driver, see Chapter 3, “The
Compiler Driver”.

130 MULTI: Building Applications for Embedded ARM


Target Options

Target Options
This is a top-level option category.

These options allow you to control aspects of compilation relating to your


target, such as available memory models and forms of floating-point support,
and to control the instruction set to be used.

For additional, more specialized options, see “Advanced Target Options” on


page 197.
Memory Description File
Specifies a .gmd file, which contains a description of the target board’s physical
memory, and instructions on how MULTI may access it. The equivalent driver
option is:
• --memory_description_file file.gmd
Register Description File
Specifies a .grd file, which contains a description of the target board’s registers,
and instructions on how MULTI may access them. The equivalent driver option is:
• --register_definition_file file.grd
Endianness
Controls the endianness of generated code. Permitted settings for this option are:
• Big Endian (-bigendian) — The most significant byte of an integer appears
at the lowest address.
• Little Endian (-littleendian) — [default] The most significant byte of an integer
appears at the highest address.

Auto-Interrupt Table
Controls whether the compiler will generate an interrupt table. Permitted settings
for this option are:
• On (-auto_interrupt_table) — [default] Enables generation of an interrupt
table.
• Off (-no_auto_interrupt_table) — Disables generation of an interrupt table.
For more information, see “Writing Interrupt Routines” on page 120.

Green Hills Software, Inc. 131


5. Builder and Driver Options

Floating-Point
This option category is contained within Target.

These options control how floating-point operations are performed. The default
setting depends on whether your target has a built-in floating-point unit, or FPU.
Floating-Point Coprocessor
Permitted settings for this option are:
• No Floating-Point (-fnone) — Disallows all floating-point operations (and
directs the C and C++ compilers to give an error for any use of floating-point
variables or constants), thus greatly reducing the size of such library functions
as printf and scanf. Passes -D__NoFloat to allow source code and
header files to hide references to floating-point objects. If your code uses
floating-point operations, then an error will be generated. This option implies
-nofloatio.
Since this setting requires support from the system libraries and header files, it
is not supported for environments using embedded operating systems with
their own C or C++ headers and libraries.
• FPAHardware Coprocessor (-fhard) — Specifies hardware floating-point
(HFP) mode using the FPA coprocessor, in which the compiler uses
floating-point registers to hold floating-point data and to perform floating-point
operations. This setting is only supported for targets with a built-in FPA fpu
and is the default for MicroRAD boards.
• VFPHardware Coprocessor (-fpu=vfp) — Specifies hardware floating-point
(HFP) mode using the VFP coprocessor, in which the compiler uses
floating-point registers to hold floating-point data and to perform floating-point
operations. This setting is only supported for v5 or higher architectures with
an optional VFP fpu.
• Software Emulation (-fsoft) — Specifies software floating-point (SFP)
mode, in which the compiler uses integer registers to hold floating-point data
and generates library subroutine calls to emulate floating-point operations,
regardless of the capabilities of the selected processor. This is the default
for targets without an fpu. If the target has an fpu, then this option selects a
different set of libraries.

132 MULTI: Building Applications for Embedded ARM


Target Options

Use Floating-Point in stdio Routines


Controls the use of floating-point in stdio operations. Permitted settings for
this option are:
• On (-floatio) — [default] Use standard libraries
• Off (-nofloatio) — Use libnoflt.a, a library containing special versions
of printf, scanf, and related functions which, since they contain no
floating-point operations, are therefore smaller. All floating-point formats (%f,
%g, %e) are printed in hexadecimal. In environments where floating-point uses
large library support routines, this option can save space for programs that use
printf, but which do not require floating-point.

Memory Models
This option category is contained within Target.

These options control the placement of code and data in memory.


Position Independent Code
Controls the generation of Position Independent Code (PIC). Permitted settings
for this option are:
• On (-pic)
• Off (-nopic) — [default]
For more information, see “Position Independent Code (PIC)” on page 112. This
option cannot be used in conjunction with -layout.
Position Independent Data
Controls generation of Position Independent Data (PID). Permitted settings for
this option are:
• On (-pid)
• Off (-nopid) — [default]
For more information, see “Position Independent Data (PID)” on page 114.
This option cannot be used in conjunction with -layout.

Green Hills Software, Inc. 133


5. Builder and Driver Options

Far Calls
Controls whether the compiler will generate a far call for every call. Permitted
settings for this option are:
• Make All Calls Far Calls (-farcalls) — Enables generation of a far function
call for every call. This allows for functions to be located at any distance from
the caller.
• Make No Far Calls (-nofarcalls) — [default] Disables generation of far
function calls. Large programs or programs with discontinuous text sections
may not link if the range of the call instruction is exceeded.
For more information, see “Near and Far Function Calls” on page 115.
Linker-Based Far Call Patching
Controls a linker-based optimization which generates far calls only for calls which
are out of range and would otherwise fail. This option will generally produce
smaller code than generating far calls for every call (see above). Permitted
settings for this option are:
• Patch Far Calls When Necessary (-farcallpatch) — [default]
• Do Not Patch Far Calls (-nofarcallpatch)
Placement of Zero-Initialized Data
Controls the allocation of variables and arrays explicitly initialized to zero.
Allocating such objects to an uninitialized section will generally reduce the size of
the executable ROM image. Permitted settings for this option are:
• Place Zero-Initialized Data in .bss (-discard_zero_initializers) — [default]
Allocates variables and arrays explicitly initialized to zero to the .bss section.
• Place Zero-Initialized Data in .data (-no_discard_zero_initializers) —
Allocates variables and arrays explicitly initialized to zero to the .data section.
In certain circumstances, the optimizer may determine that the allocation of
uninitialized variables or arrays to .data will produce more efficient code (see
“Data Definition Movement” on page 646).
Global Registers
Reserves up to 3 registers (r4, r5, and r6 in that order) to hold global variables.
The equivalent driver option is:
• -globalreg=n
For more information, see “Storing Global Variables in Registers” on page 118.
Data Model
Permitted settings for this option are:
• Data addresses are 24 bits (-data_model=small) —
• Data addresses are 32 bits (-data_model=large) —

134 MULTI: Building Applications for Embedded ARM


Target Options

Data Model
Permitted settings for this option are:
• Code addresses are 24 bits (-code_model=small) —
• Code addresses are 32 bits (-code_model=large) —

Instruction Set
This option category is contained within Target.

These options control aspects of the instruction set.


Thumb Code Generation
Controls generation of 16-bit Thumb code. Permitted settings for this option are:
• On (-thumb) — Enables Thumb mode
• Off (-nothumb) — [default] Disables Thumb mode.
For more information, see “Thumb Mode” on page 101.
Thumb Libraries
Controls linking with run-time libraries built for Thumb mode. Permitted settings
for this option are:
• On (-thumb_lib) — Enables linking with Thumb libraries.
• Off (-nothumb_lib) — [default] Disables linking with Thumb libraries.
For more information, see “Thumb Mode” on page 101.

Operating System
This option category is contained within Target.

These options are only available when your project specifies an embedded
operating system.
Shared Libraries
Controls whether the application may link in shared libraries. Permitted settings
for this option are:
• No Shared Libraries (-non_shared)
• Link With Shared Libraries (-call_shared) — [default]

Green Hills Software, Inc. 135


5. Builder and Driver Options

OS Directory
Specifies the root of the operating system distribution. The equivalent driver
option is:
• -os_dir directory
Event Logging
This option is available for ThreadX projects only.
Controls event logging, which collects event data for viewing and analysis in the
MULTI EventAnalyzer. Permitted settings for this option are:
• On (-event_logging) — Enables event logging by defining the
TX_EVENT_LOGGING preprocessor symbol.
• Off (-no_event_logging) — [default]
Use ThreadX Demo Library
This option is available for ThreadX projects only.
Controls the ThreadX library to use. Permitted settings for this option are:
• On (-use_demo_library) — Use a demonstration version of ThreadX provided
with MULTI for evaluation purposes.
• Off (-no_use_demo_library) — [default] Use the standard ThreadX library.
ThreadX Demo Library Directory
This option is available for ThreadX projects only.
Specifies the location of the ThreadX demo library. The equivalent driver option is:
• -threadx_demo_dir directory

136 MULTI: Building Applications for Embedded ARM


Target Options

Kernel Project
This option is available for INTEGRITY projects only.
Controls whether the project is to be linked as a kernel or as a standard application.
Permitted settings for this option are:
• On (Link with the default kernel) (-kernel) — Specifies linking with the
default INTEGRITY kernel library. This kernel library is fully featured and
provides full debug support.
• Off (-no_kernel) — Specifies that no INTEGRITY kernel library be linked in.
• Link with kernel optimized for production use (-kernel=kernel_opt) —
Specifies linking with a production-optimized INTEGRITY kernel library. This
kernel library is fully featured, and has run-mode debug support stripped out.
• Link with kernel optimized for minimal size (no MMU support)
(-kernel=kernel_small) — Specifies linking with an INTEGRITY kernel library
optimized for minimal size. This kernel library provides no virtual memory,
run-mode debug, or console output support, and has some other capabilities
disabled as well.
• Link with kernel optimized for maximum speed (no MMU support)
(-kernel=kernel_fast) — Specifies linking with an INTEGRITY kernel library
optimized for maximum speed. This kernel library provides no virtual memory
or run-mode debug support, and has some other capabilities disabled as well.
• Link with kernel with checked debug output enabled
(-kernel=kernel_checked) — Specifies linking with an INTEGRITY kernel
library that is fully featured, and provides extra debug output and internal
error checking for debug purposes.
• Link with kernel with no MMU support (-kernel=kernel_novirt) — Specifies
linking with an INTEGRITY kernel library that provides no virtual memory
support, and is otherwise fully featured.
• Link with kernel with no MMU or cache support (ARM only)
(-kernel=kernel_nommu) — Specifies linking with an INTEGRITY kernel
library that provides no MMU or cache support, and is otherwise fully featured
(ARM only).
Include libbsp.a
This option is available for INTEGRITY projects only.
Controls whether your INTEGRITY kernel application will link against libbsp.a.
Permitted settings for this option are:
• On (-libbsp) — [default]
• Off (-no_libbsp)
This option has no effect if you are not building an INTEGRITY kernel project.

Green Hills Software, Inc. 137


5. Builder and Driver Options

Relocatable Module
Permitted settings for this option are:
• On (-irel) —
• Off (-no_irel) —
Relocatable Module Base Image
The equivalent driver option is:
• -dyload —
Full POSIX-2001 Compilation Support
Permitted settings for this option are:
• On (--integrity_posix) —
• Off (--no_integrity_posix) —
Dynamic Download Project
This option is available for INTEGRITY projects only.
Controls whether the project will be linked to be suitable for downloading to a
running kernel. Permitted settings for this option are:
• On (-dynamic) — Is ignored if an .int file is specified.
• Off (-no_dynamic) — [default]
Display BootTable
This option is available for INTEGRITY projects only.
Controls the build-time display of the BootTable that the kernel processes at run
time. Permitted settings for this option are:
• On (-display_boot)
• Off (-no_display_boot) — [default]
Delete Unused Kernel Calls
This option is available for INTEGRITY projects only.
Controls the deletion of unused kernel calls from the final image. Permitted
settings for this option are:
• On (-generatemonolithdeletions)
The deletion is based on physical and virtual kernel calls referenced in the
component AddressSpaces. This option may cause unpredictable errors if used
in the compilation of a dynamic download project which could use a deleted kernel
call.

138 MULTI: Building Applications for Embedded ARM


Target Options

Create Raw Binary Image


This option is available for INTEGRITY projects only.
Controls the creation of a binary image in addition to the standard ELF image.
Permitted settings for this option are:
• Generate Default Binary Image (-memory) — Creates a binary image with
the name of the ELF executable plus a .bin extension.
• Generate User-Specified Binary Image (-memory=filename) — Creates a
binary image with the specified filename.
Additional Intex Options
This option is available for INTEGRITY projects only.
Specifies additional Intex options. The equivalent driver option is:
• -intexoption option
INTEGRITY Application Stripping
This option is available for INTEGRITY projects only.
Controls stripping of the executable at the conclusion of linking. Permitted settings
for this option are:
• On (-strip_application)
• Off (-no_strip_application) — [default]

Green Hills Software, Inc. 139


5. Builder and Driver Options

Project Options
This is a top-level option category.

These options allow you to control basic configuration settings for your project,
such as source, output and include directories.

For additional, more specialized options, see “Advanced Project Options” on


page 198.
Output Filename
Names the output file being generated. The output file type (for example, a library
or an assembly file) depends on the other options that have been specified. The
builder enforces specific suffixes for some types of output files. The equivalent
driver option is:
• -o filename [Note that the -o option can only be used in combination with the
-c, -P, -Q, or -S options if there is a single source file on the command line.]
Object File Output Directory
Puts object files into the specified directory, which is often a subdirectory of
the current working directory. Along with the object files, the assembly listings,
debugging information files, inliner files, and other intermediate files that have
the same base name as the object file but a different suffix are also put into this
directory. Note that the output of the linker and the output of the archiver are never
put into the object file output directory. If this option is not specified, the object files
will be put into the current working directory.
The equivalent driver option is:
• -object_dir=directory
Source Root
Specifies a source root for use by the MULTI Debugger sourceroot command
(see Chapter 30, “Debugger Commands” in the MULTI: Debugging book). The
Debugger resolves paths relative to this root. The equivalent driver option is:
• -dbg_source_root path

140 MULTI: Building Applications for Embedded ARM


Project Options

Include Directories
Specifies a directory in which the builder should search for header files. The
equivalent driver option is:
• -Idirectory
When the compiler processes source files that have #include "header_file"
or #include <header_file> directives, it looks for header_file in any
directories specified with this option. You can specify multiple directories, and the
compiler will search them in the order in which they are specified. If the source
file’s #include directive declares a full path to the header file, then the compiler
ignores any directories specified with this option.
For a detailed discussion of how the compiler searches for included files, see
“Instructing the Compiler to Search for Your Headers” on page 96.
Library Directories
Specifies a directory in which the builder should search for libraries. The
equivalent driver option is:
• -Ldirectory
Libraries
Specifies a library for the builder to link against. The equivalent driver option is:
• -llibrary
This option accepts an abbreviated library notation, which is derived by removing
the lib prefix and filename extension from the name of the library file. For example,
my specifies the library libmy.a.
You can specify multiple libraries, and they will be linked against in the order
specified. When using the driver, each library must be specified with it’s own
-l option, for example:

-lfoo -lbar -lbaz

In order to prevent multiply defined symbols, we recommend that you list your
source files on the command line first, and then any -llibrary libraries.
Source Directories Relative to This File
Specifies a directory in which the builder should search for source files. The
syntax for this option is:
• :sourceDir=directory
This is a Builder-only option. There is no equivalent driver option.

Green Hills Software, Inc. 141


5. Builder and Driver Options

Intermediate Output Directory Relative to Top-Level Project


Specifies the path where object files (and, in addition, any custom output file
types) are written to, relative to the location of your top-level default.gpj project
file. The syntax for this option is:
• :outputDir=directory
This is a Builder-only option. There is no equivalent driver option.

142 MULTI: Building Applications for Embedded ARM


Optimization Options

Optimization Options
This is a top-level option category.

Green Hills provides a wide range of optimizations to help you produce smaller
and/or faster executables.

Although code optimization is one of the most complicated aspects of the


compilation process, in most situations you can obtain maximum benefits
simply by specifying an Optimization→Optimization Strategy with the first
option below. The compiler will automatically enable or disable the various
options that follow, based upon the strategy you choose and the code that
it encounters.

For detailed descriptions of all the optimizations, see Chapter 19, “Optimization
Descriptions”. For additional, more specialized options, see “Advanced
Optimization Options” on page 203.
Optimization Strategy
Specifies the high-level optimization strategy. Permitted settings for this option are:
• Optimize for Size (-Ospace) — Enables all the optimizations which improve
both size and performance, and special optimizations which improve code size
at the expense of performance. Any optimization which is expected to increase
code size is disabled. For example, loop unrolling and function inlining are
usually not performed when this setting is selected, and some operations may
be performed by calling library routines rather than generating inline code.
• Optimize for General Use (-O) — Enables all the optimizations which improve
both performance and size, or which improve performance without dramatically
increasing size.
• Optimize for Speed (-Ospeed) — Enables all the optimizations which improve
both size and performance, and which improve performance at the expense of
size. No optimization intended to reduce code size is enabled. This option
is recommended for generating the fastest possible code without the use
of two-pass inlining.
• No Optimizations (-Onone) — [default] Disable all optimizations.

Green Hills Software, Inc. 143


5. Builder and Driver Options

Intermodule Inlining
Enables all the General Use optimizations together with two-pass inlining.
Permitted settings for this option are:
• On (-OI)
• Off (-Onoinline) — [default]
For more information, see “Inlining Optimizations” on page 625.
Linker Optimizations
Controls the linker optimizations listed in “Linker Optimizations” on page 186.
Permitted settings for this option are:
• On (-Olink) — The linker optimizations that are enabled will depend upon
whether you are optimizing for speed or size. Many of these optimizations
make complex changes to your code, and may slow down the link stage,
be harder to debug, or have other drawbacks. To disable individual linker
optimizations, set them to Off in combination with this option.
• Off (-Onolink) — [default]

Optimization Scope
This option category is contained within Optimization.

These options provide general control over the major optimizations.


Pipeline & Peephole Scope
Restricts the scope of optimizations to ensure the retention of debugging
information. Permitted settings for this option are:
• Restrict peephole optimization scope to increase debuggability
(-Olimit=peephole) —
• Restrict pipeline optimization scope to increase debuggability
(-Olimit=pipeline) —
Inline Larger Functions
Controls whether the compiler will consider larger functions for inlining. Permitted
settings for this option are:
• On (-OB)
• Off (-Onobig) — [default]
For more information, see “Varying Inlining Thresholds” on page 630.

144 MULTI: Building Applications for Embedded ARM


Optimization Options

Unroll Larger Loops


Controls the size of the loops that the compiler will consider for unrolling.
Permitted settings for this option are:
• On (-Ounrollbig) — Consider larger loops for unrolling.
For more information, see “Loop Unrolling” on page 639.
Unroll Loops Up To 8 Times
Decreases the number of times a loop may be unrolled from 8 to 4. Permitted
settings for this option are:
• On (-Ounroll8) — [default]
• Off (-Onounroll8)
For more information, see “Loop Unrolling” on page 639.
Maximize Optimizations
Controls the aggressiveness with which the compiler will pursue optimizations,
without regard for compile time. Permitted settings for this option are:
• On (-Omax)
• Off (-Onomax) — [default]
For example, to optimize most aggressively for size, without regard for compilation
time, set Optimization→Optimization Strategy to Optimize for Size (-Ospace)
and set this option to On.

Green Hills Software, Inc. 145


5. Builder and Driver Options

Individual Functions
This option category is contained within Optimization.

These options allow you to specify individual functions for optimization.


Optimize Specific Functions for Speed
Enables speed optimizations for specific functions. The equivalent driver option is:
• --fast function1[,function2…]
Note that this option has no effect unless an overall Optimization→Optimization
Strategy is specified.
Optimize Specific Functions for Size
Enables size optimizations for specific functions. The equivalent driver option is:
• --small function1[,function2…]
Note that this option has no effect unless an overall Optimization→Optimization
Strategy is specified.
Inline Specific Functions
Enables two-pass inlining for specific functions. The equivalent driver option is:
• -OI=function1[,function2...]
For more information, see “Inlining Optimizations” on page 625.
Loop Optimize Specific Functions
Enables loop optimizations for individual functions. The equivalent driver option is:
• -OL=function1[,function2...]
For more information, see “Loop Optimizations” on page 636.

146 MULTI: Building Applications for Embedded ARM


Debugging Options

Debugging Options
This is a top-level option category.

These options control the generation of debugging and profiling information.


For more information, see “Generating Debugging Information” on page 91 and
“Obtaining Profiling Information” on page 93.

For additional, more specialized options, see “Advanced Debugging Options”


on page 206.
Debugging Level
Controls the level of debugging information and cross-referencing data to be
generated. Permitted settings for this option are:
• MULTI (-G) — Generates source-level debugging information, and allows
procedure calls from the MULTI Debugger’s command line.
• Plain (-g) — Generates source-level debugging information.
• Stack Trace (-gs) — Generates minimal debugging information which is
sufficient for MULTI to perform stack traces, but not enough for source level
debugging. The Green Hills libraries are compiled with this option.
• None (--no_debug) — [default] Generates no debugging information.
Profiling - Call Count
Controls call count profiling, which records how many times each function is
called. Permitted settings for this option are:
• On with Call Graph (-pg) — Generates call count information that includes the
name of each caller. This information can be used to generate a call graph.
• On (-p) — Generates basic call count information.
• Off (-pnone) — [default] Disables call count profiling.
Profiling - Coverage
Controls coverage profiling, which records whether your application contains lines
of code that are not used. Permitted settings for this option are:
• On (-a)
• Off (--no_coverage_analysis) — [default]

Green Hills Software, Inc. 147


5. Builder and Driver Options

Profiling - Target-Based Timing


Controls timing profiling, which records the time spent in each function. Permitted
settings for this option are:
• On (-timer_profile)
• Off (-no_timer_profile) — [default]
This option requires that you modify the header file libsys/arm_manprf.h to
provide board-specific information. For more information, see “Target-Based
Timing Profiling” on page 94.
Run-Time Error Checks
Controls run-time error checking, which can be very valuable during a debugging
session, but which increases the size and reduces the speed of your application.
The various checks generate warnings or errors as specified below. Permitted
settings for this option are:
• Assignment Bounds (-check=assignbound) — Checks that the value is in
the range of the type when assigning a value to a variable or field that is a
small integral type (such as a bitfield).
• Case Label Bounds (-check=switch) — Generates a warning if the
case/switch expression does not match any of the case labels. This does
not apply when a default case label is used.
• Divide by Zero (-check=zerodivide) — Generates an error indicating that a
divide by zero occurred and then terminates the program.
• Nil Pointer Dereference (-check=nilderef) — Generates an error for
dereferences of null pointers.
• Write to Watchpoint (-check=watch) — Allows the MULTI Debugger to set
up one fast watchpoint.
To enable or disable all the checks when using the Builder, use the All toggle
switch at the bottom of the dialog. When using the driver, pass the option
-check=all or -check=none.

148 MULTI: Building Applications for Embedded ARM


Debugging Options

Run-Time Memory Checks


Controls run-time memory checking. Note that this option is not available for
projects built with PIC or PID. Permitted settings for this option are:
• General (Allocations Only) (-check=alloc) — Generates errors for a limited
number of memory allocation problems.
• Intensive (-check=memory) — Generates errors for a wider range of memory
allocation problems. This setting requires a significant amount of additional
code to be downloaded to the target, but also automatically enables Nil
Pointer Dereference checking at little additional performance cost.
• None (-check=nomemory) — Disables memory checking.
Both forms of memory checking require a frame pointer to walk the stack at run
time, and imply setting Advanced→Advanced Debugging Options→Force
Frame Pointer to On.
For detailed information, see Chapter 14, “Viewing Memory Allocation Information”
in the MULTI: Debugging book.

Note You can perform run-time error checking without the MULTI Debugger
by rebuilding your application with run-time error checking enabled, and
running a series of validations. You can also hook the run-time error checking
reporting to automatically report any failures that are detected. The following is
an example of how to set up this feature:

1. Create a new Builder project.


2. Select your Processor Family, Operating System, Endian, and Board
Name. Then click Next.
3. Select C as the language.

Under Project Type, scroll down the list and select Example (Custom
Run-Time Error Checking).
• Custom Run-Time Error Checking is not displayed as an option on
configurations that do not support run-time error checking.
4. Click Finish. After the project is created, a new window appears.
5. Scroll down the list and open user_defined_handler.c. You will find
sample code that will help you set up custom run-time error checking
without the MULTI Debugger.

Green Hills Software, Inc. 149


5. Builder and Driver Options

Preprocessor Options
This is a top-level option category.

These options control the preprocessor. For information about the Green Hills
predefined macros, see “Predefined Macro Names” on page 512.

For additional, more specialized options, see “Advanced Preprocessor Options”


on page 210.
Define Preprocessor Symbol
Defines a preprocessor symbol, and optionally can set it to a value. The equivalent
driver option is:
• -Dsymbol[=value]
If a value is not specified, then a default value of 1 is assigned. This is equivalent
to placing the following at the top of each source file:

#define symbol [value]

Undefine Preprocessor Symbol


Undefines a preprocessor symbol. The equivalent driver option is:
• -Usymbol
This is equivalent to placing the following at the top of each source file:

#undef symbol

Display #includes Listing


Controls the display to standard error of a list of files opened by a #include
directive during normal compilation. Files are compiled and linked normally.
Permitted settings for this option are:
• On (-H)
• Off (--no_trace_includes) — [default]

150 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

C/C++ Compiler Options


This is a top-level option category.

These options control various aspects of compilation that relate directly to the
C and C++ languages.

For additional, more specialized options, see “Advanced C/C++ Compiler


Options” on page 212.
C Language Dialect
Controls the version of C to be accepted by the compiler. Permitted settings for
this option are:
• Strict ANSI C (-ANSI) — Specifies strict ANSI. This mode is compliant with the
ANSI X3.159-1989 standard and does not allow any non-standard constructs.
• ANSI C (-ansi) — [default] Specifies ANSI C with extensions. This mode
extends the ANSI X3.159-1989 standard with certain useful and compatible
constructs. For details, see “ANSI C” on page 407.
• GNU C (-gcc) — Specifies full GNU mode, supporting GNU features (including
zero size arrays, multi-line string constants, and inline functions) which are
less compatible with ANSI C. For details, see “GNU C” on page 413. This
option is only available when using the New Generation Compiler..
• K+R C (-k+r) — Specifies the C version documented in Kernighan & Ritchie,
First Edition, which is somewhat compatible with the portable C compiler
(PCC). In this mode, the compiler will accept ANSI-style prototypes. For
details, see “K&R C” on page 420. This mode is implemented somewhat
differently for the Compatibility Mode Compiler. For details, see Chapter 5,
“The Compatibility Mode Compiler” in the MULTI: Legacy Building Tools book.
When using the driver, you can select the GNU dialect for both C and C++ by
passing the -gnu option.
C Japanese Automotive Extensions
Controls support for the Japanese Automotive C extensions. Permitted settings
for this option are:
• On (-japanese_automotive_c)
• Off (-no_japanese_automotive_c) — [default]
For more information, see “Japanese Automotive C Extensions” on page 426.

Green Hills Software, Inc. 151


5. Builder and Driver Options

C++ Language Dialect


Specifies the version of C++ to be accepted by the compiler. Permitted settings
for this option are:
• Standard C++ (Violations Give Errors) (--STD) — Specifies C++ Strict
Standard Mode, which gives errors when non-Standard features are used and
disables features that conflict with Standard C++.
• Standard C++ (Violations Give Warnings) (--std) — [default] Specifies C++
Standard Mode, which gives warnings when non-Standard features are used
and disables features that conflict with Standard C++.
• Standard C++ with ARM Extensions (--arm) — Specifies Standard C++ with
extensions, which extends the standard with many useful and compatible
constructs.
• GNU C++ (--g++) — Specifies GNU C++ mode.
• Extended Embedded C++ (--ee) — Specifies Extended Embedded C++,
which adds templates, namespaces, mutable new-style casts, and the
Standard Template Library (STL) to Embedded C++.
• Embedded C++ (--e) — Specifies Embedded C++.
For details of Green Hills C++ and the differences between the various modes,
see Chapter 14, “Green Hills C++”.
When using the driver, you can select the GNU dialect for both C and C++ by
passing the -gnu option.
C++ Libraries
Specifies the type of C++ library to use. Permitted settings for this option are:
• Standard C++ Library without Exceptions (--stdl)
• Standard C++ Library with Exceptions (--stdle)
• Extended Embedded C++ Library without Exceptions (--eel)
• Extended Embedded C++ Library with Exceptions (--eele)
• Embedded C++ Library without Exceptions (--el)
• Embedded C++ Library with Exceptions (--ele)
The default is to use libraries equivalent to your C/C++ Compiler→C++ Language
Dialect without exceptions, and you may not specify a library that is more
full-featured than your C/C++ Compiler→C++ Language Dialect. For more
information, see “Choosing a C++ Library” on page 553.

152 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

C++ Exception Handling


Controls support for exception handling. Permitted settings for this option are:
• On (--exceptions) — Enables support for exception handling. Code size and
speed may be impacted even when exception handling is not directly used.
• Off (--no_exceptions) — [default] Disables support for exception handling.
Allow C++ Style Slash Comments in C
Controls treatment of C++ style // comments. Permitted settings for this option
are:
• On (--slash_comment) — [default] C++ style // comments are accepted.
• Off (--no_slash_comment) — C++ style // comments are not accepted
and generate errors.
ANSI Aliasing Rules
Controls assumptions based on ANSI aliasing rules in the compiler. Permitted
settings for this option are:
• On (-ansi_alias) — [default] Enables ANSI aliasing rules.
• Off (-no_ansi_alias) — Disables ANSI aliasing.
When this option is enabled, the compiler assumes that memory may only be
accessed through pointers of compatible types. This allows the compilers to
generate better code. Illegal casts may cause the compiler to generate code that
does not behave as expected. Consider the following example:

void func(float *fp, int n)


{
int *ip = (int *)fp;
*fp = n;
*ip |= 0x80000000; /* illegal access */
}

This may behave unexpectedly because an int type may not be used to access
an object of the float type.
.c Files are C++
Controls how the compiler treats files ending with the .c extension. Permitted
settings for this option are:
• On (-dotciscxx) — Interpret .c files as C++.
• Off (-nodotciscxx) — [default] Interpret .c files as C.

Green Hills Software, Inc. 153


5. Builder and Driver Options

MISRA C
This option category is contained within C/C++ Compiler.

The options in this section are only available with the New Generation Compiler.

This section contains options which allow you to control checking of compliance
with the Motor Industry Software Reliability Association (MISRA) rules, a
set of guidelines for the C programming language that is designed to enforce
good practices in the development of embedded automotive systems. Complete
details can be found in the Guidelines For The Use Of The C Language In
Vehicle Based Software, Motor Industry Software Reliability Association, April
1998 book. For more information, see the MISRA (http://www.misra.org.uk/)
web site.

There are 127 rules, classified into two categories, as follows:

• 93 required rules (designated [R] below) — mandatory requirements placed


on the programmer that will, by default, generate an error if enabled and
breached.
• 34 advisory rules (designated [A] below) — suggestions to the programmer
that will, by default, generate a warning if enabled and breached.

The MISRA rules are organized into 17 groups, each focusing on a particular C
language topic (for example: types, functions, expressions, the C preprocessor,
etc). Each group has an associated option below.

We also provide options to control the severity of messages which alert you
to violations of the rules. Most of the messages are given at compile time,
although some are generated at run-time. Because run-time checking can
adversely affect code performance, an option is provided to disable it.

Some MISRA rules change other command line controllable options as


documented in the following section. The MISRA rules override explicit
settings of the other command line options, even if these options appear later on
the command line than the MISRA option.

Note A single driver option allows you to enable any or all of the MISRA
rules. It may be used in any of the following forms (where n is a rule number
from the list below):

• --saferc=all — enables checking of all the rules

154 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

• --saferc=none — disables checking of all the rules


• --saferc=n[,n1…] — enables checking of a comma-separated list of rules
• --saferc=n-n1 — enables checking of a range of rules
MISRA C Rules - Environment
Permitted settings for this option are:
• 1. [R] ISO 9899 C conformance w/o extensions — Enables Strict ANSI C
and disables recognition of:
non-standard keywords such as __inline, __interrupt,
__alignof__, etc.
C++ style slash comments
Kanji characters
• 2. [A] Code other than C must conform to standard interface — Not
enforced
• 3. [A] Inline assembly only in functions with no other code
• 4. [A] Run-time checking — Implemented through run-time checking.
The run-time checks performed are the array bound, assignment bound,
NULL pointer dereference, divide-by-zero, and unresolved switch
statement condition. The option --no_saferc_runtime will completely turn
this rule off.Implemented through run-time checking. This options sets
-check=assignbound, -check=bound, -check=nilderef, -check=zerodivide,
and -check=switch. The option --no_saferc_runtime will completely turn
this rule off.
MISRA C Rules - Character Set
Permitted settings for this option are:
• 5. [R] Only ISO C characters and escape sequences used — Among other
things, it will turn off the Kanji support.
• 6. [R] Values of char types restricted to subset of ISO 10646-1 — All Green
Hills compilers use the ASCII standard for mapping character sets to numeric
values. This property cannot be turned off.
• 7. [R] No trigraphs
• 8. [R] No multibyte chars and wide strings — Among other things, it will
turn off the Kanji support.

Green Hills Software, Inc. 155


5. Builder and Driver Options

MISRA C Rules - Comments


Permitted settings for this option are:
• 9. [R] No nested comments
• 10. [A] No ’commented out’ sections of code — Disallows the following
characters inside of a comment:
semicolon followed by a new-line character
open or close curly braces
MISRA C Rules - Identifiers
Permitted settings for this option are:
• 11. [R] No more than 31 chars to determine an identifier
• 12. [A] No identifiers with the same names in different namespaces
MISRA C Rules - Types
Permitted settings for this option are:
• 13. [A] Basic types used only in ‘typedef’s
• 14. [R] ‘char’ always used as ‘signed char’ or ‘unsigned char’
• 15. [A] Floating point implementation complies to a standard — The
Green Hills compilers use the IEEE floating point representation. This rule
cannot be turned off.
• 16. [R] No underlying use of bits in floating point expressions — The
Green Hills compilers disallow any use of bit-wise operators (such as &, |,
^, ~, etc.) by default.
• 17. [R] ‘typedef’ names shall not be reused
MISRA C Rules - Constants
Permitted settings for this option are:
• 18. [A] Numeric constants need suffixes when appropriate
• 19. [R] No octal constants (other than zero)

156 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

MISRA C Rules - Declarations & Definitions


Permitted settings for this option are:
• 20. [R] All objects and functions declared before used
• 21. [R] No use of same id name in inner and outer scope
• 22. [A] Function scope declarations whenever possible — Not enforced.
• 23. [A] Static linkage of file scope declarations when possible — Not
enforced.
• 24. [R] No internal and external linkages of same identifiers
• 25. [R] Only one external definition of external identifier —
• 26. [R] Compatible multiple declarations of the same object/function
— The Green Hills compilers allow only compatible declarations of
multiply-declared objects and functions within the same translation unit (by
default). No such checks are performed across different translation units.
• 27. [A] External objects declared in no more than one file — Not enforced.
• 28. [A] The ‘register’ storage class specifier should not be used
• 29. [R] The use of tag shall agree with its declaration
MISRA C Rules - Initialization
Permitted settings for this option are:
• 30. [R] Automatic variables initialized before used
• 31. [R] Braces used in non-zero initialization of arrays/structs
• 32. [R] All or only first enumerator may be explicitly initialized

Green Hills Software, Inc. 157


5. Builder and Driver Options

MISRA C Rules - Operators


Permitted settings for this option are:
• 33. [R] No side effects in right hand operand of ‘&&’ or ‘||’
• 34. [R] Operands of ‘&&’ and ‘||’ shall be primary expressions
• 35. [R] Assignment operators not used in boolean expressions
• 36. [A] Logical and bitwise operators should not be confused — Not
enforced.
• 37. [R] No bitwise operations on signed integer types
• 38. [R] Right hand value of shift operand must be in range — Both
compile-time and run-time checks are performed. The run-time check is turned
off when the option --no_saferc_runtime is passed.
• 39. [R] No unary minus operand on unsigned expressions
• 40. [A] No side effects in the ‘sizeof’ operand
• 41. [A] Implementation of division determined and documented — This
behavior is dependent on the hardware configuration of the target. Most
Green Hills compilers, however, round the division result toward 0 (including
PowerPC, MIPS, TriCore, and x86).
• 42. [R] No comma operators except in control expr of ‘for’ loops
MISRA C Rules - Conversions
Permitted settings for this option are:
• 43. [R] No implicit conversions which might lose information
• 44. [A] Redundant explicit cast should not be used
• 45. [R] Type casting to or from pointers should not be used
MISRA C Rules - Expressions
Permitted settings for this option are:
• 46. [R] No expression with values dependent on evaluation order —
Not enforced.
• 47. [A] No dependence placed on C precedence rules
• 48. [A] Mixed precision arithmetic must use explicit casting
• 49. [A] Test value against zero unless expression boolean — Not enforced.
The Green Hills C compilers do not have built-in types which would represent
the Boolean type.
• 50. [R] Floating point values not tested for (in)equality
• 51. [A] No wraparound in constant unsigned expressions

158 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

MISRA C Rules - Control Flow


Permitted settings for this option are:
• 52. [R] There shall be no unreachable code
• 53. [R] All non-null statements shall have a side-effect
• 54. [R] Null statement must occur on line by itself
• 55. [A] No labels except in ‘switch’ statements
• 56. [R] The ‘goto’ statement shall not be used
• 57. [R] The ‘continue’ statement shall not be used
• 58. [R] No ‘break’ statement except in ‘switch’
• 59. [R] Dependent statements always enclosed in braces
• 60. [A] All ‘if’ and ‘else if’ constructs must have an ‘else’
• 61. [R] Every non-empty ‘case’ clause terminated with ‘break’
• 62. [R] All ‘switch’ statements should contain a ‘default’ clause
• 63. [A] No boolean values in ‘switch’ expressions
• 64. [R] ‘switch’ statements need at least one ‘case’
• 65. [R] No floating-point variables in loop counters
• 66. [A] Only loop control expression in ‘for’ statement header — Not
enforced.
• 67. [A] No modification of control variables in ‘for’ loop body — Not
enforced.

Green Hills Software, Inc. 159


5. Builder and Driver Options

MISRA C Rules - Functions


Permitted settings for this option are:
• 68. [R] Functions always declared at file scope
• 69. [R] No variable argument functions
• 70. [R] No direct or indirect recursion
• 71. [R] Functions always have prototype declarations
• 72. [R] Function declaration and definition match prototypes — Always
enforced.
• 73. [R] Identifiers given for all or none of function parameters
• 74. [R] Declaration and definition match parameter names
• 75. [R] Every function shall have an explicit return type
• 76. [R] Functions with no parameters should have ‘void’ parameter
• 77. [R] Unqualified arguments of callee and caller compatible — Not
enforced
• 78. [R] Number of arguments matches the function prototype — Always
enforced
• 79. [R] Values returned by ‘void’ functions not used — Always enforced.
• 80. [R] No void expressions passed as parameters — Always enforced.
• 81. [A] ‘const’ present when needed on reference parameters — Not
enforced.
• 82. [A] A function should have a single point of exit
• 83. [R] Return expression matches function type
• 84. [R] No expressions returned from ‘void’ functions — Always enforced.
• 85. [A] Functions called with empty () if no parameters
• 86. [A] If error information returned, it should be tested — Not enforced.

160 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

MISRA C Rules - Preprocessor


Permitted settings for this option are:
• 87. [R] Only preprocessing directives before #include
• 88. [R] Only standard characters in file names for #include
• 89. [R] #include directive followed by <filename> or ’filename’ — Always
enforced.
• 90. [R] C macros only as constant, function-like, or specifier/qualifier
• 91. [R] Macros not ‘#define’d or ‘#undef’d within a block
• 92. [A] #undef should not be used
• 93. [A] Function used instead of function-like macro when possible —
Not enforced.
• 94. [R] Function-like macro called with all of its arguments — Always
enforced.
• 95. [R] No preprocessing directives in function-like macros
• 96. [R] Use of parentheses in function-like macros
• 97. [A] Identifiers in pre-processing directives defined before used
• 98. [R] Only one use of ‘#’ or ‘##’ operator in any one macro
• 99. [R] Uses of #pragmas documented and explained — This book lists
all #pragma constructs, their usage and effects (see “#pragma Directives”
on page 526).
• 100. [R] Correct use of ‘defined’ preprocessor operator — Always
enforced.
MISRA C Rules - Pointers and Arrays
Permitted settings for this option are:
• 101. [A] Pointer arithmetic should not be used
• 102. [A] No more than 2 levels of pointer indirection
• 103. [R] Relational operators not used except on same object — Not
enforced.
• 104. [R] No non-constant pointers to functions
• 105. [R] Function and a pointer to it match in prototypes
• 106. [R] Address of automatic variable not used out of scope — The
compiler checks if an address of a local variable is assigned to a global value.
• 107. [R] The NULL pointer should not be dereferenced — Performed via a
run-time check.

Green Hills Software, Inc. 161


5. Builder and Driver Options

MISRA C Rules - Structs and Unions


Permitted settings for this option are:
• 108. [R] All members of structures/union fully specified
• 109. [R] Overlapping variable storage should not be used — Not enforced.
• 110. [R] Unions not used to access sub-parts of larger data types —
Not enforced.
• 111. [R] Bit fields can only have ‘unsigned int’ or ‘signed int’ types
• 112. [R] Bit fields of ‘signed int’ type must be at least 2 bits long
• 113. [R] All members can be accessed only through their name
MISRA C Rules - Standard Library
Permitted settings for this option are:
• 114. [R] No redefinition of reserved words and standard library names
— Always enforced. The Green Hills compilers do not allow redefinitions
of C reserved words. Furthermore, the predefined macro names defined,
__LINE__, __FILE__, __DATE__, __TIME__, and __STDC__ cannot be
redefined.
• 115. [R] Standard library function names shall not be reused — Not
enforced.
• 116. [R] All library production code conforms to MISRA — Not enforced.
• 117. [R] Check validity of value passed to library functions — Not
enforced.
• 118. [R] Dynamic heap memory allocation shall not be used
• 119. [R] The error indicator ‘errno’ shall not be used
• 120. [R] Macro ‘offsetof’ in <stddef.h> shall not be used
• 121. [R] <locale.h> and ‘setlocale’ function shall not be used
• 122. [R] The ‘setjmp’ and ‘longjmp’ facilities shall not be used
• 123. [R] The facilities of <signal.h> shall not be used
• 124. [R] No use of <stdio.h> in production code
• 125. [R] Functions ‘atof’, ‘atoi’, and ‘atol’ not used
• 126. [R] Functions ‘abort’, ‘exit’, ‘getenv’, and ‘system’ not used
• 127. [R] The facilities of <time.h> shall not be used

162 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

MISRA C - Required Rules Level


Controls the diagnostic messages generated upon a violation of the MISRA
required rules. Permitted settings for this option are:
• Errors (--saferc_req=error) — [default]
• Warnings (--saferc_req=warn)
• Silent (--saferc_req=silent)
MISRA C - Advisory Rules Level
Controls the diagnostic messages generated upon a violation of the MISRA
advisory rules. Permitted settings for this option are:
• Errors (--saferc_adv=error)
• Warnings (--saferc_adv=warn) — [default]
• Silent (--saferc_adv=silent)
MISRA C - Run-Time Checks
Controls the performance of run-time checks for the MISRA rules that require
them. Permitted settings for this option are:
• On (--saferc_runtime) — [default]
• Off (--no_saferc_runtime)

Data Types
This option category is contained within C/C++ Compiler.

These options control the treatment of particular data types.


Signedness of Char Type
Specifies the signedness of the char type. Permitted settings for this option are:
• Signed (--signed_chars)
• Unsigned (--unsigned_chars) — [default]
Note that the standard libraries are built with the default signedness. While most
library routines work the same way regardless of the signedness of the char
type, localeconv() uses the default value of CHAR_MAX, which will not match
CHAR_MAX in the application if the signedness is changed.

Green Hills Software, Inc. 163


5. Builder and Driver Options

Signedness of Bitfields
Specifies the signedness of the bitfield type. Permitted settings for this option
are:
• Signed (--signed_fields)
• Unsigned (--unsigned_fields) — [default]
Note that single bit int fields in the Compatibility Mode Compiler are controlled by
this option, but in the New Generation Compiler these fields are always unsigned.
Signedness of Pointers
Specifies the signedness of pointers and addresses. Permitted settings for this
option are:
• Signed (--signed_pointer) — [default]
• Unsigned (--unsigned_pointer)
Signedness of Enum Type
Specifies the signedness of the enum type. Permitted settings for this option are:
• Signed (--signed_enum_fields)
• Unsigned (--unsigned_enum_fields) — [default]
Use Smallest Type Possible for Enum
Controls the allocation of enumerations. Permitted settings for this option are:
• On (--short_enum) — Store enumerations in the smallest possible type.
• Off (--no_short_enum) — [default] Store enumerations as integers.
Long Long Support
Controls support for the long long data type. Permitted settings for this option
are:
• On (--long_long) — [default]
• Off (--no_long_long)

164 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

Alignment & Packing


This option category is contained within C/C++ Compiler.

These options control the alignment and packing of various data objects in
memory. See also #pragma pack (n), in “General #pragma Directives”
on page 527.
Minimum Structure Alignment
Controls the minimal alignment of all objects of types struct, class, and union.
Permitted settings for this option are:
• 1-byte (--struct_min_alignment=1) — [default]
• 2-byte (--struct_min_alignment=2)
• 4-byte (--struct_min_alignment=4)
• 8-byte (--struct_min_alignment=8)
Packing (Maximum Structure Alignment)
Controls the default maximum alignment of all objects of types struct and
class. Permitted settings for this option are:
• 1-byte (-pack=1)
• 2-byte (-pack=2)
• 4-byte (-pack=4)
• 8-byte (-pack=8) — [default]
No struct or class or member of a struct or class will have an alignment
greater than the specified value, unless the setting is overridden by the #pragma
pack directive (see “General #pragma Directives” on page 527).

Green Hills Software, Inc. 165


5. Builder and Driver Options

C/C++ Data Allocation


This option category is contained within C/C++ Compiler.

These options control the treatment of data in C and C++.


Allocation of Uninitialized Global Variables
This option is only available when using the New Generation C Compiler. Controls
the allocation of uninitialized global variables. Permitted settings for this option are:
• Treat as Common Data (--commons) — [default] Treats a declaration at the
outermost level of a C file such as int foo; as common data. Common data
can be declared multiple times, and all declarations will be merged by the
linker. For example, multiple files may have the declaration int foo; and the
linker will merge them all into the same data entity.
• Treat as Unique Definitions (--no_commons) — Allocates such a variable to
a section which is initialized to zero (or potentially left uninitialized) at program
startup. This may improve optimizations by giving the compiler optimizer more
information about the location of the variable.
However, if your code contains multiple declarations such as int foo;
(which would cause the linker to find multiple definition spots for foo), this
setting may also cause multiply defined symbol linker errors. In
particular, you may not use a declaration such as int foo; in a header file
if it will be included in more than one source file. You can avoid these linker
errors by using the extern keyword for declarations and having a single
definition point. For example:

int foo; /* used in just one place, or */

int foo=0; /* used in just one place */

extern int foo; /* used in all other places */

Uniquely Allocate All Strings


Controls the creation of a separate space for all strings, even those which are
equivalent. Permitted settings for this option are:
• On (--unique_strings) — Create a separate space for all strings.
• Off (--no_unique_strings) — [default] Do not create separate spaces for
each instance of an equivalent string.

166 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

Retain Symbols for Unused Statics


Controls the retention of symbols for routines that are declared static, but are
not used. Permitted settings for this option are:
• On (--keep_static_symbols) — Retain unused static variables and routines.
• Off (--no_keep_static_symbols) — [default] Discard unused static variables
and routines.

Special Tokens
This option category is contained within C/C++ Compiler.

These options control the treatment of special tokens.


Alternative C++ Tokens
This option is only available when using the C++ or New Generation C Compiler.
Controls support for alternative tokens. Permitted settings for this option are:
• On (--alternative_tokens) — Recognizes alternative tokens (including
operator keywords such as and, bitand, and digraphs), which make it
possible to write C++ without using the {, }, [, ], #, &, |, ^, and ~ characters.
• Off (--no_alternative_tokens) — [default]
Multi-Byte Characters
This option is only available when using the C++ or New Generation Compiler.
Controls support for multi-byte character sequences in comments, string literals,
and character constants, which are used in character sets like the Japanese
Shift-JIS. Permitted settings for this option are:
• On (--multibyte_chars)
• Off (--no_multibyte_chars) — [default]

Green Hills Software, Inc. 167


5. Builder and Driver Options

Host & Target Kanji Support


Controls support for EUC or Shift-JIS Kanji characters. Permitted settings for
this option are:
• EUC on Host and Target (-kanji=euc) — [default for Solaris hosts] Specifies
Kanji character interpretation using the EUC format on the host and target.
• Shift-JIS on Host and Target (-kanji=shiftjis) — [default for non-Solaris
hosts] Specifies Kanji character interpretation using the Shift-JIS format on the
host and target.
• EUC on Host and Shift-JIS on Target (-kanji=euc/shiftjis) — Specifies Kanji
character interpretation using the EUC format on the host and the Shift-JIS
format on the target.
• Off (-kanji=none) — Disables Kanji support.

168 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

C++
This option category is contained within C/C++ Compiler.

These options control aspects of compilation that relate to C++.

Namespaces
This option category is contained within C/C++ Compiler→C++.

These options control the treatment of namespaces.


Namespace Support
Controls support for namespaces. Permitted settings for this option are:
• On (--namespaces) — [default for C++ and EEC++]
• Off (--no_namespaces) — [default for EC++]
Implicit Use of ’std’ Namespace
Controls the implicit use of the std namespace when standard header files are
included. Permitted settings for this option are:
• On (--using_std)
• Off (--no_using_std) — [default]

Keyword Support
This option category is contained within C/C++ Compiler→C++.

These options control the treatment of various C++ keywords.


Bool Type Support
Controls support for the bool type. Permitted settings for this option are:
• On (--bool) — [default] Also defines the preprocessor symbol _BOOL, allowing
code to determine when a typedef statement should be used to define the
bool type.
• Off (--no_bool)

Green Hills Software, Inc. 169


5. Builder and Driver Options

Explicit Specifier Support


Controls support for the explicit specifier on constructor declarations.
Permitted settings for this option are:
• On (--explicit) — [default]
• Off (--no_explicit)
’new’ and ’delete’ Keyword Support
Controls support for the new and delete keywords for arrays. Permitted settings
for this option are:
• On (--array_new_and_delete) — [default]
• Off (--no_array_new_and_delete)
’restrict’ Keyword Support
Controls support for the restrict keyword. Permitted settings for this option are:
• On (--restrict)
• Off (--no_restrict) — [default]
This is a C9X feature that can be used to indicate that a pointer is not aliased.
Anachronism Support
Controls support for the anachronisms described in section 18.3 of The Annotated
C++ Reference Manual (ARM), by Ellis and Stroustrup. Permitted settings for
this option are:
• On (--anachronisms)
• Off (--no_anachronisms) — [default]
Support __noinline Keyword
Controls support for the __noinline keyword. Permitted settings for this option
are:
• On (--enable_noinline)
• Off (--disable_noinline) — [default]
Instantiate Extern Inline
Controls instantiation of extern inline functions through the prelinker.
Permitted settings for this option are:
• On (--instantiate_extern_inline) — Produces smaller code, because inline
functions which require out-of-line copies will have exactly one out-of-line
instance. This option will, however, increase compile-time, because the
prelinker must assign each extern inline function to an object file and
recompile it.
• Off (--no_instantiate_extern_inline) — [default]

170 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

New-Style Cast Support


Controls the use of new-style casts (like static_cast< > and
reinterpret_cast < >) with Embedded C++. Permitted settings for this
option are:
• On (--new_style_casts)
• Off (--no_new_style_casts) — [default]
Using this option enables support for templates, which are usually not supported
in Embedded C++.
Support for Inline Functions with Extern
Controls support for inline functions with external linkage. Permitted settings
for this option are:
• On (--extern_inline) — [default]
• Off (--no_extern_inline)
When inline functions are allowed to have external linkage as required by the
standard, then extern and inline are compatible specifiers on a non-member
function declaration; the default linkage when inline appears alone is external
(that is, inline means extern inline on non-member functions); and an
inline member function takes on the linkage of its class, which is usually external.
However, when inline functions have only internal linkage, then extern and
inline are incompatible; the default linkage when inline appears alone is
internal (that is, inline means static inline on non-member functions);
and inline member functions have internal linkage, no matter what the linkage
of their class.
For more information about inlining, see “Inlining Optimizations” on page 625.
Support for Implicit Extern C Type Conversion
Controls an extension to permit implicit type conversion in C++ between a pointer
to an extern C function and a pointer to an extern C++ function. Permitted
settings for this option are:
• On (--implicit_extern_c_type_conversion) — [default]
• Off (--no_implicit_extern_c_type_conversion)

Constructors/Destructors
This option category is contained within C/C++ Compiler→C++.

These options control the treatment of C++ constructors and destructors.

Green Hills Software, Inc. 171


5. Builder and Driver Options

Support for Constructors/Destructors


Controls the insertion of code at the beginning of main() to call _main() which
is responsible for invoking constructors on global objects that require them, and
for invoking atexit() to cause the appropriate destructors to be invoked when
the program finishes. Permitted settings for this option are:
• On (--enable_ctors_dtors) — [default]
• Off (--disable_ctors_dtors)
This option only controls the insertion of the call to _main() (and hence the
inclusion of _main() from the C++ library) and does not affect the generation of
code and data related to invoking constructors for global objects.
Placement of Class Constructor Call to New
Permitted settings for this option are:
• Outside (--new_outside_of_constructor) — Moves the call to new outside
of a class constructor and inlines it inside the caller’s code. Using this
setting generates faster code in certain cases in which dynamic allocation is
not needed (for instance, when the class object is allocated on the stack).
However, using it might also result in larger code.
• Inside (--new_inside_of_constructor) — [default] Places the call to new
inside the constructor, adding several instructions to the generated code.

RTTI Support
This option category is contained within C/C++ Compiler→C++.

These options control the treatment of Run-Time Type Information (RTTI).


Run-Time Type Information Support
Controls support for Run-Time Type Information (RTTI) features dynamic_cast
and typeid. Permitted settings for this option are:
• On (--rtti) — [default for C++]
• Off (--no_rtti) — [default for EC++ and and EEC++]
Treatment of RTTI as ’const’
Controls the treatment of RTTI variables. Permitted settings for this option are:
• On (--readonly_typeinfo) — [default] Forces RTTI variables to be treated
as const in the compiler. In most cases, const variables end up in the
read-only data.
• Off (--no_readonly_typeinfo)

172 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

Virtual Tables
This option category is contained within C/C++ Compiler→C++.

These options control the treatment of virtual tables.


Virtual Function Definition
Controls the definition of virtual function tables in instances when the compiler
heuristic provides no guidance. The virtual function table for a class is defined
in a compilation if the compilation contains a definition of the first non-inline,
non-pure virtual function of the class. For classes that contain no such function,
the default is to define the virtual function table (but to define it as a local static
entity). Permitted settings for this option are:
• Force (--force_vtbl) — Forces the definition of virtual function tables for such
classes, but does not force the definitions to be local.
• Standard (--standard_vtbl) — [default] Defines the virtual function table as a
local static entity.
• Suppress (--suppress_vtbl) — Suppresses the definition of virtual function
tables for such classes.
Treatment of Virtual Tables as ’const’
Controls whether virtual tables are treated as const. Permitted settings for this
option are:
• On (--readonly_virtual_tables) — [default] Forces virtual function tables to
be treated as const in the compiler. In most cases, const tables end up
in the read-only data.
• Off (--no_readonly_virtual_tables)

Templates
This option category is contained within C/C++ Compiler→C++.

These options control C++ template instantiation. For a full description of this
feature, see “Template Instantiation” on page 481.

Green Hills Software, Inc. 173


5. Builder and Driver Options

Auto-Instantiation of Templates
Controls automatic instantiation of templates. Permitted settings for this option are:
• On (--auto_instantiation) — [default]
• Off (--no_auto_instantiation) — If you disable automatic instantiation, you
must ensure that the necessary entities are instantiated manually with C/C++
Compiler→C++→Templates→Manual Template Instantiation Mode, or
with #pragma directives in your code.
Manual Template Instantiation Mode
Manually controls instantiation of external template entities. External template
entities are non-inline and non-static template functions and template static data
members. The instantiation mode determines the template entities for which code
should be generated. Permitted settings for this option are:
• All (-tall) — Instantiates all template entities whether or not they are used. For
each fully instantiated template class, all of its member functions and static
data members are instantiated whether or not they are used. Nonmember
template functions are instantiated even if the only reference was a declaration.
• Local Only (-tlocal) — Instantiates only the template entities that are used in
this compilation, and forces those entities to be local to this compilation. This
is intended to provide a very simple mechanism for those new to working
with templates. The compiler will instantiate the functions that are used in
each compilation unit as local functions, and the program will link and run
correctly (barring problems due to multiple copies of local static variables).
However, one may end up with many copies of the instantiated functions,
so this is not suitable for production use. This setting disables C/C++
Compiler→C++→Templates→Auto-Instantiation of Templates.
• Used Only (-tused) — Instantiates only the template entities that are used
in this compilation. This includes all static data members for which there are
template definitions.
• None (-tnone) — [default] Instantiates no template
entities. This is usually the appropriate setting when C/C++
Compiler→C++→Templates→Auto-Instantiation of Templates is enabled.

174 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

Distinct Template Signatures


Controls whether the signatures for template functions can match those for
non-template functions when the functions appear in different compilation units.
Permitted settings for this option are:
• On (--distinct_template_signatures) — [default] Do not permit duplicate
template signatures.
• Off (--no_distinct_template_signatures) — Permit duplicate template
signatures.
A normal (non-template) function, such as void f(int), cannot be used to
satisfy the need for an instantiation of a template, such as void f(T), with
T set to int.

Guiding Declarations of Template Functions


Controls recognition of guiding declarations of template functions. Permitted
settings for this option are:
• On (--guiding_decls) — [default]
• Off (--no_guiding_decls)
A guiding declaration is a function declaration that matches an instance of a
function template but has no explicit definition (since its definition derives from
the function template). For example:

template <class T> void f(T)


{
// ...
} void f(int);

When regarded as a guiding declaration, f(int) is an instance of the template;


otherwise it is an independent function for which a definition must be supplied.
If this option is disabled and C/C++ Compiler→C++→Templates→Support for
Old-Style Specializations remains enabled, a specialization of a non-member
template function is not recognized. It is treated as a definition of an independent
function.
Implicit Source File Inclusion
Controls implicit inclusion of source files as a method of finding definitions of
template entities to be instantiated. Permitted settings for this option are:
• On (--implicit_include) — [default]
• Off (--no_implicit_include)

Green Hills Software, Inc. 175


5. Builder and Driver Options

Support for Implicit Typenames


Controls the implicit determination, from context, of whether a template
parameter-dependent name is a type or a nontype. Permitted settings for this
option are:
• On (--implicit_typename) — [default]
• Off (--no_implicit_typename)
Support for Nonstd Qualifier Deduction
Controls whether nonstandard template argument deduction should be performed
in the qualifier portion of a qualified name. Permitted settings for this option are:
• On (--nonstd_qualifier_deduction) — Enables deduction of a template
argument for the template parameter T in contexts like A<T>::B or T::B. The
standard deduction mechanism treats these as non-deduced contexts that
use the values of template parameters that were either explicitly specified or
deduced elsewhere.
• Off (--std_qualifier_deduction) — [default]
Support for Old-Style Specializations
Controls the treatment of old-style template specializations (that is, specializations
that do not use the template<> syntax). Permitted settings for this option are:
• On (--old_specializations) — [default]
• Off (--no_old_specializations)
One Instantiation Per Object
Controls whether template instantiations are put in separate object files. See also
C/C++ Compiler→C++→Templates→Hybrid One Instantiation Per Object.
Permitted settings for this option are:
• On (--one_instantiation_per_object) — Puts each template instantiation
(function or static data member) in the compilation in a separate object file.
The primary object file (the object file corresponding to the original source file)
contains everything else in the compilation; that is, everything that is not an
instantiation. This is recommended when creating libraries, because you can
pull in only the instantiations that are needed, thus reducing code size. This
option must be enabled if two different libraries include some of the same
instantiations, in order to avoid multiply defined symbol problems.
• Off (--no_one_instantiation_per_object) — [default]

176 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

Hybrid One Instantiation Per Object


Controls whether template instantiations are put in separate object
files, except where #pragma instantiate is used. See also C/C++
Compiler→C++→Templates→One Instantiation Per Object. Permitted settings
for this option are:
• On (--hybrid_one_instantiation_per_object) — Puts each instantiation in
the compilation in a separate object file, except where they are created by
#pragma instantiate. Instances created in this way are added to the
object file generated from the source file in which they appear.
• Off (--no_hybrid_one_instantiation_per_object) — [default]
Template Instantiation Output Directory
When C/C++ Compiler→C++→Templates→One Instantiation Per Object is
enabled (--one_instantiation_per_object), this option can be used to specify
or create a directory into which the generated object files should be put. The
equivalent driver option is:
• --instantiation_dir=directory
The default instantiation directory is ./template_dir.
If the directory setting used for -instantiation_dir is a relative path, that path is
resolved relative to the Object File Output Directory (-object_dir). If -object_dir
is not set, then the Instantiation Directory path is relative to the current working
directory.

Pre-link with Instantiations


Controls a mode of the Builder or driver, which runs the C++ prelink utility to
instantiate templates without running the linker or archiver. This option is used by
the clearmake process. Permitted settings for this option are:
• On (--prelink_objects) — Creates object files, but does not perform linking.
The object files contain all template instantiations required, and so can be
linked later without concern for template requirements.
• Off (--no_prelink_objects) — [default]
This option should not be used when C/C++
Compiler→C++→Templates→Auto-Instantiation of Templates
is disabled (--no_auto_instantiation), since this option prevents prelink from
being run. When using the driver, do not use this option in combination with any
option that prevents the linker from being run, such as -E, -P, -S, or -c.

Green Hills Software, Inc. 177


5. Builder and Driver Options

Support for ’typename’ Keyword


Controls recognition of the typename keyword. When recognized, typename
can be used instead of class when declaring template parameters. Permitted
settings for this option are:
• On (--typename) — [default]
• Off (--no_typename)
Dependent Name Processing
Controls the separate lookup of names in templates at the time the template is
parsed and at the time it is instantiated. Permitted settings for this option are:
• On (--dep_name) — Also implies C/C++ Compiler→C++→Templates→Parse
Templates in Generic Form (--parse_templates).
• Off (--no_dep_name) — [default]
Parse Templates in Generic Form
Controls the parsing of nonclass templates in their generic form (i.e., even if they
are not really instantiated). Permitted settings for this option are:
• On (--parse_templates)
• Off (--no_parse_templates) — [default]
This option is implied by Dependent Name Processing (see above).
Recognition of Exported Templates
Controls recognition of exported templates. Permitted settings for this option are:
• On (--export)
• Off (--no_export) — [default]
This option enables C/C++ Compiler→C++→Templates→Dependent
Name Processing (--dep_name) (see above). It cannot be used with
C/C++ Compiler→C++→Templates→Implicit Source File Inclusion
(--implicit_include).
PreLink File to Create Template Instances
Specifies an external object file or executable to notify the prelinker of existing
template instances. The equivalent driver option is:
• -prelink_against file

Precompiled Header Files


This option category is contained within C/C++ Compiler→C++.

178 MULTI: Building Applications for Embedded ARM


C/C++ Compiler Options

These options control the generation of a Precompiled Header File, which


may save compilation time. For detailed documentation of this feature, see
“Precompiled Header Files” on page 497.
Precompiled Header File
Controls the generation of a Precompiled Header File. Permitted settings for
this option are:
• Automatically Use and/or Create a PCH (--pch) — Use an existing file if
available, or create one.
• Create and Use a New PCH (--create_pch file) — Create a precompiled
header file with the specified name (if other conditions are satisfied).
• Use a Pre-existing PCH (--use_pch file) — Use a precompiled header file,
file, as part of the current compilation.
• Do Not Use a PCH (--no_pch) — [default]
PCH Search Directory
Specifies the directory in which to search for precompiled header files. If the
specified directory does not already exist, it will be created. The equivalent driver
option is:
• --pch_dir directory
If this option is not passed, and Project→Object File Output Directory
(-object_dir) is used to specify an alternate object file directory (see “Project
Options” on page 140), then the compiler will search for precompiled header
files in that directory.
If both this option and Project→Object File Output Directory (-object_dir) is
used, then the path to the PCH directory is treated as relative to the object file
directory.

PCH Messages
Controls the display of the message which reports the creation or use of a
precompiled header file. Permitted settings for this option are:
• On (--pch_messages) — [default]
• Off (--no_pch_messages)

Green Hills Software, Inc. 179


5. Builder and Driver Options

Assembler Options
This is a top-level option category.

These options control the general operation of the assembler.

For additional, more specialized options, see “Advanced Assembler Options”


on page 216.
Source Listing Generation
Controls the generation of a source listing. Permitted settings for this option are:
• Generate Default Listing (-list) — Creates a list with the name of the object
file plus a .lst extension.
• Generate User-Specified Listing (-list=filename) — Creates a listing with
the specified filename.
• Suppress Listing (-no_list) — [default]
Preprocess Assembly Files
Controls whether assembly files other than those with a .c extension are
preprocessed. Permitted settings for this option are:
• On (-preprocess_assembly_files)
• Off (-no_preprocess_assembly_files) — [default] Only preprocess files
with the .c suffix.
Preprocess Special Assembly Files
Controls whether assembly files with a .c extension are preprocessed. Permitted
settings for this option are:
• On (-preprocess_special_assembly_files) — [default]
• Off (-no_preprocess_special_assembly_files)
Interleaved Source and Assembly
Controls the interleaving of your original source code with the generated assembly
code when used with the Assembler→Source Listing Generation option.
Permitted settings for this option are:
• On (-passsource)
• Off (-nopasssource) — [default]
Not every line of the original source code will appear in the output.

180 MULTI: Building Applications for Embedded ARM


Assembler Options

ARM UK Assembler Compatibility


Controls ARM Ltd. compatibility mode, which is required to assemble most ARM
Ltd. syntax. Permitted settings for this option are:
• On (-arm_uk_asm)
• Off (-no_arm_uk_asm) — [default]
ARM UK Internal Variables
Sets the values of simulated ARM Ltd. internal variables. The equivalent driver
option is:
• -apcs=qualifiers
The qualifiers are either /none or a concatenation of one or less entries from each
of the following qualifier sets:
• /inter or /nointer — (ARM/Thumb interworking)
• /ropi, /pic, /noropi, or /nopic — (Position Independent Code)
• /rwpi, /pid, /norwpi, or /nopid — (Position Independent Data)
• /swst, /noswt, or /swstna — (Software Stack Count Checking)
ARM UK Assembler Predefines
Declares and sets the value of a variable prior to assembly by executing either the
SETA, SETL, or SETS directive. The equivalent driver option is:
• -pd="variable [SETA|SETL|SETS] expr"
For more information about ARM UK assembler compatibility, see Chapter 7,
“The asarm Assembler”.
Additional Assembler Options
Passes the specified assembler options to the asarm assembler command line.
The equivalent driver option is:
• -asm=options — To pass multiple options, separate the options by spaces and
enclose the whole string in quotes, or specify -asm=options multiple times.
For example:

-asm="-nogen -ref -w"

or:

-asm=-nogen -asm=-ref -asm=-w

For a full list of assembler options which may be passed in this manner, see
Chapter 7, “The asarm Assembler”.

Green Hills Software, Inc. 181


5. Builder and Driver Options

Assembler Command File


Passes the options specified in file directly to the assembler. The equivalent driver
option is:
• -asmcmd=file
The file must contain only one assembler option per line. For example:

-nogen
-ref
-w

For a full list of assembler options which may be passed in this manner, see
Chapter 7, “The asarm Assembler”.

182 MULTI: Building Applications for Embedded ARM


Linker Options

Linker Options
This is a top-level option category.

These options control the general operation of the linker.

For additional, more specialized options, see “Advanced Linker Options” on


page 216.
Output File Type
Controls the form of linker output. Permitted settings for this option are:
• Executable / Located Program (-locatedprogram) — [default] Generates an
executable program.
• Relocatable Object File (-relobj) — Generates a relocatable object file, which
is suitable for being passed as input to another run of the linker. Implies
-nostdlib, which prevents the linking in of any startup files or libraries. Does
not allocate common variables or give errors for undefined symbols, as
Relocatable Program does.
• Relocatable Program (-relprog) — Retains relocation information in the
output file. The resulting file is suitable for execution, or it may be passed as
input to another run of the linker to allow further relocation of the program.
Relocates all references to functions and variables so that the program can
be executed.
Generate Additional Output
Creates the specified output type in addition to the project executable. Permitted
settings for this option are:
• Memory Image File (-memory) – Generates output file with .mem extension
containing the output of the image as translated by the gmemfile utility
program. For more information about gmemfile, see “The gmemfile Utility
Program” on page 363.
• S-Record File (-srec) – Generates output file with .run extension containing
the output of the image as translated by the gsrec utility program. For more
information about gsrec, see “The gsrec Utility Program” on page 382.
• None (--no_additional_output) — [default]

Green Hills Software, Inc. 183


5. Builder and Driver Options

Executable Stripping
Controls stripping the executable at the conclusion of linking. Permitted settings
for this option are:
• On (-strip) — Stripping involves removing line number, symbol table, and
debugging information to reduce the file size of the executable.
• Off (-nostrip) — [default]
For information about stripping executables after link-time, see “The gstrip Utility
Program” on page 389.
Start Address Symbol
Specifies the symbol whose address will be used as the program entry point or
start address. Permitted settings for this option are:
• Start Address (-e symbol) —The default symbol is _start.
• No Entry Synbol (-noentry)
Linker Directives Directory
Specifies a directory in which to search for linker directives files. The equivalent
driver option is:
• -directive_dir directory
Preprocess Linker Directives Files
Controls whether linker directives files are preprocessed. Permitted settings for
this option are:
• On (--preprocess_linker_directive)
• Off (--no_preprocess_linker_directive) — [default]
Linker Warnings
Controls the display of linker warnings. Permitted settings for this option are:
• Display (-linker_warnings) — [default]
• Suppress (-no_linker_warnings)
Additional Linker Options (before .ld files)
Passes the specified linker options to the elxr linker command line before any .ld
files. The equivalent driver option is:
• -Wl,option[,option]…

184 MULTI: Building Applications for Embedded ARM


Linker Options

Additional Linker Options (after .ld files)


Passes the specified linker options to the elxr linker command line after any .ld
files. The equivalent driver option is:
• -lnk=options — To pass multiple options, separate the options by spaces and
enclose the whole string in quotes, or specify -lnk=options multiple times.
For example:

-lnk="-multiple -undefined"

or:

-lnk=-multiple -lnk=-undefined

For a full list of linker options which may be passed in this manner, see Chapter 9,
“The elxr Linker”. The option is passed to the linker in approximately the position
in which it appears on the driver command line.
Linker Command File
Passes the options specified in file directly to the linker. The equivalent driver
option is:
• -lnkcmd=file
The file must contain only one linker option per line. For example:

-nogen
-ref
-w

For a full list of linker options which may be passed in this manner, see “Linker
Options” on page 183.

Green Hills Software, Inc. 185


5. Builder and Driver Options

Linker Optimizations
This option category is contained within Linker.

These options control individual optimizations that can be implemented at


link-time. You can enable or disable all of them with the Optimization→Linker
Optimizations option (see “Optimization Options” on page 143).
Deletion of Unused Functions
Controls the removal from the executable of functions and data which are unused
and unreferenced. Permitted settings for this option are:
• On (-delete)
• Off (-no_delete) — [default]
Certain options that create references to functions may inhibit this option.
Code Factoring
Controls the code factoring optimization, which reduces code size by removing
redundant sequences of object code at link-time. Permitted settings for this option
are:
• On (-codefactor)
• Off (-no_codefactor) — [default]
For more information see “Code Factoring” on page 307.
Link-Time Constant Propagation
Controls the link-time constant propagation optimization. Permitted settings for
this option are:
• On (--link_constprop) — Instructs the linker to optimize the program further
when new constants are resolved at link time, for example, when weak
symbols are defined/left undefined during the final link (i.e. the constant 0 will
be propagated for weak undefined symbols).
• Off (--no_link_constprop) — [default]
Similar Pool Merging
Controls a link-time speed optimization which uses linker information about the
contents of relocated data to replace pool loads with faster arithmetic instructions.
Permitted settings for this option are:
• On (--link_similar_pools)
• Off (--no_link_similar_pools) — [default]

186 MULTI: Building Applications for Embedded ARM


Linker Options

Start and End Files


This option category is contained within Linker.

These options control the use of start and end files.


Start Files
Controls the start files to be linked into the executable. The default is to use the
Green Hills start files. Permitted settings for this option are:
• Use Specified Start Files (-startfiles=file[,file…])
• Do Not Use Start Files (-nostartfiles)
End Files
Specifies end files to be linked into the executable. End files are the last object
files passed on the command line to the linker. The equivalent driver option is:
• -endfile=file[,file…]
Start File Directory
Specifies a directory in which to search for start files. The equivalent driver option
is:
• -startfile_dir=directory

Green Hills Software, Inc. 187


5. Builder and Driver Options

Symbols
This option category is contained within Linker.

These options control the linker’s treatment of symbols.


Multiply-Defined Symbols
Controls the treatment of multiply-defined symbols. Permitted settings for this
option are:
• Errors (-no_multiple) — [default]
• Silent (-multiple)
Undefined Symbols
Controls the treatment of undefined symbol references. Permitted settings for
this option are:
• Errors (-no_undefined) — [default]
• Silent (-undefined)
Force Undefined Symbol
Forces an undefined symbol reference for symbol, as if there had been some use
of the symbol in one of the modules to be linked. This may cause modules to
be linked in from libraries that would not otherwise be included. The equivalent
driver option is:
• -u symbol
Import Symbols
Makes available symbol names and addresses from a separately linked, fully
located file during linking. The contents of the file will not be included in the
output; only those symbol addresses needed by the current link are imported.
The equivalent driver option is:
• -A file
This option is useful when one linker image must refer to symbols that are located
in another separately linked image.

188 MULTI: Building Applications for Embedded ARM


Linker Options

Linker Output Analysis


This option category is contained within Linker.

These options control various forms of linker output.


Map File Generation
Controls the generation of a map file. Permitted settings for this option are:
• Generate Default Map File (-map) — [default] Creates a map file with the
name of the object file plus a .map extension.
• Generate User-Specified Map File (-map=filename) — Creates a map file
with the specified filename.
• Suppress Map(-nomap)
Map File Retention
Controls the retention of the map file in the event of a link error. Permitted settings
for this option are:
• On (-keepmap)
• Off (-nokeepmap) — [default]
Map File Page Length
Specifies the length, n, of a map file page. The equivalent driver option is:
• -maplines n
Map File Sorting
Controls the method for ordering the map file. Permitted settings for this option are:
• Alphabetic (-Ma) — [default]
• Numeric (-Mn)
Map File Cross-Referencing
Controls the generating of cross-reference information in the map file. Permitted
settings for this option are:
• On (-Mx)

Green Hills Software, Inc. 189


5. Builder and Driver Options

Output File Size Analysis


Controls use of the gsize utility to determine the size of the output executable.
gsize creates a file called executable_name.siz, which contains a list of the
sizes of the ROM sections of the output executable. Permitted settings for this
option are:
• On (-gsize)
• Off (-no_gsize) — [default]
For more information, see “The gsize Utility Program” on page 380.
Call Graph Generation
Controls the generation of a call graph. Permitted settings for this option are:
• Generate Default Call Graph (-callgraph) — Creates a call graph with the
name of the object file plus a .graph extension.
• Generate User-Specified Call Graph (-callgraph=filename) — Creates a
call graph with the specified filename.
• Suppress Call Graph (-no_callgraph) — [default]

Link-Time Checking
This option category is contained within Linker.

These options control various forms of linker checking.


Section Overlap Checking
Controls the treatment of overlapping sections. Permitted settings for this option
are:
• Errors on Any Overlap (-strict_overlap_check)
• Errors on Non-Zero Overlap (-nooverlap)
• Warnings (-overlap_warn) — [default]
• Silent (-overlap)
Checksum
Controls the creation of section checksums. Permitted settings for this option are:
• On (-checksum) — Appends a 4-byte checksum to the end of every initialized
program section.
• Off (-nochecksum) — [default]
The algorithm used is a standard 32-bit CRC. Sample source code for verifying
checksums is included in libstartup/cksum.c of your installation.

190 MULTI: Building Applications for Embedded ARM


Compiler Diagnostics Options

Compiler Diagnostics Options


This is a top-level option category.

These options control the type, form, and quantity of diagnostic messages you
may receive during building.
Warnings
Controls the display of warnings for most Green Hills tools. Permitted settings
for this option are:
• Display (--warnings) — [default]
• Suppress (-w)
Remarks
Controls the display of remarks for most Green Hills tools. Permitted settings
for this option are:
• Display (--remarks)
• Suppress (--no_remarks) — [default]
Maximum Number of Errors to Display
Limits to n the number of error messages the compiler will print before quitting.
The default is 100 and the minimum is 2.
The equivalent driver option is:
• -errmax=n
Redirect Error Output to File
Specifies a file to which all error output is redirected. The equivalent driver option
is:
• -stderr=file
Quit Building if Warnings are Generated
Controls whether building will cease upon the generation of any warning.
Permitted settings for this option are:
• On (--quit_after_warnings)
• Off (--no_quit_after_warnings) — [default]
Display Version Information
Instructs the compiler and other tools to print its copyright banner and version
number. Permitted settings for this option are:
• On (-V)
• Off (--no_version) — [default]

Green Hills Software, Inc. 191


5. Builder and Driver Options

Varying Message Format


This option category is contained within Compiler Diagnostics.

These options control various aspects of the display of diagnostic messages.


Brief Error Message Mode
Controls a mode in which a shorter form of the diagnostic output is used. When
enabled, the original source line is not displayed and the error message text is
not wrapped when it is too long to fit on a single line. Permitted settings for this
option are:
• On (--brief_diagnostics)
• Off (--no_brief_diagnostics) — [default]
Line Wrap Messages
Controls whether diagnostic messages are wrapped when they are too long to fit
on a single line. Permitted settings for this option are:
• On (--wrap_diagnostics) — [default]
• Off (--no_wrap_diagnostics)
Display Error Message Paths
Controls whether full pathnames are given for files mentioned in diagnostic
messages. Permitted settings for this option are:
• On (-error_basename)
• Off (-no_error_basename) — [default]
Error Style
Controls the format of error messages. Permitted settings for this option are:
• FORTRAN-Style Error Messages (-error_fortran_style)
• C/C++ Style Error Messages (-no_error_fortran_style) — [default]

C/C++ Messages
This option category is contained within Compiler Diagnostics.

These options control various diagnostic messages specific to the C and C++
languages.

192 MULTI: Building Applications for Embedded ARM


Compiler Diagnostics Options

Functions Without Prototypes


Controls the treatment of functions that are referenced or called when no prototype
has been provided. Permitted settings for this option are:
• Errors (--prototype_errors)
• Warnings (--prototype_warnings)
• Silent (--prototype_silent) — [default]
Asm Statements
Controls the treatment of asm statements. Permitted settings for this option are:
• Errors (--asm_errors)
• Warnings (--asm_warnings) — [default for strict ANSI C and strict ANSI C++]
• Silent (--asm_silent) — [default for all other C and C++ modes]
In strict ANSI C, the spelling asm is not part of the C language. It is unknown to
the compiler and may be used as the name of a variable or function. To write an
asm macro in strict ANSI C, you must use __asm. In non-strict ANSI C, and in
C++, the two spellings (asm and __asm) are identical.
Any correct use of __asm may still give a diagnostic indicating that__asm is
non-standard.
Unknown #pragmas
Controls the treatment of #pragma directives that are not recognized by the
compiler. Permitted settings for this option are:
• Errors (--unknown_pragma_errors)
• Warnings (--unknown_pragma_warnings) — [default]
• Silent (--unknown_pragma_silent)
Incorrect #pragmas
Controls the treatment of valid #pragma directives that use the wrong syntax.
Permitted settings for this option are:
• Errors (--incorrect_pragma_errors)
• Warnings (--incorrect_pragma_warnings) — [default]
• Silent (--incorrect_pragma_silent)
New-Style ’for-init’ Code
Controls a warning that is issued when C++ programs compiled under the new
for-init scoping rules would have had a different behavior under the old rules.
Permitted settings for this option are:
• On (--for_init_diff_warning) — [default]
• Off (--no_for_init_diff_warning)

Green Hills Software, Inc. 193


5. Builder and Driver Options

Use Before ’Set’


Controls a warning that is issued when local automatic variables are used before
their values are set. Permitted settings for this option are:
• On (--use_before_set_warnings) — [default]
• Off (--no_use_before_set_warnings)
The compiler’s algorithm for detecting such uses is conservative and may miss
some cases.
printf & scanf Argument Type Checking
Controls argument type checking against the format string in calls to printf and
scanf. The checking is only performed if the format string is a constant. More
extensive checking is done if GNU support is enabled (see “C/C++ Compiler
Options” on page 151). Permitted settings for this option are:
• On (-Wformat)
• Off (-Wno-format) — [default]
This option has no effect if Green Hills header files are not used.
Implicit Int Return Type
Controls a warning that is issued if the return type of a function is not declared
before it is called (thus causing the return type to be implicitly declared int).
Permitted settings for this option are:
• On (-Wimplicit-int)
• Off (-Wno-implicit-int) — [default]
For broader prototype checking, see Compiler Diagnostics→C/C++
Messages→Functions Without Prototypes.
Shadow Declarations
Controls a warning that is issued if the declaration of a local variable shadows the
declaration of a variable of the same name declared at the global scope, or at an
outer scope. Permitted settings for this option are:
• On (-Wshadow)
• Off (-Wno-shadow) — [default]
Trigraphs
Controls a warning that is issued for any use of trigraphs. Permitted settings
for this option are:
• On (-Wtrigraphs)
• Off (-Wno-trigraphs) — [default]

194 MULTI: Building Applications for Embedded ARM


Compiler Diagnostics Options

Undefined Preprocessor Symbols


Controls a warning that is issued for undefined symbols in preprocessor
expressions. Such undefined symbols are always given the value of 0. Permitted
settings for this option are:
• On (-Wundef)
• Off (-Wno-undef) — [default]

Varying Message Severity


This option category is contained within Compiler Diagnostics→C/C++
Messages.

These options allow you to increase or decrease the severity of any of the C and
C++ compiler diagnostic messages.

Values for the error number, n, can be obtained by enabling the Compiler
Diagnostics→C/C++ Messages→Varying Message Severity→Display Error
Message Numbers (--display_error_number) option (see below). The
complete set of error numbers is also listed in the online only MULTI: C and
C++ Compiler Error Messages.
Set Message to Error
Sets the specified diagnostics message to the level of error. The equivalent driver
option is:
• --diag_error n[,n2]...
Set Message to Warning
Sets the specified diagnostics message to the level of warning. The equivalent
driver option is:
• --diag_warning n[,n2]...
Set Message to Remark
Sets the specified diagnostics message to the level of remark. The equivalent
driver option is:
• --diag_remark n[,n2]...
Set Message to Silent
Sets the specified diagnostics message to the level of silent. The equivalent driver
option is:
• --diag_suppress n[,n2]...

Green Hills Software, Inc. 195


5. Builder and Driver Options

Display Error Message Numbers


Controls the display of error message numbers in any diagnostic messages that
are generated. Permitted settings for this option are:
• On (--display_error_number) — [default]
• Off (--no_display_error_number)
This option may be used to determine the error number to be used when overriding
the severity of a diagnostic message.

196 MULTI: Building Applications for Embedded ARM


Advanced Options

Advanced Options
This is a top-level option category.

Advanced Target Options


This option category is contained within Advanced.

These options control advanced settings that affect compilation for your target.
For more common options, see “Target Options” on page 131.
Target Processor
Specifies code generation for a particular target processor.
If you specify a processor, the driver selects the appropriate instruction set and
a generic .ld file. For more information about these .ld files, see “Working with
Linker Directives Files” on page 43. You can override the default .ld file by
specifying an alternate linker directives file elsewhere on the command line. For a
more detailed discussion on .ld files, see “Linker Directives Files” on page 285.
The equivalent driver option is:
• Generic CPU (-cpu=cpu) — To obtain a list of supported processors from the
command line, enter -cpu=? (or -cpu=\? in many shells).
Initialization of PIC Pointers
Controls extensions in the compiler, linker, and libraries which enable special fixup
operations to be performed at program startup. These operations adjust the initial
values of all pointers to reflect the addresses where the objects were loaded at run
time. Permitted settings for this option are:
• On (--initpipointers) — [default]
• Off (--no_initpipointers)
For more information, see “Customizing the Run-Time Environment Program
Sections” on page 299.
Support For Very Large Switch Statements
Controls the size of switch statement offset entries. Permitted settings for this
option are:
• On (-bigswitch) — Use a 32-bit offset.
• Off (-nobigswitch) — [default] Use a 16-bit offset, which is smaller and faster,
but which will fail if a label is too far away.

Green Hills Software, Inc. 197


5. Builder and Driver Options

Advanced Project Options


This option category is contained within Advanced.

These options control advanced project configuration settings. For more


common options, see “Project Options” on page 140.
Binary Code Generation
Controls binary code generation. By default, the toolchain generates binary object
files directly from source code rather than via the creation of assembly language
files. Since the assembler is not invoked, binary code generation significantly
decreases compile time. Permitted settings for this option are:
• On (-obj) — [default] Enables direct binary generation.
• Off (-noobj) — Disables direct binary generation.
Temporary Output Directory
Specifies a directory for writing temporary files to. This option is useful if your
default temporary directory is on a small file system that might run out of disk
space during compilations which involve inlining or template processing. The
equivalent driver option is:
• -tmp=directory
(UNIX) By default, temporary files are written to the first of the following directories
that exists:
• The directory specified by the environment variable TMPDIR.
• The directory specified by the constant value of variable P_tmpdir (usually
/var/tmp on Solaris and HPUX, and /tmp on Linux), which is defined in the
operating system header file (usually located in /usr/include/stdio.h).
• /tmp.
(Windows) By default, temporary files are written to the first of the following
directories that exists:
• The directory specified by the environment variable TMP.
• The directory specified by the constant value of variable P_tmpdir (usually
the root directory of the current drive), which is defined in the operating system
header file.
• The current working directory.

198 MULTI: Building Applications for Embedded ARM


Advanced Options

Temporary Output
Controls whether temporary files generated during compilation are retained.
Permitted settings for this option are:
• Retain (-keeptempfiles) — Prevents the deletion of temporary files after they
are used. If an assembly language file is created by the compiler, this option
will place it in the current directory instead of the temporary directory.
• Delete (-nokeeptempfiles) — [default]
Non-Standard Output Suffix
Controls the acceptance of non-standard output suffixes. Permitted settings for
this option are:
• Accepted (--any_output_suffix)
• Not Accepted (--no_any_output_suffix) — [default]
Source Directories Relative to Top-Level Project
Specifies a directory in which the builder should search for source files. The
syntax for this option is:
• :sourceDirNonRelative=directory
This is a Builder-only option. There is no equivalent driver option.
Intermediate Output Directory Relative to This File
Specifies the path to where object files (and any custom file types) are written,
relative to the location of the current .gpj project file. The syntax for this option is:
• :outputDirRelative=directory
This is a Builder-only option. There is no equivalent driver option.
Binary Output Directory Relative to Top-Level Project
Specifies the path to where final executable output files are written, relative to the
location of your top-level default.gpj project file. The syntax for this option is:
• :binDir=directory
This is a Builder-only option. There is no equivalent driver option.
Binary Output Directory Relative to This File
Specifies the path to where final executable output files are written, relative to the
location of the current .gpj project file. The syntax for this option is:
• :binDirRelative=directory
This is a Builder-only option. There is no equivalent driver option.
Dependencies Relative to Source Directory
Specifies that the present file must be rebuilt if the specified file, relative to the
location of your source directory, changes. The syntax for this option is:
• :depends=filename
This is a Builder-only option. There is no equivalent driver option.

Green Hills Software, Inc. 199


5. Builder and Driver Options

Dependencies Relative to This File


Specifies that the present file must be rebuilt if the specified file, relative to the
location of the present .gpj project file, changes. The syntax for this option is:
• :dependsRelative=filename
This is a Builder-only option. There is no equivalent driver option.
Dependencies Relative to Top-Level Project
Specifies that the present file must be rebuilt if the specified file, relative to the
location of your top-level default.gpj project file, changes. The syntax for this
option is:
• :dependsNonRelative=filename
This is a Builder-only option. There is no equivalent driver option.
Self-Dependency
Any changes to this file will cause it and all of its children to be rebuilt. The syntax
for this option is:
• :noselfdepend
This is a Builder-only option. There is no equivalent driver option.
Suppress Dependencies
Specifies that the present file must not be rebuilt if the specified file changes.
The syntax for this option is:
• :nodepends=filename
This is a Builder-only option. There is no equivalent driver option.
Output Filename for Generic Types
Specifies a name for the output file. The syntax for this option is:
• :outputName=filename
This is a Builder-only option. There is no equivalent driver option.
Append Default Extension to Output Filename
Automatically appends the default file extension to any output files (for example,
.o for object files). The syntax for this option is:
• :appendExtension
This is a Builder-only option. There is no equivalent driver option.
Commands to Execute Before Associated Command
Specifies commands that are executed before or after the file is processed,
dependent on the file type (that is, a header file or a program file). The syntax
for this option is:
• :preexec=command
This is a Builder-only option. There is no equivalent driver option.

200 MULTI: Building Applications for Embedded ARM


Advanced Options

Commands to Execute Before Associated Command (via Shell)


Specifies commands to be executed before link-time via the native shell. The
syntax for this option is:
• :preexecShell=command
This is a Builder-only option. There is no equivalent driver option.
Commands to Execute After Associated Command
Specifies commands to be executed after link-time. The syntax for this option is:
• :postexec=command
This is a Builder-only option. There is no equivalent driver option.
Commands to Execute After Associated Command (via Shell)
Specifies commands to be executed after link-time via the native shell. The syntax
for this option is:
• :postexecShell=command
This is a Builder-only option. There is no equivalent driver option.
Additional Output Files
Specifies any non-standard output files that are generated during building, so that
the Builder can include them in file cleanup. The syntax for this option is:
• :extraOutputFile=filename
This is a Builder-only option. There is no equivalent driver option.
’Select One’ Project Extension List
For use with the Select One project type. Specifies a list of file extensions to
determine the order of preference with which alternate versions of the module are
chosen. The syntax for this option is:
• :select=argument
This is a Builder-only option. There is no equivalent driver option.
Pass Through Arguments
Passes unknown options to a command (any tool or utility invoked by the Builder).
This is one way of quickly defining custom types. The syntax for this option is:
• :passThrough=argument
This is a Builder-only option. There is no equivalent driver option.

Green Hills Software, Inc. 201


5. Builder and Driver Options

Toolchain Component Locations


This option category is contained within Advanced→Advanced Project
Options.

These options allow you to vary the location of toolchain components.


Alternate Compiler Directory
Specifies an alternate location from which to invoke the compiler. The equivalent
driver option is:
• -Y0,directory
Alternate Library Directory
Specifies an alternate location in which to search for the standard system libraries.
The equivalent driver option is:
• -YL,directory
Alternate Assembler Directory
Specifies an alternate location from which to invoke the assembler. The equivalent
driver option is:
• -Ya,directory
Alternate Linker Directory
Specifies an alternate location from which to invoke the linker. The equivalent
driver option is:
• -Yl,directory
Alternate Tools Directory
Specifies an alternate location from which to invoke the tools. The equivalent
driver option is:
• -alttools directory

202 MULTI: Building Applications for Embedded ARM


Advanced Options

Advanced Optimization Options


This option category is contained within Advanced.

These options provide very low-level control over various minor optimizations.
These optimizations are generally controlled most effectively by the compiler
when you specify an Optimization→Optimization Strategy, and you should
not use these options unless you have very particular optimization needs. For
more common options, see “Optimization Options” on page 143.
Inline Tiny Functions
Controls the inlining of very small functions. Permitted settings for this option are:
• On (--inline_tiny_functions) — This setting is implied by
Optimization→Optimization Strategy is enabled unless
Debugging→Debugging Level is also enabled.
• Off (--no_inline_tiny_functions) — [default]
For more information, see “Automatic Inlining” on page 625.
Inline C Memory Functions
Controls the inlining of C Memory Functions. Permitted settings for this option are:
• On (-Omemfuncs)
• Off (-Onomemfuncs) — [default]
For more information, see “Inlining of C Memory Functions” on page 632.
Inline C String Functions
Controls the inlining of C String Functions. Permitted settings for this option are:
• On (-Ostrfuncs)
• Off (-Onostrfuncs) — [default]
For more information, see “Inlining of C String Functions” on page 633.
Loop Unrolling
Controls the Loop Unrolling optimization. Permitted settings for this option are:
• On (-Ounroll)
• Off (-Onounroll) — [default]
For more information, see “Loop Unrolling” on page 639.

Green Hills Software, Inc. 203


5. Builder and Driver Options

Register Allocation by Coloring


Controls the dynamic storage of variables in registers. Permitted settings for
this option are:
• On (-overload) — [default]
• Off (-nooverload)
For more information, see “Register Allocation by Coloring” on page 653.
Automatic Register Allocation
Controls the automatic allocation of local variables to registers. Permitted settings
for this option are:
• On (-autoregister) — [default]
• Off (-noautoregister)
For more information, see “Automatic Register Allocation” on page 654.
Common Subexpression Elimination
Controls the Common Subexpression Elimination optimization. Permitted settings
for this option are:
• On (-Ocse)
• Off (-Onocse) — [default]
For more information, see “Common Subexpression Elimination/Partial
Redundancy Elimination” on page 647.
Tail Recursion
Controls the Tail Recursion optimization. Permitted settings for this option are:
• On (-Otailrecursion)
• Off (-Onotailrecursion) — [default]
For more information, see “Tail Recursion” on page 648.
Constant Propagation
Controls the Constant Propagation optimization. Permitted settings for this option
are:
• On (-Oconstprop)
• Off (-Onoconstprop) — [default]
For more information, see “Constant Propagation” on page 649.

204 MULTI: Building Applications for Embedded ARM


Advanced Options

C/C++ Minimum/Maximum Optimization


Controls the C/C++ Minimum/Maximum optimization. Permitted settings for this
option are:
• On (-Ominmax)
• Off (-Onominmax) — [default]
For more information, see “C/C++ Minimum/Maximum Optimization” on page 650.
Memory Optimization
Controls the K+R C Memory optimization. Permitted settings for this option are:
• On (-OM)
• Off (-Onomemory) — [default]
For more information, see “Memory Optimization” on page 650.
Data Definition Movement
Controls the allocation of certain uninitialized variables to .data to simplify access
and loading. Permitted settings for this option are:
• On (-Oinitializers)
• Off (-Onoinitializers) — [default]
For more information see “Data Definition Movement” on page 646.
Optimize All Appropriate Loops
Turns on all the General Use optimizations, together with loop strength reduction,
loop invariant analysis, and loop unrolling. Permitted settings for this option are:
• On (-OL)
• Off (-Onoloop) — [default]
For more information, see “Loop Optimizations” on page 636.
Peephole Optimization
Controls peephole optimizations. Permitted settings for this option are:
• On (-Opeep)
• Off (-Onopeephole) — [default]
For more information, see “Peephole Optimization” on page 641.
Pipeline Instruction Scheduling
Controls pipeline optimizations. Permitted settings for this option are:
• On (-Opipeline)
• Off (-Onopipeline) — [default]
For more information, see “Pipeline Instruction Scheduling” on page 642.

Green Hills Software, Inc. 205


5. Builder and Driver Options

Conditional Instructions
Controls the use of conditional instructions as an optimization. Permitted settings
for this option are:
• On (-Ocond)
• Off (-Onocond) — [default]
For more information, see “Conditional Instructions” on page 644.
GNU Compatibility Optimizations
Provides compatibility with the general GNU optimization options. Permitted
settings for this option are:
• O1 (-O1) — Turns on all the -O optimizations.
• O2 (-O2) — Turns on all the -O1 optimizations, loop strength reduction, and
loop invariant analysis. For further details, see “Loop Optimizations” on page
636.
• O3 (-O3) — Turns on all the -O2 optimizations and two-pass inlining. For
further details, see “Inlining Optimizations” on page 625.
• O0 (-O0) — [default] No optimizations.

Advanced Debugging Options


This option category is contained within Advanced.

These options provide control over advanced debugging features. For more
common options, see “Debugging Options” on page 147.
Generate Target-Walkable Stack
Creates a frame pointer in register r11. You can use this option to perform
stack traces if you do not have debugging information. The current ARM libraries
are built with this option to support stack traces. Without this option, some
routines do not create a stack frame (in order to reduce code size and improve
performance). Note that this option may produce unexpected complications, such
as disabling good leaf procedure optimization. Using this option without setting
Debugging→Debugging Level to MULTI (-G) may only guarantee a stack trace
and use of the return button in the MULTI Debugger. Permitted settings for this
option are:
• On (-gtws)
• Off (-nogtws) — [default]

206 MULTI: Building Applications for Embedded ARM


Advanced Options

Search Path for .dbo Files


Specifies a directory to search for .dbo debugging information files. The equivalent
driver option is:
• -dbopath directory
This option is only needed if object files are moved between being compiled and
linked.
Use Debug Library List (.dli) Files
Controls the retrieval of debugging information for library files which have been
moved and used in a relocatable object. Permitted settings for this option are:
• On (-use_dli_files)
• Off (-no_use_dli_files) — [default]
Use ViewPath as Source Root
Controls whether all .dbo debugging information file paths are treated as relative
to the root of the viewpath. Permitted settings for this option are:
• On (-use_vp_as_dbg_source_root)
• Off (-no_use_vp_as_dbg_source_root) — [default]
This option is for UNIX hosts only, and is enabled automatically if viewpathing
is in use.
Relative Xof Path
Controls whether full path information is output in situations where the default
debugging information root has been overridden. Permitted settings for this option
are:
• On (--relative_xof_path)
• Off (--no_relative_xof_path) — [default]
Search for DBA
Controls searching for .dba files in incremental link situations. Permitted settings
for this option are:
• On (-search_for_dba)
• Off (-no_search_for_dba) — [default]
Force Frame Pointer
Controls the use of a frame pointer during code generation. Permitted settings
for this option are:
• On (-ga) — Always use a frame pointer. Implied by Debugging→Run-Time
Memory Checks.
• Off (-noga) — [default] Never use a frame pointer.

Green Hills Software, Inc. 207


5. Builder and Driver Options

Reducing Debug File Size


This option category is contained within Advanced→Advanced Debugging
Options.

These options allow you to vary the amount of debugging information that will
be generated for use with the MULTI Debugger. Note that reducing the amount
of information collected may speed up performance, but it may also reduce the
depth of analysis available through the Debugger.
Cross-Reference Information
This option is only available with the New Generation Compiler.
Controls the amount of debugging cross-referencing information that is generated.
By default, the compiler generates cross-reference data for each user-defined
construct (describing where the construct is declared, defined, read from, written
to, and so on), to allow the Debugger to display cross references. Permitted
settings for this option are:
• Generate for All Objects (--xref=full) — [default] Generates cross-referencing
data for all objects.
• Generate for Object Declarations and Definitions (--xref=declare) —
Generates cross-referencing data only for the declarations and definitions of
the objects.
• Generate for Objects in the Global Scope (--xref=global) — Generates
cross-referencing data for the objects that are declared in the global scope.
• Do Not Generate (--xref=none) — Disables all cross-referencing data.
Debugging Information
Controls the generation of debugging information for types and defines that are
never used in a file. Permitted settings for this option are:
• All (-full_debug_info) — Enables the generation of debugging information
for types and defines that are never used in a file.
• Reduced (-no_full_debug_info) — [default] Disables the generation of
debugging information for types and defines that are never used in a file.
Macro Debugging Information
Controls whether debugging information is generated for all macros, or only for
those that are used. Permitted settings for this option are:
• All (-full_macro_debug_info)
• Reduced (-no_full_macro_debug_info) — [default]

208 MULTI: Building Applications for Embedded ARM


Advanced Options

Native Debugging Information


This option category is contained within Advanced→Advanced Debugging
Options.

These options control the generation of alternate native debugging formats. Use
them only if you use third-party tools that require native debugging information.
The MULTI Debugger only uses the .dbo format.
Generate MULTI and Native Information
Enables the generation of DWARF, COFF, or BSD debugging information in the
object file (in addition to the Green Hills .dbo format), according to the convention
for your target. Permitted settings for this option are:
• On (-dual_debug)
• Off (-no_dual_debug) — [default]
Requires that the Debugging→Debugging Level be set to Plain or MULTI for the
option to have any affect (see “Debugging Options” on page 147).
Convert DWARF Files to MULTI (.dbo) Format
Controls the conversion of DWARF debugging information to the MULTI .dbo
format. Permitted settings for this option are:
• On (-dwarf_to_dbo)
• Off (-no_dwarf2dbo) — [default]
This option will normally be invoked automatically when necessary by the builder.
Convert Stabs Files to MULTI (.dbo) Format
Controls the conversion of Stabs debugging information to the MULTI .dbo format.
Permitted settings for this option are:
• On (-stabs_to_dbo)
• Off (-no_stabs2dbo) — [default]
This option will normally be invoked automatically when necessary by the builder.

Green Hills Software, Inc. 209


5. Builder and Driver Options

Advanced Preprocessor Options


This option category is contained within Advanced.

These options control advanced preprocessor settings. For more common


options, see “Preprocessor Options” on page 150.
Duplicate #includes
Controls the treatment of duplicate #include statements. Permitted settings
for this option are:
• Prevent (-include_once) — Includes a file only once, even if it is referenced
in multiple #include statements.
• Allow (-no_include_once) — [default] Includes a file every time it is
referenced.
Some third party header files expect a file to be included multiple times (for
instance Linux C header files). In these environments, you should not set this
option to Prevent (-include_once). The compiler will still automatically skip those
files which have include macro guards, even without this option.
(Windows) This option does not prevent a file from being included twice if the file
is specified using a different pathname. For example, the compiler will treat test.h
as two different files if specified like this on Windows:

#include "test.h"

#include "sub/../test.h"

(Unix) The compiler detects that both #include directives refer to the same file.
Files to Pre-Include
Includes the source code of the specified filename at the beginning of the
compilation. The equivalent driver option is:
• -include filename
This can be used to establish standard macro definitions, and so on. The filename
is searched for in the directories on the include search list.
Definition of Standard Symbols
Controls the definition of the set of default symbols. Permitted settings for this
option are:
• Define (-stddef) — [default]
• Do Not Define (-nostddef)

210 MULTI: Building Applications for Embedded ARM


Advanced Options

Definition of Unsafe Symbols


Controls the predefinition of preprocessor macros without leading underscores.
Permitted settings for this option are:
• Define (--unsafe_predefines) — Predefine macros both with and without
leading underscores.
• Do Not Define (--no_unsafe_predefines) — [default] Predefine macros only
with leading underscores.
When compiling C++ code in Strict Standard Mode, this option has no effect.
Retain Comments During Preprocessing
Controls the retention of preprocessor comments. Permitted settings for this
option are:
• Retain (-C)
• Strip (--no_comments) — [default]

Advanced Include Directories


This option category is contained within Advanced→Advanced Preprocessor
Options.

By default, the Builder and driver search for header files in various standard
directories provided with your distribution. These options allow you to vary the
location of these standard directories.
Standard Include Directories
Controls whether the standard include directories are searched. Permitted settings
for this option are:
• Search (-stdinc) — [default]
• Do Not Search (-nostdinc)
C Include Directories
Changes the default location in which the compiler searches for C header files.
The equivalent driver option is:
• -c_include_directory directory
C++ Include Directories
Specifies a directory in which the builder should search for C++ header files.
The equivalent driver option is:
• --cxx_include_directory directory

Green Hills Software, Inc. 211


5. Builder and Driver Options

C++ Standard Include Directories


Changes the default location in which the compiler searches for C++ header files.
The equivalent driver option is:
• -std_cxx_include_directory directory
System Include Directories
Changes the default location in which the compiler searches for system header
files. The equivalent driver option is:
• -sys_include_directory directory

Advanced C/C++ Compiler Options


This option category is contained within Advanced.

These options control advanced C and C++ compilation settings. For more
common options, see “C/C++ Compiler Options” on page 151.
ANSI C and Standard C++ Extensions
This option is only available with the New Generation Compiler.
Controls the treatment of the “ANSI C Extensions” on page 407 and the “Standard
C++ Extensions” on page 465. Permitted settings for this option are:
• Errors (--discretionary_errors) — [default for Strict ANSI C (-ANSI) and
Standard C++ (Violations Give Errors) (--STD)]
• Warnings (--discretionary_warnings) — [default for Standard C++
(Violations Give Warnings) (--std)]
This option only affects projects where the C/C++ Compiler→C Language
Dialect option is set to Strict ANSI C (-ANSI) or the C/C++ Compiler→C++
Language Dialect option is set to Standard C++ (Violations Give Errors)
(--STD) or Standard C++ (Violations Give Warnings) (--std).

212 MULTI: Building Applications for Embedded ARM


Advanced Options

C++ Inlining Level


Controls the inlining of C++ functions. Permitted settings for this option are:
• Maximum (--max_inlining) — Considers all appropriate functions for inlining.
• Maximum Unless Debugging (--max_inlining_unless_debug) — Performs
maximum inlining unless debugging information is being collected.
• Standard (--inlining) — [default] Considers only relatively small functions
without control flow statements for inlining.
• Standard Unless Debugging (--inlining_unless_debug) — Performs
standard inlining unless debugging information is being collected.
• None (--no_inlining) — Disables inlining of C++ functions.
For more information, see “Additional C++ Inlining Information” on page 634.
longjmp() does not restore local vars
Controls whether the values of local non-volatile variables are modified by
longjmp calls. ANSI C standards require only that the values of volatile variables
are not modified. Protecting non-volatile values requires additional overhead.
Permitted settings for this option are:
• On (-locals_unchanged_by_longjmp) — Guarantees that the values of all
local variables are not modified by longjmp calls.
• Off (-no_locals_unchanged_by_longjmp) — [default] Guarantees only that
the values of volatile local variables are not modified by longjmp calls.
Ignore #include Directives
This option is only available when using the Compatibility Mode Compiler.
Controls the treatment of #include directives. Permitted settings for this option
are:
• On (--include_never) — Ignore all #include directives.
• Off (--no_include_never) — [default] Process all #include directives.

Green Hills Software, Inc. 213


5. Builder and Driver Options

Advanced C++ Options


This option category is contained within Advanced→Advanced C/C++
Compiler Options.

These options control advanced C++ compilation settings.


For-Loop Initialization Scope
Controls the scope of a declaration in a for-init statement. Permitted settings
for this option are:
• New (--new_for_init) — [default] The new ANSI standard conforming rules, in
effect, wrap the entire for statement in its own implicitly generated scope.
• Old (--old_for_init) — The old pre-ANSI compatible rule specifies that the
declaration is in the scope to which the for statement itself belongs.
Treat .bss as Commons
Controls the treatment of data objects in section .bss. Permitted settings for
this option are:
• On (--common_implicit_initialization) — Define all data objects in section
.bss as common variables.
• Off (--no_common_implicit_initialization) — [default] Define all data objects
in section .bss as global variables.
Demangling of Names in Linker Messages
Controls the demangling of names that appear in linker messages. These are
typically symbol names that are either undefined or multiply defined. Permitted
settings for this option are:
• On (--link_filter) — [default]
• Off (--no_link_filter)
C++ Linking Method
Controls the method for generating constructors/destructors at link-time. Permitted
settings for this option are:
• Use Green Hills Linker (--linker_link) — [default]
• Create Array of Static Constructors/Destructors for Post-Link Phase
(--munch)
• Do not Generate Constructors/Destructors (--nocpp)

214 MULTI: Building Applications for Embedded ARM


Advanced Options

Overloading of enums
Controls support for using operator functions to overload built-in operations on
enum-typed operands. Permitted settings for this option are:
• On (--enum_overloading) — [default]
• Off (--no_enum_overloading)
Support for Friend Injection
Controls whether the name of a class or function that is declared only in friend
declarations is visible when using normal lookup mechanisms. Permitted settings
for this option are:
• On (--friend_injection) — Friend names are visible to such lookups.
• Off (--no_friend_injection) — [default] Function names are visible only when
using argument-dependent lookups, and class names are never visible.
Temporaries’ Lifetime
Specifies the lifetime for temporaries. Permitted settings for this option are:
• Long (--long_lifetime_temps) — Refer to the earliest of end of scope, end of
switch clause, or next label.
• Short (--short_lifetime_temps) — [default] Refer to the end of full
expressions. This is standard C++.
Tiebreaker Processing Time
Specifies the way that tiebreakers apply in overload resolution. Tiebreakers are
decided through the differences of the type qualifiers (const and volatile).
Permitted settings for this option are:
• Early (--early_tiebreaker) — [default] Consider tiebreakers at the same time
as other measures of the quality of the match of an argument value and the
corresponding parameter type.
• Late (--late_tiebreaker) — Ignore tiebreakers during the initial comparison
and consider them only if two functions are otherwise equally good on all
arguments. The tiebreakers can then be used to choose one function over
another.
Distinct C and C++ Functions
Controls whether identical C and C++ functions are treated as distinct. Permitted
settings for this option are:
• On (--c_and_cpp_functions_are_distinct) — Treat function types as distinct
if their only difference is that one has extern "C" linkage and the other
has extern "C++" routine linkage.
• Off (--no_c_and_cpp_functions_are_distinct) — [default] Do not treat such
functions as distinct.

Green Hills Software, Inc. 215


5. Builder and Driver Options

Advanced Assembler Options


This option category is contained within Advanced.

These options control advanced assembler settings. For more common options,
see “C/C++ Compiler Options” on page 151.
Assembler Warnings
Controls the display of assembler warning messages. Permitted settings for this
option are:
• Display (--assembler_warnings) — [default]
• Suppress (--no_assembler_warnings)
Identifier Definition
Passes the arbitrary string string to the output file. The equivalent driver option is:
• -ident=string
This is the same as using the directive #pragma ident “string” in C (see
“General #pragma Directives” on page 527). This option can be used to place the
date of the source file in the object file.
Identifier Support
Controls support for identifier definition and insertion (via the Builder and driver
options above, and through #pragma ident "string"). Permitted settings
for this option are:
• On (-identoutput) — [default]
• Off (-noidentoutput)

Advanced Linker Options


This option category is contained within Advanced.

These options control advanced linker settings. For more common options, see
“Linker Options” on page 183.

216 MULTI: Building Applications for Embedded ARM


Advanced Options

Link in Standard Libraries


Controls the linking-in of any standard startup files or libraries. User-specified
libraries are not affected. Permitted settings for this option are:
• Link (-stdlib) — [default] Use standard libraries.
• Do Not Link (-nostdlib) — The linker may return an undefined symbol error
due to references to architecture support routines, even if your code has no
apparent external library dependencies.
Disabling this option also instructs the compiler to not link against the Green Hills
or any user-defined start or end files (see “Start and End Files” on page 187).
Link Mode
Controls overwriting of an existing executable. Permitted settings for this option
are:
• Link into the existing executable (--link_output_mode_reuse) — [default]
• Link to a temp file, then overwrite existing exec (unless it’s a link)
(--link_output_mode_safe)
• Unlink existing exec before linking (unless it’s a link)
(--link_output_mode_unlink)
• Link to a temp file, then overwrite existing exec
(--link_output_mode_linksafe)
Prepend String to Every Section Name
Specifies a string to prepend to every section name. The equivalent driver option
is:
• --section_prefix string
Append String to Every Section Name
Specifies a string to append to every section name. The equivalent driver option is:
• --section_suffix string

Without Directives File


This option category is contained within Advanced→Advanced Linker
Options.

These options allow you to perform old-style linking, without a linker directives
file.

Green Hills Software, Inc. 217


5. Builder and Driver Options

Link Map Method


Controls whether a linker directives file will be used for linking. Permitted settings
for this option are:
• Use Linker Directives File (-default_lnk) — [default]
• Specify Sections Manually (with -Tsection) (-no_default_lnk) — Requires
that you set addresses for the start of the .data and .text sections using
the options below.
Start of .data Section
Manually specifies an address for the start of the .data section when a linker
directives file is not being used. The equivalent driver option is:
• -Tdata address
Start of .text Section
Manually specifies an address for the start of the .text section when a linker
directives file is not being used. The equivalent driver option is:
• -Ttext address

218 MULTI: Building Applications for Embedded ARM


Advanced Options

Advanced Support Diagnostics Options


This option category is contained within Advanced.

You should use these options only if instructed to do so by Green Hills support
staff.
X-Switches
Specifies one or more internal compiler switches. The equivalent driver option is:
• -Xswitch
EDG Front End Options
Specifies one or more internal EDG front end options. The equivalent driver
option is:
• --option=option
Change Assembler
Specifies the assembler to use. Permitted settings for this option are:
• Use Old Assembler (-old_assembler)
• Use New Assembler (-new_assembler) — [default]
Debug Information (.dbo) Tracing Diagnostics
Controls the collection of diagnostic information pertaining to a search for .dbo
files. Permitted settings for this option are:
• On (-dbo_trace)
This option is useful if you are seeking support for an incident involving missing
.dbo files.
Dbo File Version
Specifies an older version of .dbo debugging information files, for use with an old
MULTI Debugger. Permitted settings for this option are:
• On (--dbo_version n)

Green Hills Software, Inc. 219


5. Builder and Driver Options

Driver Option Synonyms


The following table lists synonyms that are permitted in place of the preferred
driver options.
Primary Option Synonyms
-os_dir -rtos_dir
-threadx_dir
-ose_dir
-linux_dir
-vxworks_dir
-groot
-threadx_demo_dir -os_demo_dir
-o --output
-I --include_directory
--fast -fast
--small -small
-D --define_macro
-U --undefine_macro
-asm -Wa,
-e -entry
-lnk -WS,
-startfiles -startfile
-startfile_dir -YS,
-errmax -errormax
--error_limit
-YL, -YU,
-dbopath -dbgpath
-include --include
--preinclude
-c_include_directory --c_include_directory
-YI,
--cxx_include_directory -cxx_include_directory

220 MULTI: Building Applications for Embedded ARM


Driver Option Synonyms

Primary Option Synonyms


-std_cxx_include_directory --std_cxx_include_directory
-sys_include_directory --sys_include_directory

Green Hills Software, Inc. 221


5. Builder and Driver Options

222 MULTI: Building Applications for Embedded ARM


Chapter 6

The Builder GUI Reference

This Chapter Contains:


• The File Menu
• The Edit Menu
• The Build Menu
• The Connect Menu
• The Debug Menu
• The Tools Menu
• The Windows Menu
• The Help Menu
6. The Builder GUI Reference

This chapter provides a comprehensive description of the commands and


options in the main Builder window menu bar.

The File Menu


The following table lists the selections available from the Builder File menu:
New Project

Opens the New Project Wizard, which guides you through the process of creating
a new project. For more information, see “Creating a New Project: The New
Project Wizard” on page 24.
Open Project (Ctrl + O)

Opens a project.
Close Project
Closes the current project.
Save Project (Ctrl + S)

Saves the current project.


Revert to Saved Project
Reloads the current project from disk, discarding any changes made since the
last save.
Print Current View (Ctrl + P)
Prints the currently displayed project hierarchy. The hierarchy will be printed in the
exact state that it is displayed in the source pane. If you want to print the contents
of subprojects, you need to expand them first so that they are displayed.
Print Expanded Project
Prints the fully expanded project hierarchy. All projects will be expanded first, then
the entire project hierarchy will be printed.
Write Expanded Project to File
Writes a formatted view of the fully expanded project hierarchy to a text file.
Recent Files
This submenu contains recently opened files. Select one to open it in the Editor.
Recent Projects
This submenu contains recently opened projects. Select one to open it in the
Builder.

224 MULTI: Building Applications for Embedded ARM


The Edit Menu

New Window
Opens a new Builder window with no open project.
Exit (Ctrl + Q)
Closes the current Builder window, prompting to save any outstanding changes.

The Edit Menu


The following table lists the selections available from the Builder Edit menu:
Edit
Opens the selected file in an Editor window.
Graphically Edit
This item is only available for some file types.
Opens a customized graphical editor for the file, such as the Connection
Organizer (see Chapter 3, “Connecting to Your Target” in the MULTI: Debugging
book) or Linker Directives File Editor (see “Working with Linker Directives Files”
on page 43).
Set Options
Opens the Options window for the selected file. For more information, see
“Setting Builder Options” on page 50.
Set Type
Opens the Set Type dialog box, to change the type of the selected file. For more
information, see “Builder File Types” on page 32.
Create Subproject
Creates a project file as the next entry after the current selection.
Create File
Creates a new source file as the next entry after the current selection and opens it
in the Editor.
Add File After selected file
Opens a file chooser for you to add files to the current project. The files are added
immediately after the selected file, on the current level of the hierarchy.
To make the project file portable, MULTI uses relative or base names for the added
files whenever possible by resolving them relative to the set source directories.

Green Hills Software, Inc. 225


6. The Builder GUI Reference

Add File Into selected file


This item is only available when you select a .gpj file.
Opens a file chooser for you to add files to the current project. The files are added
at the beginning of the selected project file.
Remove selected file
Removes the currently selected files from the project. The file itself is not deleted.
Search in selected file
Opens the Search window to perform a full-text search of your source files. For
more information, see “Searching in Files” on page 40.
Show Full Paths
Toggles the display of full path information for files in the Builder window. This
setting is saved across sessions.
Highlight Selections
Toggles the highlighting of all the files that are included within the currently-selected
project file. This setting is saved across sessions.
Set Build Target
Opens the Target Selector dialog box, which allows you to change the Board and
Operating System that your project will be built for. For more information, see “The
Target Selector Dialog Box” on page 228.
Set Build Macros
Opens the Set Build Macros dialog box, which allows you to define macros to
stand in for commonly used strings in option settings. For more information, see
“Setting Build Option Macros” on page 58.

226 MULTI: Building Applications for Embedded ARM


The Edit Menu

Advanced
Displays the Advanced submenu which offers options to:
• Contract All Within selected file — Recursively contracts the selected file
to hide all its children.
• Expand All Within selected file — Recursively expands the selected file to
show all its children.
• Set Imported Environment Variables — Opens a dialog box that allows
you to import variables from your environment to stand in for strings used in
your option settings.
• Set Options in Parent — Opens the Options window to set Builder options
on the immediate parent of the selected file. For source files, this is the normal
behavior provided by Set Options, but for projects this allows options to be
set for a particular occurrence of the project.
• Simplify All Filenames — Attempts to convert any absolute filenames into
filenames relative to the set source directories. Specifically, if the path of
a file is removed and if the file can still be found by searching the source
directories list, then the full pathname is replaced by the filename without a
path. This is a simple means of converting absolute pathnames in projects
to short relative pathnames, which increases portability. This resolving is
done automatically when files are added, so this functionality is usually only
useful after changing source directories.

Green Hills Software, Inc. 227


6. The Builder GUI Reference

The Target Selector Dialog Box


When you create a project (see “Creating a New Project: The New Project
Wizard” on page 24) you must specify a target to build for.

To subsequently change your Build Target, select Edit → Set Build target
to open the Target Selector window.

To select a new target:

• Choose a processor family and operating system combination from the


Target list.
• Choose a board from the Board Name list. Some boards are not
supported for all operating systems. If your board is not listed, expand the
Generic-ARM item, and select your processor from the list.

Note Advanced users can add customizing target files, which may define
custom file types or control custom tools. To add such a file, click the
Customizations button, and select a custom .bod file with the file chooser.
An example of how to use this functionality is provided in the C: Custom
File Types example.

228 MULTI: Building Applications for Embedded ARM


The Build Menu

The Build Menu


The following table lists the selections available from the Builder Build menu:
Build selected file (F7)

Invokes the compiler, assembler, and linker as appropriate, to build the currently
selected files and projects.
Preprocess selected file
Preprocesses the selected file.
This item is available for both source files and Program and Library projects.
Rebuild selected file
Builds the currently selected files after first removing the intermediate output files.
Build Ignoring Errors selected file
Builds the current project, ignoring any detected errors. Normally, the build stops
when an error occurs to prevent downstream failures like a link failing because of
missing objects.
Clean selected file
Deletes all of the files that are normally created when building the project. This
includes object files, libraries, and executables. In other words, at each step where
a file would be created in a normal build, the file is deleted instead. The only files
that remain will be the source files necessary for building the project from scratch.
Advanced Build
Opens the Advanced Build dialog box, through which you can execute builds
with less common options. For more information, see “The Advanced Build
Dialog Box” on page 230.
Settings
Opens the Build Settings dialog box, through which you can set common build
options that will be applied to all normal builds. These settings will be saved when
you close the Builder. For more information, see “The Build Settings Dialog
Box” on page 231.
View Build Details
Opens a window displaying Builder feedback from the latest build.

Green Hills Software, Inc. 229


6. The Builder GUI Reference

The Advanced Build Dialog Box


To open the Advanced Build window, select Build → Advanced Build:

Note These options apply only to the current build.

Clean all output before building


Deletes all previous output files, and then builds.
Only remove intermediate output
Deletes intermediate output files, and then builds.
Stop after cleaning output
Deletes all previous output files, without building.
Force link
Forces linking. The default behavior is to re-link the executable only if any of
its components have changed.
Ignore build errors
Continues building, even if errors are encountered.

230 MULTI: Building Applications for Embedded ARM


The Build Menu

Show tool commands


Displays commands as they are executed.
Show internal commands
Displays full commands (including internal commands), before as are executed.
Show build without execution
Simulates the build without executing the commands.
Ignore dependencies
Simulates the build, ignoring dependency information (rebuilding all files even if
they are up-to-date), without executing the commands.
Number of parallel processes
Specifies the number of processes that may be run in parallel. The default value
is 1, or no parallelism.
Execute tools at low priority
Executes the build with lower than normal priority — scheduling priority 10 (UNIX),
or the idle priority class (Windows).
Use lock files
Prevents multiple simultaneous builds of the same program or library by creating
temporary .lck lock files.

The Build Settings Dialog Box


To open the Build Settings window, select Build → Settings:

Number of parallel processes


Specifies the number of processes that may be run in parallel. The default value
is 1, or no parallelism.

Green Hills Software, Inc. 231


6. The Builder GUI Reference

Use lock files


Prevents multiple simultaneous builds of the same program or library by creating
temporary .lck lock files.
Execute tools at low priority
Executes the build with lower than normal priority — scheduling priority 10 (UNIX),
or the idle priority class (Windows).
Show tool commands
Displays commands as they are executed.

The Connect Menu


The following table lists the selections available from the Builder Connect
menu:
Connect (F4)
Opens the Connection Chooser dialog box, which allows you to connect to a
target or simulator. Only available if there are no connected targets.
Disconnect Target
Disconnects all target connections. Only available if there is a connected target.
Connection Organizer
Opens the Connection Organizer, which configures how you connect to target
hardware or simulators. For more information, see Chapter 3, “Connecting to Your
Target” in the MULTI: Debugging book.
Task Window
Opens the Task window, which displays the tasks running on the target. Only
available for multitasking debug servers.
Load Module
This submenu is only available for multitasking debug servers. It allows you to
download a new object module to the target. Choose Load Module again from
the submenu to choose the module to download from a dialog box, or choose one
of the recently downloaded modules from the list provided.

232 MULTI: Building Applications for Embedded ARM


The Debug Menu

1 connection
2 connection
3 connection
4 connection
Lists the most recently connected debug servers. To connect to one of them,
select it.

The Debug Menu


The following table lists the selections available from the Builder Debug menu:
Debug selected program (F5)

Opens the Debugger on the currently selected project.


Debug Other Executable
Opens a file chooser to select the executable you want to debug.
1 pathname
2 pathname
3 pathname
4 pathname
Lists the most recent programs opened in the Debugger. To open a new Debugger
window on one of them, select it.

Green Hills Software, Inc. 233


6. The Builder GUI Reference

The Tools Menu


The following table lists the selections available from the Builder Tools menu:
Version Control
Opens the submenu which offers the following options:
• Check Out: Retrieves a writable copy of the latest version and locks the file so
that other users cannot change the file while you work on it. (This selection is
not meaningful if you are using CVS.)
• Check In: Saves the changes made to the file, makes the file read-only, and
removes the lock from the file. You will be asked for comments to be saved in
the log file along with your changes.
• Check In + Out: Saves the changes made to the file, but keeps the file
checked out (locked). (This selection is not meaningful if you are using CVS.)
• Retrieve: Retrieves a read-only copy of the current version of the file, even if
the file is locked.
• Discard Changes: Discards changes made to the file, removes the lock from
the file, and reverts to the latest version. Use this to undo a checkout without
making any changes.
• Place Under VC: Puts the current file under version control. Once a file is
placed under version control, the file must be checked out before changes
can be made to it.
• Show History: Opens the History Browser to display information about all
versions of the selected file.
• Checkout Browser: Opens the Checkout Browser.
• Other VC Command: Opens a dialog box in which you can enter additional
version control commands. For a complete list of the version control
commands, see Chapter 6, “Using Version Control with MULTI” in the MULTI:
Editing Files and Configuring the IDE book.
Configuration
Opens a submenu offering the following options:
• Save Configuration as Default: Saves the current configuration into the
default user configuration file for MULTI, so that it will be used for future
sessions.
• Clear Default Configuration: Deletes the default user configuration file for
MULTI.
• Save Configuration: Opens a file chooser dialog box for you to choose a file
and then saves the current configuration into it.
• Load Configuration: Opens a file chooser dialog box for you to choose a file
to load a saved configuration.

234 MULTI: Building Applications for Embedded ARM


The Tools Menu

Editor
Opens a file chooser to select a file to open in the Editor.
Start Launcher
Opens the Launcher. For more information, see “The MULTI Launcher” on page 4.
Flash selected program
Opens the Write to Flash Memory dialog box, which allows you to write the
selected program to flash chips on the target. The Flash menu item is not
available if MULTI is connected to multiple targets.
CodeBalance selected program
Opens the selected program in the CodeBalance utility, which analyzes profiling
information to optimize an executable. For more information, see Chapter 12,
“The CodeBalance Optimization Wizard”.
Use Utilities
Opens the Utility Program Launcher dialog box. For more information, see “The
Utility Program Launcher Dialog Box” on page 236.
Convert Legacy Project
Opens a file chooser to select a legacy project (*.bld) to be converted to a new
format project (*.gpj).
Options
Opens the Options dialog box for you to change options that affect the way
the Builder and other MULTI tools look and behave. For more information, see
Chapter 9, “Configuration Options” in the MULTI: Editing Files and Configuring
the IDE book.

Green Hills Software, Inc. 235


6. The Builder GUI Reference

The Utility Program Launcher Dialog Box


To open the Utility Program Launcher, select Tools → Use Utilities.

To use a utility:

1. Select the utility from the list on the left.


2. Click to navigate to the Working Directory where you will run the
command.
3. Enter any Arguments you want to pass. As a minimum, you must
generally pass the name of the file to be processed. To display information
about the syntax of arguments, click Show Help.
4. Click Run to run the utility.

For documentation of all the utilities, see Chapter 11, “Utility Programs”.

The Windows Menu


The Windows menu provides a submenu for each kind of window open in
MULTI, allowing you easy access to any of them.

236 MULTI: Building Applications for Embedded ARM


The Help Menu

The Help Menu


The following table lists the selections available from the Builder Help menu:
MULTI Project Builder Help (F1)
Opens online help for the Builder.
Manuals
Opens the Manuals submenu, which displays a list of manuals appropriate to
your version of MULTI.
About MULTI Project Builder
Opens the About dialog box, which provides copyright and version information.
Troubleshooting Info
Launches the gbugrpt utility program, which collects information about your
MULTI installation and allows you to append it to a bug report form that you can fill
out and email to Green Hills technical support.

Green Hills Software, Inc. 237


6. The Builder GUI Reference

238 MULTI: Building Applications for Embedded ARM


Part II

Using Advanced Tools


Chapter 7

The asarm Assembler

This Chapter Contains:


• Running the Assembler from the Builder or Driver
• Running the Assembler Directly
• Assembler Options
• Assembler Syntax
• Expressions
• Labels
• Reading the Compiler’s Assembly Output
• Porting Guide for ARM Limited Assembly
7. The asarm Assembler

The assembler translates ASCII files containing assembly language instructions


into binary files containing relocatable object code. Its features include:

• ELF object modules


• Very long identifiers (up to 4096 characters)
• Relocatable object modules
• Optional source and generated code listings
• Macro, repeat block, and conditional assembly directives
• Free form assembly input format
• Full IEEE format floating-point support
• Full symbolic debugger support
• High-speed assembly

Running the Assembler from the Builder or Driver


We recommend that you invoke the assembler via the Builder or driver. Simply
add assembly files to the Builder’s source pane, or to the driver’s command
line. If your assembly file ends with .arm rather than .s, the Builder or driver
first invokes the preprocessor to take advantage of preprocessor facilities (such
as #include and #define) that are not normally available to an assembly
language programmer. To run the preprocessor on all assembly files (including
those with a .s extension:

Set the Assembler→Preprocess Assembly Files option to On


(-preprocess_assembly_files).

The Builder and driver accept a limited number of assembler-specific options


directly (see “Assembler Options” on page 180). To pass the full range of
assembler options listed in this chapter:

242 MULTI: Building Applications for Embedded ARM


Running the Assembler Directly

Enter the required assembler option (see “Assembler Options” on


page 244) in the Assembler→Additional Assembler Options option
(-asm=assembler_option).
When using the driver, you can either precede each assembler option
with a -asm=, or list multiple options, separated by whitespace and
enclosed within quotes. Hence the two following command lines are
equivalent:

ccarm -asm=-stack_debug -asm=-v stack.s -c -o stack.o


ccarm -asm="-stack_debug -v" stack.s -c -o stack.o

Alternatively, if you have a large number of options to pass to the


assembler, you can place them in a text file and enter its filename in
the Assembler→Assembler Command File option (-asmcmd=file).

Generating Assembly Language Files


At times, you might want to generate and review assembly language output
from a high-level language file. To do this:
From the driver, pass the -S option. For example, the following
command line would compile main.c and place the assembly language
output in the file main.s:

ccarm -S main.c

Running the Assembler Directly


The syntax for running the assembler directly is:

asarm [options] [input_files]

where options are assembler options. When running the assembler directly,
do not use the-asm= option.

Green Hills Software, Inc. 243


7. The asarm Assembler

Assembler Options
The assembler combines each specified ASCII input_file and produces a single
output object module. For information about using these options with the
Builder or driver, see “Running the Assembler from the Builder or Driver”
on page 242.

General Assembler Options


@file
Passes commands listed in file to the assembler.
-cpu=cpu
Specifies the target cpu.
-fpu=[none|soft|hard]
Specifies whether the target uses software floating-point or hardware floating-point.
-help
Prints a help message.
-I dir (an uppercase letter “i”)
Searches directory dir for files specified in .include directives.
-list[=file]
Generates a source listing. If =file is not specified, then the listing file is written
to a file with the same name as the original file, but with an .lst extension. If =file
is specified, then the listing is written to file.
-o file
Sets the name of the output object file to file. Without the -o option, the assembler
produces an object file that has the name of the assembly language file with an .o
extension. For example, foo.o is produced for foo.s.
-source=name
Overrides the source file’s name.
-stack_debug
Restricts the assembler to generating debugging information that contains only
the stack and symbols.
-v
Prints detailed information about the assembler during the assembly process.
-w
Disables assembler warnings.

244 MULTI: Building Applications for Embedded ARM


Assembler Syntax

Assembler Syntax

Character Set
The assembler recognizes the standard ASCII character set, consisting of
uppercase and lowercase letters (A-Z, a-z), digits (0-9), and a group of special
characters listed in the following table. The assembler also recognizes the
ASCII control characters signifying carriage return, newline, form feed, vertical
tab, and horizontal tab.
Character Name Character Name
’ single quotation mark " double quotation mark
( left parenthesis ) right parenthesis
blank (space) % percent
- minus sign + plus sign
: colon ! exclamation mark
, comma \ backslash
. decimal point (period) * asterisk
& ampersand _ underscore
~ tilde | vertical bar
= equal sign ^ carat
< less than > greater than
/ slash $ dollar sign
@ at sign # number sign

Identifiers
Identifiers, or symbols, are composed of letters, digits, and the following special
characters: dollar sign ($), period (.), and underscore (_). The first character
of an identifier must be alphabetic, or one of these three special characters.
Uppercase and lowercase letters are distinct; the identifier abc is not the same
as the identifier ABC. Characters in reserved symbols, such as directives,
machine instructions, and registers, are case-sensitive.

Identifiers can be up to 4096 characters in length, with all characters significant.

Green Hills Software, Inc. 245


7. The asarm Assembler

Examples
The following table shows some valid and invalid identifiers:
Identifier Validity
*star Invalid (may not start with *)
123test Invalid (may not start with digit)
f-ptr Invalid (may not use hyphen)
_hello Valid
LABEL Valid
test4 Valid

Reserved Symbols
The following identifiers are built into ARM assembly language.
Identifier Meaning
a1-a4 Aliases for integer registers r0-r3
f0-f7 Floating-point registers
fp Frame pointer (r11)
lr Link register (r14)
pc Program counter (r15)
r0-r15 Integer registers
sb Alias for integer register r9
sl Alias for integer register r10
sp Stack pointer (r13)
v1-v7 Aliases for integer registers r4-r10

In addition, the names of the special purpose registers (SPR’s) such as XER, LR,
and CTR are reserved. Consult the appropriate microprocessor user’s manual
for the list of implemented SPR’s.

246 MULTI: Building Applications for Embedded ARM


Assembler Syntax

Note In addition, the operator names are reserved. For a list of operators, see
“Scalar Expression Operators” on page 251.

Constants
Assembler constants can be numeric, character, or string constants.

Numeric Constants
A sequence of digits defines a numeric constant. Constants can be specified
in hexadecimal, octal, or binary formats, or as floating-point numbers, by
preceding the number with one of the following special prefixes:
Type Prefix Example
hexadecimal 0x 0xb0b
octal 0 0747
binary 0b 0b110011
floating-point 0f 0f6.02e+23

To specify a negative floating-point number, the minus sign must be placed


in front of the number, but after the 0f prefix. For example, to specify the
negative of the floating-point number listed in the table, use 0f-6.02e+23,
not -0f6.02e+23.

All integer constants are signed 32-bit two’s complement values.

A pound sign, "#", is required in front of constants used as immediate operands


in instructions. (for example, movi #5, %d9).

String Constants
Some directives take a string constant as one or more of their arguments. A
string constant consists of a sequence of characters enclosed in double quotation
marks ("). A string constant can contain any ASCII character (including ASCII
null), except newline. The null character is not appended to strings by the
assembler, as it is in C or C++.

Green Hills Software, Inc. 247


7. The asarm Assembler

Character Constants
A character constant can be used in any location where an integer constant is
needed.

A character constant consists of the following items in this order, enclosed


within single quotation marks (’ ’):

• either a single ASCII character, or


• a backslash character (\) and one of the escape character values
A character constant is considered equivalent to the ASCII value of the
character or escape sequence.

For example, the character constant ’a’ is equivalent to the decimal integer 97,
and the character constant ’\r’ is equivalent to the decimal integer 13.

Character Escape Sequences


Character and string constants consist of ASCII characters. The ASCII
backslash (\) is used within character and string constants to escape the
quotation marks and to specify certain control characters symbolically. A
backslash followed by any non-escape character is equivalent to that character
(for example, \a is equivalent to a because \a is not an escape sequence).
Escape
Sequence Character ASCII value
\0 null 0 (0x0)
\b backspace 8 (0x8)
\t horizontal tab 9 (0x9)
\n newline 10 (0xA)
\v vertical tab 11 (0xB)
\f form feed 12 (0xC)
\r return 13 (0xD)
\nnn octal value nnn n/a
\xnn hexadecimal value nn n/a
\’ single quotation mark 39 (0x27)

248 MULTI: Building Applications for Embedded ARM


Assembler Syntax

Escape
Sequence Character ASCII value
\" double quotation mark 34 (0x22)
\\ backslash in a constant or string 92 (0x5C)

Source Statements
An assembler source statement consists of a series of fields delimited by spaces
and/or horizontal tabs, in the following format:
[label:] operator arguments [comments]

Label Field
See “Labels” on page 253.

Operator Field
The operator field starts with the first non-whitespace character after the
optional label field and is terminated by the first whitespace character or line
terminator encountered after the operator. An operator is any symbolic opcode,
directive, or macro call.

Argument Field
The argument field starts with the first non-whitespace character following the
operator field and ends with a line terminator or the beginning of a comment
field. Arguments qualify the opcode, directive, or macro call.

Comment Field
The comment field is optional and begins with “;”, “@”, or the number symbol
("#"). The # symbol must be in the first column of a line or be followed
by a space to be considered a comment character. The assembler ignores all
characters to the right of the comment symbol until the end of the line.

Green Hills Software, Inc. 249


7. The asarm Assembler

Continuation Lines
The assembler does not support continuation lines.

Whitespace
Whitespace consists of spaces, form feeds, and horizontal tabs.

Line Terminators
Assembly input lines are terminated by a line feed, a form feed, or a carriage
return.

Expressions

Assignment Statements
An expression is assigned to a symbol by an assignment statement in one of the
following forms, where ident is the symbol name:

ident = const-expr

.set ident,const-expr

The expression specifies any addressing mode that is generated when the
symbol becomes an instruction operand. An assignment in the form of = defines
a local constant, while =: specifies that the symbol is also global.

For example:
a = 1 ; set a to be 1
xyz = 123 ; set xyz to be 123
.set sofa, 7 ; set sofa to be 7 (legal)
.set sofa, 8 ; reset sofa to be 8 (legal)

An expression is either absolute or relocatable. See “Expression Types” on page


252 for more information about absolute or relocatable expressions.

250 MULTI: Building Applications for Embedded ARM


Expressions

Scalar Expression Operators


A number of operators are available to form expressions. The type unary
indicates that the function is recognized when the operator has only a right
operand. The type binary indicates that the operator has two operands, one to
the left of the operator and one to the right.
Operator Type Meaning
~ unary Bitwise-not operator.
- unary Negative.
+ binary Add.
- binary Subtract.
* binary Multiply.
/ binary Divide.
% binary Modulo.
& binary Bitwise-and operator.
| binary Bitwise-or operator.
^ binary Bitwise-exclusive-or operator.
=,== binary Equality (0 or 1).
!= binary Inequality (0 or 1).
>,>=,<,<= binary Signed compare (0 or 1): greater than, greater than
or equal to, less than, less than or equal to.
UGT, UGE, ULT, binary Unsigned compare (0 or 1): greater than, greater
ULE than or equal to, less than, less than or equal to.
<<,>> binary Signed shift left, signed shift right.
USHR binary Unsigned shift right (shift 0 into high bit).
ROTR, ROTL binary Rotate right, rotate left.

Operator Precedence
The following table lists the operators in decreasing order of precedence. The
binary operators are associative from left to right:
~ and - (unary)
*, /, %
<<, >>, USHR, ROTR, and ROTL

Green Hills Software, Inc. 251


7. The asarm Assembler

+ and - (binary)
=, .equ, <, >, <=, >=, ULT, UGT, ULE, and UGE
== and !=
&
^
|

Expressions are grouped with matching parentheses ().

Expression Types
The primary expression types are:
Expression type Meaning
absolute A value of an identifier or expression that is computed by the
assembler during assembly. Essentially, any absolute value
is a manifest value with the exception of an absolute
value derived from the difference between two relocatable
values in the same section.
manifest A value of an identifier or expression that is computed by the
assembler when encountered.
quoted string A C-style character string delimited by double quotation
marks is used in conjunction with a number of assembler
directives. All string escape sequences defined in the C
language, such as \n for newline, are allowed. These
sequences are described in “Character Escape Sequences”
on page 248.
relocatable A relocatable expression or identifier assigns a value relative
to the beginning of a particular section. These values are
not determined at assembly time. All label identifiers are
relocatable values.
undefined If an identifier is unassigned, its value cannot be determined
until link time. This is an undefined external.

Type Combinations
The constant types are combined with all operators, except when a relocatable
type was made immediate or absolute. You can combine a constant with a

252 MULTI: Building Applications for Embedded ARM


Labels

relocatable type to form an expressions that is evaluated by the linker. The


following operators are supported:
Operator Type Meaning
+ binary addition (if one operand to the plus operator is a
constant, the result is the type of the other operand)
- binary subtraction (if the second operand is constant, the
result is the type of the first operand. If both operands
are in the same section, then the result is a constant
that is the difference of the addresses)

Examples
4 ; constant
4*(5+6) ; constant
label ; relocatable

Labels
A statement can begin with one or more named labels, which are identifiers
followed by one or two colon characters. Labels defined with one colon are not
referenced outside the source module. A second colon specifies that the label is
made visible external to its source file, instead of local to that file.

To create temporary labels for the assembler, use the .macrolocal directive.

Current Location
The symbol . refers to the current location in the current section, which can
be used as an alternative to creating a label when the current location must
be referenced. For example:

Green Hills Software, Inc. 253


7. The asarm Assembler

sparse_table:
.word 1,2

; move to address that is 16 bytes from sparse_table


.space 0x10-(.-sparse_table)
.word 3,4

; move to address that is 32 bytes from sparse_table


.space 0x20-(.-sparse_table)
.word 5,6

Reading the Compiler’s Assembly Output


The assembly language file generated by the Green Hills compilers contains
many useful comments, which are explained here. Keep in mind that the format
of these comments is subject to change without notice. In particular, additional
comments might be generated by new releases of the compiler.

There are three sections of comments: a header comment at the beginning of


the file, a function comment after each function, and a file comment at the
end of the file.

Header Comment File


The first comment shows the command line to invoke the compiler driver,
ccarm:
;Driver Command: ccarm file1.c -S

The next few lines provide the name of the source file, the current directory,
the date and time the compiler was invoked, and the name and version of the
host operating system in use:
;Source File: file1.c
;Directory: /tmp
;Compile Date: Thu Dec 13 13:45:02 2001
;Host OS: SunOS 5.8 Generic_108528-06

Then the version of the compiler and the exact date of the compiler is shown:

254 MULTI: Building Applications for Embedded ARM


Reading the Compiler’s Assembly Output

;Version: target version RELEASE VERSION


;Release: Version version
;Revision Date: Revision Date
;Release Date: Release Date

Function Comment Section


The function comment section follows the function and lists parameters and
local variables. It indicates where they are stored, either in a register, on
the stack, or in static memory. However, if the program is compiled with
optimization enabled, the generated code might drastically reduce variable
lifetimes and make other alterations. In extreme cases, all uses of a variable in
the register or memory location to which it is assigned can be optimized away.
;f %FP0 local
;c %D1 local
;.L12 .L15 static

;a %D0 param
;b %D1 param

File Comment Section


This section lists imported and static variables declared at the file level and
indicates where they are stored:
;y y static
;z z import

Source Line Comments


In addition to the three sections of comments described above, the Green
Hills compilers can show the original source code in the assembly language
output file in the form of comments. This is enabled with the -passsource
option. Source lines for #include files are never shown. Some blank or
inconsequential lines are deleted by the compiler. Otherwise, the source lines
are shown exactly as they occur in the original source before preprocessor
expansion.

Green Hills Software, Inc. 255


7. The asarm Assembler

Porting Guide for ARM Limited Assembly


When porting a project to the Green Hills environment, some assembly source
code may already have been written using the syntax and conventions of the
ARM Ltd. assembler. The Green Hills assembler provides an ARM Ltd.
compatibility mode which supports many aspects of both the Green Hills
and ARM Ltd. assembly language specifications, to minimize the need for
modification of preexisting assembly source code. This support has limitations,
so certain modifications may be unavoidable, depending on which features
you are using.

Driver and Builder Options


The compiler preprocessor is not fully compatible with ARM Ltd. assembly
syntax, so in ARM Ltd. compatibility mode assembly files will not be
preprocessed regardless of their suffix. You can override this default by passing
the -preprocess_special_assembly_files driver option.

To enable ARM Ltd. compatibility mode:

Set the Assembler→ARM UK Assembler Compatibility option to


On (-arm_uk_asm).

Assembler Options
When using the assembler directly from the command line, you can pass the
following options to control ARM Ltd. compatibility:
-armuk
Enables ARM Ltd. compatibility mode, which is required to assemble most ARM
Ltd. syntax, including the other assembler command line options in this section.
-pd "variable [SETA|SETL|SETS] expr"
Declares and sets the value of a variable prior to assembly by executing either the
SETA, SETL, or SETS directive.
This option can be passed to the driver in the form
-pd="variable [SETA|SETL|SETS] expr".

256 MULTI: Building Applications for Embedded ARM


Porting Guide for ARM Limited Assembly

-apcs qualifiers
Sets the values of simulated ARM Ltd. internal variables. The qualifiers are
either /none or a concatenation of one or less entries from each of the following
qualifier sets:
• /inter or /nointer (ARM/Thumb interworking)
• /ropi, /pic, /noropi, or /nopic (Position Independent Code)
• /rwpi, /pid, /norwpi, or /nopid (Position Independent Data)
• /swst, /noswt, or /swstna (Software Stack Count Checking)
This option can be passed to the driver in the form -apcs=qualifiers.

For example, when invoking the assembler directly from the command line:
asarm -armuk -pd "Debug SETA 3" -apcs /pic/rwpi test.s

This command translates the assembly file test.s into an object file, having first:

• invoked ARM Ltd. compatibility mode (-armuk)


• set the values of the ARM Ltd. internal variables /pic and /rwpi to
resolve to TRUE (-apcs /pic/rwpi)
• set the user-defined variable Debug to the value 3 (-pd "Debug SETA 3")
To do the same with the driver, use the following command:
ccarm -arm_uk_asm -pd="Debug SETA 3" -apcs=/pic/rwpi test.s -c

Support for ARM Ltd. Syntax


The Green Hills assembler’s default interpretation of assembly source lines
differs from that of the ARM Ltd. assembler. ARM Ltd. compatibility mode
provides the following additional support:

• Recognition of escaped newline characters. Any source line ending with a


backslash is assumed to continue on the next line.
• Recognition of identifiers in the form |NAME| and ||NAME||.
• Acceptance of several numeric constant formats, including hexadecimal
values preceded by &, decimal values followed by type specifiers, U for
unsigned and L for long, and arbitrary-base numbers specified as n_value
(where n is an integer base from 2 to 9 and value is a number in that base).

Green Hills Software, Inc. 257


7. The asarm Assembler

• Support for the ARM Ltd. implementation of local labels, including


scanning one or both directions bounded by a ROUT directive for them.

Support for ARM Ltd. Variables


The ARM Ltd. assembler’s internal variables are supported by ARM Ltd.
compatibility mode, with the exception of {ARMASM_VERSION} and
|ads$version|, since the Green Hills assembler does not have an ARM
Ltd. assembler version number.

The ARM Ltd. implementation of user-defined variables is also supported.


These variables are declared and set with the appropriate directives or with the
-pd option. All three types of variables - arithmetic, logical, and string - are
supported. User-defined variables of global and local scope, as well as macro
parameters, can also be substituted within strings and identifier names (only),
starting with a $ and ending with whitespace or a period. The two exceptions to
$ interpolation are the identifiers $function and $object, which are used
as parameters to the Green Hills .type directive. User-defined variables can also
be referred to directly, without the use of $ prefixed substitution.

Support for ARM Ltd. Expressions


The Green Hills assembler retains its own expression syntax in ARM Ltd.
compatibility mode, but adds support for ARM Ltd. operators in the form
:operator:. These are listed below, categorized by type of operation.

• Bitwise operators: :and:, :eor:, :mod:, :not:, :or:, :rol:,


:ror:, :shl:, :shr:
• Logical operators: :land:, :leor:, :lnot:, :lor:
• String operators: :cc:, :chr:, :left:, :len:, :right:, :str:
• Register-relative symbol operators: :base:, :index:
• static base relative symbol operators: :sb_offset_19_12:,
:sb_offset_11_0:

The ARM Ltd. assembler’s two synonyms for !=, <> and /=, are supported.
The unary ? operator used for determining code size is not supported.

258 MULTI: Building Applications for Embedded ARM


Porting Guide for ARM Limited Assembly

Support for ARM Ltd. Directives


The Green Hills assembler accepts many of the ARM Ltd. assembler’s
directives by default, and most of them when in ARM Ltd. compatibility mode.
These ARM Ltd. directives are fully These ARM Ltd. directives are supported
supported by default, whether ARM Ltd. by default with some limitations:
compatibility mode is activated or not: • AREA
• ALIGN • EQU, *, or =
• ASSERT • GET, INCBIN, and INCLUDE
• CN and CP • INFO
• CODE16 and CODE32 • KEEP
• DCB or = • MACRO and MEND
• DCD and DCDU • OPT
• DCDO • RLIST
• DCFD and DCFS • TTL and SUBT
• DCI For more information, see “Directives
• DCQ and DCQU Supported with Limitations” on page 260.
• DCW and DCWU These ARM Ltd. directives are
supported without restrictions in ARM
• DN and SN Ltd. compatibility mode only:
• END • DATA
• EXPORT, or GLOBAL • ENDFUNC or ENDP
• EXTERN • FIELD or #
• FN • FUNCTION or PROC
• IF, ELSE, ELSEIF, and ENDIF • GBLA, GBLL, and GBLS
• IMPORT • [, |, and ]
• LTORG • LCLA, LCLL, and LCLS
• MEXIT • MAP or ^
• NOFP • ROUT
• ORG These ARM Ltd. directives are
recognized in ARM Ltd. compatibility
• REQUIRE mode, but are ignored and generate
• RN warnings:
• SPACE or % • ENTRY
• WHILE and WEND • FRAME subdirective
• PRESERVE8 and REQUIRE8

Green Hills Software, Inc. 259


7. The asarm Assembler

Directives Supported with Limitations


The following ARM Ltd. directives are supported by default with certain
limitations:
AREA
Emulated with sections, but the AREA directive must sometimes be replaced by a
.section directive and appropriate linker directives in order to properly place
code or data in memory. For more information, see “Porting the AREA Directive”
on page 260.
EQU, *, or =
Retroactive definitions not supported. The definition using the EQU directive must
precede any use of the defined identifier.
GET, INCBIN, and INCLUDE
Filenames are accepted with or without quotes.
INFO
As the Green Hills assembler is not limited to two passes, INFO does not print out
its message on success in the second pass.
KEEP
The behavior this specifies is the default behavior of the Green Hills assembler, so
this directive is accepted, but does nothing.
MACRO and MEND
All features except macro parameter substitution using $ are supported in the
default mode. For more information, see “Porting the MACRO Directive” on page
263.
OPT
Some option numbers are supported, while others are accepted with a warning.
RLIST
Emulated with the EQU directive.
TTL and SUBT
The Green Hills assembler does not output a listing file with titles or subtitles, so
these directives are silently ignored.

Porting the AREA Directive


The ARM Ltd. assembler allocates code to specific areas of object files using
the AREA directive. The Green Hills assembler and linker use sections instead,
so some translation is necessary. The syntax of the AREA directive is:

260 MULTI: Building Applications for Embedded ARM


Porting Guide for ARM Limited Assembly

AREA areaname [, attribute [ ... ] ]

where areaname denotes the name of an area to be stored in the object files,
and the attribute list corresponds to attribute bits in the object file. The ARM
Ltd. linker combines all areas with similar attributes into a single section in the
final executable.

The Green Hills assembler recognizes some key attributes passed to the AREA
directive and, rather than generate one area per directive to be recombined
by the linker, puts each area in its appropriate section at assemble-time. The
recognized combinations of attributes and their corresponding sections are as
follows:
Attribute Section
CODE .text
DATA, NOINIT .bss
DATA, READWRITE .data
DATA, READONLY .rodata

The Green Hills assembler also supports the ALIGN=n attribute for aligning
sections. All other attributes are accepted but ignored.

For the most part, AREA directives in ARM Ltd. assembly code may be left as
they are, and will function properly using Green Hills tools. However, some
projects rely on some areas residing in specific places in memory. For this to
work, an AREA directive must be replaced with an appropriate .section
directive and the location can then be specified in a linker directives file. If the
AREA directive is left as it is, the area will be subsumed by a larger section and
its location will not be separately configurable.

Example 1. Simple AREA Translation

Here is a fragment of ARM Ltd. assembly code:


AREA MyCode,CODE,READONLY,REENTRANT
...
AREA MyData,DATA,READWRITE,PID ...

The Green Hills assembler interprets these directives as section declarations.


Since it is declared with the CODE attribute, the MyCode area is placed in the
.text section (which is read-only by default), and the REENTRANT attribute

Green Hills Software, Inc. 261


7. The asarm Assembler

is ignored. The MyData area is placed in the .data section because it is


declared with the DATA and READWRITE attributes, and PID is ignored.

Example 2. More Complex AREA Translation

Here is a fragment of code which defines areas ___Always_First___


and ~~~Always_Last~~~ which, for this hypothetical project, must be
respectively the first and last areas in the final linked executable:
AREA ___Always_First___,CODE,READONLY
FirstWord
LDR pc, PlaceToJumpTo
AREA |~~~Always_Last~~~|,DATA,READWRITE
FinalWord
DCD FirstWord

Using the ARM Ltd. assembler and linker, all areas would be sorted
by their names in a way that, assuming all other area names begin with
alphabetic characters, would place ___Always_First___ first and
~~~Always_Last~~~ last. However, the Green Hills assembler would
place these areas in the sections .text and .data, respectively, and within
those sections they would be ordered based on the order in which their file
was encountered. In order to guarantee proper ordering of these sections, new
sections must be created for them. The above code should be modified to
read as follows:
.section "Always_First", "ax"
FirstWord
LDR pc, PlaceToJumpTo
.section "Always_Last", "awx"
FinalWord
DCD FirstWord

With this code, separate sections with descriptive names are generated. Then, in
the linker directive file, entries such as the following can be used to properly
order the sections:
-sec {
Always_First:
.text :
.rodata :
.data :
.bss :
Always_Last :
}

262 MULTI: Building Applications for Embedded ARM


Porting Guide for ARM Limited Assembly

Porting the MACRO Directive


The MACRO directive can be used as a synonym for the Green Hills .macro
directive, or it can be used with the ARM Ltd. assembly syntax. The Green
Hills syntax is as follows:
MACRO macroname [parameter [, ...] ]
body
MEND

The ARM Ltd. syntax is as follows:


MACRO
[$label] macroname [$parameter[=default] [, ...] ]
body
MEND

Both formats are supported by default in the Green Hills assembler, though
macro parameter substitution, using $parameter rather than just parameter in
the body of the macro, is only supported in ARM Ltd. compatibility mode.
Each assembly file must consistently use one or the other of the macro styles;
both cannot be used within the same file.

The Green Hills .macro and .endm directives support macros in the same
way, but always using the first syntax above.

ARM Address Operators


The ARM assembler supports the following pseudo-instructions:
LDR reg, lab
Loads the contents of lab into reg using a PC-relative addressing mode. You
must ensure that lab is within range.
ADR reg, lab
Loads the address of lab into reg ; using an add reg, pc, offset instruction.
You must ensure that the required offset is within the range of the add instruction.
LDR reg, =expr
Loads the value of expr (either an immediate value or a label) into reg. The
assembler may use a pc-relative add, a pc-relative load, or a reference to a new
pool item to implement this as efficiently as possible. Even if expr is a label within
range, there is no guarantee that a pc-relative add will be used. Therefore loading
labels using this method is not suitable for position independent code or data.

Green Hills Software, Inc. 263


7. The asarm Assembler

264 MULTI: Building Applications for Embedded ARM


Chapter 8

Assembler Directives

This Chapter Contains:


• Alignment Directives
• Conditional Assembly Directives
• Data Initialization Directives
• File Inclusion Directives
• Macro Definition Directives
• Repeat Block Directives
• Section Control Directives
• Symbol Definition Directives
• Symbolic Debugging Directives
• Miscellaneous Directives
8. Assembler Directives

Assembler directives are instructions to the assembler to perform various


functions. The following tables provide detailed descriptions of the assembler
directives available to you when using the asarm assembler.

Alignment Directives
.align const-expr
Advances the location counter to the specified addressing boundary, where
const-expr is a number of bytes. The location counter advances to the next
address that is a multiple of the specified addressing boundary. For example,
8, 16, 24, 32, and 40 all have an 8-byte addressing boundary. As the location
counter advances, skipped addresses are filled with zeros for the .data section
and nop instructions for the .text section.
If you place .align const-expr immediately following a section directive such as
.data or .text, the linker ensures that the entire section begins on the specified
addressing boundary. For example, suppose an assembly source file contains
the following:

.data
.align 8

When the source file is linked, the starting address of the .data section is aligned
on an 8-byte boundary. If the addressing boundary is defined in more than one
source file being linked, the linker aligns the final section to the largest boundary
found in the individual sections. For example, suppose two source files, file_1.s
and file_2.s, contain the following:
• file_1.s:
.data
.align 8

• file_2.s:
.data
.align 32

When file_1.s and file_2.s are linked, the .data section is aligned on a 32-byte
boundary.

266 MULTI: Building Applications for Embedded ARM


Conditional Assembly Directives

Conditional Assembly Directives


The .if const-expr directive starts a block of assembly statements that are
assembled only if const-expr is true. The .endif directive terminates the
conditional block of assembly statements.

Within an .if / .endif block, .else and .elseif provide alternative


assembly statements that are assembled only if the .if const-expr directive
evaluates to false.

You can nest conditional blocks within conditional blocks.

By default, when the assembler creates a source listing, it always lists .if /
.endif assembly statements, but lists the corresponding object code only if
the block is assembled. That is, the assembler produces and lists object code
only if const-expr evaluates to true.
.if x==2
.ascii "if directive is TRUE"
.elseif x-6
.ascii "elseif directive is TRUE"
.else
.ascii "both if and elseif are FALSE"
.endif

.else
Assembles the subsequent block of assembly statements if previous .if directive
evaluates to false.
.elseif const-expr
Assembles the subsequent block of assembly statements if previous .if directive
evaluates to false and .elseif const-expr evaluates to true. The assembler must
be able to resolve const-expr to a constant without referring to information within
the conditional block of code that follows the .elseif directive.
.endif
Terminates the code block that began with the previous .if directive.
.if const-expr
Starts a conditional block of assembly statements; the assembler generates object
code for these statements only if const-expr evaluates to true. The assembler
must be able to resolve const-expr to a constant without referring to information
within the .if / .endif conditional block of code.

Green Hills Software, Inc. 267


8. Assembler Directives

Data Initialization Directives


The following directives evaluate expressions and place successive values of
the specified type in the assembly output.
.ascii "string"
Evaluates a C-style string enclosed in double quotation marks (" ") and places the
characters in successive bytes. The delimiting double quotation mark characters
and terminating null are discarded.
.asciiz "string"
Evaluates a C-style string enclosed in double quotation marks (" ") and places the
characters in successive bytes. Unlike .ascii, the terminating null is placed with
the string. The delimiting double quotation mark characters are discarded.
Identical to .string.
.byte const-expr,const-expr,...
Stores the values of constant expressions in successive bytes. Each constant
expression must be in the signed range -128 to 127 or in the unsigned range
0 to 255.
.double flt-expr,flt-expr,...
Stores the values of floating-point expressions as successive 64-bit
IEEE-754 floating-point values. Each floating-point expression must be within
double-precision range.
.float flt-expr,flt-expr,...
Computes the values supplied by the floating-point expressions and produces
successive 32-bit IEEE-754 floating-point values. Each floating-point expression
must be within single-precision range.
.half const-expr,const-expr,...
Stores the values of manifest expressions as successive 16-bit data. The manifest
expressions must be in the signed range -32768 to 32767 or the unsigned range 0
to 63535.
.space const-expr
Generates const-expr bytes of zero data.
.string "string"
Evaluates a C-style string enclosed in double quotation marks (" ") and places the
characters in successive bytes. Unlike .ascii, the terminating null is placed with
the string. The delimiting double quotation mark characters are discarded.
Identical to .asciiz.

268 MULTI: Building Applications for Embedded ARM


File Inclusion Directives

.word const-expr,const-expr,...
Stores the values of constant expressions as successive 32-bit data. The
expressions can be absolute expressions, relocatable expressions, or undefined
external identifiers. The actual values of relocatable and undefined external
identifiers are supplied at link time. The value of each expression must be in
the signed range -2147483648 to 2147483647 or the unsigned range 0 to
4294967295.

File Inclusion Directives


.include "file"
Inserts the contents of file at the location of this directive. The assembler searches
for file in the current working directory, then searches in directories specified by
the -Iinc_directory compiler driver option.

Macro Definition Directives


A .macro/.endm block defines the contents of a macro. When the name of
the macro appears in an assembly file, the assembler replaces the name of the
macro with the macro’s contents. This replacement is called macro expansion.

A macro might contain another macro. In this case, the assembler processes
the enclosed macro when it expands the enclosing macro. Macros can call
themselves recursively.

The .macro directive marks the beginning of a macro and is followed by


the name of the macro and a list of parameters. Next, the body of the macro
contains assembly statements that are included in an assembly file during
macro expansion. To end the body of the macro, place a .endm directive as
the first symbol on its line.

If you want the assembler to prematurely terminate macro expansion when a


certain condition is true, enclose the .exitm directive within an .if / .endif
block in the body of the macro. If the assembler encounters an .exitm
directive during macro expansion, it prematurely terminates macro expansion.

To create a a temporary label that changes each time a macro is called, use the
.macrolocal directive. At every macro invocation, all identifiers throughout
the macro body that are listed with .macrolocal are appended with a suffix

Green Hills Software, Inc. 269


8. Assembler Directives

unique to that macro expansion. This allows local identifiers to be created and
referenced within the macro without conflicting with the equivalent identifiers
local to a subsequent macro expansion.

Example 1.

Each time the following macro mymac is invoked, label and label2 are
mangled into unique labels.
.macro mymac
.macrolocal label, label2
blt label
mov r0, 1
bgt label2
mov r0, 0
b label2
label:
mvn r0, 0
label2:
.endm

If mymac was defined without the .macrolocal directive, label and


label2 would be defined more than once if the macro mymac was invoked
more than once.

The following example defines two macros trythis and log_and:


.macro trythis parm1
ldrsh r1, [r4,parm1*2]
.endm
.macro log_and parm1 parm2
ldrsh parm1, [r4,parm2]
.endm

To call a macro, put the name of the macro and its arguments in an assembly
file. The macro must have been previously defined in the assembly file. You
must specify a value for every parameter in the macro.

During macro expansion, the macro’s parameters are replaced by the values
specified after the macro name. The concatenation operator >< can be used
to concatenate two parameters or a parameter with a symbol. The resulting
assembly statement is not scanned for further parameter matches. If one macro
calls another, the parameters of the first invocation are hidden from that of
the inner one.

270 MULTI: Building Applications for Embedded ARM


Repeat Block Directives

For example, to call the macros trythis and log_and (defined above)
and place the resulting assembly statements in the .text section, enter the
following:
.text
trythis 16
log_and r1, 0
log_and r1, 2

The assembler performs macro expansion and generates the following:


.text
ldrsh r1,[r4,32]
ldrsh r1,[r4,0]
ldrsh r1,[r4,2]

.endm
Terminates the body of a macro whose definition began with a preceding .macro
directive. The .endm directive must be the first symbol on its line and cannot
have a label.
.exitm
Causes the assembler to exit a macro without further expanding its body of
assembly statements. Use within a .if / .endif block to specify a condition
under which you do not want a macro expanded beyond that point.
.macro name [param1, param2,...]
Begins the definition of a macro, where name is a string representing the name of
the macro and param1 is the first parameter that the macro accepts. Parameters
must be separated by a comma or whitespace. Because the namespace of a
macro is distinct from the other user-defined symbols, the macro’s name and
parameters can duplicate non-macro identifiers.
.macrolabel name
Defines a temporary label.

Repeat Block Directives


The following directives specify a block of assembly statements that repeat
const-expr times.
.rept const-expr
. . .
.endr

Green Hills Software, Inc. 271


8. Assembler Directives

Repeat blocks can occur within repeat blocks. In this case, the enclosed repeat
block is expanded once for each expansion of the enclosing block. The repeat
count of an inner block is evaluated each time the block is expanded.

You can define a repeat block within a macro definition as long as the repeat
block is completely enclosed within the macro. Likewise, you can define a
macro within a repeat block as long as the macro is completely enclosed within
the repeat block.
.endr
Terminates a repeat block that began with a preceding .rept const-expr directive.
The .endr directive must be the first symbol on its line and cannot have a label.
.rept const-expr
Begins a block of assembly statements that repeats const-expr times, where
const-expr resolves to a constant number.

Section Control Directives


These directives direct assembly output into the specified section.
.data
Changes the active section to the .data section. Data that follows this directive is
placed in the .data section.
.ltorg
Marks the current location for dumping psuedoinstruction pools.
.note "string" [, "a" | "b" | |"w" | "x" ]
Changes the active section to an ELF note section. The new section is called
string. The attribute letters a, b, , w, and x function as they do with the
.section directive.
.org const-expr
Creates an absolutely-located data section at address const-expr. The name of
the section is the same as the address of the section (const-expr). The MULTI
Debugger cannot debug code placed at an address with a .org directive.
Therefore, we recommend that you use the .section directive to declare code
and data in a section instead, and then define the address of the section in a
linker directives file.
.previous
Changes the active section back to the one in use before the most recent
.section directive.

272 MULTI: Building Applications for Embedded ARM


Symbol Definition Directives

.rodata
Changes the active section to the .rodata section. Data that follows this directive
is placed in the .rodata section.
.section "string" [, "a" | "b" | |"w" | "x" ]
Directs assembly output into the section named string, which is defined in terms of
the optional attributes as listed below.
• a: the section should have memory allocated for it; that is, it should not be
used solely for debugging or for symbolic information.
• b: the section will have BSS semantics. Although normal data directives
such as .word and .byte, are allowed in a .bss section, all of the values
specified in those directives are discarded by the assembler. In the ELF output
file, the assembler records only the size of the section, and its contents are
omitted. When the section is downloaded to the target, space is allocated for
the section, but no data is downloaded to this section. Instead, the application
is responsible for initializing all bytes in the section to zero.
• w: the section is writable.
• x: the section contains executable code.
If none of these letters are specified, then no attributes are set. This is appropriate
only for sections containing debugging or other information not intended to be part
of the final linked file. Sections that are intended to be part of the final linked
output should have at least the a attribute. After the attributes are set they cannot
be specified again.
The standard sections have predefined attributes as follows:
• .text (Program code): “ax”
• .data (Initialized data): “aw”
• .rodata (Read-only initialized data): “a”
• .bss (Uninitialized data): “ab”
This example creates a section called .mytext with allocation and execute
attributes:

.section ".mytext","ax"

.text
Changes the active section to the .text section. Assembly code and data that
follows this directive is placed in the .text section.

Symbol Definition Directives


The following directives define the type and value of an identifier.

Green Hills Software, Inc. 273


8. Assembler Directives

.comm ident,const-expr[,const-expr]
Assigns the specified identifier ident to a common area of const-expr bytes in
length, and causes ident to be visible externally. If ident is not defined by another
relocatable object file, the linker assigns space for the identifier in the .bss
section. The optional const-expr specifies the variable alignment in bytes.
.dsect
Begins a block for defining constants. Within a .dsect / .end block, only labels
and .space directives are permitted. The symbolic names used for labels are
defined to have values equal to the number of bytes from the beginning of the
.dsect block. No space is actually allocated; only the symbolic names in the
label fields are defined.
.end
Terminates a block of constants that began with a preceding .dsect directive.
ident .equ const-expr
Defines the constant value const-expr to the symbol ident. After a symbol is
defined with a .equ directive, it cannot be redefined by another .equ directive.
.export ident
Identical to .import. It is common for .import to cause symbols defined in the
current module to be externally visible, while .export explicitly declares symbols
defined in other modules. The assembler does not require this usage, however.
.global ident
Causes the identifier ident to be visible externally. If the identifier is defined in the
current program, this directive allows the linker to resolve references by other
programs. If the identifier is not defined in the current program, the assembler
resolves it externally.
.import ident
Same as .export.
.lcomm ident,const-expr[,const-expr]
Assigns the specified identifier ident to an area in .bss of const-expr bytes in
length. The optional const-expr specifies the variable alignment in bytes. The
.lcomm directive is similar to .comm, except that ident is not exported.
.lsbss ident,const-expr[,const-expr]
Assigns the specified identifier ident to an area in .sbss of const-expr bytes in
length. The optional const-expr specifies the variable alignment in bytes. The
.lsbss directive is similar to .sbss, except that ident is not exported.

274 MULTI: Building Applications for Embedded ARM


Symbolic Debugging Directives

.sbss ident,const-expr[,const-expr]
Assigns the specified identifier ident to a common area of const-expr bytes in
length and causes ident to be visible externally. If ident is not defined by another
relocatable object file, the linker assigns space for the identifier in the .sbss
section. The optional const-expr specifies the variable alignment in bytes.
.set ident,const-expr
Defines the constant value const-expr to the symbol ident. You can use multiple
.set directives to change the value of the same symbol.
.weak ident
Makes the symbol weak. If the ident cannot be located, the linker sets the
symbol’s value to zero.

Symbolic Debugging Directives


These directives are used for symbolic debugging.
.file "string"
Stores source filename string in the object file symbol table. The string filename
must be from 1 to 255 characters in length and be delimited by double quotation
marks.
.nodebug
Turns off debugging for the remainder of the file.
.size ident, const-expr
Specifies the size, const-expr, of the function or data object ident. To successfully
debug an assembly language source file, it should either be assembled with -g
(which outputs full debug symbols) or else a .size directive should be used to
specify the size of each function.
The .size directive should appear at the end of the function, just after the last
assembly language statement in the function. It should be of the form:
.size ident,.-ident
where ident is the name of the function. The expression .-ident will be equal
to the size of the function in bytes, allowing the creation of correct debugging
information.
.type ident, [ $function | $object ]
Specifies whether the symbol ident is a function or a data object. The .type
directive is usually used in conjunction with the .size directive to define a
function or data object.

Green Hills Software, Inc. 275


8. Assembler Directives

Miscellaneous Directives
.ident "string"
Adds string to the .comment section within the object file. The .comment section
is not allocatable; it does not occupy memory on the target.
.need ident
Defines a relationship between the function ident and the current function. The
linker will not delete the function ident as long as the current function is used, even
if ident is not used. Suppose a source file contains the following:

myfunc:
.ascii "simple example"
.need otherfunc

The linker will not delete the function otherfunc, even if it is unused, because
it is needed by the function myfunc.
.nothumb
Switches from 16-bit Thumb code (specified by the .thumb directive) back to
32-bit ARM code.
.thumb
Switches to 16-bit Thumb code. To switch back to 32-bit ARM code, use the
.nothumb directive. For more information, see “Thumb Mode” on page 101.

276 MULTI: Building Applications for Embedded ARM


Chapter 9

The elxr Linker

This Chapter Contains:


• Running the Linker from the Builder or Driver
• Running the Linker Directly
• Linker Options
• Specifying the Program Entry Point
• Linker Directives Files
• Symbol Definitions
• Advanced Linker Features
• Porting to the elxr Linker from the old lx Linker
• Working with ARM ADS Object Files
9. The elxr Linker

The Green Hills elxr linker combines ELF object files into a single executable
output file. The relocation section of each given file “resolves” its external text
and data references with the files containing the required text and data. Linker
directives files (*.ld) are used to lay out section and memory maps, which
instruct elxr in its placement of sections in memory (see “Linker Directives
Files” on page 285).

Running the Linker from the Builder or Driver


We recommend that you invoke the linker via the Builder or driver by adding
object files to the Builder’s source pane or to the driver’s command line. The
Builder and driver accept a limited number of linker-specific options directly
(see “Linker Options” on page 183). You can also pass any of the linker options
listed in this chapter as follows:
Enter the required linker option in the Linker→Additional Linker
Options (after .ld files) option (-lnk=linker_option).
When using the driver, you can either precede each linker option with a
-lnk=, or list multiple options, separated by a whitespace and enclosed
within quotes. Hence, the following command lines are equivalent:

ccarm -lnk=-keep=foo -lnk=-keep=bar hello.c


ccarm -lnk="-keep=foo -keep=bar" hello.c

Alternatively, if you have a large number of options to pass to the


linker, you can place them in a text file and enter its filename in the
Linker→Linker Command File option (-lnkcmd=file).

Note See also:

• “Working with Linker Directives Files” on page 43


• “Passing Linker Directives Files to the Driver” on page 70

278 MULTI: Building Applications for Embedded ARM


Running the Linker Directly

Running the Linker Directly


You can invoke elxr from the command line to link object files (*.o), using
the following syntax:

elxr option file...

Options must be separated from their arguments by a whitespace or an equal


sign (=).

Example 1. elxr Syntax

To set the program’s entry point to the address of symbol foo when building
the file hello.c and using the linker directives file hello.ld, enter the following:

elxr -e=foo -T hello.ld hello.o

Note When invoking elxr from the command line, you must preface your
linker directives file with the option -T. To pass multiple linker directives files,
use a -T option for each file.

Green Hills Software, Inc. 279


9. The elxr Linker

Linker Options
The following table lists all the elxr options. These options are available to you
whether you invoke elxr with the Builder or driver (see “Running the Linker
from the Builder or Driver” on page 278), or directly from the command line:
@file
Reads additional elxr options from file file. To include a comment in an elxr option
file, place a number sign (#) as the first non-whitespace character of the line you
want treated as a comment.
-A file
Makes symbol names and addresses from a separately linked, fully located file
available during linking (a “fully-located” file is one linked without the use of the
-a or -r options).
The file’s contents are not included in the output; only those symbol addresses
needed by the current link are imported. This option is useful when one linker
image must refer to symbols that are located in another separately linked image.
-a
Causes the output file to be relocatable and executable. Relocation and final
link steps are performed (such as C++ constructor creation, common allocation,
and special symbol creation), but relocation information is retained in the output
file. Implies -r.
Some of the final link steps, including but not limited to C++ constructors and
special symbols, are not guaranteed to have relocations, and thus may not be
valid if the output file is loaded at a different address.
-allabsolute
(For use with the -A option) Imports all absolute symbols, not just those required.
-allow_bad_relocations
Emits only warnings when encountering bad or unknown relocations. The default
behavior is to generate errors.
-append
Suppresses warnings concerning object file sections that do not appear in the
section map.
-C name=value
Sets a constant, name, to the value value, for use in section and memory maps.
If this option is used, it overrides any default value specified in a CONSTANTS
directive in a linker directives file (see “The CONSTANTS Directive” on page 287).
-callgraph[=file]
Generates a call graph, file.graph.

280 MULTI: Building Applications for Embedded ARM


Linker Options

-checksum
-nochecksum
Appends a 4-byte checksum to the end of every program section. The algorithm
used is a standard 32-bit CRC. Sample source code for verifying checksums is
included in libstartup/cksum.c of your installation. The default is -nochecksum.
-cmd=optionfile
Equivalent to -@optionfile.
-codefactor
Enables the code factoring optimization, which reduces code size by removing
redundant sequences of object code at link-time. For more information see “Code
Factoring” on page 307.
-crc
Equivalent to -checksum.
-D symbol=value
Defines symbol, so that references to it resolve to value.
-delete
Removes unused functions from the executable program. For more information,
see “Deleting Unused Functions” on page 305.
-deletedebug
Deletes special debugging symbols associated with deleted functions.
-e address|symbol
Sets the program’s entry point to address, or to the address of symbol. See
“Specifying the Program Entry Point” on page 284.
-earlyabsolute
(For use with the -A option) Imports absolute symbols before searching libraries.
-explicit_padding
(Relevant to Win9x hosts only) Ensures that empty parts of the executable are
filled with 0x00’s, instead of random data.
-extractall
Imports all object members from libraries, instead of only those required.
-extractweak
Treats weak symbols as normal symbols when importing objects from libraries.
-help
Displays a list of the most commonly used linker options.

Green Hills Software, Inc. 281


9. The elxr Linker

-Help
Displays a list of all available linker options.
-keep=function
Prevents the deletion of function during function deletion. See -delete.
-keepmap
Prevents the deletion of the map file in the event of a link time error. By default,
the map file is deleted if linking fails.
-L directory
Adds a directory to be searched for libraries specified by -l; may be repeated. All
-L options on the command line are processed before any searches for -l libraries.
Directories are searched in the order in which they appear on the command line.
-lname
Looks for the library libname.a in the directories specified by -L.
-M[a][n][x]
Generates a map file with alphabetical and/or numeric ordering and/or with
cross-referencing.
-many_segments
Prevents multiple sections from being allocated to a single segment. By default,
multiple sections can be allocated to a segment if they are contiguous.
-map[=file]
Generates a map file, file.map, with alphabetic ordering.
-maplines=n
Specifies a page break in the map file every n lines.
-merge_threshold=n
Permits gaps of n bytes when merging program segments. By default, the
permitted size of gaps is 64 bytes.
-multiple
Permits multiply defined symbols. By default, an error is generated.
-no_crom
Disables the use of compressed ROM. Sections that are specified as compressed
ROM copies (through use of the attribute CROM) are treated as if they were
specified as ROM copies using the ROM attribute. For more information about the
CROM attribute, see “Section Attributes” on page 292.
-nocpp
Prevents the creation of C++ constructor/destructor tables.

282 MULTI: Building Applications for Embedded ARM


Linker Options

-no_strict_overlap_check
Gives a warning if sections overlap. An error is given by default. See also
-overlap.
-o file
Specifies the name of the output file as file.
-overlap
Suppresses the default error messages relating to section overlaps. See also
-no_strict_overlap_check.
-prog2
Produces exactly two segments: one to contain sections .text and .rodata,
and the other to contain .data and .bss.
-Q [ y | n ]
Specifies whether or not the linker creates a .comment section containing an
identifying string that records the time at which the executable was linked and
the linker that was used.
-R directory
Specifies a run-time linker library search in directory (Solaris only).
-r
Causes the output file to retain relocation information. The resulting output file can
be used as an elxr input file in further link steps. Implies -undefined. See also -a.
-saferc=rule
Specifies which MISRA SaferC rules to turn on. rule may be specified as all or
as a comma-delimited list of rule numbers.
For more information, see “MISRA C” on page 154.
-saferc_adv=level
Specifies the severity of advisory MISRA rules as none, warn, or error.
-saferc_req=level
Specifies the severity of required MISRA rules as none, warn, or error.
-skip_layout
Leaves all sections at address 0 for run-time loader (for Chorus users only).
-stderr=file
Redirects stderr output to file.
-T file.ld
Reads additional options and memory and section maps from the linker directives
file file.ld. See “Linker Directives Files” on page 285.

Green Hills Software, Inc. 283


9. The elxr Linker

-Tsection org
Sets the origin of section (text, data, or bss) to org. This option forces a three
section (.text/.data/.bss.) section map.
-tvec[=nogen]
Links absolute libraries using transfer vectors. If -tvec=nogen is specified then
transfer vectors are not generated for the image (for INTEGRITY users only).
-u symbol
Forces an undefined symbol reference for symbol, as if there had been some use
of the symbol in one of the modules listed on the command line. This might cause
modules to be linked in from libraries that would not otherwise be included.
-unalign_debug_sections
Overrides the section alignment specified in object files and forces .debug
sections to have a 1-byte alignment.
-undefined
Prevents the linker from checking for undefined symbol references. Any undefined
symbols are given an address of 0. See also -a.
-underscore
Adds an underscore to the beginning of all symbols created at link time.
-v
Prints verbose information about the activities of the linker, including the libraries it
searches to resolve undefined symbols.
-V
Displays the version number and copyright information for elxr.
-w
Suppresses linker warnings.
-Y U|L|UL,directory
Changes the default (U), alternative (L), or both (UL) library directories to directory.

Specifying the Program Entry Point


There are several ways to specify the program entry point. The following list
shows (in descending order of precedence) how the linker sets the entry point:

• the -e address|symbol option, if present


• the value of the symbol _start, if present

284 MULTI: Building Applications for Embedded ARM


Linker Directives Files

• the value of the symbol start, if present


• the value of the symbol _main, if present
• the value of the symbol main, if present
• the zero address

Linker Directives Files


Linker directives files (.ld) are used to define program sections, and to assign
them to specific addresses in memory. These files might contain the following
directives:

• OPTION — Specifies linker options (see “The OPTION Directive” on page


287).
• CONSTANTS — Sets constant values for use in memory and section maps
(see “The CONSTANTS Directive” on page 287).
• MEMORY — Defines a memory map by specifying the name, starting
address, and size of memory regions (see “Memory Maps (the MEMORY
Directive)” on page 288).
• SECTIONS — Defines a section map by specifying the name, attributes,
and address or memory location of program sections (see “Section Maps
(the SECTIONS Directive)” on page 289).

Note The New Project Wizard automatically generates default linker


directives files for various program layouts for your board (see “Creating a
New Project: The New Project Wizard” on page 24). For information about
these default files, and using the graphical Linker Directives File Editor
to edit them, see “Working with Linker Directives Files” on page 43. The
memory and section maps that are used to generate these are taken from
install_dir/target/arm of your distribution. If you intend to write your own
linker directives file, we recommend that you begin with one of these default
files.

To customize a linker directives file, copy it and make appropriate changes to


the memory and/or section map, such as altering the addresses of .text and
.data, specifying additional user-defined sections, changing the sizes of the
stack (.stack) and heap (.heap) areas, specifying different sections to be
placed in ROM, and removing unnecessary sections. Use caution when deleting

Green Hills Software, Inc. 285


9. The elxr Linker

program sections, as certain sections are used by the Green Hills run-time
environment (see “Customizing the Run-Time Environment Program Sections”
on page 299).

Note You can specify more than one linker directives file. The files are
processed in the order in which they are specified. If a memory map and a
section map appear in separate files, the file containing the memory map must
appear first.

The following file demonstrates the use of all four linker directives:
OPTION ("-checksum -map")

CONSTANTS {
heap_reserve = 1M
stack_reserve = 512K
}

MEMORY {
dram_rsvd1 : ORIGIN = 0x80000000, LENGTH = 32K
dram_memory : ORIGIN = ., LENGTH = 10M-32K
dram_rsvd2 : ORIGIN = ., LENGTH = 0

flash_rsvd1 : ORIGIN = 0xbfc00000, LENGTH = 32K


flash_memory : ORIGIN = ., LENGTH = 10M - 32K
flash_rsvd2 : ORIGIN = ., LENGTH = 0
}

SECTIONS {
.text : > dram_memory
.syscall : > .
.secinfo : > .
.fixaddr : > .
.fixtype : > .
.robase ALIGN(8) : > .
.rodata : > .

.data : > .
.profile : > .
.bss : > .
.heap ALIGN(8) PAD(heap_reserve) : > .
.stack ALIGN(8) PAD(stack_reserve) : > .

// These special symbols mark the bounds of RAM and ROM memory.
// They are used by the MULTI debugger.

__ghs_ramstart = MEMADDR(dram_rsvd1);
__ghs_ramend = MEMENDADDR(dram_rsvd2);
__ghs_romstart = MEMADDR(flash_rsvd1);
__ghs_romend = MEMENDADDR(flash_rsvd2);
}

286 MULTI: Building Applications for Embedded ARM


Linker Directives Files

The OPTION Directive


You can include command line options in a linker directives file, using the
following syntax:
OPTION ("option")

Example 1. Using the OPTION Directive

To specify the -checksum and map options in a linker directives file, add the
following line:
OPTION ("-checksum -map")

Note You can also use the OPTION directive to specify files to be linked,
using the following syntax:
OPTION ("file")

The CONSTANTS Directive


You can specify constants for use in .ld files using the following syntax:
CONSTANTS {name=value}

Example 2. Using the CONSTANTS Directive

For example, to set the constant foo to the value 0x2000 in a linker directives
file, add the following line:
CONSTANTS {foo=0x2000}

Multiple constants can be specified, separated by a semicolon. For example:


CONSTANTS {foo=0x2000; bar=0x4000}

Constants specified in this manner can be used in place of absolute values in


section and memory maps.

Note The CONSTANTS directive can be used in conjunction with the -C linker
option (see “Linker Options” on page 280). If you specify a constant, foo,
using a CONSTANTS directive, you can then vary its value without altering your
linker directives file by passing the -C option at link time.

Green Hills Software, Inc. 287


9. The elxr Linker

Memory Maps (the MEMORY Directive)


The linker uses a memory map to define regions of memory, to which the
sections of the executable can be assigned. A memory map is formatted as
follows:
MEMORY
{
...
memname: ORIGIN=origin_expression, LENGTH=length_expression
...
}

where:
memname
Specifies the name of a memory region.
origin_expression
Specifies the starting address of the memory region.
length_expression
Specifies the length of the memory region.

All three of these elements must be specified for each region to produce a valid
memory map. Comment lines are prefixed by a number symbol (#).

If a memory map is passed to the linker, only the memory regions named and
defined in it can be referenced in an associated section map.

Example 3. Format of a Memory Map

The linker directives file, memory.ld, contains the following memory map:
MEMORY
{
dram_memory : ORIGIN = 0, LENGTH = 4M
flash_memory : ORIGIN = 0x40000000, LENGTH = 1024K
internal_memory : ORIGIN = 0xffff8000, LENGTH = 0x2000
alt_reset : ORIGIN = 0xfff00100, LENGTH = 256
}

Note You can use “M” (meaning megabyte, or 220 bytes) and “K” (meaning
kilobyte or 210 bytes) in memory maps, as shown in the first two lines of the
example above.

288 MULTI: Building Applications for Embedded ARM


Linker Directives Files

Section Maps (the SECTIONS Directive)


The linker uses a section map to write program sections in the executable to
particular memory regions. A section map is formatted as follows:
SECTIONS
{
...
secname [start_expression] [attributes] : [{ contents }] [> memname]
...
}

where:
secname
Specifies the name of a section.
start_expression
Specifies the starting address of the section. If omitted, the section starts at the
next available address. Usually, this is the address immediately after the previous
section. However, if a memory map has been specified and there is not enough
space to hold the section in the current memory region, the linker searches for the
next valid area of memory (specified in the memory map) into which the section
fits. The starting address can be further modified to fit alignment constraints of
the subsections included by contents.
If both a start_expression and a memname memory region are specified in a line
in the section map, the start_expression takes precedence.
attributes
Specifies the attributes of the section. Any number of the attributes listed in
“Section Attributes” on page 292 can be included.

Green Hills Software, Inc. 289


9. The elxr Linker

{ contents }
Specifies section inclusion commands and assignments. There is no limit to the
number of commands and assignments.
Section inclusion commands take the form filename(secname), which directs that
the section secname from filename must be included. The filename parameter
can be replaced by an asterisk (“*”) to specify sections in all files not otherwise
mentioned. Multiple section inclusion commands are included in the order that
they are specified. If { contents } is omitted, the linker includes sections
named secname from all files, as if { *(secname) } had been entered. For
examples, see Example 5 on page 291.
The special variable dot (“.”), represents the current offset within the section. You
can assign symbols to dot using the syntax “symbol=.;”. You can create holes
in section using dot. For example, “.+=0x100;” would create a 0x100-byte
hole inside a section.
> memname
Allocates the section to memory region memname, which is defined in the
memory map (see “Memory Maps (the MEMORY Directive)” on page 288). If both a
start_expression and a memname memory region are specified in a line in the
section map, then the start_expression takes precedence.
If more than one section is assigned to a memname memory region, the section
that appears first in the section map is written to that region first.
Whether the start address is determined by a start_expression or by the next
available address in the memory region, it can be further modified to fit alignment
constraints of the subsections included by contents.
If you enter a “.” as the memname, the linker returns an error if the section cannot
fit into the same memory region as the preceding section.

All sections in input files that participate in memory layout must be referenced
in the section map.

Expressions may be used to create or modify the value of any symbol. If a


non-existent symbol is assigned a value, that symbol is created relative to that
section.

Example 4. Format of a Section Map

The linker directives file, sections.ld, contains the following section map, which
references some of the named memory regions defined by the memory map in
memory.ld (see “Memory Maps (the MEMORY Directive)” on page 288):

290 MULTI: Building Applications for Embedded ARM


Linker Directives Files

SECTIONS
{
# RAM SECTIONS

.data : > dram_memory


.bss : >.
.heap ALIGN(16) MIN_SIZE(stack_reserve) : >.
.stack ALIGN(16) MIN_SIZE(heap_reserve) : >.

# ROM SECTIONS

.ROM.data ROM(.data) : > flash_memory


.text : >.
.syscall : >.
.rodata : >.
}

In this example, .data is written to the memory region dram_memory.


Because no memory region is specified for .bss, this section is written to
dram_memory, directly after .data.

Example 5. Including and Renaming Sections

The section map lines given in this example demonstrate the syntax of the most
commonly used forms of section inclusion. For the sake of clarity, only the
executable section name and the { contents } argument are given.
.data :{*(.data)}
.data :

The first line above includes the .data sections from all object files in the
.data section of the executable. Because the executable section and the object
file sections have the same name, it is not necessary to specify a { contents }
argument in this case, and the syntax given in the second line is sufficient.
.newdata :{*(.data)}

The line above includes the .data sections from all object files in the
.newdata section of the executable.
.newdata :{foo.o(.data) bar.o(.data)}

The line above includes the .data sections from foo.o and then bar.o in the
.newdata section of the executable. The .data sections from all other
object files are included, by default, in the .data section of the executable.
.newtext :{lib.a(foo.o(.text))}

Green Hills Software, Inc. 291


9. The elxr Linker

The line above includes the .text section from the object file foo.o contained
within lib.a in the .newtext section of the executable. The .text sections
from all other object files are included, by default, in the .text section of
the executable.
.newbss :{lib.a(*(.bss))}

The line above includes the .bss section from all object files contained within
lib.a in the .newbss section of the executable. The .bss sections from all
other object files are included, by default, in the .bss section of the executable.

Note Library filenames are case-sensitive. You can give just the library name,
rather than a full path.

The .bss section in addition to containing sections named .bss by default,


also contains uninitialized global data designated by the name COMMON (and
SMALLCOMMON and ZEROCOMMON). The COMMON data can, instead, be
allocated separately from .bss. For example, to allocate all COMMON data to a
section called .mybss, enter the following:
.mybss :{*(COMMON)}

To allocate only the COMMON data from the main.o object file to .mybss,
enter the following:
.mybss :{main.o(COMMON)}

Section Attributes
You can use the following attributes to configure section behavior:
ABS
Sets a flag in the output file that indicates that this section has an absolute address
and should not be moved. Program loaders and other utilities that manipulate the
output image should not include this section in any movement related to position
independent code or position independent data.

292 MULTI: Building Applications for Embedded ARM


Linker Directives Files

CLEAR
NOCLEAR
Sets or removes the CLEAR attribute of the section. If CLEAR is present, an
entry is made in the run-time clear table, which is often used by startup code to
initialize memory regions to a particular value (see “Run-Time Clear and Copy
Tables” on page 310).
The CLEAR attribute is set by default for any section that includes a COMMON,
SMALLCOMMON, or ZEROCOMMON section, which are by default included by .bss,
.sbss, and .zbss respectively.
For suggested uses, see Example 6 on page 293.
PAD (value)
Places value bytes of padding at the beginning of the section. This is equivalent
to specifying padding at the beginning of the section contents.
Example:
The following two definitions are equivalent:

.stack pad(0x10000) : {}
.stack : { . += 0x10000; }
ROM (sect_name)
CROM (sect_name)
These attributes allocate the contents of a section, sect_name, to ROM at link
time, while reserving space for the data to be copied to RAM at startup.
CROM compresses its copy by as much as 40% to 50%, and thus can greatly
reduce the amount of ROM required for your application. For more information,
see Example 7 on page 294.

Working with Attributes


Example 6. Using CLEAR and NOCLEAR

The section map line above defaults to CLEAR:


.sbss NOCLEAR :

The line above overrides the default CLEAR attribute of .sbss.


.mysbss NOCLEAR :{*(SMALLCOMMON)}

The line above disables the default clearing that results from the inclusion of
COMMONS:

Green Hills Software, Inc. 293


9. The elxr Linker

.heap CLEAR PAD(0x10000):

The line above causes the heap, which is normally uninitialized, to be cleared at
startup:

Example 7. Using ROM and CROM

A section created with either of these attributes inherits the attributes and
contents of the original section. The original section is marked uninitialized;
it is modified to reserve address space only, as if it were all padding with no
contents.

To place the .data section in ROM with instructions to have it copied to RAM
at startup, you include, as a minimum, the following lines in your section map:
.data :
...
.ROM.data ROM(.data) :

An entry is automatically made in the ROM copy table to ensure that during
program startup the ROM image of .ROM.data is copied into the space
reserved for .data. See also“Run-Time Clear and Copy Tables” on page 310.

To place the .text section in compressed ROM with instructions to have it


copied to RAM at startup, enter the following lines in a section map:
.text :
...
.CROM.text CROM(.text) :

An entry is automatically made in the compressed copy table to ensure that


during program startup the ROM image of .CROM.text is copied into the
space reserved for .text. See also “Run-Time Clear and Copy Tables” on
page 310.

The behavior of a compressed ROM copy is similar to that of a ROM copy, but it
is smaller, and its placement is more restricted than that of a regular ROM copy.

Making the placement of any section other than a ROM copy or compressed
ROM copy dependent on the size of a CROM section can cause a link-time
error. Furthermore, relocations should not reference any symbols, including
__ghsbegin_section or __ghsend_section, whose locations depend on
the size of a CROM section.

294 MULTI: Building Applications for Embedded ARM


Linker Directives Files

For example, the following section map would generate errors because
the placement of .rodata depends on the size of .CROM.data and
.CROM.text:
.data : >RAM
.text :
...
.CROM.data CROM(.data) : >ROM
.CROM.text CROM(.text) :
.rodata :

A correct section map for this layout would have only a CROM section dependent
on the size of .CROM.data:
.data : >RAM
.text :
...
.rodata : >ROM
.CROM.data CROM(.data) :
.CROM.text CROM(.text) :

The effects of the CROM attribute can be disabled by passing the option
-no_crom on the command line (see “Linker Options” on page 280). Sections
marked as CROM are still copied to ROM but are not compressed.

It is an error to specify section contents for a ROM or compressed ROM section,


or to have multiple ROM() or CROM() copies of the same original section.

Expressions
Expressions support the standard C operators with their normal precedence.

In addition, the dot (“.”) can be referred to in expressions within a section’s


contents. The dot evaluates to the current position, which is the offset from
the beginning of the section. An assignment increasing the value of dot adds
padding at the current position. An assignment decreasing the value of dot
will result in an error.

The following functions are recognized during expression evaluation. Their


names are case-insensitive.

Green Hills Software, Inc. 295


9. The elxr Linker

absolute(expr)
Given a section-relative offset value, absolute returns the absolute address
by adding the address of the containing section to expr. It is an error to use
absolute outside of the parentheses that specify a section contents.
addr(sectname)
Returns the memory address of the section sectname.
align(expr)
Returns the current position (.) aligned to an expr boundary. This is equivalent to:

(. + expr - 1) & ~(expr -1)


error("string")
Generates a linker error, displaying string, the current section’s name and
address, and the current section offset.
final(finalexpression [,earlyexpression=0])
Evaluates the given expression only during the final layout pass. An optional
second argument is evaluated during all preceding passes.
isdefined(symbol)
Returns 1 if a global symbol exists and is defined, 0 otherwise.
min(value1,value2)
max(value1,value2)
Returns the minimum or maximum, respectively, of the two values supplied.
pack_or_align(value)
This is generally used only as the start_expression for a section map. It returns
the current position (.) aligned such that the section cannot span a page
boundary of size value. This is equivalent to:

(. % value)+sizeof(this_section)>value?align(value):.

sizeof(sectname)
Returns the current size of the section sectname.

All assignments to any symbol are section-relative; the numbers involved are
offsets from the start address of the section. Use the absolute() function
to get an address instead of an offset.

Depending on the target and the enabled optimizations, program layout might
occur multiple times. Therefore, you should avoid using expressions that
depend on the number of evaluations. If necessary, you can use the expression
final() to ensure that an expression is evaluated during the final layout only.

296 MULTI: Building Applications for Embedded ARM


Linker Directives Files

Example 8.

To increment the address of a symbol func if the symbol already exists:


.text : { final(isdefined(func) ? (func += 1):0); }

In contrast, the following does not properly set the low bit of a symbol because
it may increment multiple times:
# incorrect, will be incremented multiple times
.text : { isdefined(func) ? (func += 1) : 0; }

Modifying your Section Map for Speed or Size


The New Project Wizard (see “Creating a New Project: The New Project
Wizard” on page 24) provides a variety of default linker directives files with
section maps that either maximize the speed or minimize the size of your
program by varying the number of sections copied to RAM at startup. You can
control this feature by manually editing your section map:

Maximizing Execution Speed


Your program will execute faster if all of its sections are copied from ROM to
RAM at startup. In this situation each section requires two lines in the section
map. The first line locates the section, secname, in ROM, in memory region
romname. The Green Hills startup code automatically copies from ROM to
RAM those sections identified with the ROM () attribute:
.ROM.secname ROM(.secname) : > romname

The second line specifies where in RAM secname is copied to at startup:


.secname : > ramname

If you want to use custom code instead of the Green Hills startup code to copy
from ROM to RAM, see “Run-Time Clear and Copy Tables” on page 310.

Minimizing RAM Usage


To minimize RAM usage, you must ensure that as few program sections as
possible are copied to RAM at startup.

Green Hills Software, Inc. 297


9. The elxr Linker

It is not necessary to copy into RAM any sections that do not change at run
time. Although the .data section must generally be copied to RAM, the Green
Hills ARM compiler can determine whether certain data items do not change
at run time, and so can be retained in ROM. In order to take advantage of this
capability, you should create a section called .rodata . Data items placed into
the .rodata section are user-defined const variables. Declaring a variable
with the keyword const makes the value a constant, and ensures that it is
located to the .rodata section.

The .rodata section should be placed in the link map adjacent to the program
.text section, causing this data to be put into ROM along with the program
text.

298 MULTI: Building Applications for Embedded ARM


Linker Directives Files

Customizing the Run-Time Environment Program Sections


This section describes the special program sections that are created for and
maintained by the Green Hills run-time environment system (the libraries
libsys.a and libstartup.a and the module crt0.o). These sections appear in all
the default linker directives files provided with your distribution, and their
contents are generated automatically, so you should not explicitly add to them:

• .fixaddr, .fixtype — These sections are created by the compiler.


These two sections contain information that enables the Green Hills startup
code to relocate PIC/PID initializers of data variables. The compiler
automatically generates data in the .fixaddr and .fixtype sections,
if needed, when using PIC and/or PID. The default Green Hills run-time
libraries may also already have information in these sections because many
of these libraries are always built with PIC and PID.

These two sections contain read-only data and can be placed in ROM.
Failure to include these sections in the linker directives file may cause them
to be added to the end of the section list by the Green Hills linker, which can
then emit the following warning message:
[elxr] warning: section .fixaddr from libsys.a(ind_crt1.o)
isn’t included by the section map (as .fixaddr);
appending after last section
add to section map or use -append to append without warning

If the program depends on dynamic memory expanding past the end of the
last specified section in a section map, having sections appended to the
section map might be fatal because they can be overwritten. Therefore,
these sections should be included in section maps.
• .heap — This section is created by linker directives, which specifies
the size and location of the run-time heap. This section is required when
using the Green Hills run-time libraries for dynamic memory allocation. A
reference to the predefined linker symbol __ghsbegin_heap , which
denotes the beginning of the .heap section, is located in the ind_heap.c
module of the libsys.a library. If the Green Hills run-time libraries are
not being used at all, then the .heap section can be omitted. Otherwise,
failure to include a .heap section in the linker directives specification for
a program that uses dynamic memory allocation (that is, when the library
modules handling this feature are linked in with the program) causes one or
more linker errors, such as the following:

Green Hills Software, Inc. 299


9. The elxr Linker

[elxr] error: undefined: ’__ghsbegin_heap’


referenced in ’/usr/green/arm/libsys.a(ind_heap.o)’

The Green Hills run-time libraries ensure that the dynamic memory
allocation does not overrun the specified .heap area. The libraries do so by
returning an error code from sbrk,() which, in turn, causes malloc()
and other memory allocation routines to return a NULL pointer. Your code
should always check for erroneous return values when calling dynamic
memory allocation routines. You can customize the Green Hills sbrk()
routine, located in ind_heap.c, to avoid using the .heap section.
• .intercall / .interfunc — These sections may be used
by Thumb-capable processor variants to create correct mixed-mode
applications. Intercall veneers will be inserted into the .intercall
section when they cannot be prepended to the function they are associated
with. The .interfunc section contains helper functions that may be
required by mixed-mode applications.
• .rodata — This section is created by the compiler. Some Green Hills
compilers place read-only data (such as data declared with the C const
specifier and string constants) into a read-only section called .rodata.
The convention used in the default linker directives files is to place
.rodata with other sections that can be placed in ROM. Failure to include
a .rodata section in the section map may cause the linker to append it to
the end of the section map.
• .ROM.data ROM(.data) — When the linker encounters a section
directive that contains ROM(), it creates a read-only copy of the section.
By convention, a section that contains the ROM(.xxx) directive is named
.ROM.xxx, where .xxx is the name of the section that is copied from ROM
into RAM. The Green Hills startup code, ind_crt0.c (see “ind_crt0.c” on
page 583), automatically copies the data from the .ROM.xxx section to the
.xxx section when copying initialized data from ROM to RAM.

If the ROM() directive is used but the Green Hills automatic ROM-RAM
initialization code is not desired (for example, when custom ROM-RAM
copy code is used), ensure that the ROM-RAM copy mechanism in
ind_crt0.c is disabled by modifying or deleting that code.

If no ROM-RAM copying of code is necessary, then the .ROM.xxx sections


can be omitted from the linker directives file.

300 MULTI: Building Applications for Embedded ARM


Linker Directives Files

• .sdabase — For completeness, .sdabase should appear in all linker


directives files, regardless of whether or not the target supports the SDA
optimization.
• .secinfo — This is a special section output by the Green Hills linker,
which contains information about the section layout of programs. The
startup code, ind_crt0.c, uses this information to determine which sections
must be cleared (.bss sections) and which sections must be copied (ROM
sections) at program startup. This section is read-only and thus can be
placed in ROM. Failure to include this section in the link map causes the
linker to append it to the end of the section map. The following three section
flags control the information placed in the .secinfo section:
x — executable
a — allocated for downloading
w — writable

For example:
.section ".foo", "aw"
.section ".bar", "ax"

Consult the extensive comments in the ind_crt0.c file for further


documentation on the automatic copy/clear feature.
• .stack — Specifies your intended stack area and size, although there is
no general mechanism for ensuring that the stack will stay within the limits
specified by the .stack section. Green Hills startup code (when running
in stand-alone mode) and debug servers initializes the initial stack pointer
of a process based on this .stack section. When building programs to
run under an operating system that does not allow user-specification of the
stack area, an empty .stack section can still be included in the section
map to resolve references in the startup code. The reference to the .stack
area in the Green Hills startup code (crt0.o) is used only when programs
are in stand-alone mode (that is, when they are not downloaded through
the MULTI Debugger). Use of the .stack section in the startup code
can also be customized by editing and rebuilding the crt0.arm assembly
module. The Debugger also allows the initial stack pointer to be specified
differently with each download of a program via the special _INIT_SP
variable; use of _INIT_SP supersedes use of a .stack section to locate
the initial stack pointer.

Green Hills Software, Inc. 301


9. The elxr Linker

• .syscall — Contains the run-time library code for Green Hills emulation
of system calls, and is required when using the Green Hills run-time libraries
for system call emulation. When system call emulation is not being handled
in this way, you can remove use of the .syscall code by customizing the
file ind_dots.arm (see “ind_call.arm, ind_dots.arm” on page 584).

Note Any attempt to explicitly place text or data into these special sections
produces undefined and potentially fatal results. When creating custom-named
sections, you must take care not to use any of the names of these special
sections. For more detailed descriptions of the functions that use these
linker directives and special sections to set up the run-time environment, see
“Customizing the Run-Time Environment Libraries and Object Modules” on
page 580. You can also look at the comments in the customizable source files,
which are located in the libsys and libstartup directories.

Symbol Definitions
The linker can define several symbols that, if referenced but not defined in the
source code, are given particular addresses corresponding to the final image.

Beginning, End, and Size of Section Symbols


When the linker is performing final symbol resolution for a fully linked output
file, certain undefined symbol names are recognized as referring to memory
addresses in the final section map. These symbol names are constructed by
prepending the strings __ghsbegin, __ghsend, and __ghssize to the
name of each section in the output file, with any period (.) characters in the
section names changed to underscores (_).

For example, for a section named .text the symbols __ghsbegin_text,


__ghsend_text, and __ghssize_text resolve to the absolute addresses
of the beginning, end, and size of the section.

Example 1.

For a section map containing these lines:

302 MULTI: Building Applications for Embedded ARM


Symbol Definitions

SECTIONS
{
.bss1 0x400000:
.bss:
}

and this portion of main.c program code:


extern char __ghsbegin_bss1[], __ghssize_bss1[];

void foo() {
memset(__ghsbegin_bss1, 0, (int)__ghssize_bss1);
__ghsbegin_bss[0] = 0xff;
}

if the size of section .bss1 is 0x100, then the linker resolves the following
labels:

__ghsbegin_bss1 to 0x400000

__ghsend_bss1 to 0x400100

__ghssize_bss1 to 0x100

__ghsbegin_bss to 0x400100

End of Function Symbols


When the linker is performing final symbol resolution for a fully linked output
file, certain undefined symbol names are recognized as referring to the memory
addresses of the end of functions in the final executable. These symbol names
are constructed by prepending the string __ghs_eofn_ to the name of
each function in the output file. For example, for function foo, the symbol
__ghs_eofn_foo resolves to the virtual address of the end of that function.

Example 2.

For this program:


extern void __ghs_eofn_foo(void);
int foo(int x) { return x+1; }
void main () {
printf("Size of foo() is%d\n",(int)__ghs_eofn_foo-(int)foo);
}

Green Hills Software, Inc. 303


9. The elxr Linker

if the function foo() is at address 0x100000 and has size 0x20 bytes, then the
linker resolves __ghs_eofn_foo to be 0x100020.

Linker Generated Tables


When the linker performs final symbol resolution for a fully linked output file,
certain undefined symbol names are recognized as tables. In particular, if an
undefined symbol of the name __ghstable_[tablename] is encountered, the
linker can resolve the symbol to a table that will be allocated to the read-only
.rodata section. The table contains the addresses of all defined symbols of
the form __ghsentry_[tablename][entryname], and the table is terminated
with a NULL pointer. The order of the entries within the table is unpredictable.
If the name of an entry symbol matches multiple tables that the linker is filling,
the entry is added to the table with the longest matching name.

Note __ghstable_[tablename] is not supported with Position Independent


Code (PIC) or Position Independent Data (PID).

In the following example, __ghstable_resetvectors


is an array of pointers to functions. The array contains the
addresses of __ghsentry_resetvectors_foo() and
__ghsentry_resetvectors_bar(). The function reset_all() has
the ability of calling both functions.

304 MULTI: Building Applications for Embedded ARM


Symbol Definitions

extern void (*__ghstable_resetvectors[])(void);

int foo = 5;
void __ghsentry_resetvectors_foo(void)
{
foo = 0;
}

double bar = 2.0;


void __ghsentry_resetvectors_bar(void)
{
bar = 0.0;
}

void reset_all()
{
int i = 0;
while (__ghstable_resetvectors[i] != (void (*)(void))0) {
(__ghstable_resetvectors[i])();
i = i + 1;
}
}

Deleting Unused Functions


The -delete option instructs the linker to remove functions that are not
referenced in the final executable. The linker iterates to find functions that
do not have relocations pointing to them and eliminates them. If a symbol
is referenced by a relocation in the first pass, it can still be eliminated in a
subsequent pass if the referencing symbol is eliminated. Note that the -delete
option can increase the time and memory required for linking.

The linker supports -delete only for object files produced by the Green Hills
assembler. Other assemblers might produce object files that do not preserve
information required for -delete to function properly.

Tip In cases where a symbol should never be deleted, use the -keep=funcname
compiler driver option or the .need assembler directive.

The .need assembler directive introduces an explicit dependency between two


symbols (usually functions) so that the linker keeps one function if another

Green Hills Software, Inc. 305


9. The elxr Linker

function is used. An instance in which this is needed is an assembly function


that does not return but instead “falls through” into the next function of the file.

The linker never deletes symbols preserved by these methods, even if they
appear unused. It is useful to preserve symbols such as interrupt table entry
points, non-standard entry-points, or other portions of code not reached by
normal control transfer within the program.

Symbols specified via the -u linker option are also always considered as needed.

306 MULTI: Building Applications for Embedded ARM


Advanced Linker Features

Advanced Linker Features

Code Factoring
Code factoring is a link-time optimization, which reduces overall program size,
removing redundant segments of code from object files by using subroutine
calls and tail merges. The standard libraries provided with the Green Hills tools
for ARM are all prepared for code factoring.

To enable code factoring:

Set the Linker→Linker Optimizations→Code Factoring option to


On (-codefactor).

Note Linker based farcall patching can also trigger the creation of a .linfix
section. See “Frequently Used Sections” on page 668 for more information.

Example 1. Basic Usage

For example, to factor code from source files foo.c and bar.c, use:
ccarm -codefactor -o hello foo.c bar.c

This command generates two object files, foo.o and bar.o, which are prepared
for code factoring and then passed to elxr, which performs the optimization and
links them into an executable, hello.

Example 2. Controlling the Scope of Code Factoring

Code factoring only factors code within the same output section. For example:
SECTIONS {
.footext : { foo1.o(.text) foo2.o(.text) }
.bartext : { bar1.o(.text) bar2.o(.text) }
}

The code to be linked using the above section map is factored separately as
follows:

Green Hills Software, Inc. 307


9. The elxr Linker

• Code from foo1.o(.text) and foo2.o(.text), is factored and the


optimized code is placed into section .footext
• Code from bar1.o(.text) and bar2.o(.text), is factored and the
optimized code is placed into section .bartext

This behavior can be useful when you want to prevent code factoring from
creating dependencies between sections that must remain independent.

Example 3. Code Factoring and Incremental Linking

Code factoring runs during the final stage of linking, in which an executable file
is produced. If you want to incrementally link your files before producing an
executable, you must pass the -codefactor option at each stage to ensure
that the necessary relocation and symbol information is preserved. For example,
to generate a relocatable object file mod.o from object files foo.c and bar.c,
enter the following:
ccarm -codefactor -relobj -o mod.o foo.c bar.c

This command generates the relocatable object file mod.o, and preserves all
symbol and relocation information. To subsequently generate a code factored
executable, enter the following:
ccarm -codefactor mod.o -o hello

This produces the code-factored executable, hello.

Example 4. Partial Code Factoring

It is possible to apply code factoring to only some of the modules that are linked
into the final executable. If foo.c, bar.c, and baz.c are to be linked together to
produce the executable hello, but only bar.c and baz.c are to be code factored,
first generate an object file from foo.c, as follows:
ccarm -c foo.c

This command produces an object file named foo.o, which is excluded from
code factoring in any subsequent link.

Next, generate object files from bar.c and baz.c, using the -codefactor
option, as follows:
ccarm -codefactor -c bar.c baz.c

308 MULTI: Building Applications for Embedded ARM


Advanced Linker Features

This command produces the object files bar.o and baz.o, which are prepared
for subsequent code factoring.

Finally, generate an executable, as follows:


ccarm -codefactor foo.o bar.o baz.o -o hello

This command produces an executable, hello, in which code factoring is applied


only to bar.o and baz.o.

Note Please note the following:

• Hand-written assembly code files and mixed assembly and C/C++ source
files (that is, C or C++ source files with #pragma startasm, asm
macros, etc.) cannot be code factored. For optimal results, do not mix both
assembly and C/C++ code within the same source file.
• When using the MULTI Debugger, you cannot set breakpoints on lines of
source code that have been altered or removed by code factoring. These
lines of code display a red breakdot instead of a green breakdot. Switch
to interlaced source and assembly mode, and then set breakpoints at the
assembly level.
• To control code factoring in the linker, the compiler generates a number
of .ghsnote assembler directives (which reside in the non-allocated
.ghs_info SHT_NOTE section, and have no impact on final code size).
You should not modify these directives or the contents of this section.

Compressed ROM
The elxr linker has the capability to compress sections that are placed in ROM.
These sections are then decompressed and copied into RAM during program
startup (see “Run-Time Clear and Copy Tables” on page 310). This compression
makes the executable smaller and reduces the amount of ROM required to store
the program, at the cost of an increase in the time required to link and in the
program startup time. For information about how to use Compressed ROM, see
the CROM attribute in “Section Attributes” on page 292.

Green Hills Software, Inc. 309


9. The elxr Linker

Section-information Section (.secinfo)


The .secinfo section contains special tables that contain information needed
by startup code to clear sections (Run-Time Clear Table), and to copy sections
from ROM to RAM (Run-Time Copy Table).

Obtaining Run-Time Section Information


The linker allows a program to obtain the locations, sizes, and types of its
sections at run time. If the symbol __secinfo is referenced but not defined in
a program, the linker fills in additional section information in the .secinfo
section and sets the __secinfo symbol to point to it. The indsecinfo.h
header file in the libsys directory of your distribution has a declaration for this
structure and a sample program that shows its use.

Run-Time Clear and Copy Tables


These three tables are contained within the .secinfo section.

• The clear table is bounded by the symbols __ghsbinfo_clear and


__ghseinfo_clear.
• The copy table is bounded by the symbols __ghsbinfo_copy and
__ghseinfo_copy.
• The compressed copy table is bounded by the symbols
__ghsbinfo_comcopy and __ghseinfo_comcopy.

These tables each contain zero or more records detailing the action to be taken
at startup.

By default, the Green Hills C run-time library libstartup.a automatically clears


.bss, and copies ROM and decompressed CROM sections to RAM based on this
table. The actual implementation of the above three routines for your CRT code
can be found in libstartup/ind_crt0.c and libstartup/ind_uzip.c in your Green
Hills product and differs slightly for PIC/PID support on some targets.

310 MULTI: Building Applications for Embedded ARM


Porting to the elxr Linker from the old lx Linker

Porting to the elxr Linker from the old lx Linker


Users of previous Green Hills tools releases may have written link scripts
particular to the lx linker. While most older scripts are still accepted, some
modifications are required when upgrading to the elxr linker:

• If you run elxr directly, be careful to use -T linkscript.ld instead of


@optionfile to specify linker directives files to elxr. Continue to use
@optionfile to specify a file containing additional command line options.
• If you want to include command line options within a linker directives file,
use OPTION("...") (see “The OPTION Directive” on page 287). The lx
linker permitted stand-alone options within a script file.
• Use SECTIONS rather than the deprecated -sec to introduce a section map
(see “Section Maps (the SECTIONS Directive)” on page 289).
• When specifying section attributes, use max_endaddress() in place of
limit(), and max_size() in place of size() (see “Section Attributes” on page
292).
• When including sections, use curly braces on the right-hand side of the
colon. The elxr syntax is:
.newtext : { file1.o(.text) file2.o(.text) }

while the lx format was:


.newtext : file1.o(.text) file2.o(.text) ;

Green Hills Software, Inc. 311


9. The elxr Linker

Working with ARM ADS Object Files


The Green Hills elxr linker provides limited support for linking in object files
generated with the ARM ADS tools. If your project contains such legacy files,
you should consider the following factors when linking your project:

• If you intend to use Green Hills startup code, the module containing
main() must be compiled with the Green Hills tools.
• You can link in the ADS run-time libraries to fulfill ADS compiler helpers.
This forces any symbol definitions unresolved by the Green Hills libraries
to be resolved against ads_library.l. To do this:

Enter ads_library.l in the Linker→Start and End Files→End Files


option (-endfile=ads_library.l).

• Any ADS modules must have been compiled using the usual -apcs/interwork
rules. elxr completes intercall stub patching as usual.
• Implementation-defined C constructs (such as va_list) might not be
compatible.
• You should ensure that all modules are compiled for the same target
architecture throughout the compilation process (using the ADS and Green
Hills -cpu cpu options).
• The -r option (which instructs elxr to retain relocation information in the
output file) is not supported when ADS modules are linked in.
• You can use a section map in a linker directives file to rename ADS
sections to their corresponding Green Hills names (see “Section Maps (the
SECTIONS Directive)” on page 289).
• To obtain maximum debugging information, you should pass -dwarf_to_dbo
to translate ADS DWARF2 tables to the Green Hills .dbo format. You might
need to use the MULTI Debugger source command to specify the path to
the ADS source files.

Note The final executable will be a standard Green Hills executable. e_flags
will be dictated by Green Hills modules only.

312 MULTI: Building Applications for Embedded ARM


Chapter 10

The ax Librarian

This Chapter Contains:


• Creating a Library from the Builder
• Creating a Library from the Compiler Driver
• Modifying Libraries
• Creating and Updating Tables of Contents
10. The ax Librarian

The librarian combines object modules created by the assembler or linker into a
library, which is also referred to as an archive file. By convention, library files
have .a extensions. At link time, the linker can search libraries and extract
object files that are needed to provide definitions for undefined symbols.

Creating a Library from the Builder


To create a library from the Builder, add the source files for the library to a
project file, filename.gpj, then designate the build file as a library as follows:

1. Highlight the build file (filename.gpj).


2. Right-click the new library project file and select Set Type from the
context-sensitive menu.
3. Choose Library from the drop-down list, and click OK.

When you build the project, the Builder compiles and assembles the source
files, and then runs the librarian to create a library from the resulting object
files. For more information, see “Linking with a Pre-Built Library” on page 37.

Creating a Library from the Compiler Driver


To create a library using the compiler driver, enter the following:
ccarm filename1 filename2 filename3... -archive -o libname.a

where filename1, filename2, filename3, etc. are the source files or object files
that are used to create the library, and libname.a is the name of the library to be
created. The compiler driver compiles and assembles the source files, and then
runs the librarian to create a library from the resulting object files.

Example 1.

To create a library libfoo.a from the source file foo.c, enter:


ccarm foo.c -archive -o libfoo.a

To create a library libhello.a from the object files hello.o and world.o, enter:
ccarm hello.o world.o -archive -o libhello.a

314 MULTI: Building Applications for Embedded ARM


Modifying Libraries

Modifying Libraries
You can modify libraries (*.a files) by invoking the librarian (ax) directly, as
follows:
ax -command [options] libraryfile.a [objectfile.o]

where -command is one or more of the librarian commands, and option is one
or more of the librarian command options. The valid commands and options
are listed below.

Librarian Commands
The Librarian commands and any options that can be appended to them must
be entered as one string without spaces. The librarian commands are listed in
the table below (the options in square brackets are explained in the subsequent
table, “Librarian Command Options ” on page 316):
-d [e] [S] [v] libraryfile memberfile...
Deletes the specified memberfile (or files) from the specified libraryfile.
-p [e] libraryfile...
Prints the specified libraryfile (or files) to standard output (if the members are
object files, then the output might not be human-readable).
-q [e] [S] [v] libraryfile memberfile
Appends the specified memberfile (or files) to the end of the specified libraryfile.
The -q command is similar to the -r command except that, with -q, the files will
always be added to the end of the library, rather than replacing any existing
version of the file with the new version.
-r [c] [C] [e] [S] [v] libraryfile memberfile...
Replaces the specified memberfile (or files) in the specified libraryfile. The new
version of memberfile overwrites the existing version.
If memberfile was not previously in libraryfile, it is added.
If libraryfile did not previously exist, it is created.

Note We recommend that you create libraries with the compiler driver and not with
the librarian because only the former method generates the *.dba files necessary
for subsequent debugging.

Green Hills Software, Inc. 315


10. The ax Librarian

-t [e] [s] [v] libraryfile...


Lists the names of the files contained in the specified libraryfile (or files). Use the v
option to list names, file sizes, and the dates that the members were last modified.
-x [e] [v] [o] libraryfile memberfile...
Extracts the specified memberfile (or files) from the specified libraryfile. The library
is searched for the specified filenames and the named files are created and written
with the contents of the library. The library is not altered by this command.

Librarian Command Options


These options may be appended to the librarian commands to give you greater
control over operations on library files. See “Librarian Commands” on page
315 to determine which options are available with each command.
c Suppresses warnings when creating a library that did not exist.
C Replaces the existing library.
e Prefixes messages with ERROR or WARNING. Equivalent to the compiler
driver option -prefixed_msgs.
o Keeps original timestamps when extracting files from a library.
s Regenerates the table of contents; use with the -t command.
S Prevents the creation of a table of contents.
v Prints verbose messages when executing a command.

Examples
To add a new object file foo.o to an existing library lib.a, enter:

ax -r lib.a foo.o

To delete object files foo.o and bar.o from library lib.a, enter:

ax -d lib.a foo.o bar.o

To append object files foo.o and bar.o to library lib.a, enter:

ax -q lib.a foo.o bar.o

To extract object file foo.o from library lib.a and rename it to newfoo.o, enter:

316 MULTI: Building Applications for Embedded ARM


Creating and Updating Tables of Contents

ax -p lib.a foo.o > newfoo.o

To print the table of contents of library lib.a in verbose mode, enter:

ax -tv lib.a

Creating and Updating Tables of Contents


The librarian creates a table of contents (also known as a symbol table), by
default, whenever a library is created or modified. This improves performance
during linking, because the linker does not have to create a table of contents
every time it reads a library. This table of contents is stored in the form of a
hidden file named / (slash), which is always the first file in the library.

If you want to suppress the creation of a table of contents when appending a


member, use the -q command with the S option. For example, to append foo.o
to lib.a without creating a table of contents, enter:

ax -qS lib.a foo.o

To subsequently create or update a table of contents without altering the library,


use the -t command with the s option. For example, if you want to create a
table of contents for lib.a, enter:

ax -ts lib.a

Green Hills Software, Inc. 317


10. The ax Librarian

318 MULTI: Building Applications for Embedded ARM


Chapter 11

Utility Programs

This Chapter Contains:


• The gasmlist Utility Program
• The gbin2c Utility Program
• The gbincmp Utility Program
• The gbldconvert Utility Program
• The gbuild Utility Program
• The gcolor Utility Program
• The gcompare Utility Program
• The gdump Utility Program
• The gfile Utility Program
• The gfunsize Utility Program
• The ghexfile Utility Program
• The ghide Utility Program
• The gmemfile Utility Program
• The gnm Utility Program
• The gpjmodify Utility Program
• The grun Utility Program
• The gsize Utility Program
• The gsrec Utility Program
• The gstack Utility Program
• The gstrip Utility Program
• The gversion Utility Program
• The gwhat Utility Program
11. Utility Programs

The MULTI IDE includes many useful command line utility programs,
including functional replacements for the standard UNIX utilities dump, file,
hide, nm, size, strip, and what. All utility programs work with files generated
by any Green Hills development tools.

• gasmlist: Generates interlaced assembly and source output (object files


only).
• gbin2c: Converts binary files into C array definitions.
• gbincmp: Compares two binary files (single object files or executables
only).
• gbldconvert: Converts old-style build files (.bld) to new-style Green Hills
project files (.gpj).
• gbuild: A command line interface to the MULTI Builder.
• gcolor: Takes text input and colors it using ANSI escape sequences.
• gcompare: Compares space or time performance.
• gdump: Similar to the UNIX dump program. Dumps or disassembles a file.
• gfile: Similar to the UNIX file program. Describes the file type.
• gfunsize: Returns the code size of a function.
• ghexfile: Converts an executable file to Intel hexadecimal format.
• ghide: Similar to the UNIX hide program. Hides global symbols in an
object file.
• gmemfile: Converts an executable file to a binary image suitable for loading.
• gnm: Similar to the UNIX nm program. Displays file information.
• gpjmodify: Performs command line editing of new-style .gpj project files.
• grun: (for executable files) Runs a server in batch mode.
• gsize: Similar to the UNIX size program. Displays section sizes.
• gsrec: Converts an executable file to Motorola S-Record format.
• gstack: (for executable files) Computes stack size for each task.
• gstrip: Similar to the UNIX strip program. Removes symbol or debugging
information from an executable.
• gversion: (for executable files) Returns version date and time information.
• gwhat: Similar to the UNIX what program. Reports or updates version
information.

320 MULTI: Building Applications for Embedded ARM


The gasmlist Utility Program

The gasmlist Utility Program


The gasmlist utility program displays interlaced assembly and source for the
specified object files.

The syntax for this utility is as follows:


gasmlist [options] file.o[,file.o…]

where options are drawn from the following table:


--all
--all_with_asm
Controls which files have source lines printed:
• --all prints source lines for all files
• --all_with_asm prints source lines for all files that produce assembly or, if
--src_then_asm is specified, for all files.
The default is to restrict output to the object file’s base source file (so only source
lines from the base source file are printed).
--file_num
--proc_num
Restricts identification of output lines to one of the following:
• file line numbers
• procedure line numbers
The default is to print both procedure and file line numbers.
--file_offset
Calculates offsets from the start of the present object file. The default is to
calculate them from the start of the present section.
--help
Prints usage information.
--hide_all_labels
Suppresses the printing of detailed label information.
--hide_mangled
Suppresses the printing of mangled versions of labels. The demangled versions
are always printed.

Green Hills Software, Inc. 321


11. Utility Programs

-I directory
Specifies an additional directory to search for source files.
The following directories are searched for source files in this order:
• the relative or absolute path specified in the object file
• directories specified using -I directory
• the user’s path
The current directory is not searched unless it is specified in one of these
categories.
--max_header_lines n
Specifies the maximum number n of header source lines to be printed.
The default value for n is 4. Setting n to 0 instructs gasmlist to print all associated
header file lines.
--no_prefix_file
Suppresses the printing of the filename at the beginning of each source line.
--omit_headings
Suppresses the printing of headings to separate files and sections.
--proc_num_on_left
When both file and procedure line numbers are enabled, prints the procedure
numbers on the left. The default is to print them on the right.
--root_remap rt dir
Re-maps the original path rt to the new path dir. For example to map a/b/c to
d/c, pass:

--root_remap a/b d
--show_func_labels
Prints line offsets with the label they are offset from. For instance, +0x4" would
instead be printed label+0x4".
--src_then_asm
Orients the output primarily towards source code. The default is to emphasize
assembly.

322 MULTI: Building Applications for Embedded ARM


The gasmlist Utility Program

Example 1.

In this example, the object file test.o is compiled with the following command
line:
ccarm -G -c test.cc

The gasmlist utility is used to generate an interlaced source and assembly


listing from test.o as follows:
gasmlist test.o

This command generates a listing, an excerpt from which is given in the


following:
Section 3: ".text", size: 76 bytes
test.cc: 1 ***** #include "example.h"
test.cc: 2 *****
test.cc: 3 ***** static int staticLocal = 0;
test.cc: 4 *****
test.cc: 5 ***** int main()
test.cc: 5 0 main
test.cc: 5 0 : 7c0802a6 mflr r0
test.cc: 5 0x4 + 0x4: 90010004 stw r0, 4(sp)
test.cc: 5 0x8 + 0x8: 9421fff8 stwu sp, -8(sp)
test.cc: 6 1 ***** {
test.cc: 6 1 0xc + 0xc: 4bfffff5 bl _main
test.cc: 7 2 ***** staticLocal = getDeadbeef();
test.cc: 7 2 0x10 +0x10: 3d600000 lis r11, %hiadj(staticLocal)
test.cc: 7 2 0x14 +0x14: 3d80deae lis r12, 0xdeae
test.cc: 7 2 0x18 +0x18: 398cbeef subi r12, r12, 0x4111
test.cc: 7 2 0x1c +0x1c: 918b0000 stw r12, %lo(staticLocal)(r11)
test.cc: 8 3 *****
test.cc: 9 4 ***** return staticLocal - getDeadbeef();
test.cc: 9 4 0x20 +0x20: 3d800000 lis r12, %hiadj(staticLocal)
test.cc: 9 4 0x24 +0x24: 818c0000 lwz r12, %lo(staticLocal)(r12)
test.cc: 9 4 0x28 +0x28: 7d8b6378 mr r11, r12
test.cc: 9 4 0x2c +0x2c: 3d80deae lis r12, 0xdeae
test.cc: 9 4 0x30 +0x30: 398cbeef subi r12, r12, 0x4111
test.cc: 9 4 0x34 +0x34: 7d8c5850 subf r12, r12, r11
test.cc: 10 5 ***** }
test.cc: 10 5 0x38 +0x38: 7d836378 mr r3, r12
test.cc: 10 5 0x3c +0x3c: 8001000c lwz r0, 0xc(sp)
test.cc: 10 5 0x40 +0x40: 7c0803a6 mtlr r0
test.cc: 10 5 0x44 +0x44: 38210008 addi sp, sp, 8
test.cc: 10 5 0x48 +0x48: 4e800020 blr

If the object file has been moved from its original compilation directory, you
might receive an error message similar to the following:
gasmlist: error: aborted without finding file ’/export/samples/test.cc’

Green Hills Software, Inc. 323


11. Utility Programs

You can use one of the following methods to locate missing source files:

• Pass the --root_remap rt dir command to relocate all the paths in the object
to the correct local directories. For instance, if /export/samples/ is available
to you as /home/samples, pass the following command line:
gasmlist --root_remap /export/samples /home/samples test.o

• Alternately, pass the -I directory command to include specific directories to


search for source files. For instance, if /export/samples/ is available to you
as /home/samples, pass the following command line:
gasmlist -I /home/samples test.o

324 MULTI: Building Applications for Embedded ARM


The gbin2c Utility Program

The gbin2c Utility Program


The gbin2c utility is used to convert a group of binary files into a set of array
definitions in a source file suitable for inclusion in C or C++ projects. The byte
by byte conversion of each binary file into a char array is controlled through
the command line arguments passed.

The syntax for this utility is as follows:


gbin2c [global_options] [-input] file1 [file1_local_options]…

Command line options for gbin2c are divided into three categories. Global
options can be specified anywhere on the command line and apply to all binary
files to be converted. Module inclusion options specify binary files to be
converted. Local options apply only to the binary file specified by the nearest
module inclusion option preceding them on the command line.

Global Options
-compat
Runs gbin2c in gbin2src compatibility mode.
Implies:
• the -list global option
• the -static local option for each binary file.
If an additional options file is not specified on the command line (with -i), this
option also instructs gbin2c to read standard input for additional options in lieu of
an additional options file.
-crc
Outputs a crc value for each converted binary file.
The declaration of the crc variable for the array named name is:
const unsigned int name_crc;
-help
Displays basic usage information.

Green Hills Software, Inc. 325


11. Utility Programs

-i file
Reads file as a list of additional options.
The contents of file are parsed as additional options. Extra whitespace and new
line characters are ignored. Options listed in the file have the same effect as
options on the command line with the following exceptions:
• The options file is not preprocessed by the user’s shell so no special treatment,
such as wildcard substitution, is performed.
• The meaning of the -o option in the additional options file context differs from
its meaning in the command line context. In the options file, -o name means
“refer to the current module as name in the module list, and set the array
name for the current module to name_data". In essence, the -o option is
an alias for the -output option when it occurs on the command line and the
-module_name and -array_name options when it occurs in the options file.
Note that only one additional options file can be specified using the -i option.
-list
Outputs a list of converted modules.
The default definition for the type of each list element is:

struct static_module_info {
const char * const name;
const char * const data;
const struct static_module_info * const next;
};

The default declaration of the module list is:

const struct static_module_info __static_modules[];


-list_name name
Sets the name of the module list to name.
-list_type name
Sets the name of the module list element struct type to name.
-o file
-output file
Writes output to file. See -i, above, for the -o option’s alternate meaning in an
options file.
If neither of these options is passed, then output is written to stdout.

326 MULTI: Building Applications for Embedded ARM


The gbin2c Utility Program

-size
Outputs the length of each array written.
The declaration of the size variable for the array named name is:

const unsigned int name_size;

Module Inclusion Options


[-input] file
Adds file to the list of binary files to convert.
An array is defined for each converted binary file. The default declaration for the
array generated from file file (stripped of all path information, and with any periods
replaced with underscores) is:

const char file_data[];

The nature of the array can be controlled via the local options.

Local Options
These options modify settings for the most recently included module:
-array_name name
Sets the array name for the current module to name.
By default the array name for a file is the base name of the file with all periods
replaced with underscores.
-limit n
Outputs a maximum of n bytes of the current module.
-module_name name
Refers to the current module as name in the module list.
-noconst
Removes const from the type of the array for the current module.
-signed
-unsigned
Adds signed or unsigned to the type of the array for the current module.

Green Hills Software, Inc. 327


11. Utility Programs

-skip n
Skips the first n bytes of the current module.
-static
Adds static to the type of the array for the current module.

Example 1.
gbin2c mod.o

The contents of mod.o are converted to a const char array named


mod_o_data and printed on stdout. The output looks similar to the
following:
/**
* This file was automatically generated by gbin2c v1.08
* Green Hills Software, Inc. [ http://www.ghs.com ]
* Using command line: gbin2c mod.o
* Date generated: Wed Jul 9 16:04:18 2003
**/

/* mod.o: */

const char mod_o_data[] = {


0x7F, 0x45, etc.
};

Example 2.
gbin2c -crc -size mod.o

In addition to the output from example 1, size and crc information for mod.o
are displayed:

328 MULTI: Building Applications for Embedded ARM


The gbin2c Utility Program

/**
* This file was automatically generated by gbin2c v1.08
* Green Hills Software, Inc. [ http://www.ghs.com ]
* Using command line: gbin2c -crc -size mod.o
* Date generated: Wed Jul 9 16:09:48 2003
* Note: CRC of input file and this array can be found at end of file
**/

/* mod.o: */

const char mod_o_data[] = {


0x7F, 0x45, etc.
};

const unsigned int mod_o_data_size = 2620;

const unsigned int mod_o_data_crc = 0xD91D5642;


/* CRC of input file = 0xD91D5642 */
/* Note that file CRC may not match array CRC if -skip or -limit were used */

Example 3.
gbin2c -crc -size mod.o -static -skip 64 -limit 4

In this example, the static keyword is added to the type of mod_o_data


and only bytes 64-67 (starting counting at 0) of mod.o are output:
/**
* This file was automatically generated by gbin2c v1.08
* Green Hills Software, Inc. [ http://www.ghs.com ]
* Using command line: gbin2c -crc -size mod.o -static -skip 64 -limit 4
* Date generated: Wed Jul 9 16:16:19 2003
* Note: CRC of input file and this array can be found at end of file
**/

/* mod.o: skipped 64 bytes and limited to 4 bytes */

static const char mod_o_data[] = {


0x65, 0x2F, 0x73, 0x73
};

const unsigned int mod_o_data_size = 4;

const unsigned int mod_o_data_crc = 0x358E11C6;


/* CRC of input file = 0xD91D5642 */
/* Note that file CRC may not match array CRC if -skip or -limit were used */

Example 4.
gbin2c -crc mod.o -static foo -signed -size -array_name bar

Green Hills Software, Inc. 329


11. Utility Programs

In this example, both mod.o and foo are converted. Notice that the -crc and
-size global options apply to both files while -static and -signed only apply to
mod.o and foo respectively. This example also demonstrates the use of the
-array_name option and its effect on the size and crc variable names.
/**
* This file was automatically generated by gbin2c v1.08
* Green Hills Software, Inc. [ http://www.ghs.com ]
* Using command line:
* gbin2c -crc mod.o -static foo -signed -size -array_name bar
* Date generated: Wed Jul 9 16:28:19 2003
* Note: CRC of input file and this array can be found at end of file
**/

/* foo: */

const signed char bar[] = {


0x66, 0x64, 0x61, 0x73, 0x0A
};

const unsigned int bar_size = 5;

const unsigned int bar_crc = 0x11A9EBE1;


/* CRC of input file = 0x11A9EBE1 */
/* Note that file CRC may not match array CRC if -skip or -limit were used */

/* mod.o: */

static const char mod_o_data[] = {


0x7F, 0x45, etc.
};

const unsigned int mod_o_data_size = 2620;

const unsigned int mod_o_data_crc = 0xD91D5642;


/* CRC of input file = 0xD91D5642 */
/* Note that file CRC may not match array CRC if -skip or -limit were used */

Example 5.
gbin2c mod.o foo -module_name bar -list

In this example the module list is output and the module name for foo is
changed to bar.

330 MULTI: Building Applications for Embedded ARM


The gbin2c Utility Program

/**
* This file was automatically generated by gbin2c v1.08
* Green Hills Software, Inc. [ http://www.ghs.com ]
* Using command line: gbin2c mod.o foo -module_name bar -list
* Date generated: Wed Jul 9 16:30:48 2003
**/

#include <stdio.h> /* Get definition of NULL */

struct static_module_info {
const char * const name;
const char * const data;
const struct static_module_info * const next;
};

/* foo: */

const char foo_data[] = {


0x66, 0x64, 0x61, 0x73, 0x0A
};

/* mod.o: */

const char mod_o_data[] = {


0x7F, 0x45, etc.
};

const struct static_module_info __static_modules[] = {


{
"bar",
(const char *)&foo_data,
&__static_modules[1],
},
{
"mod.o",
(const char *)&mod_o_data,
NULL,
}
};

Example 6.
gbin2c -i modules -list -crc

In this example, the -i option is used to include an additional options file called
modules, which contains the following text:
mod.o
foo -o bar

The -o option in modules specifies that the module name for foo should be bar
and that its array name should be bar_data.

Green Hills Software, Inc. 331


11. Utility Programs

/**
* This file was automatically generated by gbin2c v1.08
* Green Hills Software, Inc. [ http://www.ghs.com ]
* Using command line: gbin2c -i modules -list -crc
* Additional options from file: mod.o foo -o bar
* Date generated: Wed Jul 9 16:38:51 2003
* Note: CRC of input file and this array can be found at end of file
**/

#include <stdio.h> /* Get definition of NULL */

struct static_module_info {
const char * const name;
const char * const data;
const struct static_module_info * const next;
};

/* foo: */

const char bar_data[] = {


0x66, 0x64, 0x61, 0x73, 0x0A
};

const unsigned int bar_data_crc = 0x11A9EBE1;


/* CRC of input file = 0x11A9EBE1 */
/* Note that file CRC may not match array CRC if -skip or -limit were used */

/* mod.o: */

const char mod_o_data[] = {


0x7F, 0x45, etc.
};

const unsigned int mod_o_data_crc = 0xD91D5642;


/* CRC of input file = 0xD91D5642 */
/* Note that file CRC may not match array CRC if -skip or -limit were used */

const struct static_module_info __static_modules[] = {


{
"bar",
(const char *)&bar_data,
&__static_modules[1],
},
{
"mod.o",
(const char *)&mod_o_data,
NULL,
}
};

332 MULTI: Building Applications for Embedded ARM


The gbincmp Utility Program

The gbincmp Utility Program


The gbincmp utility program compares two binary input files. The two input
files can be Berkeley (BSD), COFF, or ELF format object files or executable
files.

If the two files are identical, except for time-stamps, gbincmp returns with no
output. If they differ, gbincmp prints the section name and byte offset within
the section of the first difference.

The gbincmp utility program can compare any of the following:

• Contents of sections loaded on the target (target sections) [this is the default]
• Contents of sections not loaded on the target (host sections)
• File headers
• Program headers (ELF headers)
• Section headers
• Relocation tables
• String tables
• Symbol sections
• DWARF debugging sections
• DWARF line number sections
The syntax for this utility is as follows:
gbincmp [options] file1 file2

where file1 and file2 are the names of the two files to be compared.

The gbincmp options are:


-all
Compares all sections.
-continue
Instructs gbincmp not to stop at the first difference.
-debug
-nodebug
Enables or disables comparison of DWARF debugging information. (ELF only)

Green Hills Software, Inc. 333


11. Utility Programs

-help
Displays information about all options.
-host
-nohost
Enables or disables comparison of the contents of host sections.
-line
-noline
Enables or disables comparison of line number information. (ELF only)
-prefixed_msgs
-no_prefixed_msgs
Enables or disables the insertion of the words WARNING and ERROR before every
warning and error message.
-reloc
-noreloc
Enables or disables comparison of relocation information.
-section=sections
-nosection=sections
Enables or disables comparison of the sections named in the comma-separated
sections list. For example, -section=text,data. (ELF only)
-string
-nostring
Enables or disables comparison of string table information.
-symbol
-nosymbol
Enables or disables comparison of symbol table information.
-target
-notarget
Enables or disables comparison of the contents of target sections.
-v
Verbose output. Shows what files and sections are compared.

334 MULTI: Building Applications for Embedded ARM


The gbldconvert Utility Program

The gbldconvert Utility Program


The gbldconvert utility program converts old-style build files (.bld) to
new-style Green Hills project files (.gpj).

The syntax for this utility is as follows:


gbldconvert [options] file.bld

where file.bld is the name of the build file to convert.

The gbldconvert options are:


-#
Enables dry-run processing of .bld files without generation of .gpj files.
-no_r
Disables recursive processing of children of the input .bld file.
-overwrite
Enables overwriting of the .gpj file, even if it is newer than the .bld file being
converted.
-q [quiet mode]
-v [verbose mode]
-V [very verbose mode]
Controls the verbosity of the output to stdout.
-s
Enables strict mode, in which the conversion stops if a subproject cannot be read.
-target target_file.tgt
Specifies the output target for a subproject or overrides the target specified in
top-level .bld files.

Green Hills Software, Inc. 335


11. Utility Programs

The gbuild Utility Program


The gbuild utility program provides a command line interface to build projects
created with the MULTI Builder (see Chapter 2, “The MULTI Builder”). This
utility can be used to integrate building your project into a script.

The syntax for this utility is as follows:


gbuild [options] [file]

where the optional file parameter can be:

• one or more project files (.gpj)


• one or more source or object files
• one or more executables
The gbuild options are:
-#
Displays status messages and commands but does not perform any actions.
This option is a shortcut for -info -commands.
-all
Rebuilds all files, even if they are up to date.
-allinfo
Displays the status messages that you would encounter if you rebuilt all files.
This option does not actually build your files or perform the actions described in
the messages.
This option is a shortcut for -all -info.
-autoconvert[=target]
Uses gbldconvert to convert a legacy .bld project to a .gpj project. The argument
allows you to specify a target or to override a target in the .bld project. If you do not
specify a target and the .bld project does not specify a target, a warning message
appears and gbldconvert uses the default target for your installation.
-clean
Deletes all previous output files without building.
-cleanfirst
Deletes all previous output files and then builds.

336 MULTI: Building Applications for Embedded ARM


The gbuild Utility Program

-commands
Displays commands before they are executed.
-convert=options
Passes options to gbldconvert. This option is only available if you also pass
-autoconvert.
-find filename
Displays the first build path to the file filename. The build path specifies a route
through the build structure to reach filename.
-findall filename
Displays all build paths to the file filename. The build paths specify routes through
the build structure to reach filename.
-help
Displays usage information for basic gbuild options.
-Help
Displays usage information for all gbuild options.
-ignore
Continues building, even if errors are encountered.
-info
Displays status messages but does not perform the actions described in the
messages.
-leave_output
Deletes only intermediate output files. This option is only available with -clean
or -cleanfirst.
-link
Forces linking. The default behavior is to re-link the executable only if any of its
components have changed.
-list
Lists all filenames. This option does not perform any build actions.
-list_depends
Lists known dependencies. You must build your project before passing this option.
This option does not perform any build actions.
-list_options
Lists options specified in the .gpj file. This option does not perform any build
actions.

Green Hills Software, Inc. 337


11. Utility Programs

-lockout
Uses a lock file to prevent simultaneous builds of the same program or library.
-lockoutretry
Waits to obtain a lock file.
-nested_commands
Displays full commands, including internal commands, before they are executed.
-nice
Executes the build with low priority.
-nolink
Generates object files but does not link them.
-noprogress
Suppresses progress messages.
-noreasons
Restricts the information given in progress messages.
For example, the message:

Compiling hello.c because hello.obj does not exist

is reduced to:

Compiling hello.c
-parallel[=n]
Specifies the number of processes that gbuild can run in parallel. The default
value for n is 2.
-path list_of_project_files filename
Specifies a build path of project (.gpj) files to follow when building the file filename.
The build path specifies a route through the build structure to reach filename. This
option is helpful when one file is utilized in multiple paths in your build tree, and you
want to specify which path to use for building.
-quiet
Prevents the utility from outputting any warning or error messages.
-skip=target
Skips the specified build target target when building. Here, target is the output
name associated with a build file.
-statistics
Displays comprehensive timing information.

338 MULTI: Building Applications for Embedded ARM


The gbuild Utility Program

-stderr=filename
Redirects stderr output (status and error messages) to filename.
-strict
Aborts gbuild if gbuild is unable to open a .gpj file in your build tree or if you
specify an unrecognized option on the command line. Without this option, these
problems only generate warning messages.
-time
Displays basic timing information.
-top filename.gpj
Specifies the top-level project file. By default, gbuild uses default.gpj in the
current directory as the top-level project file.
This option allows you to specify a path to a project file in another directory.
-unix
Displays directory slashes as /.
-within intermediate.gpj
Looks for build targets that are children of intermediate.gpj. This option is helpful
when one file is utilized in multiple paths in your build tree, and you want to specify
which path to use for building.

Using gbuild
The following examples take place in a directory, MyProjects/Project1, which
contains a top-level project file called default.gpj, and a number of levels of
subprojects.

Example 1. Building the Entire Project

To build the entire project, enter the following:


gbuild

If you do not pass any arguments, gbuild attempts to process default.gpj in


the current directory.

Example 2. Building a Subproject

To build a particular executable, you must specify either its project file or the
name of the executable itself.

Green Hills Software, Inc. 339


11. Utility Programs

For example, to build print_utility.gpj, a subproject that generates an


executable called print_utility, enter the following:
gbuild print_utility.gpj

or:
gbuild print_utility

Example 3. Building Individual Object Files

To build individual object files, you must specify either the initial source files
or the object files that they will be compiled into.

For example, to build the source files foo.c, bar.s, and baz.cxx into object
files, enter the following:
gbuild foo.c bar.s baz.cxx

or:
gbuild foo.o bar.o baz.o

Example 4. Finding Project Files

As your project grows in size, it might become difficult to find individual files,
particularly if you are using several levels of subprojects. To search for the
project file print_utility.gpj, enter the following:
gbuild -find print_utility.gpj

This command prints the position of print_utility.gpj in the project tree and the
path to it from the current directory. The output resembles the following:
default.gpj utilities.gpj utilities/print_utility/print_utility.gpj

In this case, print_utility.gpj is a subproject of utilities.gpj, which


is a subproject of default.gpj. The actual file can be found at
utilities/print_utility/print_utility.gpj.

Example 5. Running gbuild in a Project Subdirectory

Build options can be set at any level of the project file hierarchy. If you are
building a subproject, it is best to specify the top-level project file, particularly
if it is in a different directory.

340 MULTI: Building Applications for Embedded ARM


The gbuild Utility Program

For example, if you have navigated to utilities/print_utility/, and intend to


build print_utility.gpj, you should enter:
gbuild -top ../../default.gpj print_utility.gpj

By specifying ../../default.gpj as the top-level build file, you will ensure that
any build options set in the upper portions of the project structure are inherited
appropriately.

Green Hills Software, Inc. 341


11. Utility Programs

The gcolor Utility Program


The gcolor program takes text input, colors it using ANSI escape sequences,
and outputs it to stdout.

The syntax for this utility is as follows:


gcolor [options] [filenames]…

where filenames is an optional list of one or more whitespace-delimited input


filenames. If no files are specified, stdin is used.

The options for gcolor are as follows:


-f
Forces coloring even when output is redirected.
-help
Shows the list of gcolor options.
-r file
Reads the coloring rules from file. If this option is not passed, the default rules
contained within defaults/colors/build.rul are used.

The gcolor utility reads in a set of rules from a rules file to determine how
the input should be colored. If a line from the input cannot be identified as
conforming to any rule, then no coloring is performed.

There are five types that can be defined using rules that are recognized by
gcolor. Each one can output a specific foreground, background, and attribute.
Rule Default Coloring
info Foreground = Bold, Default
warnings Foreground = Bold, Magenta
errors Foreground = Bold, Red
before Foreground = Normal, Default
after Foreground = Bold, Default

Note The types before and after are used for coloring output from a
diff, for example when comparing changes in a cvs file.

342 MULTI: Building Applications for Embedded ARM


The gcolor Utility Program

Color Configuration Files


The color configuration for each of the types can be controlled by creating a
colors.ini file and saving it in your user configuration directory.

The syntax of a color configuration file is as follows:


[type]
attribute = value
foreground = value
background = value

where type and value are drawn from the following tables:

Colors Attributes
Types Background
Value Value Attribute
or Foreground
info -1 Default -1 Default
warnings 0 Black 0 None
errors 1 Red 1 Bold
before 2 Green 4 Underscore
after 3 Yellow 5 Blink
4 Blue 7 Reverse
5 Magenta 8 Concealed
6 Cyan
7 White

Comment lines must be prefixed with a ’#’ character as the first non-whitespace
character.

For example, to make info display in normal white text on a blue background,
you would use the following:
[info]
attribute = 0
foreground = 7
background = 4

Green Hills Software, Inc. 343


11. Utility Programs

Note If you do not specify coloring for a type, that type is colored in the default
manner. If you do not specify values for attribute, foreground, or
background, the default values are used.

Rules Files
The default set of rules is located in defaults/colors/build.rul. These
correspond to the output from the builder and any of the programs that it
invokes (the compiler, assembler, linker, etc.).

A second set of rules is supplied that correspond to standard cvs output. These
are located in defaults/color/cvs.rul. To use these rules, pass the -r cvs.rul
option.

Alternatively, you can specify your own set of rules to use with the -r file option.
You must create a rules file (file.rul) and save it in the following location:

• Site-wide rules should be saved in the config/colors directory.


• User-specific rules should be saved in your .ghs/colors directory.

Writing a Rules File


Rules are described using regular expressions. To add a rule to a rules file, first
you must give the type of the rule, followed by a colon, and then the desired
regular expression. The regular expression begins with the first non-whitespace
character following the colon.

For example, if you wanted to define directories in a standard UNIX-style


directory listing as info, you can use a simple rule such as:
info: ^d

There are two special rule types: none and previous.The none type causes
matching text to be printed without color. This is useful if you want to prevent
the coloring of specific lines that would otherwise match against a later rule.
For example, the rules:
none: ^foobar
info: ^foo

would color lines beginning with foo, except those beginning with foobar.

344 MULTI: Building Applications for Embedded ARM


The gcolor Utility Program

The previous type causes matching text to be colored the same as the
previous line of text. This is useful to ensure that continuation lines are colored
the same as their parents.

Comment lines must be prefixed with a ’#’ character as the first non-whitespace
character.

Example 1.

To color file foo, using your own set of rules contained within myrules.rul:
gcolor -r myrules.rul foo

To color builder output using the standard rules, enter (for sh shells):
gbuild default.gpj 2>&1 | gcolor

Note that the syntax for csh shells is different. If you are using a csh shell, enter:
gbuild default.gpj |& gcolor

To color CVS output, using the cvs.rul rules, enter (for sh shells):
cvs update 2>&1 | gcolor -r cvs.rul

For csh shells, enter:


cvs update |& gcolor -r cvs.rul

Note Regular expression support is provided by the PCRE library


package, which is open source software, written by Philip Hazel,
and copyrighted by the University of Cambridge, England. It
can be downloaded from theUniversity of Cambridge FTP server
(ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/).

Green Hills Software, Inc. 345


11. Utility Programs

The gcompare Utility Program


The gcompare utility program compares the code size of matching functions in
two input files and produces a report. Input files can be ASCII text files, object
files, object file libraries, or executable files. If an input file is a text file, it
consists of lines in the following format:
name1 number1
name2 number2
...

Each name/number pair is on its own line, separated by blanks or tabs.

If either input file is an object file, an object library file, or an executable file,
gcompare automatically runs gfunsize -gcompare -all (or another command
specified by the -x option) to produce an input text file to compare.

You can mix all input file types with no restrictions, including files for different
target CPU’s.

The gcompare utility reads both input text files. For any name that does not
exist in both files, gcompare prints a warning, unless -w is specified. For each
name that exists in both files, gcompare compares the old and new numbers.
If the new number is worse (larger is worse unless -i is specified), gcompare
writes a line to the output report file containing the name, new number, old
number, and percentage by which the new number is worse.

In the following example, the size of the function main has increased by
14% from 28 to 32:
main 32 28 -14%

The syntax for this utility is as follows:


gcompare [options] oldfile newfile

where oldfile is the base line input file and newfile is the input file for which
deviations (improvements or degradations) are reported.

346 MULTI: Building Applications for Embedded ARM


The gcompare Utility Program

The gcompare options are:


-1
Produces a report with comparisons sorted from worst to best. All comparisons
(including those in which newfile is no larger than oldfile) are shown. In addition, a
summary is provided at the top, showing the aggregate size comparison between
newfile and oldfile.
-a
Prints comparisons even when items exist in only one file.
-help
Displays information about all options.
-i
With -i, larger is better. Without -i, smaller is better.
-ignore name
Suppresses comparisons of symbol name.
-L
Formats the report in 132-column (landscape) mode. The default is 80-column
(portrait) mode.
-min=n
Suppresses comparisons where the difference between the compared items is
less than n percent.
-r
Produces a 2-column report with comparisons sorted both from worst to best
and from best to worst.
-v
Verbose mode, similar to -1, but with additional diagnostics.
-w
Suppresses warnings.
-width=n
Sets width (n) to any value greater than 32.
-x cmd
Specifies the command to execute on a non-ASCII input file. The default -x
command is:

-x "gfunsize -gcompare -all"

Green Hills Software, Inc. 347


11. Utility Programs

-z
Does not show cases where files are the same.

If the -r, -1, or -v options are used, all comparisons are shown, regardless of the
result of the comparison. With -r, two reports are shown side by side in two
columns. The left column is sorted from best to worst, and the right column
is sorted from worst to best.

Sample -r output:
linpack.188.O.a vs linpack.188.OS.a vs
linpack.188.OS.a linpack.188.O.a
WORSE by: 4172 3746 11% BETTER by: 3726 4172 10%
linpack.o:_daxpy 152 112 -36% linpack.o:_dscal 34 34 0%
linpack.o:_matgen 342 258 -33% linpack.o:_epslon 20 20 0%
linpack.o:_dgesl 294 240 -23% linpack.o:_idamax 72 72 0%
linpack.o:_dgefa 524 442 -19% linpack.o:_dmxpy 1516 1598 5%
linpack.o:_main 1136 1052 -8% linpack.o:_main 1052 1136 7%
linpack.o:_dmxpy 1598 1516 -5% linpack.o:_dgefa 442 524 16%
linpack.o:_idamax 72 72 0% linpack.o:_dgesl 240 294 18%
linpack.o:_epslon 20 20 0% linpack.o:_matgen 258 342 25%
linpack.o:_dscal 34 34 0% linpack.o:_daxpy 112 152 26%

This output can require many columns. Use the -L option for a 132-column
format. On UNIX, use the lpr -L command to print in landscape mode.

348 MULTI: Building Applications for Embedded ARM


The gdump Utility Program

The gdump Utility Program


The gdump utility program performs a similar function to the UNIX dump
program. It produces information about various types of files.

The syntax for this utility is as follows:


gdump [options] filename

where filename is the name of the input file, and options are drawn from one of
the following tables:

Debugging File Options


You can use the gdump utility to print symbolic debugging information from a
.dbo, .dba, .dlo, .dla, or .dnm file. The options for .dnm files are different than
those for the other debugging files.
-c
Performs internal consistency checks.
-C
Performs internal consistency checks, but ignores warnings.

Green Hills Software, Inc. 349


11. Utility Programs

-dinfo
Enables the display of particular information, where info is one of:
• a: raw auxiliary table (not .dnm)
• b: linkage stubs (.dnm only)
• c: static call information (not .dnm)
• d: .dlo file information (for .dnm), or the #define table (for other debugging
files)
• f: filename table
• h: the file header
• k: link labels (.dnm only)
• l: libraries (.dnm only)
• p: the procedure table
• s: sections (for .dnm), or the symbol table (for other debugging files)
• t: the typedef table
• u: .dnm updates (.dnm only)
• x: the section table (not .dnm)
-help
Displays information about all options.
-v
Performs internal consistency checks only. Does not display symbols.
-V
Same as -v, but ignores warnings.

ELF File Options


The gdump options for ELF format files are as follows:
-asm
Produces text sections as pure assembly language (see also the -ytext option).
-dwarf
Produces DWARF information only.
-full
Produces everything except section contents (see also the -ysec option).

350 MULTI: Building Applications for Embedded ARM


The gdump Utility Program

-help
Displays information about all options.
-load
Displays ELF header summary.
-map
Displays section summary.
-N
Only displays information as indicated by the -y options.
-print_checksum
Prints the checksum for each appropriate section. If -verify_checksum is
also specified, checksums are assumed to exist and -print_checksum prints
them for those sections where the checksum is found to be correct. If the
-verify_checksum option is not specified, checksums are assumed not to exist in
the section, so they are calculated using all bytes in the section.
-raw
If the -ysec option is specified, this produces text sections in hexadecimal format
instead of disassembly.
-sx
-nx
Enables or disables attempted shorter C++ demangling.
-sym
Uses symbol names instead of numbers in relocation output.
-v1
-v2
Specifies display of DWARF Version 1 or 2. The DWARF version in use is
detected automatically by gdump, and the appropriate option set automatically.
-verify_checksum
Instructs gdump that all non-empty, allocated sections have a 4-byte checksum
generated by the Green Hills linker. Compares the content of each section against
the existing checksum and, if they do not match, displays both.

Green Hills Software, Inc. 351


11. Utility Programs

-yinfo
-ninfo
Enables or disables the display of particular information, where info is one of:
• d: DWARF debugging information
• dynamic: dynamic linkage information
• f: DWARF call frame information
• g: global offset table
• h: ELF header information
• l: DWARF line number information
• m: DWARF macro information
• r: relocation information
• p: procedure linkage table
• s: symbol table information
• sec: section contents
• sh: section header information
• str: string table information
• text: text section contents

352 MULTI: Building Applications for Embedded ARM


The gdump Utility Program

COFF File Options


The gdump options for COFF files are as follows:
-ascii
Displays section contents in ASCII.
-aux
Displays auxiliary entries (in hex) with symbol entries.
-bigendian
-littleendian
Forces either a big or little endian target.
-brief
Displays symbols only.
-c
Displays string table.
-cpu= name
Sets CPU type (name).
-d num[+d num2]
Displays section num or sections from num to num2.
-f
Displays file header.
-full
Displays everything.
-g
Displays global symbols.
-h
Displays section headers.
-helpcoff
Displays all options.
-l
Displays line number information.
-map
Displays section summary.

Green Hills Software, Inc. 353


11. Utility Programs

-nx
Does not attempt to demangle C++ names.
-o
Displays optional header.
-r
Displays relocation information.
-raw
Produces section contents in raw form.
-s
Produces section contents.
-sx
Attempts shorter C++ demangling.
-sym
Uses symbol names instead of numbers in relocation output.
-t num[+t num2]
Displays symbol num or symbols from num to num2.
-ysec
-ytext
Enables the display of section contents and/or text section contents.

354 MULTI: Building Applications for Embedded ARM


The gdump Utility Program

BSD File Options


The gdump options for BSD format files are as follows:
-c
Displays section contents.
-h
Displays file header.
-help
Displays information about all options.
-r
Displays relocation entries.
-s
Displays symbol table.

Green Hills Software, Inc. 355


11. Utility Programs

The gfile Utility Program


The gfile utility program performs a similar function to the UNIX file
program. It displays the file type of each filename argument, and can also
display additional information. For example, if a machine supports both
big endian and little endian data ordering, then for an object file, object file
library, or executable file, gfile displays the machine type and byte order. For
unrecognized object files, gfile prints unknown machine type. In general,
gfile handles BSD, ELF, and some COFF formats.

The syntax for this utility is as follows:


gfile filenames…

where filenames is a list of one or more filenames separated by whitespace.

Example 1.

If the current host system is a SPARC workstation running the Solaris 2.x
operating system (which uses the ELF format for executable files), you will
see the following behavior:
gfile /bin/od
/bin/od: SPARC big endian executable ELF

356 MULTI: Building Applications for Embedded ARM


The gfunsize Utility Program

The gfunsize Utility Program


The gfunsize utility program displays the code size of one or more named
functions in an object file, library file, or executable. The code size of ELF
functions is part of the ELF symbol information. For BSD or COFF, the size of
a function is calculated as the difference between its address and the address
of the next function.

The syntax for this utility is as follows:


gfunsize [options] filename

where filename is the file to examine, and options are drawn from the following
table:
-addr
Displays the address of each function.
-all
Displays the code sizes of all functions. This is the default.
-file
Displays the filename before each function.
-func=name
Displays the code sizes of the specified function or functions.
-gcompare
Displays the output in a format suitable for input to the gcompare utility program.
-help
Displays information about all options.
-hex
Displays function code sizes and addresses in hexadecimal.
-nounderscores
Removes leading underscores from function names.
-sect=name
Displays functions in section name.
-sectnum=n
Displays functions in section number n.
-w
Suppresses warnings.

Green Hills Software, Inc. 357


11. Utility Programs

The ghexfile Utility Program


The ghexfile utility program converts an executable file to an Intel or Tektronix
hexadecimal output file. Little endian Intel HEX86, Intel HEX386 and
Tektronix extended tekhex formats are supported. HEX86 is the default output.

The syntax for this utility is as follows:


ghexfile [options] filename

where filename is the executable to convert, and options are drawn from the
following table:
-auto
Automatically determines byte order and BCS/COFF based on header information.
This is the default.
-B
-L
Specifies that the input object file is big or little endian.
-BCS
-noBCS (default)
Specifies that the input object file is either an 88K BCS variant of COFF or
standard COFF.
-bytes n
Sets the maximum count of unpaired data bytes/data record (minimum 4,
maximum 28). The default is 28.
-e n
Sets the entry point in the hexadecimal file to the specified address n.
-end address
Specifies the end address of the data you want to output to the hexadecimal file.
-fillx n1 n2 v
Fills x-byte value v from addresses n1 to n2 (where x is 1,2, or 4).
-h
Does not produce an end mark of (empty) symbol table.
-help
Lists these ghexfile options.

358 MULTI: Building Applications for Embedded ARM


The ghexfile Utility Program

-hex86 (default)
-hex386
-tekhex
Specifies output of Intel HEX86, HEX386, or extended Tektronix hexadecimal
format.
-interval n[:m]
Restricts output to data bytes at interval n, where n is a value between 2 and 8,
inclusive. The argument m is the number of bytes (the default is 1) included in
each interval. For example, ghexfile -interval 2 outputs every other byte.
-o filename
Sets output filename. The default is stdout.
-padx n1 n2 v
Pads x-byte holes between hexadecimal data records from address n1 to n2 with
value v. x may be 1, 2, or 4.
-romaddr address
Sets starting address in ROM where you want to place data.
-skip sn
Specifies a section (sn) that you do not want to output to the Intel hexadecimal file.
-start address
Specifies the start address of the data you want to output to the Intel hexadecimal
file.

Address Space
The Intel HEX86 hexadecimal format can handle memory addresses only in
the range of 0x00000000 to 0x0010ffef. When this address range is
exceeded, ghexfile displays the message: an address is too big.

The Intel HEX386 format supports the full 32-bit address space. A linear
address record containing the upper 16-bits of the address was added to the
HEX86 format to form the HEX386 format.

The Tektronix extended tekhex format supports the full 32-bit address space.

Green Hills Software, Inc. 359


11. Utility Programs

Data Splitting
In some hardware implementations, the width of the bus differs from the width
of the PROM’s. Depending on how the bus and PROM’s are connected, it
might be necessary to store even bytes in one PROM and odd bytes in another
PROM. The technique of dividing the data into even and odd bytes, or other
ways, is called data splitting.

Data splitting can be done in ghexfile using a few options. The -start option
specifies the starting address of the data in the object input file that you want to
output to the Intel hexadecimal output file. The -end option specifies the last
address of data in the object input file that you want to output. The -interval
option specifies the distance between bytes in the input file that you want to
output. A value of 2 for -interval outputs every other byte. Sometimes it is
necessary to relocate the data to address zero in the Intel hexadecimal output
file for programming PROM. The -romaddr option specifies the start address
of the data bytes in the Intel hexadecimal output file.

The following examples use an executable file named prog1, which has the
following standard sections:
1: .text, address: 0x1000, size: 0x100
2: .data, address: 0x2000, size: 0x200
3: .bss, address: 0x3000, size: 0x200 (No Load Section)

Example 1.
ghexfile -start 0x1000 -end 0x1080 prog1 -o prog1.hex

ghexfile extracts the data in the input file prog1 starting at address 0x1000
and ending at address 0x1080, converts the extracted data to Intel hexadecimal
format, and writes the output to prog1.hex.

Example 2.
ghexfile -start 0x1000 -end 0x1080 -romaddr 0 prog1 -o prog1.hex

Same as the previous example, but the data is relocated to start at address zero.

Example 3.
ghexfile -start 0x1000 -end 0x1080 -romaddr 0 -interval 2 prog1

ghexfile extracts the even data bytes in the input file prog1 starting at address
0x1000 and ending at address 0x1080, relocates the data to start at address

360 MULTI: Building Applications for Embedded ARM


The ghexfile Utility Program

zero, converts the extracted data to Intel hexadecimal format, and writes the
results to the standard output.

Example 4.
ghexfile -start 0x1001 -end 0x1080 -romaddr 0 -interval 2 prog1

Same as the previous example, except the odd data bytes, starting at address
0x1001 and ending at address 0x107F, are extracted.

Example 5.
ghexfile -start 0x1002 -end 0x107F -romaddr 0 -interval 4:2 prog1

ghexfile extracts 2 out of every 4 bytes of data in the input file prog1 starting
at address 0x1002 and ending at address 0x107F, relocates the data to start
at address zero, converts the extracted data to Intel hexadecimal format, and
writes the results to the standard output.

Green Hills Software, Inc. 361


11. Utility Programs

The ghide Utility Program


The ghide utility program modifies the symbol table of an existing object file
by converting all global symbols to local symbols, except for a specified list
of global symbols that remain global. The object file can be either relocatable
or not relocatable, but it must contain a symbol table; otherwise ghide has
no effect.

The syntax for this utility is as follows:


ghide [options] retain_list object_file

where retain_list is the name of an input file containing symbol names,


separated by whitespace, that are to be retained (not hidden), and object_file is
the name of the existing object file to be modified by ghide.

The ghide options are:


-help
Displays information about ghide.

Example 1.

Suppose an embedded application system consists of a kernel and several


application tasks, all developed independently. Some global functions in the
kernel are for kernel use only. Other global kernel functions can be called from
the application tasks.

First, the kernel is linked into a single file using the linker’s -r option to retain
relocation information. Then, ghide is run on the kernel using a retain list
of the functions that should remain visible to the application tasks. Finally,
the application tasks are linked with the kernel file, producing a complete
executable file.

The use of ghide ensures that only the desired global symbols in the kernel are
visible to the application tasks. This also prevents duplicate symbol errors in
the linker if any application might have a global symbol with the same name
as an internal kernel-only function.

362 MULTI: Building Applications for Embedded ARM


The gmemfile Utility Program

The gmemfile Utility Program


The gmemfile utility program creates a binary memory-image of a fully linked
executable. This memory image is suitable for downloading to target memory.

The syntax for this utility is as follows:


gmemfile [options] executable

where executable is the name of the executable from which to generate the
memory image, and options are drawn from the following table:
-byte b [of] n
By default, gmemfile outputs all data bytes to the memory image. This option
looks at data in the input file in chunks the size of the bus width (n) and writes
only the specified data bytes (b) within each data chunk in the input data to the
output file. It can be used to separate odd or even data bytes or words for burning
PROMs when the size of the PROMs differs from the size of the bus. It is also
used to reverse the order of the data bytes for a shared bus environment.
The width, n, represents the width of the data bus. The maximum width allowed is
32 that represents a 256 bit bus. The bytes, b, within the specified bus width n are
numbered 1 through n where 1 is the first byte and n is the last byte.
The bytes, b, can be specified in one of the following ways:
• as a single byte (for example, -byte 1 of 4). In this example, for each 4
byte chunk of input data, only byte 1 is written to the output file.
• as a range of bytes (for example, -byte 1-4 of 8). In this example, for
each 8 byte chuck of data in the input file, bytes 1, 2, 3 and 4 are written
to the output file.
• as a list of bytes (for example, -byte 4,3,2,1 of 4). In this example, for
each 4 byte chunk of data, the bytes are reversed and written to the output file.
-end address
Specifies the highest address of data to be placed in the memory image. If
address is higher than the highest address of the executable, the bytes between
them are padded with zeros unless -fillx is passed. You can specify a section
name instead of an address, and the highest address of that section is used.

Green Hills Software, Inc. 363


11. Utility Programs

-fillx start end value


Fills holes before, after, or between sections of the executable in the specified
range start to end with the specified value. The same byte order (big or little
endian) of the input file is applied to the fill value.
-fill1 fills holes with a single byte of data.
-fill2 fills holes with two bytes of data, aligning the fill bytes on a 2-byte boundary.
-fill4 fills holes with four bytes of data, aligning the fill bytes on a 4-byte boundary.
If the start and/or end parameters are outside the address range of the data in
the executable, the fill value is applied to the gaps at the beginning and/or end
of the memory image. Section names can be specified instead of addresses for
the start and end parameters. The start address of a section is used for the start
parameter. The end address of a section is used for the end parameter.
When multiple -fill options cover the same area, -fill4, -fill2, -fill1 options are
processed in that order. The -start and -end options take precedence over the
-fill options and can be used to control the bounds of the memory image.
-help
Displays a summary of the command line syntax and options for using gmemfile.
-hole size
Overrides the default checking for holes between sections.
By default, a warning message is displayed if there is a hole larger than 4096
bytes; no error is generated for any size hole.
This option causes an error to be emitted if there is a hole larger than size bytes.
-import start filename
Copies the binary data from the specified filename to the specified start address in
the memory image. Use the -import option to bring in input from a previous run of
gmemfile or from some other utility that produces a memory image.
If you specify a section name for the start parameter, the binary data is copied to
the next byte after the last address in the specified section.
-map filename
Creates a detailed map file. The map file contains the command input, a list of all
sections from the input executable file, a list of -import data, a memory map of the
output memory file, and a summary of the memory image.
-o filename
Specifies the name of the memory image file to be output. The default is the name
of the executable with the extension, if any, replaced by.bin. If there is no input
file, the default name of the output file is a.bin.

364 MULTI: Building Applications for Embedded ARM


The gmemfile Utility Program

-size value
Limits the memory image to the size specified in the value parameter. This is an
alternative to using the -end option. An error is displayed if both -size and -end
appear in the command input.
By default, all data from the executable is written to the memory image.
-skip sname
Excludes data in the specified section sname of the executable from the memory
image.
-start address
Specifies the address in the executable at which to begin copying data to the
memory image. A section name can be specified instead of an address, and then
the start address is the first address in the section. If the start address is lower
than the lowest address in the executable, the bytes between the start address
and the executable are padded with zeros or with a fill value if one was specified
with -fill1, -fill2, or -fill4.

Data Splitting
In some hardware implementations, the width of the data bus differs from the
width of the PROMs. Depending on how the bus and PROMs are connected, it
might be necessary to store low bytes, or words, in one PROM and high bytes,
or words, in another PROM. The gmemfile utility supports such data splitting
through the -byte option (see examples 6 and 7 below).

The following examples use for illustration a program file prog1 that contains
the following sections:
Name Start Address End Address Size
.text 0x1000 0x10ff 0x100
.rodata 0x1100 0x12ff 0x200
.rdata 0x1300 0x15ff 0x300
.data 0x2000 0x22ff 0x300
.bss 0x2300 0x24ff 0x200

The .text section contains all of the code in the program that is executed
from ROM. The .rodata section contains read-only data that is accessed in
ROM. The .rdata section contains initialized data that is stored in ROM
and copied to .data in RAM at program startup. The program references

Green Hills Software, Inc. 365


11. Utility Programs

initialized data at the addresses in section .data in RAM. The .bss section
contains uninitialized data. It is set to zero at program startup.

Example 1.
gmemfile prog1.elf

In this example, because no options have been specified, the output file is
called prog1.bin, the first byte in the memory image is the first byte of section
.text, and its last byte is the last byte of .rdata (which is the last section
that contains initialized data).

Example 2.
gmemfile -start 0 prog1.elf -o prog1.mem

In this example, the option -start 0 sets the starting address at which
gmemfile begins reading the executable to 0. Because the first section of the
executable is .text, which begins at 0x1000, the first 0x1000 bytes of the
memory image are set to zero. The utility continues reading and outputting
the data from sections .text, .rodata, and .rdata. The last byte in
the memory image is the last byte of section .rdata, which is at file offset
0x15ff in the memory image and at address 0x15ff in the executable.

The option -o prog1.mem sets the name of the memory image to


prog1.mem.

Example 3.
gmemfile prog1.elf -fill2 0 .text 0x3e7f -o prog1.mem

In this example, the -fill2 option specifies that any holes between 0 and the
end of section .text be filled with the value 0x3e7f. The initialized data
in .text is not overwritten by -fill2. The memory image produced in
this example has the same start (0) and end (0x15ff) addresses as that in the
previous example (the -start 0 option is not needed, since -fill2 starts
at zero).

Example 4.
gmemfile prog1.elf -start 0 -end 0x1fff -o prog1.mem

In this example, the PROM is 0x2000 bytes wide and the PROM burner
requires that all bytes in the PROM be filled. The prog1 executable has a

366 MULTI: Building Applications for Embedded ARM


The gmemfile Utility Program

hole in front of its first section (from 0x0 to 0xfff) and after the end of its
initialized data (from 0x1600 to 0x1fff).

The -start option sets the start address of the memory image to zero and
-end sets its end address to 0x1fff. Because no -fill options have been
used, the holes 0x0 to 0xfff and 0x1600 to 0x1fff are filled with zeros.

Example 5.
gmemfile prog1.elf -start 0 -size 0x2000 -o prog1.mem

In this example, the memory image produced is identical to that of the previous
example. Instead of specifying an end address with -end, a size is specified
with -size 0x2000.

Example 6.
gmemfile -byte 1 of 2 prog1.elf -start .text -size 0x100 -o prog1.low.mem
gmemfile -byte 2 of 2 prog1.elf -start .text -size 0x100 -o prog1.high.mem

In this example it is necessary to separate low and high bytes of data into
separate PROMs, each of which is 0x100 bytes wide. The gmemfile utility
is run twice, using the -byte option to select alternate bytes for each of the
output files.

In the first command line, the option -byte 1 of 2 outputs the first byte of
data in each two byte interval. The -start option sets gmemfile to reading
the executable at 0x1000 (the first byte of .text). The -size option sets
the size of the memory image to 0x100 bytes.

The first byte of data in the memory image is the first byte of data in section
.text. The second byte of data in the memory image is the third byte of data
in section .text. The last byte of data in the memory image at file offset
0xff is from the .rodata section in the executable at address 0x11fe
(0x200 bytes above 0x1000).

If the bytes in the .text section of the executable consisted of:


0102030405060708090a0b0c0d0e0f10....

The following bytes would be output to the first memory image file:
01030507090b0d0f....

Green Hills Software, Inc. 367


11. Utility Programs

The second command line takes the second byte in each 2-byte interval starting
at the address of .text (0x1000). The first byte of data in the memory image
is the second byte of data in section .text. The second byte of data in the
memory image is the fourth byte of data in section .text. The last byte of
data in the memory image is the byte in section .rodata at address 0x11ff.

If the bytes in the .text section of the executable consisted of:


0102030405060708090a0b0c0d0e0f10....

The following bytes would be in the second memory image file:


020406080a0c0e10...

Example 7.
gmemfile -byte 1,2 of 4 prog1.elf -start .text -size 0x100 -o prog1.low.mem
gmemfile -byte 3,4 of 4 prog1.elf -start .text -size 0x100 -o prog1.high.mem

This example is similar to the previous example, except that the low half and
high half of each 4-byte interval is separated. The first command takes the
low 2-byte half of each 4-byte interval of data in the executable starting at
the address of .text (-x1000) until there are 0x100 bytes of data in the
memory image.

If the bytes in the .text section of the executable consisted of:


0102030405060708090a0b0c0d0e0f10....

The following bytes would be in the first memory image file:


01020506090a0d0e....

The second command takes the high 2-byte half of each 4-byte interval of data
in the executable starting at the address of .text (-x1000) until there are
0x100 bytes of data in the memory image.

If the bytes in the .text section of the executable consisted of:


0102030405060708090a0b0c0d0e0f10....

The following bytes would be in the second memory image file:


030407080b0c0f10....

368 MULTI: Building Applications for Embedded ARM


The gmemfile Utility Program

Example 8.
gmemfile prog1.elf -start .rdata -end .rdata -byte 4,3,2,1
of 4 -o reverse.bin
gmemfile -import .text reverse.bin -skip .rdata -o prog1.bin

In this example, it is necessary to change the data in the .rdata section from
big endian to little endian byte ordering. The first command uses the option
-byte 4,3,2,1 of 4 to take data from section .rdata, reverse the byte
order, and write the resultant data to the memory image file reverse.bin.

The second command takes the data from file reverse.bin and loads it after
the .text section. The -import .text reverse.bin option loads
reverse.bin after the end of the .text section (which is the start address of
.rdata). The -skip .rdata option discards any data in section .rdata.

Green Hills Software, Inc. 369


11. Utility Programs

The gnm Utility Program


The gnm utility program performs a similar function to the UNIX nm program.
It displays the symbol table of an object file, object library file, or executable
file created by Green Hills development tools.

The syntax for this utility is as follows:


gnm [options] filenames…

where filenames is one or more whitespace-delimited input files, and options


is drawn from the general options table and the appropriate object format
options table:

General Options
The general gnm options are as follows:
-help
Displays general options and ELF-specific options.
-helpbsd
Displays BSD-specific options.
-helpcoff
Displays COFF-specific options.
-helpelf
Displays ELF-specific options.
-output file
Writes the output from gnm to file.
-V
Prints the gnm version.

ELF File Options


The gnm options for ELF format files are as follows:
-a
Prints special symbols that are normally suppressed.

370 MULTI: Building Applications for Embedded ARM


The gnm Utility Program

-D
Prints symbols from the dynamic symbol table.
-h
Does not print headers.
-l
Prints an asterisk (*) after symbol type for WEAK symbols. This is for -p mode
only.
-n
Sorts output by symbol name.
-o
Prints value and size of symbols in octal.
-p
Uses 3-column output format.
-prefixed_msgs
-no_prefixed_msgs
Enables or disables the printing of WARNING and ERROR before messages.
-r
Prefixes filename to each line of output.
-u
Prints undefined symbols only.
-v
Sorts output by symbol value.
-x
Prints value and size of symbols in hexadecimal.

BSD File Options


The gnm options for BSD format files are as follows:
-a
Prints all symbols, including debugging information. Not available with the -s
option.
-g
Prints only external symbols.

Green Hills Software, Inc. 371


11. Utility Programs

-n
Sorts symbols by value.
-o
Prefixes lines with object or archive element name.
-p
Does not sort symbols.
-r
Sorts in reverse order.
-s
Sorts external symbols by size.
-u
Prints only undefined symbols.

Output Formats
By default, gnm produces output similar to the following excerpt (indexes 3
through 11 are omitted for brevity):
[Index] Value Size Type Bind Other Shndx Name

[1] | 0| 0|FILE |LOCL |0 |ABS |hi.c


[2] | 0| 0|SECT |LOCL |0 |.text |.text
[12] | 0| 52|FUNC |GLOB |0 |.text |main
[13] | 0| 0|NOTY |GLOB |0 |UNDEF |printf

Column Meaning
Index Position of symbol in the symbol table.
Value The value or address of the symbol.
Size Size of the symbol (for example, a 4-byte integer symbol has a size of 4).
Type One of the following:
• NOTY: Symbol without type.
• FILE: Filename symbol.
• SECT: Section name symbol.
• OBJT: Data symbol.
• FUNC: Code symbol.

372 MULTI: Building Applications for Embedded ARM


The gnm Utility Program

Column Meaning
Bind One of the following:
• LOCL: Local symbol (for example, C/C++ static).
• GLOB: Global symbol.
• WEAK: Weak global symbol (if undefined, the symbol’s value resolves
to zero).
Other Reserved field, generally zero.
Shndx The name of the section where the symbol is defined. For example:
• .text: Code defined in the .text section.
• .data: Data defined in the .data section.
• ABS: No section (for example, a filename symbol).
• COMMON: Common variable whose section is not yet determined.
Name Symbol name.

The -p option enables an alternate, easily parsable, 3-column format, which


provides backward compatibility with tools that can read only this format:
0000000000 F hi.c
0000000000 S .text
0000000000 T main
0000000000 U printf

The first column is the value or address of the symbol. The second column is its
type (as shown in the following table), and the third is the symbol name. Note
that this format cannot fully describe all sections and storage classes.
Type Meaning
A External absolute
a Local absolute
B External zeroed data
b Local zeroed data
C Common variable (same as B except not yet assigned to a section)
D External initialized data
d Local initialized data
F Filename
I Local thread local storage
L External thread local storage

Green Hills Software, Inc. 373


11. Utility Programs

Type Meaning
N Informational symbol
S Section name
T External text
t Local text
U External undefined

374 MULTI: Building Applications for Embedded ARM


The gpjmodify Utility Program

The gpjmodify Utility Program


The gpjmodify utility program allows you to automate editing of new-style .gpj
project files. General editing should be performed through the MULTI Builder
GUI (see Chapter 2, “The MULTI Builder”), or via a text editor.

Note You can edit only one file at a time using gpjmodify.

Editing Existing .gpj Files


The syntax for editing existing .gpj files is as follows:
gpjmodify file.gpj [[sub.gpj…] | [@path-to-child]] [options] action

where:

• file.gpj is a top-level project file. This is either the file to be edited or the
ultimate parent of sub.gpj.
• The optional sub.gpj… is an immediate child subproject of file.gpj or a
chain of subprojects (the last of which will be edited). Alternately, you can
specify @path-to-sub.gpj, an absolute path to a subproject at any point in
the project tree.
• options are drawn from the following table:
-f
Forces the edit, even if errors would result.
-help
Displays help information.
-multidir directory
Specifies an alternate MULTI installation directory.
-o output.gpj
Writes the edited file to output.gpj. By default, edits are written to the existing file.
-quiet
Suppresses warning messages.

• action is drawn from the following table:

Green Hills Software, Inc. 375


11. Utility Programs

-add_after dependent [-filetype type] files


Inserts a list of files in the list of dependents directly after the existing dependent
file.
-add_before dependent [-filetype type] files
Inserts a list of files in the list of dependents directly before the existing dependent
file.
-add_to_back [-filetype type] files
Inserts a list of files at the end of the file’s list of dependents.
-add_to_front [-filetype type] files
Inserts a list of files at the beginning of the file’s list of dependents.
-remove files
Deletes a list of existing dependent files
-replace_with existing_file [-filetype type] new_file
Replaces the references to existing_file with references to new_file.
-set options
Inserts a list of build options.
-unset options
Deletes a list of build options.

Note Several of these actions take an optional -filetype type parameter. You
should pass this only if the files you are adding have non-standard extensions
that the Builder is unable to recognize.

Where actions accept a list of files or options, each item in the list must be
separated with a space.

Creating a New .gpj File


The syntax for creating a new .gpj file is as follows:
gpjmodify file.gpj -create type -target target_file [options]

where file.gpj is the name of the file to be created, type is one of program,
subproject, or nobuild, and target_file specifies the project’s target. The
options are drawn from the following table:
-top
Specifies that the new file will be a top-level project file.

376 MULTI: Building Applications for Embedded ARM


The gpjmodify Utility Program

-multidir directory
Specifies an alternate MULTI installation directory.

Generating a makefile
The gpjmodify utility can generate a rudimentary makefile from a .gpj file.
This makefile can be used as a guide to help you integrate the Green Hills tools
with an existing makefile structure.

The syntax for generating a makefile is as follows:


gpjmodify file.gpj -generate_makefile [options]

where file.gpj is the .gpj file to be converted, and options are drawn from the
following table:
-multidir directory
Specifies an alternate MULTI installation directory.
-quiet
Suppresses warning messages.

Green Hills Software, Inc. 377


11. Utility Programs

The grun Utility Program


The grun utility program downloads and remotely executes a program using
a debug server to control the execution environment. While grun is running,
its standard input and output are copied to and from the executing program,
redirecting the program’s I/O to your terminal.

The syntax for this utility is as follows (note the use of the double dash “--”):
grun [options] [dbserv_cmd] -- program_cmd

where:

• dbserv_cmd is the name of a debug server and any arguments


• program_cmd is the name of the executable and any arguments
• options are drawn from the following table:
-commands=file
Sends the commands specified in file to the simulator.
-data address
Sets the starting address of the program’s data.
-detach
Instructs grun to terminate immediately after downloading the program to the
target system. The grun program usually communicates with the debug server
before exiting, which can halt an executing target program. This option can
be used with various target monitors or boot ROM’s when the program being
downloaded takes control of the target system and terminates the target monitor.
If you do not specify the -detach option, grun waits either for the program to
complete, or for up to 10 minutes with no host I/O requests from the program.
If you interrupt grun, or if the program exceeds the 10 minute time out, grun
terminates the program and exits.
-download
Causes the program to be downloaded, but does not start it running.
-log[=file]
Outputs a log of the Debugger and debug server communications to stdout, or
to file, if specified.
-nsp
Uses new server protocol.

378 MULTI: Building Applications for Embedded ARM


The grun Utility Program

-pro
Same as the -profile option, but also translates the profiling data.
-profile
Executes the target program with profiling enabled.
-stack address
Sets the initial value for the program’s stack pointer to address.
-subcpu n
Specifies n as the “subcpu” number.
-text address
Sets the starting address of the program’s text (code).
-timeout seconds
Sets the number of seconds to wait before assuming the target has hung. The
default is 600 seconds.

Green Hills Software, Inc. 379


11. Utility Programs

The gsize Utility Program


The gsize utility program performs a similar function to the UNIX size program.
It analyzes object files, object library files, or executable files and, for each file,
displays the size of each section in bytes. If more than one file is named, or if
an object library is named, gsize prints the name of the file with the section
name and totals for each section.

The syntax for this utility is as follows:


gsize [options] filename

where filename is the name of the input BSD or ELF object file, object file
library, or executable file.

The options for gsize are as follows.


-all
Causes empty sections and non-allocated sections to be displayed.
-commons
Displays information about common (.bss) symbols (ELF only).
-help
Displays information about all options.
-ram
Displays a sum total of RAM size for the input files. File segments are considered
to be RAM only if they are writable and not executable.
This option must be passed alone (or in conjunction with -rom), and must precede
any input files on the command line. For example:

> gsize -ram kernel


RAM_Size: 3904

380 MULTI: Building Applications for Embedded ARM


The gsize Utility Program

-rom
Displays a sum total of ROM size for the input files. File segments are considered
to be ROM only if they contain initialized data or program code.
This option must be passed alone (or in conjunction with -ram), and must precede
any input files on the command line. For example:

> gsize -rom kernel


ROM_Size: 37818

or:

> gsize -rom -ram kernel


RAM_Size: 3904
ROM_Size: 37818
-table
Displays output in table format.
-totals— default
-nototals
Displays or suppresses the summary information that is printed if more than one
file is processed.

Green Hills Software, Inc. 381


11. Utility Programs

The gsrec Utility Program


The gsrec utility program converts an executable file into a Motorola S-Record
format file. Motorola S-Records are an ASCII representation of binary data.
Many simulators, In-Circuit Emulators (ICEs), PROM programmers, and
debuggers use S-Records as a program download format.

The syntax for this utility is as follows:


gsrec [options] filename

where filename is the name of the input executable file to be converted to


S-Records.

The gsrec options are:


-auto
Determines byte order from the file header. This is the default.
-B
-L
Specifies a big or little endian input file.
-BCS
-noBCS (default)
Specifies the 88K BCS variant of COFF, or standard COFF.
-bytes n
Sets the maximum count of unpaired data bytes/records (minimum 4, maximum
28). The default is 28.
-e addr
Sets entry point in the termination record to given address.
-end address
Sets end address in object file.
-eol char
Specifies the character used to terminate each record, where char is one of:
• cr: a \r character.
• crlf: a \r\n combination. This is the default in Windows.
• lf: a \n character. This is the default in UNIX.

382 MULTI: Building Applications for Embedded ARM


The gsrec Utility Program

-fillx n1 n2 v
Fills memory from address n1 to address n2 with the x-byte value v (where x
is 1, 2, or 4).
-help
Displays information about all options.
-interval n[:m]
Places only those data bytes from the input file that occur within the specified
interval in the output file. Values for n are 1 through 8. The default is 1, indicating
that every byte will be output. The m value specifies the number of output bytes
for each interval. For example, 4:2 outputs 2 consecutive bytes out of every 4.
This option requires that you set the -start and -romaddr options.
-noS5
Suppresses production of an S5 block count record.
-o filename
Specifies the output filename. By default, output is sent to standard output.
-padx n1 n2 v
Pads x-byte holes between hexadecimal data records from address n1 to n2 with
value v. x may be 1, 2, or 4.
-prefixed_msgs
-no_prefixed_msgs
Enables or disables the printing of WARNING and ERROR before messages.
-romaddr addr
Sets start address in ROM to place data. The default is the same address as in
the input file.
-Stype
Specifies the type of S-Record to be produced, where type is one of the following:
• 1: S1 data records (16-bit addresses)
• 2: S2 data records (24-bit addresses)
• 3 (default): S3 data records (32-bit addresses)
• 5: an S5 record with a count of data records (16-bit addresses)
• 5old: an old format S5 record (16-bit addresses)
• 7: an S7 end record (32-bit entry point)
• 8: an S8 end record (24-bit entry point)
• 9: an S9 end record (16-bit entry point)
The default is to produce S3 data records, an S5 record, and an S7 end record.

Green Hills Software, Inc. 383


11. Utility Programs

-skip s
Does not output data for section s.
-start address
Specifies starting address in object file for output.

S-Record Output Format


An S-Record file contains ASCII text that can be displayed or edited. There are
ten types of S-Records, numbered S0 to S9, including the following:

• An S0 header record that identifies the program.


• Several data records that represent the binary data in the program.
• An S5 data count record that contains the count of data records in the
S-Record file.
• A termination record that contains the address to begin program execution.
Not all S-Record reader programs behave the same way. Some programs require
certain types of data records. Some target environments do not accept S5 data
count records, and some require certain types of termination records. The gsrec
utility provides options that handle many of these cases.

Data and Termination Records


A data record contains the address where data is loaded, followed by the data
itself. The three types of data records, S1, S2, and S3, differ in load address
size, as indicated in the previous table.

By default, an S5 data count record is emitted. If your S-Record loader does


not handle S5 records, use the option -noS5 to avoid outputting an S5 data
count record.

By default, the S5 data record contains a 4-byte address. Some old S-Record
readers expect an S5 record to contain a 2-byte address. In this case, use the
-S5old option.

A termination record contains the entry point (the address where program
execution begins). There are three types of termination records, S7, S8, and
S9, as indicated in the previous table.

384 MULTI: Building Applications for Embedded ARM


The gsrec Utility Program

Some S-Record readers accept data records up to a specified length. Use the
option -bytes size to set the maximum data record length.

If you forget to specify the entry point address when linking, you can use -e
address to set the entry point to the given address.

Data Splitting
In some hardware implementations, the width of the bus differs from the width
of the PROMs. Depending on how the bus and PROM’s are connected, it might
be necessary to store even bytes in one PROM and odd bytes in another PROM.
Data splitting is a technique of dividing the data into even and odd bytes, or in
other ways.

gsrec can perform data splitting. The -start option specifies the starting address
of the data in the object input file to output to the S-Record output file. The -end
option specifies the last address of data in the object input file to output. The
-interval option specifies the distance between bytes in the input file to output.
A value of 2 for -interval outputs every other byte. Sometimes it is necessary
to relocate the data to address zero in the S-Record output file for programming
PROMs. The -romaddr option specifies the start address of the data bytes in
the S-Record output file. The last two succeeding examples separate even and
odd bytes into two different S-Record files.

The following examples use a program file prog1 that contains the following
sections:
1: .text, address: 0x1000, size: 0x100
2: .data, address: 0x2000, size: 0x200
3: .bss, address: 0x3000, size: 0x200 (No Load Section)
4: .data2, address: 0x4000, size: 0x200

Example 1.
gsrec prog1

The gsrec program translates the data in the input file prog1 and writes the
S-Records to the standard output. Because the contents of section .bss are not
loaded, no S-Records are output for its data.

Example 2.
gsrec -S1 -S9 prog1 -o prog1.run

Green Hills Software, Inc. 385


11. Utility Programs

The gsrec program translates the data in the input file prog1 and writes the
S-Records to the specified output file prog1.run. Data are output as S1 records
that have a 16-bit address space. The start address is output as an S9 record
that has a 16-bit address space.

Example 3.
gsrec -start 0x1000 -end 0x1080 prog1 -o prog1.run

The gsrec program translates the data in the input file prog1 starting at address
0x1000 and ending at address 0x1080 to the output file prog1.run.

Example 4.
gsrec -start 0x1000 -end 0x1080 -romaddr 0 prog1 -o prog1.run

The gsrec program translates the data in the input file prog1 starting at address
0x1000 and ending at address 0x1080, relocates the data starting at address
zero, and copies the resulting S-Records to the output file prog1.run.

Example 5.
gsrec -start 0x1000 -end 0x1080 -romaddr 0 -interval 2 prog1

The gsrec program translates the even data bytes in the input file prog1 starting
at address 0x1000 and ending at address 0x1080, relocates the data to start at
address zero, and copies the resulting S-Records to the standard output.

Example 6.
gsrec -start 0x1001 -end 0x107F -romaddr 0 -interval 2 prog1

The gsrec program translates the odd data bytes in the input file prog1 starting
at address 0x1001 and ending at address 0x107F, relocates the data to start at
address zero, and copies the resulting S-Records to the standard output.

Example 7.
gsrec -start 0x1002 -end 0x107F -romaddr 0 -interval 4:2 prog1

The gsrec program translates 2 out of every 4 data bytes in the input file prog1
starting at address 0x1002 and ending at address 0x107F, relocates the data to
start at address zero, and copies the resulting S-Records to the standard output.

386 MULTI: Building Applications for Embedded ARM


The gstack Utility Program

The gstack Utility Program


The gstack utility program analyzes a program to report the maximum stack
size each task might need during execution and the call chain that produces this
maximum stack size.

To produce the information required for gstack, all files comprising the program
must be compiled with -G.

The syntax for this utility is as follows:


gstack [[options]] [program]

where program is the name of an input executable program to examine.

The gstack options are:


-a
Adds functions or connections to the call graph. -a fun1:fun2, fun3 adds fun1,
fun2, fun3 to the call graph, with fun2 and fun3 being called by fun1.
-c func
Displays all callers of func.
-f func=size
Specifies function stack frame size.
-g
Displays the call graph.
-help
Displays information about all options.
-j
Displays all functions and frame sizes.
-s func
Displays the maximum stack size for the program, starting with func.
-u
Displays all functions that have no callers.

Green Hills Software, Inc. 387


11. Utility Programs

Caveats
• gstack cannot work if there are potential direct or indirect recursive calls
in the program because it cannot predict how many times the recursion can
occur. gstack prints a warning message if it detects a possible recursion
in the call graph.
• gstack prints a warning message if it detects a call to a function for which
there is no stack frame size information, or for which there is no call
information. Both of these situations might be caused by compiling the
function without using the -G option, or the function might be an assembly
language routine.
• gstack does not understand function calls through pointers. No warning is
printed.
• gstack cannot differentiate between static functions of the same name from
different files.

Example 1.

For the file test.c:


void f3(char* s) { *s = ’\0’; }
void f2(char* s) { char a[20]; f3(a); f3(s); }
void f1(char* s) { char a[10]; f2(a); f3(s); }
void f0(char* s) { f1(s); f3(s); }
int main(void) { char a[100]; f0(a); f1(a);
f2(a); f3(a); return 0; }

Compile with the -G option:


$ccarm -G test.c

Run gstack:
$ gstack -s main a.out
Task main, 184 byte stack produced by the call chain of:

Framesize Function
--------- --------
112 main
16 f0
24 f1
32 f2

388 MULTI: Building Applications for Embedded ARM


The gstrip Utility Program

The gstrip Utility Program


The gstrip utility program can remove line number, symbol table, and
debugging information from an executable file to reduce its file size on disk.

The gstrip utility processes executable files created by the Green Hills Software
linker as well as those created by some native linkers.

The syntax for this utility is as follows:


gstrip [options] filename

where filename is the name of an executable file.

The options for gstrip are as follows:


-help
Displays information about all the options.
-l
Removes line number information only, without stripping the symbol table or
debugging information.
-prefixed_msgs
-no_prefixed_msgs
Enables or disables the insertion of the words WARNING and ERROR before every
warning and error message.
-V
Displays the version number of gstrip to standard error output.
-x
Does not remove the symbol table; debugging and line number information might
be removed.

Green Hills Software, Inc. 389


11. Utility Programs

The gversion Utility Program


The gversion utility program extracts and prints date and time information
from an executable file provided by Green Hills. If no options or slots are
specified, then gversion outputs the executable’s revision and release dates
from slots 0 and 6.

The syntax for this utility is as follows:


gversion [options] [slot] [file1] [file2 ...]

where:

• options: Drawn from the table below.


• slot: A single digit number, specifying the slot to print (see Example 1 on
page 391). gversion displays the file modification date when no valid time
stamp corresponding to the slot requested can be found.
• file1, file2: The executable files for which you want to print date and time
information.
-all
Displays all non-zero dates, marked [0] through [9]. Each date is preceded by a
digit in square brackets “[]” called a time stamp. The revision date is preceded by
[0] and the release date is preceded by [6]. See Example 2 on page 391.
-date (default)
Displays the value as a date string.
-help
Displays information about all options.
-mtime
-nomtime (default)
Enables or disables display of the file’s modification date. The -mtime option must
be used with -all. See Example 3 on page 391.
-quiet
Suppresses errors for files that are not stamped.
-value
Displays all stamp values without converting to date.

390 MULTI: Building Applications for Embedded ARM


The gversion Utility Program

Example 1.

In this example, suppose the executable elxr has only time slot 0 set:
gversion elxr
elxr: Green Hills Software, Version 3.0
elxr: Revision Date Tue Oct 31 09:12:51 2000
gversion 0 elxr
elxr: Green Hills Software, Version 3.0
elxr: [0] Tue Oct 31 09:12:51 2000

If asked to print the value of slot 1, which is not stamped, gversion will display
an error message:
elxr: Green Hills Software, Version 3.0
elxr has not been time stamped
elxr: [m] Tue Oct 31 09:12:51 2000

Example 2. Using -all

The following is a sample output for the command gversion -all ax.
ax: Green Hills Software, Version 3.0
ax: [0] Mon Oct 31 01:55:10 2000
ax: [6] Mon Oct 31 17:20:43 2000
ax: License Managed by Elan License Manager

The revision date is the last modification date of the source code. The release
date is the program’s distribution date.

Example 3. Using -mtime

The following is a sample output for the command


gversion -mtime -all ax.
ax: Green Hills Software, Version 3.0
ax: [0] Mon Oct 31 01:55:10 2000
ax: [6] Mon Oct 31 17:20:43 2000
ax: License Managed by Elan License Manager
ax: [m] Fri Nov 1 21:22:30 2000

Green Hills Software, Inc. 391


11. Utility Programs

The gwhat Utility Program


The gwhat utility program performs a similar function to the UNIX what
program. It reports or updates the version information of a file.

The syntax for this utility is as follows:


gwhat [options] [file1] [file2 ...]

The options to gwhat are as follows:


-all
Prints out all what-strings.
-c what_str
Overwrites the default what-string space reserved for customers with what_str.
-f
Overwrites the what-string, even if it is read-only.
-help
Displays help message.
-m what_str
Overwrites the Green Hills what-string space with what_str.
-sn
Stops after the nth occurrence of the pattern. The default is 1 (first occurrence).
There is no space between the -s and n.
-w what_str
Changes the what-string marker from @(#) to what_str.

If neither the -c nor -m option is specified, then by default gwhat outputs the
first string in the file. You can set the number of strings to output with the
-all or -s option.

Version Extract Mode


In version extract mode, gwhat searches each filename for occurrences of the
following 4-byte what-string marker:
@(#)

392 MULTI: Building Applications for Embedded ARM


The gwhat Utility Program

It then displays all subsequent characters up to but not including any of the
following terminator characters (expressed in C) or end-of-file:
Character Character name
" Straight double quotation mark
> Greater than sign
\\ Backslash
\n Newline
\0 Null character

For example, if the C program in file program.c contains:


char sccsid[] = "@(#)Version 3.0";

and if program.c is compiled to yield program.o and linked to yield a.out,


then the command:
gwhat program.c program.o a.out

produces:
program.c:
Version 3.0
program.o:
Version 3.0
a.out:
Version 3.0

Version Update Mode


In version update mode, gwhat can write new version information into a file.
This feature has several applications. All Green Hills executables are built with
two default what-strings. For example:
"@(#)Green Hills Software, Version 4.0"
"@(#)[Customer version stamp space]"

Under some circumstances, Green Hills may change the Green Hills release
what-string, using the -m option. For example:

Green Hills Software, Inc. 393


11. Utility Programs

gwhat -m ’special release abc’ elxr


gwhat -s2 elxr
Green Hills Software, special release abc
[Customer version stamp space]

This capability is available to Green Hills customers as well, although it is


recommended that the Green Hills release what-string be left unchanged.

If you want to stamp a Green Hills executable with a private identification


mark, change the [Customer version stamp space] that is provided
for this purpose. For example:
gwhat -c ’Mary likes this version’ elxr
gwhat -s2 elxr
Green Hills Software, Version 4.0
Mary likes this version

The -c option can only be used once on a binary because it looks for the original
[Customer version stamp space] identifier.

You might want to build a custom what-string into your own software to mark
the executables. For example, suppose your executable, acmeprog, contains
a C source file that contains:
char sccsid[] = "@(#)ACME SOFTWARE ";

The following shows the different outputs of gwhat before and after using
the -m and -w options.
gwhat acmeprog
ACME SOFTWARE
gwhat -w "@(#)ACME SOFTWARE " -m "version 12" acmeprog
gwhat acmeprog
ACME SOFTWARE version 12

394 MULTI: Building Applications for Embedded ARM


Chapter 12

The CodeBalance
Optimization Wizard

This Chapter Contains:


• Completing the Setup Tab
• Completing the Build Tab
• Completing the Profile Tab
• Completing the Optimize Tab
• Advanced Options
12. The CodeBalance Optimization Wizard

CodeBalance analyzes profiling information to optimize an executable. It can


control 16-bit and 32-bit modes (where these are supported by the target), along
with size, speed, and loop optimizations for individual functions. CodeBalance
uses build files created by the MULTI Builder to obtain information about the
executable to be optimized. Consequently, it cannot be used with projects built
with makefiles or other third party build systems.

If your target supports 16-bit compilation, code compiled in this mode is


usually much smaller (but slower) than the same code compiled in 32-bit mode.
Building an executable in which time-critical routines are compiled in 32-bit
mode while less important ones are compiled in 16-bit mode results in a much
smaller code size with relatively modest performance loss.

CodeBalance provides a GUI interface to automate the process of optimizing a


project defined by a build file. You are directed through the process of building,
profiling, and optimizing an executable. If your executable requires user input,
it must be profiled manually, but it can still be optimized using CodeBalance.

CodeBalance builds up to six copies of your executable with different sets of


global optimizations as follows:

• 16-bit (if available) and 32-bit, optimized for speed


• 16-bit (if available) and 32-bit, optimized for space
• 16-bit (if available) and 32-bit, optimized for space, with loop optimizations
CodeBalance profiles each executable to determine the execution times for each
individual function. It then calculates the best set of optimizations for size and
for speed for each function, and allows you to choose between generating:

• the fastest possible executable


• the smallest possible executable
• the fastest possible executable within a specified size
Codebalance then combines the best optimizations for each function into a build
file to enable you to build a final optimized executable.

396 MULTI: Building Applications for Embedded ARM


Completing the Setup Tab

Completing the Setup Tab


To run CodeBalance, type codebalance in your installation directory. The
program starts and displays a window with four tabs: Setup, Build, Profile,
and Optimize. The first tab, Setup, prompts you to enter the location of the
build file for the project you want to optimize, together with the forms of
optimization you want to compare.

Complete this tab as follows:

1. Choose either .gpj files or .bld files in the first set of buttons. These file
types may not be mixed in later text fields.
2. Enter the path of the ultimate parent build file of the project in the first
field. You do not need to complete this field if your project build file is the
top-level build file.
3. Enter the path of the build file for your executable in the second field.
CodeBalance only attempts to balance source code under a program’s build
file. External libraries and other source files are not considered.
4. Enter the path to the Green Hills tool chain directory in the third field if
it differs from the default setting.
5. By default, CodeBalance will compare 16- and 32-bit instructions (where
these are supported), along with Size/Space and Loop optimizations. To
disable any of these optimizations, clear the appropriate check box.
6. Check Use MVC if the project build file you are optimizing has been
checked in to MULTI Version Control.

Green Hills Software, Inc. 397


12. The CodeBalance Optimization Wizard

Completing the Build Tab


The Build tab prompts you to specify names and locations for the executables
that CodeBalance builds to profile the different sets of optimization options.
Some of the fields might be disabled if you have cleared any of the optimization
options in the Setup tab, or if they are not supported by your target.

Complete this tab as follows:

1. Each optimization set generates two executables, one containing code for
profiling, and the other (with a _nopro suffix) used to measure the size
of the final executable. By default, the executables are saved to the same
path as your project build file. To override the defaults, enter new names or
paths in the appropriate fields or use the browse button.

To reset the field to its default value, click the Use Default button. To
change the paths of all the other executables to be built to the path entered
in a field, click its Propagate button.
2. Codebalance uses (or generates) a call graph which, by default, is assumed
to be in the same path as your executable. To override the default, enter a
new name or path in the Call graph path field.
3. To instruct CodeBalance to build new executables, click the Rebuild All
button. Skip this step if you have already built these executables in a
previous invocation of CodeBalance.

398 MULTI: Building Applications for Embedded ARM


Completing the Profile Tab

Completing the Profile Tab


If your executable is self-terminating and requires no user input other than
command line arguments, CodeBalance can obtain profiling information by
automatically simulating it for you. Otherwise, you must profile the executables
manually (see Chapter 15, “Using the Profiler” in the MULTI: Debugging book
or “The grun Utility Program” on page 378).

Complete this tab as follows:

1. The top fields show the default names and paths for the profiling data files
for your optimization sets. To override these defaults, enter a new name or
path in the appropriate field, or navigate to it using the browse button. If
you have manually profiled the executables, you must enter the paths to
the profile data files here.

To reset a field to its default value, click the Use Default button. To change
the paths of all the other executables to be built to the path entered in a
field, click its Propagate button.
2. In the next field, enter any command line arguments to be passed to your
executables during simulation.
3. In the next field, enter the command for the appropriate debug server. For
example, to profile using the ARM simulator, enter simarm. Native debug
servers are not compatible with CodeBalance.

Green Hills Software, Inc. 399


12. The CodeBalance Optimization Wizard

4. Click the Generate button to create profile data for the optimized
executables. If the profile data files were generated manually or by a
previous invocation of CodeBalance, you can skip this step.

Completing the Optimize Tab


The Optimize tab displays a chart showing the range of available executable
sizes and speeds, together with a list of all the functions that make up the
project. The vertical axis of the graph, Speed, shows the time, in seconds,
which the optimized executable takes to run, while the horizontal axis shows
its Size in bytes.

Complete this tab as follows:

1. By default, the Optimize tab displays the graph and optimization sets for
an executable optimized for speed. The red arrows on the graph that point
to the size and speed of the recommended executable are in the bottom right
corner of the graph. The chart shows the optimization sets for each function
needed to produce the fastest possible executable, without regard for size.

To change the default setting and to optimize for size instead, select the
Smallest radio button at the top left of the tab.

To obtain the fastest executable within a specified size, select the Fit size
radio button, and enter the required maximum size in bytes in the text field.
Alternatively, you can specify a maximum size by clicking the graph.

400 MULTI: Building Applications for Embedded ARM


Completing the Optimize Tab

The chart shows the optimizations required for each function to produce
the fastest executable that can fit in that size. Because there is not a set of
optimizations for the entire range of executable sizes, CodeBalance might
make recommendations for an executable smaller than the size you specify.
The actual size and speed of the executable generated by the recommended
optimizations is indicated by the red arrows on the chart axes.
2. After you have decided on a suitable balance between size and speed, click
Create buildfile to create an optimizing build file. By default, this build
file overwrites the initial project build file, but you can preserve the original
by choosing a new name and/or path in the Set optimized buildfile field.

If MVC is enabled and the optimizing build file overwrites the original,
this revised build file remains checked out.
3. Choose a path for a wizard file and click Create wizard file. The wizard
file contains optimization options that is set as #pragmas in the source
code. The optimizing build file contains instructions to include this wizard
file when your executable is rebuilt.
4. Click Finish to exit CodeBalance.
5. If you want to build the optimized executable immediately, start the Builder
and build the project in the usual way.

Note The values for the executable size are approximations. CodeBalance is
unable to calculate exact final sizes, and so any size that you specify must be
viewed as a guide, rather than an absolute maximum.

Green Hills Software, Inc. 401


12. The CodeBalance Optimization Wizard

Advanced Options
You can open CodeBalance with many of its fields already completed by
running the program as follows:
codebalance filename -options

Where filename is the build file of the project you want to optimize and -options
can consist of any or all of the following:
-gpj
Turns on the CodeBalance new project mode. This option is necessary if the build
file for your project is in .gpj format.
-help
Displays a help screen.
-parentbld=file
Specifies the name of the top-level build file which contains the project to be
optimized (see “Completing the Setup Tab” on page 397).
-remote="debug_server"
Specifies the debug_server to be used for profiling (see “Completing the Profile
Tab” on page 399).
-simopts="arguments"
Specifies the arguments to be passed to the executable in simulation (see
“Completing the Profile Tab” on page 399). If multiple arguments are specified,
they must be contained in quotation marks.
-tooldir=path
Specifies the path where CodeBalance can find the Green Hills profiling utilities
and compilers (see “Completing the Setup Tab” on page 397).

For example, the following command initializes CodeBalance to compare


optimizations for the executable to be built within foo.gpj (whose parent build
file is default.gpj), and to use the ARM simulator, simarm, as the debug server:
codebalance foo.gpj -parentbld=default.gpj -remote="simarm" -gpj

402 MULTI: Building Applications for Embedded ARM


Part III

Language Reference
Chapter 13

Green Hills C

This Chapter Contains:


• Specifying a C Language Dialect
• ANSI C
• GNU C
• K&R C
• Motor Industry Software Reliability Association (MISRA) Rules
• Japanese Automotive C Extensions
• Type Qualifiers
• Assignment and Comparisons on struct and union Types
• Bitfields
• Enumerated Types
• Functions with Variable Arguments
• The asm Statement
• The Preprocessor
• C Run-Time Library
• Extended Characters
• Compiler Limitations
• ANSI C Implementation Defined Features
• Amendment 1 Compliance
• ISO C99 Compliance
13. Green Hills C

This chapter describes the Green Hills implementation of C, including aspects


of the language particular to our compilers.

Note This release of MULTI includes two optimizing C compilers, the


superior New Generation Compiler, which is selected by default, and the older
Compatibility Mode Compiler, which is provided for backward compatibility.
This chapter focuses primarily on the New Generation Compiler. For
information about the Compatibility Mode Compiler, see Chapter 5, “The
Compatibility Mode Compiler” in the MULTI: Legacy Building Tools book.

Specifying a C Language Dialect


The Green Hills C Compiler supports four main variants of the C Language.

To specify a C dialect:
Set the C/C++ Compiler→C Language Dialect option to one of the
following settings:
• Strict ANSI C (-ANSI) — Accepts the ANSI C language as defined
by X3.159–1989 and does not support extensions.
• ANSI C (-ansi) — [default] Recommended for all new development,
and for the compilation of any existing C code which approximates
to ANSI C. For more information, see “ANSI C” on page 407.
• GNU C (-gcc) — Recommended for porting existing GNU code to
the Green Hills development environment. For more information,
see “GNU C” on page 413.
• K&R C (-k+r) — Recommended for porting existing K&R code to
the Green Hills development environment. For more information,
see “K&R C” on page 420.

Note We strongly recommend that you compile all modules in a particular


program using the same dialect, as a failure to do so could result in obscure
failures at link time or run time.

In addition to the four primary C dialects, we also provide support for:

• the Motor Industry Software Reliability Association (MISRA) C rules


(see page 154)
• the Japanese Automotive C extensions (see page 426)

406 MULTI: Building Applications for Embedded ARM


ANSI C

ANSI C
The ANSI C dialect is the default. We recommend using this mode for all new
development, as well as for the compilation of any existing C code that comes
close to ANSI C.

To specify use of this dialect:

Set the C/C++ Compiler→C Language Dialect option to ANSI C


(-ansi).

The compiler accepts the ANSI C mode as defined by X3.159–1989, with the
addition of support for numerous extensions. These extensions may be useful,
or even necessary, in certain cases. Some cases which are prohibited by the
ANSI standard generate a warning in this mode.

ANSI C Extensions
The extensions provided in this mode are as follows:

• Bitfields may have base types that are enumerated or integral types besides
int and unsigned int. This matches A.6.5.8 in the ANSI Common
Extensions appendix.
• Empty source files.
• Anonymous struct and union types.
• A translation unit (input file) can contain no declarations.
• Comment text can appear at the ends of preprocessing directives.
• __ALIGNOF__ is accepted. It behaves exactly like __alignof__ in
the list of GNU extensions below.
• __INTADDR__(expression) scans the enclosed expression as a constant
expression, and converts it to an integer constant (it is used in the
offsetof macro).
• The last member of a structure may have an incomplete array type. It may
not be the only member of the structure (otherwise, the structure would
have zero size).

Green Hills Software, Inc. 407


13. Green Hills C

• A file-scope array can have an incomplete structure, union, or enumerated


type as its element type. The type must be completed before the array
is subscripted (if it is), and by the end of the compilation if the array is
not extern.
• Static functions may be declared in function and block scopes. Their
declarations are moved to the file scope.
• enum tags may be incomplete: one may define the tag name and resolve it
later (by specifying the brace-enclosed list).
• The values of enumeration constants may be given by expressions that
evaluate to unsigned quantities that fit in the unsigned int range, but
not in the int range. A warning is issued for suspicious cases. For example:
/* when ints are 32 bits: */
enum a { w = -2147483648}; /* No warning */
enum b { x = 0x80000000}; /* No warning */
enum c { y = 0x80000001}; /* No warning */
enum d { z = 2147483649}; /* Warning */

• An extra comma is allowed at the end of an enum list.


• The final semicolon preceding the closing } of a structure or union specifier
may be omitted. A warning is issued.
• A label definition can be immediately followed by a right brace. (Normally,
a statement must follow a label definition.) A warning is issued.
• An empty declaration (a semicolon with nothing before it) is allowed.
• An initializer expression that is a single value and is used to initialize an
entire static array, structure, or union need not be enclosed in braces. Strict
ANSI C requires the braces.
• In an initializer, a pointer constant value may be cast to an integral type if
the integral type is big enough to contain it.
• The address of a variable with register storage class can be taken. A
warning is issued.
• In an integral constant expression, an integer constant may be cast to a
pointer type and then back to an integral type.
• In duplicate size and sign specifiers (e.g., short short or unsigned
unsigned) the redundancy is ignored. A warning is issued.
• long float is accepted as a synonym for double.
• The long long and unsigned long long types are accepted.

408 MULTI: Building Applications for Embedded ARM


ANSI C

• Integer constants suffixed by LL are given the type long long, and those
suffixed by ULL are given the type unsigned long long (any of the
suffix letters may be written in lower case).
• The long long types are accommodated in the usual arithmetic
conversions.
• Benign redeclarations of typedef names are allowed. That is, a typedef
name may be redeclared in the same scope as the same type. A warning is
issued.
• Dollar signs ($) can be accepted in identifiers with all dialects except Strict
ANSI C (-ANSI) and Standard C++ (Violations give Errors) (--STD).
• Numbers are scanned according to the syntax for numbers rather than the
pp-number syntax. Thus, 0x123e+1 is scanned as three tokens instead
of one invalid token.
• Assignment and pointer difference are allowed between pointers to types
that are interchangeable but not identical (e.g., unsigned char * and
char *). This includes pointer to same-sized integral types (e.g., typically,
int * and long *). Assignment of a string constant to a pointer to any
kind of character is allowed without a warning.
• Assignment of pointer types is allowed in cases where the destination type
has added type qualifiers that are not at the top level (e.g., int ** to
const int **). Comparison and pointer difference of such pairs of
pointer types are also allowed. A warning is issued.
• In operations on pointers, a pointer to void is always implicitly converted
to another type if necessary, and a null pointer constant is always implicitly
converted to a null pointer of the right type if necessary. In Strict ANSI
C, some operators allow such things, and others (generally, where it does
not make sense) do not allow them.
• Pointers to different function types may be assigned or compared for equality
(==) or inequality (!=) without an explicit type cast. A warning is issued.
• A pointer to void may be implicitly converted to or from a pointer to
a function type.
• The #assert preprocessing extensions of AT&T System V Release 4 are
allowed. These allow definition and testing of predicate names. Such names
are in a name space distinct from all other names, including macro names. A
predicate name is given a definition by a preprocessing directive of the form:

Green Hills Software, Inc. 409


13. Green Hills C

#assert name
#assert name(token-sequence)

which defines the predicate name. In the first form, the predicate is not
given a value. In the second form, it is given the value token-sequence.
Such a predicate can be tested in a #if expression, as follows:
#name(token-sequence)

which has the value 1 if #assert of that name with that


token-sequence has appeared, and 0 otherwise. A given predicate can
be given more than one value at a given time. A predicate may be deleted by
a preprocessing directive of the form:
#unassert name
#unassert name(token-sequence)

The first form removes all definitions of the indicated predicate name; the
second form removes just the indicated definition, leaving any others that
might exist.
• asm statements and declarations are accepted. This feature is disabled in
Strict ANSI C mode because it conflicts with the ANSI C Standard for
statements such as:
asm("xyz");

ANSI C interprets this syntax as a call of an implicitly-defined function


asm, which (by default) the compiler interprets as an asm statement.
• asm functions are accepted, and __asm is recognized as a synonym for
asm. An asm function must be declared with no storage class, with a
prototyped parameter list, and with no omitted parameters:
asm void f(int, int) {
...
}

• An extension is supported to allow constructs similar to C++ anonymous


unions. In addition, anonymous structures are allowed—that is, their
members are promoted to the scope of the containing structure and looked
up in the same manner as ordinary members.
• An ellipsis can appear by itself in the parameter list of a function:
declaration - e.g. ’f(...)’.

410 MULTI: Building Applications for Embedded ARM


ANSI C

• External entities declared in other scopes are visible. A warning is issued.


For example:
void f1(void) { extern void f(); }
void f2() { f(); /* Using out of scope declaration */ }

• End-of-line comments (using // as delimiter) are supported.


• A non-lvalue array expression is converted to a pointer to the first element
of the array when it is subscripted or similarly used.
• A structure that has no named fields, but at least one unnamed field, is
accepted by default.

The following extensions are also supported in this mode and are inspired by
the GNU compiler:

• Attributes, introduced by the keyword __attribute__, can be used


on declarations of variables, functions, types, and fields. This extension
mimics the GNU compiler for the attributes that are accepted. The following
attributes are accepted:

alias, aligned, cdecl, const, deprecated, format,


format_arg, mode, no_check_memory_usage,
no_instrument_function, nocommon, noreturn, packed,
pure, section, stdcall, transparent_union, unused,
used, volatile, weak
• The __alignof__ keyword is supported. It is similar to sizeof, but
returns the alignment requirement value for a type, or 1 if there is no
alignment requirement. It can be followed by a type or expression in
parentheses:
__alignof__(type)
__alignof__(expression)

The expression in the second form is not evaluated.


• pointer arithmetic on expressions of type void *
• Preprocessing directive #import is supported.
#import "filename"

or
#import <filename>

Green Hills Software, Inc. 411


13. Green Hills C

causes filename to be included only once.


• A function may be declared __inline__.
• The last case label in a switch construct need not be followed by a
statement. For example:
switch (expr) {
default:
}

• The construct __attribute__ is recognized.


declarator __attribute__((attribute-list))

This allows the object declared via the “declarator” to have a set of GNU C
extended attributes. Currently, the construct is parsed but has no effect.
• Keyword __typeof__ is supported. It takes an expression as the
argument, and returns the type of the expression. For instance, the following
code:
int i;
__typeof__(i) j;

would declare variables i and j, both of type int.


• Local initializations of aggregate-type variables (structures and arrays) may
contain non-constant initial values.
• The preprocessor directive #include_next is recognized. This directive
behaves in a similar manner to #include, but only searches those include
directories specified on the command line after the present directory.
• The macros __FUNCTION__ and __PRETTY_FUNCTION__ are
supported. They expand to the name of the function surrounding them or, in
the global scope, to the empty string. In C++, __PRETTY_FUNCTION__
expands to the fully-qualified name of the surrounding function.

412 MULTI: Building Applications for Embedded ARM


GNU C

GNU C
The GNU C dialect provides close compatibility with code written for the
GNU compiler. It accepts all of the ANSI C dialect features, together with a
number of GNU-specific extensions listed below. We recommend that you
use this dialect only when porting existing GNU-compiled code to the Green
Hills development environment.

To specify use of this dialect:

Set the C/C++ Compiler→C Language Dialect option to GNU C


(-gcc).

GNU C only Extensions


This dialect enables all the ANSI extensions listed in “ANSI C Extensions” on
page 407, together with the extensions listed in this section, and those listed in
“GNU C/C++ Extensions” on page 416.

• The nocommon attribute is accepted. It indicates that a variable definition


is not tentative.
• Variable length arrays (VLAs) are supported. GNU C also allows VLA types
for fields of local structures, which can lead to run-time dependent sizes
and offsets. The front end does not implement this, but instead treats such
arrays as having length zero (with a warning); this enables some popular
programming idioms involving fields with VLA types.
void f(int n) {
struct {
int a[n]; /* Warning: n ignored and replaced by zero
};
}

• A nonconstant may appear in the initializer list of an aggregate variable


with automatic storage class.
• Typedef initializers are supported. For example:
int f();
typedef T = f(); // Same effect as "typedef int T;"

Green Hills Software, Inc. 413


13. Green Hills C

• GNU C style inlining can be requested using the keywords inline or


__inline__. If an inline function is explicitly declared extern, its
definition will only be used for inlining and no out-of-line copy will be
spilled. If inlining cannot be done for some reason, you must provide a
non-inline definition somewhere in the program.
• Structs and unions without fields are accepted. They have size zero. Class
types containing only fields of size zero (zero-length bitfields, zero-length
arrays, and class types of size zero) also have size zero.
• In conditional expressions, the middle operand can be left out. When that
is the case, the result of the expression is the value of the first operand if
that first operand is “true”.
x = x ?: -1; /* If x is zero, evaluates to -1; otherwise, just x */

• A function definition written with both of the keywords extern and


inline is treated as an external declaration, with the added property that
the body is available for inlining of calls in the current translation unit. This
is slightly different than the C99 definition of extern inline.
• Old-style definitions with unpromoted parameter types can follow prototype
declarations with those same types.
void f(short); // Prototype
void f() short p; {} // Old-style definition OK

• An unprototyped declaration can follow a prototyped declaration. After such


a redeclaration the original prototype is ignored.
void f(char); // Original prototype
void f(); // Unprototyped redeclaration
void f(double x) {} // Accepted in GNU C mode
// (original prototype ignored)

• Certain “generalized lvalues” are supported. The ternary conditional


operator produces an lvalue if its second and third operand are lvalues.
Similarly, the comma operator produces an lvalue if its second operand is
an lvalue. Some casts also preserve the lvalueness of their operand. For
example:
unsigned x, y, z;
(x ? y : z) = 4; // Updates y or z depending on x
(x += y, y) = 3; // Updates y
(int)x = -1; // Updates x

414 MULTI: Building Applications for Embedded ARM


GNU C

A “?” operator can also be treated as an lvalue if its operands have types
that are different but are close enough that an lvalue cast can bridge the gap
(e.g., int and int *). A warning is issued.
• An expression can be cast to a union type containing a field with the type of
that expression. For example:
union X { int i; char c; };
union X f(int i) { return (union X)i; }

• Implicit conversions are allowed between integral and pointer types, and
between incompatible pointer types, with a warning. Implicit conversions
between pointer types can drop cv-qualifiers (e.g., const char * to
char *).
• Pointer arithmetic applies to void pointers and function pointers as if they
were char*.
• Explicit casts to struct and union types are allowed if they are do-nothing
casts, i.e., if the source type is the same as the destination type. (cv-qualifier
differences are allowed but ignored.) The result is an lvalue if the source
is an lvalue.
• Functions with return type void can have return expressions. A warning is
issued if the return expression does not have type void.
• Bitfield lengths that are too large for the associated type are ignored with
a warning (i.e., the field becomes an ordinary field whose address can be
taken). For example:
struct S {
char c: 9; // Oversized bitfield becomes regular field of type char
}; // (assuming a char can hold at most 8 bits)

• The _Bool keyword and boolean type of C99 are accepted.


• Casts on an lvalue that do not fall under the usual “lvalue cast” interpretation
(e.g., because they cast to a type having a different size) are ignored, and the
operand remains an lvalue. A warning is issued.
int i;
(short)i = 0; // Accepted,cast is ignored; entire int is set

• “?” operators with mixed void/non-void operands in the second and third
operands are accepted. The result has type void.
• Extraneous short and long specifiers in typedef declarations are ignored
with a warning.

Green Hills Software, Inc. 415


13. Green Hills C

typedef long short L; // "short" ignored.


typedef long long long LL; // Last "long" ignored.

• In function definitions, local declarations can hide parameters.


void f(int x) {
double x; // Accepted in GNU C mode (with a warning).
}

• An old-style parameter list can be followed by an ellipsis to indicate that the


function accepts variable-length argument lists.
void f(x) int x; ... {} // Accepted in GNU C mode

GNU C/C++ Extensions


The extensions listed in this section are enabled when GNU C or GNU C++
is selected. See also “GNU C only Extensions” on page 413 and “GNU C++
Extensions” on page 473.

• alignof is accepted. It behaves exactly like __alignof__.


• A function can be declared inline. It denotes that the inliner should
attempt to inline calls to the function.
• Multi-line string constants are legal. They do not require the continuation
characters (\ at end of line). The line breaks are interpreted as \n characters.
Thus:
"This is
a single string constant."

is equivalent to:
"This is \na single string constant."

• Keyword typeof is supported. It behaves exactly like __typeof__


under safe GNU extensions.
• Implicit conversion of pointer types with the source type having a more
qualified base type is allowed with a warning. Hence, only a warning is
emitted in respect of the following:

416 MULTI: Building Applications for Embedded ARM


GNU C

const char *s;


char *p;
/* ... */
p = s; /* error in ANSI, warning with GNU */

• Extended designators are accepted.


• Compound literals are accepted. In addition to the features of C99
compound literals, GNU C mode also allows such literals to be used to
initialize variables in file scope (if they only involve constant-expressions)
and to initialize elements of aggregate types in brace-enclosed aggregate
initializers.
• Nonstandard anonymous unions (a Microsoft extension) are accepted.
• The typeof operator is supported. This operator can take an expression or
a type (like the sizeof operator, but parentheses are always required) and
expands to the type of the given entity. It can be used wherever a typedef
name is allowed:
typeof(2*2.3) d; // Declares a "double"
typeof(int) i; // Declares an "int"

This can be useful in macro and template definitions.


• The __extension__ keyword is accepted preceding declarations and
certain expressions. It has no effect on the meaning of a program:
__extension__ __inline__ int f(int a) {
return a > 0 ? a/2 : f(__extension__ 1-a); }

• The type modifiers signed, unsigned, long, and short can be used
with typedef types if the specifier is valid with the underlying type of the
typedef in ANSI C. For example:
typedef int I;
unsigned I *pui; // OK in GNU C/C++ modes; same as
// "unsigned int *pui"

• Zero-length array types (specified by [0]) are supported. These are


complete types of size zero.
• C99-style flexible array members are accepted. In addition, the last field of a
class type has a class type whose last field is a flexible array member. In
GNU C++ mode, flexible array members are treated exactly like zero-length
arrays, and can therefore appear anywhere in the class type.

Green Hills Software, Inc. 417


13. Green Hills C

• The sizeof operator is applicable to void and to function types and


evaluates to the value 1.
• Variables can be redeclared with different top-level cv-qualifiers (the new
qualification is merged into existing qualifiers). For example:
extern int volatile x;
int const x = 32; // x is now const volatile

• The “assembler name” of variables and routines can be specified. For


example:
int counter __asm__("counter_v1") = 0;

• The keyword inline is ignored (with a warning) on variable declarations


and on block-extern function declarations.
• Excess aggregate initializers are ignored with a warning.
struct S { int a, b; };
struct S a1 = { 1, 2, 3 }; // "3" ignored with a warning; no error
int a2[2] = { 7, 8, 9 }; // "9" ignored with a warning; no error

• Expressions of types void*, void const*, void volatile* and


void const volatile* can be dereferenced; the result is an lvalue.
• The __restrict__ keyword is accepted. It is identical to the C99
restrict keyword, except for its spelling.
• Out-of-range floating point values are accepted without a diagnostic. When
IEEE floating point is being used, the “infinity” value is used.
• Extended variadic macros are supported.
• Hexadecimal floating point constants are recognized.
• The \e escape sequence is recognized and stands for the ASCII “ESC”
character.
• The special token __FUNCTION__ expands to a string literal representing
the (undecorated) name of the function in which is appears.
• The address of a statement label can be taken by use of the prefix “&&”
operator, e.g., void *a = &&L A transfer to the address of a label can be
done by the “goto *” statement, e.g., goto *a.
• Multi-line strings are supported, e.g., char *p = "abc def";
• ASCII “NULL” characters are accepted in source files.

418 MULTI: Building Applications for Embedded ARM


GNU C

• A source file can end with a backslash (“\”) character.


• Case ranges (e.g., “case ’a’ ... ’z’:”) are supported.
• A number of macros are predefined in GNU mode (see “GNU Compatibility
Macros” on page 522).
• A large number of special functions of the form __builtin_xyz (e.g.,
__builtin_alloca) are predeclared.
• Some expressions are considered to be constant-expressions even though
they are not so considered in standard C and C++. Examples include
“((char *)&((struct S *)0)->c[0]) - (char *)0” and
“(int)"Hello" & 0”.
• The macro __GNUC__ is predefined to the major version number of
the emulated GNU compiler. Similarly, the macro __GNUC_MINOR__
is predefined to the corresponding minor version number. Finally,
__VERSION__ is predefined to a string describing the compiler version.
• An extern inline function that is referenced but not defined is
permitted (with a warning).
• Nonstandard casts are allowed in null pointer constants, e.g., (int)(int
*)0 is considered a null pointer constant in spite of the pointer cast in the
middle.
• Statement expressions, e.g., ({int j; j = f(); j;)} are
accepted. Branches into a statement expression are not allowed. In
C++ mode, branches out are also not allowed. Variable-length arrays,
destructible entities, try, catch, local non-POD class definitions, and
dynamically-initialized local static variables are not allowed inside a
statement expression.
• Labels can be declared to be local in statement expressions by introducing
them with a __label__ declaration.
({ __label__ lab; int i = 4; lab: i = 2*i-1; if (!(i%17)) goto lab; i; })

The following GNU extensions are not currently supported in any GNU mode:

• The forward declaration of function parameters (so they can participate in


variable-length array parameters).
• GNU-style complex numbers (including complex literals).
• Nested functions.

Green Hills Software, Inc. 419


13. Green Hills C

K&R C
K&R is the classic dialect of C in which UNIX was originally written. The first
edition of The C Programming Language by Kernighan and Ritchie describes
the K&R dialect. The most important implementation of this dialect was
the Portable C Compiler (PCC). There are many versions of this compiler,
including the C compilers distributed with System V.3, BSD 4.3 and SunOS
4x. Together these compilers implement hundreds of extensions, without which
it is impossible to compile the UNIX operating system or many existing C
application programs.

Green Hills compilers follow the version of PCC distributed with the Berkeley
4.3 BSD version of UNIX. We have also added many documented and
undocumented extensions from other compilers to simplify the process of
porting existing C programs to the Green Hills compiler.

To specify use of this dialect:

Set the C/C++ Compiler→C Language Dialect option to K&R C


(-k+r).

The following is a list of incompatibilities between the Green Hills K&R Mode
and PCC:

• Token pasting is not performed outside of macro expansions when only a


comment separates two tokens. For example, a/**/b is not considered to
be ab. The PCC behavior in that case can be achieved by preprocessing to a
text file and then compiling that file.

Note that /**/ may be used to concatenate two strings in macro definitions.
• PCC considers the result of a ? : operator to be an lvalue if the first
operand is constant and the second and third operands are compatible
lvalues. The Green Hills compilers do not.
• PCC incorrectly parses the third operand of a ? : operator in a way that
some programs exploit. For example:
i ? j : k += l

is parsed by PCC as

420 MULTI: Building Applications for Embedded ARM


K&R C

i ? j : (k += l)

which is incorrect, since the precedence of += is lower than the precedence


of ? :. The compiler will generate an error for that case.

The following section lists K&R Mode extensions to ANSI C.

K&R Mode Extensions to ANSI C


• the void keyword
• enum types
• the predefined macro names__LINE__, __FILE__, __TIME__, and
__DATE__
• #error, #ident, #elif, #defined(id) preprocessor directives
• functions that return struct types
• asm(str) statements
• initialized extern variables
• initialized variables of union types
• initialized automatic variables of struct and array types
• keywords const, signed, and volatile are recognized
• The keywords signed, const, and volatile are disabled in order to
avoid problems with items declared with those names in old-style code.
Those keywords were ANSI C inventions. The other non-K&R keywords
(enum and void) are judged to have existed already in code and are not
disabled.
• Declarations of the form
typedef some-type void;

are ignored.
• Assignment is allowed between pointers and integers, and between
incompatible pointer types, without an explicit cast. A warning is issued.
• A field selection of the form p->field is allowed if p does not point to a
structure or union that contains field. p must be a pointer or an integer.
Likewise, x.field is allowed even if x is not a structure or union that

Green Hills Software, Inc. 421


13. Green Hills C

contains field. x must be an lvalue. For both cases, all definitions of


field as a field must have the same offset within their structure or union.
• Overflows detected while folding signed integer operations on constants
cause warnings rather than errors.
• A warning will be issued for an & applied to an array. The type of such an
operation is “address of array element” rather than “address of array”.
• For the shift operators << and >>, the usual arithmetic conversions are done,
the right operand is converted to int, and the result type is the type of
the left operand. In ANSI C, the integral promotions are done on the two
operands, and the result type is the type of the left operand. The effect of
this difference is that, in K&R mode, a long shift count will force the
shift to be done as long.
• When preprocessing output is generated, the line-identifying directives will
have the K&R form instead of the ANSI form.
• String literals will not be shared. Identical string literals will cause multiple
copies of the string to be allocated.
• sizeof may be applied to bitfields; the size is that of the underlying type
(e.g., unsigned int).
• lvalues cast to a type of the same size remain lvalues, except when they
involve a floating-point conversion.
• When a function parameter list begins with a typedef identifier, the
parameter list is considered prototyped only if the typedef identifier is
followed by something other than a comma or right parenthesis:
typedef int t;
int f(t) {} /* Old-style list */
int g(t x) {} /* Prototyped list, parameter x of type t */

That is, function parameters are allowed to have the same names as
typedef identifiers. In the normal ANSI mode, any parameter list that
begins with a typedef identifier is considered prototyped, so the first
example above would give an error.
• The names of functions and of external variables are always entered at the
file scope.
• A function declared static, used, and never defined is treated as if its
storage class were extern.

422 MULTI: Building Applications for Embedded ARM


K&R C

• A file-scope array that has an unspecified storage class and remains


incomplete at the end of the compilation will be treated as if its storage class
is extern (in ANSI mode, the number of elements is changed to 1, and the
storage class remains unspecified).
• The empty declaration:
struct x;

will not hide an outer-scope declaration of the same tag.


• In a declaration of a member of a structure or union, no diagnostic is issued
for omitting the declarator list; nevertheless, such a declaration has no effect
on the layout. For example:
struct s {
char a;
int;
char b[2];
} v; /* sizeof(v) is 3 */

• Enumerated types are always given type int. In ANSI mode, and depending
on the command line options, smaller integral types will be used if possible.
• No warning is generated for a storage specified appearing in other than the
first position in a list of specifiers (as in int static).
• short, long, and unsigned are treated as “adjectives” in type specifiers,
and they may be used to modify a typedef type.
• A “plain” char is considered to be the same as either signed char or
unsigned char, depending on the target and command line options. In
ANSI C, “plain” char is a third type distinct from both signed char
and unsigned char.
• Free-standing tag declarations are allowed in the parameter declaration list
for a function with old-style parameters.
• float function parameters are promoted to double function parameters.
• float functions are promoted to double functions.
• Declaration specifiers are allowed to be completely omitted in declarations
(ANSI C allows this only for function declarations). Thus,
i;

declares i as an int variable. A warning is issued.

Green Hills Software, Inc. 423


13. Green Hills C

• All float operations are done as double.


• __STDC__ is left undefined.
• Extra spaces to prevent the pasting of easily confused adjacent tokens are
not generated in textual preprocessing output.
• The first directory searched for include files is the directory containing
the file containing the #include instead of the directory containing the
primary source file.
• Trigraphs are not recognized.
• Comments are deleted entirely (instead of being replaced by one space) in
preprocessing output.
• 0x is accepted as a hexadecimal value 0, with a warning.
• 1E+ is accepted as a floating-point constant with an exponent of 0, and a
warning is emitted.
• The compound assignment operators may be written as two tokens (e.g.,
+= may be written as + =).
• The digits 8 and 9 are allowed in octal constants.
• A warning, rather than an error, is issued for integer constants that are
larger than can be accommodated in an unsigned long. The value is
truncated to an acceptable number of low-order bits.
• The types of large integer constants are determined according to the K&R
rules (they will not be unsigned in some cases where ANSI C would
define them that way). Integer constants with apparent values larger than
LONG_MAX are typed as long and are also marked as “non-arithmetic”,
which suppresses some warnings when using them.
• The escape \a (alert) is not recognized in character and string constants.
• Macro expansion is performed differently. Arguments to macros are not
macro-expanded before being inserted into the expansion of the macro.
Any macro invocations in the argument text are expanded when the macro
expansion is rescanned. With this method, macro recursion is both possible
and checked for.
• Token pasting inside macro expansions is performed differently.
End-of-token markers are not maintained, so tokens that abut after macro
substitution may be parsed as a single token.
• Macro parameter names inside character and string constants are recognized
and appropriately substituted.

424 MULTI: Building Applications for Embedded ARM


K&R C

• Macro invocations having too many arguments are flagged with a warning
rather than an error. The extra arguments are ignored.
• Macro invocations having too few arguments are flagged with a warning
rather than an error. A null string is used as the value of the missing
parameters.
• Extra #else statements (after the first has appeared in an #if block) are
ignored, and a warning is emitted.
• Expressions in a switch statement are cast to int; this differs from the
ANSI C definition in that a long expression is (possibly) truncated.
• The promotion rules for integers are different; unsigned char and
unsigned short are promoted to unsigned int.
• An identifier in a function is allowed to have the same name as a parameter
of the function. A warning is issued.

Green Hills Software, Inc. 425


13. Green Hills C

Motor Industry Software Reliability Association (MISRA) Rules


We provide support for the Motor Industry Software Reliability Association
(MISRA) rules. For more information, see “MISRA C” on page 154.

Japanese Automotive C Extensions


We provide support for the Japanese Automotive C extensions to ANSI
C, which are used by Japanese automobile manufacturers. For complete
specifications, refer to the C-Language Specification for Automotive Control
(Proposal) by Toyota Motor Corporation, July 29, 1993.

Japanese Automotive C generally conforms to the principles of ISO 9899,


equivalent to the ANSI X3.159–1989 standard, with the exception of the
“Implementation-Defined Behavior” specification of Annex G.3, which it
modifies and extends to support portability. These extensions conform to the
“Common Extension” section, in Annex G.5.

To enable support for the Japanese Automotive C extensions:

Set the C/C++ Compiler→C Japanese Automotive Extensions


option to On (-japanese_automotive_c).

Enabling C/C++ Compiler→C Japanese Automotive Extensions


(-japanese_automotive_c). implicitly modifies the following options:

• Sets C/C++ Compiler→Data Types→Signedness of Char Type to


Unsigned (--unsigned_chars)
• Sets C/C++ Compiler→Data Types→Signedness of Bitfields to Unsigned
(--unsigned_fields)
• Sets C/C++ Compiler→Data Types→Use Smallest Type Possible for
Enum to Off (--no_short_enum)
• Sets Compiler Diagnostics→C/C++ Messages→Asm Statements to
Silent (--asm_silent)

Selecting Japanese Automotive C also enforces the following behavior: in the


case of a pointer being cast to an integer, if the pointer and the integer are the

426 MULTI: Building Applications for Embedded ARM


Type Qualifiers

same size, no data is lost. If the integer is smaller than the pointer, then the data
is reduced from the upper bit.

Japanese Automotive C also makes it legal to declare a bitfield with a type other
than int, signed int, or unsigned int.

For example, compiling the following code with the C/C++ Compiler→C
Language Dialect option set to Strict ANSI C (-ANSI) :
struct {
char b:3;
char c:5;
} s;

would normally generate the following errors:


"x.c", line 3: error #230: nonstandard type for a bitfield
char i:3;
^
"x.c", line 4: error #230: nonstandard type for a bitfield
char c:5;
^

Enabling C/C++ Compiler→C Japanese Automotive Extensions


(-japanese_automotive_c) suppresses these errors.

Type Qualifiers
There are two type qualifiers in all modes except K&R mode: volatile
and const.

volatile
When your C/C++ Compiler→C Language Dialect is set to ANSI (-ansi)
or Strict ANSI (-ANSI), enabling any of the Optimization→Optimization
Strategy settings (see “Optimization Options” on page 143) will implicitly
enable the Advanced→Advanced Optimization Options→Memory
Optimization option (-OM), which assumes that memory locations only
change under the control of the compiler. This assumption is usually, but
not always, true. Exceptions include memory which is updated by interrupt
routines, and memory-mapped I/O.

Green Hills Software, Inc. 427


13. Green Hills C

This optimization allows the compiler sometimes to avoid and/or delay reads or
writes to memory locations by maintaining a copy of the memory location in a
register. This is generally much faster because reads and writes to registers are
faster than reads and writes to memory.

You can use the volatile qualifier to disable this optimization for particular
variables (indicating that they may change), and retain its use for all other
variables.

const
The compiler gives a compile-time error for any attempt to modify an object
declared const. This qualifier also provides the compiler with additional
information for use in optimizations. Wherever the value of a const variable
is visible, the optimizer makes full use of the fact that this variable is simply
a named constant value, combining it with other constants at compile time,
and performing other simplifications. Even when the value of a const is not
visible, the optimizer can make use of the fact that the variable is invariant to
re-sequence statements and instructions or to move them outside of loops.

When const is used with volatile, the compiler never replaces a use of the
object with its value, even if the value of the object is visible.

Assignment and Comparisons on struct and union Types


The assignment operator (=), which is supported in all modes of C, can be used
to assign a value of a structure or a union type to a variable of the same type.
Assignment of one structure or union to another is done with a memory copy of
the data. Comparison is performed on a bit-by-bit basis on the entire structure
or union (including padding bytes).

If there are padding bytes between fields or members of a struct or union


type due to memory alignment requirements, those holes cannot be accessed by
means of the structure or union. Note also that global variables will always be
initialized to zero, and therefore the holes will always be zero; local variables,
however, may have random data in the holes. Therefore, two structures or
unions with the same values for every field may not be equal when compared.
For structures or unions that will be compared, it is important to either have no
holes in the memory representation or to explicitly initialize each such variable

428 MULTI: Building Applications for Embedded ARM


Bitfields

with a structure assignment from a global variable known to have zeros in


the holes.

A structure or a union can be passed as an argument to a function without


restriction. The structure or union is copied when it is passed, however, so
passing a very large structure or union is much less efficient than passing a
pointer. For this reason, we recommend that pointers be passed where possible.

Bitfields
Bitfields in C have a base type which determines the field’s alignment,
maximum size, and whether the field is signed or unsigned.

ANSI C Limitations
The ANSI C standard requires that the base type of a bitfield be either int,
signed int, or unsigned int. This restriction is enforced when the
C/C++ Compiler→C Language Dialect option is set to Strict ANSI C
(-ANSI), and is ignored without warning for all other dialects.

Signedness of Bitfields
Bitfields defined without either a signed or unsigned qualifier are
unsigned by default (note that this default varies between target processor
families). To control the signedness of bitfields manually:

Use the C/C++ Compiler→Data Types→Signedness of Bitfields


option (--signed_fields/--unsigned_fields).

The choice of signed versus unsigned bitfields can significantly affect code
efficiency. Unless the processor has special instructions for this purpose, it
may require two or even three instructions to extract the bits of a signed field
whenever that field is evaluated. This is because the bits must be sign-extended
to the size of an int, which may require two arithmetic shifts.

The following example demonstrates another difficulty with signed bitfields:

Green Hills Software, Inc. 429


13. Green Hills C

int i;
struct {int x:2; } y;
y.x = 2;
i = y.x;
if (y.x > 0) func();

In this example, if x is an unsigned field, i is assigned the value 2 and func() is


called. If x is a signed field, i is assigned the value -2 and func() is not called.
This is because the range represented by a signed field with two bits is from -2
to 1. The value 2 is out of range and so is not detected. Instead, it is interpreted
as -2 when y.x is later evaluated.

Size and Alignment of Bitfields


There is a close relationship between the base type of a field and the space it
occupies, which can be summarized in three ways. First, an individual bitfield
can never have more bits than its base type.

Second, a bitfield must always fit entirely within a memory location that could
hold its base type. It cannot cross a boundary that a simple variable of that type
cannot cross. Thus, a field of type char can be placed in any memory location,
but cannot cross a byte boundary. For example:
struct {
char a:4;
char b:6;
char c:6;
} w;

Variable w requires three bytes because fields a and b do not fit in a single byte.
Therefore, four bits of padding are inserted before field b. Similarly, the fields
b and c do not fit in a single byte, so two bits of padding are inserted before the
field c. On the other hand, if we had:
struct {
short a:4;
short b:6;
short c:6;
} x;

then, variable x would require only two bytes because the total size of the three
fields is less than the size of a short.

430 MULTI: Building Applications for Embedded ARM


Enumerated Types

Third, the alignment of a bitfield is determined by its base type. Padding may
be inserted so that the field and the structure containing it are properly aligned.
In the examples above, w has the alignment of a char, which is usually one
byte, and x has the alignment of a short, which is usually either one or two
bytes. Neither w nor x would be any larger due to alignment. However, in the
following example, y and z will have an extra byte of padding added if short
is 2 byte aligned:
struct {
char byte;
short a:4; /* padding inserted before
’a’ for alignment */
short b:6;
short c:6;
} y;
struct {
short a:4;
short b:6;
short c:6;
char byte; /* padding added after
’byte’ for alignment */
} z;

For information about the size and alignment of C and C++ data types, see
“ARM Characteristics” on page 84.

Enumerated Types
The enum type is treated as one of the integral types. By default, the members
of an enum type (enumerators) are treated as integral constants of type int
or greater (in case any of the values of the enumerators are out of int range).
To instruct the compiler to attempt to use the smallest possible predefined type
(including unsigned types) that allows representation of all listed values:

Set the C/C++ Compiler→Data Types→Use Smallest Type Possible


for Enum option to On (--short_enum).

The ANSI standard does not call for strict type checking with respect to enum
types. In fact, a variable of enumerated type is considered equivalent to any
other integral value. Most operations which are allowed on values of integral

Green Hills Software, Inc. 431


13. Green Hills C

types are also allowed on enumerated types, including assignment of a variable


or member of one enumerated type to a variable or parameter of another type.

Functions with Variable Arguments


Green Hills C and C++ compilers support functions with variable parameters.
In C K&R mode, this is done using the <varargs.h> facility, while in
ANSI C modes and C++, it is done using the <stdarg.h> facility. The two
implementations are different and incompatible. Take care to use the correct
facility for the appropriate mode of C.

An important limitation of variable parameters is that the types char, short,


and float are not supported. When a function with variable parameters is
called, the caller promotes expressions of these types to int (for char and
short) and double (for float). Overall, inside a function with variable
parameters, only variables of types int, long, double, and pointer should
be expected as parameters.

The <varargs.h> Facility


To use the <varargs.h> facility, you must perform the following steps:

1. The line #include <varargs.h> must appear before the first


function definition.
2. The last parameter of a variable argument list function must be named
va_alist.
3. The last parameter declaration of a variable argument list function must
be va_dcl.
4. There must not be a semicolon (;) between va_dcl and the initial left
brace ({) of the function.
5. There must be a variable declared in the function of type va_list.
6. The <varargs.h> facility must be initialized at the top of the function by
passing the variable of type va_list to a call of the macro va_start.
7. To obtain the variable arguments to the function, in left-to-right order, the
macro va_arg is invoked once for each argument. The first argument to
the macro va_arg is the variable of type va_list. The second argument

432 MULTI: Building Applications for Embedded ARM


Functions with Variable Arguments

is the type of the current argument of the function. The va_arg macro
returns the value of the current argument of the function.
8. The <varargs.h> facility must be terminated by passing the variable of
type va_list to a call of the macro va_end at the end of the function.

Example 1.
#include <varargs.h>
/* Return the sum of a variable number of "int" arguments */
Sum(n, va_alist)
int n;
va_dcl /* steps 3 and 4 */
{
va_list params; /* step 5 */
int ret = 0;
va_start(params); /* step 6 */
while (n-- > 0) {
ret += va_arg(params,int); /* step 7 */
}
va_end(params); /* step 8 */
return(ret);
}

The <stdarg.h> Facility


The <stdarg.h> facility has some additional limitations. First, every function
with variable parameters is required to have at least one fixed parameter.
Second, a prototype for the function must appear before its first invocation.

To use the <stdarg.h> facility, you must perform the following steps:

1. The line #include <stdarg.h> must appear before the first function
definition.
2. In the function definition, at least one fixed parameter must appear in the
parameter list before the ellipsis (...).
3. The last parameter in the function’s parameter list must be ellipsis (...).
4. There must be a variable declared in the function of type va_list.
5. The variable argument processing must be initialized by invoking the
macro va_start at the beginning of the function with two parameters:
(1) the variable of type va_list, and (2) the last fixed parameter in the
function parameter list.

Green Hills Software, Inc. 433


13. Green Hills C

6. To obtain the variable parameters to the function in left to right order,


invoke the macro va_arg once for each parameter. The first parameter to
va_arg is the variable of type va_list. The second parameter is the
type of the current parameter of the function. The va_arg macro returns
the value of the current parameter of the function.
7. The variable argument processing must be terminated by invoking the
macro va_end with the variable of type va_list as its parameter.

Example 2.
#include <stdarg.h>

/* Return the sum of the parameter, with the first


parameter being a parameter type string. */
double sum(const char *key, ...)
{
double ret = 0;
va_list ap;
va_start(ap, key);
while (*key) {
switch (*key++) {
case ’i’: ret += va_arg(ap, int); break;
case ’l’: ret += va_arg(ap, long); break;
case ’d’: ret += va_arg(ap, double); break;
case ’p’: ret += *(va_arg(ap, int*)); break;
}
}
va_end(ap);
return ret;
}

The asm Statement


The asm statement generates in-line assembly code; it can be used anywhere a
statement can be used within a function and anywhere a declaration can be used
outside of a function. There are two spellings: __asm and asm. Only __asm
is recognized in the Strict ANSI C mode.
__asm ("assembler_string");

or
asm ("assembler_string");

434 MULTI: Building Applications for Embedded ARM


The Preprocessor

The entire contents of the string will be passed through to the assembly
language output file in the same position as it appears in the source file. If the
underlying assembler requires a space or tab before the opcode, this tab or
space must appear in the string.

For example:
asm (" sethi %hi(L16),%o0");

This statement drops the sethi instruction into the assembly code generated by
the compiler, corresponding exactly to where the compiler found it in the source
code. See also Chapter 18, “Enhanced asm Macro Facility for C and C++”.

To control the diagnostic messages associated with asm statements:


Set the Compiler Diagnostics→C/C++ Messages→Asm Statements
option to one of the following settings:
• Errors (--asm_errors)
• Warnings (--asm_warnings)
• Silent (--asm_silent)

Note The compiler uses assembly language instructions and directives


throughout the file without concern for possible interactions with user asm
statements. Furthermore, the allocation of variables to registers and memory
may vary from one compilation to another. Therefore, the use of the asm
statement is considered non-portable and may be difficult to maintain.

The Preprocessor
Green Hills C and C++ compilers include a built-in preprocessor. Preprocessing
is normally performed in a single pass. The setting of the C/C++ Compiler→C
Language Dialect option affects the behavior of the preprocessor. If ANSI C
(-ansi) or Strict ANSI C (-ANSI) is specified, then preprocessing follows the
ANSI standard, while K+R C (-k+r) follows the traditional UNIX rules.

Preprocessor Output File


By default, preprocessing is performed concurrently with compilation and no
intermediate output is generated. Preprocessed output may be written to a
.i file as follows:

Green Hills Software, Inc. 435


13. Green Hills C

When using the Builder, right-click the appropriate file and choose
Preprocess from the context-sensitive menu.
When using the driver, pass the -P option. You can also use the -E
option to direct output to stdout. This latter option includes #line
directives corresponding to the original file.

C Run-Time Library
On UNIX systems, Green Hills C can use the standard C library. The Green
Hills ANSI C Library, libansi.a , is provided for users needing an ANSI C
library and for those on non-UNIX systems which do not already have a C
library.

Extended Characters
English has a small alphabet, which is easily represented in eight bits by the
ASCII character set. However, many languages require more space, and
character sets that need more than 8 bits can be handled in two ways by ISO
C/C++:

• Multi-Byte Characters — uses traditional C strings to represent the


non-ASCII characters. For example, Kanji characters in the EUC or
Shift-JIS format require two consecutive bytes to represent a single Kanji
character. In both cases, the first byte has a value outside the normal ASCII
range, which allows a program to recognize that the following byte should
be treated as the rest of the current Kanji character. Multi-byte characters
can be mixed with normal ASCII characters within the same string. Thus
the length of a string in bytes does not directly correspond to the number
of characters represented by the string. Some characters are one byte and
others require more. Hence the term multi-byte.
• Wide Characters — are simply fixed-width (16 or 32 bit) characters. Wide
characters were introduced by the ANSI/ISO C standard of 1990. The prefix
“L” is used to mark a character or string literal as wide. The wchar_t type
matches the type of L’x’ and L"hello"[3].

The multi-byte string looks just like a traditional string in C, where each element
of the string has type char (or signed char or unsigned char). The
wide character string uses more space because each element of the string has
type wchar_t, which occupies either 16 or 32 bits depending on the target.

436 MULTI: Building Applications for Embedded ARM


Extended Characters

The advantages of wide characters over multi-byte characters are:

• The length of the string directly corresponds to the number of characters in


that string. For example, the third character in a wide character string is
always the third element, but in a multi-byte character string it could be one
element or two. The character could even begin after the second, third, or
fourth byte, depending upon whether there are Kanji or ASCII characters
preceding it in the string.
• You can form a single wide character, such as L’5’, representing one
extended character.

However, wide characters take up more space and, more importantly, they
cannot be manipulated by the large number of existing routines that were
written for traditional C character strings, requiring instead special wide
character functions.

Amendment 1 to the ISO C standard, adopted in 1995 and incorporated into both
the ISO C++ standard and the ISO C99 standard, added many new functions to
the standard C library in order to provide support for wide characters. These
new functions include wprintf() and wscanf(), together with most of the
functions in string.h and ctype.h, and have been added to libansi.a.

Note In addition to requiring the new functions, the standard also modifies
the behavior of printf() and scanf() and their derivatives to support
wide character strings and individual wide characters. The Green Hills
implementation does not provide these modifications in order to minimize the
impact of such changes on the size, speed, and stability of existing applications.

Compiler Support for Extended Characters


The Green Hills Software C/C++ compilers deal with extended character sets
in two different places and reject them elsewhere. Extended characters may
appear in comments and in character or string literals, but they may not appear
in variable names.

The compiler may not need to know everything about an extended character
set in order to parse comments or character and string literals which contain
extended characters. The compiler does need to be able to detect the end of a
string or comment. Therefore, if the extended character set contains no values
which have bytes that match punctuation the compiler is looking for, such as ’

Green Hills Software, Inc. 437


13. Green Hills C

\ ", the compiler will be able to scan the comment or literal without requiring
knowledge of the extended character set.

Parsing of wide character literals, however, is more difficult. The compiler must
know the encoding of the extended character set in order to determine which
bytes make up each element of type wchar_t. For example, L"hello"
will result in a string of type wchar_t[6], because each of the characters is
ASCII (which the compiler understands). If, however, the five bytes in the
string literal were not ASCII, the compiler must decide which bytes compose
the first wchar_t element, and so on.

Applications requiring an extended character set other than these will not
be able to use wide character literals with the Green Hills Software C/C++
compilers. Instead, all literals must be written as multi-byte strings and
converted using functions such as mbstowcs(). Furthermore, if the extended
character set has bytes which match certain ASCII punctuation characters,
multi-byte string literals may not be used either. In either case, it is possible to
place extended character strings in external data files and load them into the
application at run time. The application can still make full use of the Green
Hills C and C++ library routines to manipulate both wide character strings and
multi-byte strings even if the compiler cannot parse string literals containing the
extended character set.

The following list details the limitations to wide character support:

1. The regular printf() and scanf() routines do not support wide


characters (such as %lc for wint_t or %ls for wchar_t *).
2. Since the extended character sets that we support directly do not require
state information, our implementation ignores mbstate_t. Consequently
support for state-dependent encoding is not provided.
3. The fwide() function implies a file orientation that can be either wide or
non-wide. To set the orientation to byte-oriented, call fwide() with a
negative value.
4. Locale is ignored. The default (and only) behavior is to support a
combination EUC and Shift-JIS encodings.

Kanji Character Support


Kanji is the Japanese name for one of the written forms of Japanese. Almost all
Kanji characters are taken from Chinese, although a few are specific to Japanese.

438 MULTI: Building Applications for Embedded ARM


Extended Characters

Both Chinese and Kanji use one or more characters to represent a word. In
Chinese, each character is monosyllabic; in Japanese, a Kanji character can
be monosyllabic, polysyllabic, or both, depending on the character. (Almost
all Kanji characters have multiple pronunciations.) There are over 30,000
characters in Chinese, but Kanji routinely uses only a portion of them. For
example, one can read a Japanese newspaper knowing fewer than 2,000 Kanji
characters. The computer representations for Kanji provide between 5,000
and 10,000 Kanji characters.

In Japanese, there is also a phonetic alphabet with fewer than 100 characters.
Just like the English alphabet, this alphabet has cursive and block forms. They
are called Hiragana (cursive) and Katakana (block). Today Katakana characters
are used to spell foreign words and proper names phonetically.

The Green Hills Software C/C++ compiler supports two representations of


Kanji, EUC and Shift-JIS. To enable support for Kanji:
Set the C/C++ Compiler→Special Tokens→Host & Target Kanji
Support option to:
• EUC on Host and Target (-kanji=euc)
• Shift-JIS on Host and Target (-kanji=shiftjis)
• EUC on Host and Shift-JIS on Target (-kanji=euc/shiftjis)

The Green Hills C and C++ compilers provide support for Kanji characters in
comments, character strings, and character constants. Their use in variable
names or other identifiers is not supported because of the conflicts it would
cause with syntactic rules requiring identifiers to begin with a letter or
underscore. For example, the EUC representation of Kanji uses two bytes
for a single character, and neither byte is in the normal ASCII range. Thus a
compiler can scan a C string literal containing EUC Kanji characters without
any knowledge of the multi-byte representation. The Shift-JIS representation
of Kanji, however, allows normal ASCII characters in the second byte. The
compiler must have knowledge of Shift-JIS in order to correctly parse a string
literal containing Shift-JIS characters where the second byte has the value \
or ", for example.

Some Japanese vendors provide a Kanji preprocessor which allows Kanji


characters to be used in identifiers in C. Many companies manufacture PCs and
Workstations with support for Kanji in both the keyboard and display.

Green Hills Software, Inc. 439


13. Green Hills C

Green Hills run-time libraries also correctly process character data containing
Kanji characters. There are several different ways to represent Kanji characters.
The Kanji representation directly supported by Green Hills compilers uses a
pair of characters to represent a single Kanji character. The first character is
always in the range of 0xa0 to 0xfe and the second character is always in
the range of 0x80 to 0xfe.

The exact representation of Kanji is usually irrelevant to the compiler and


libraries, as long as neither byte conflicts with special values such as \0, \n,
\r, ", \’, etc.

The C compiler allows a 2-byte Kanji character with single quotes. This is
easily done, as C allows two ASCII characters between single quotes.

Compiler Limitations
The ANSI standard requires that a conforming compiler implementation accept
programs of a certain complexity and size. These requirements are expressed
in terms of a list of acceptable limits. The Green Hills compiler meets the
requirements. The compiler has a specific upper limit for only one of the limits
(nested #include files). All other features are limited only by available
memory. For completeness, we list below all of the limits addressed by the
ANSI standard, giving, first, the number which the standard requires and,
second in parentheses, the number which the Green Hills compiler supports.
The code (U) indicates the compiler is theoretically unlimited.

The code (U > n) indicates that the compiler is theoretically unlimited, but it is
tested to handle the value n.

• 15 nesting levels of compound statements, iteration control structures and


selection control structures (U > 500)
• 8 nesting levels of conditional inclusion (U > 500)
• 12 pointer, array, and function declarators (in any combination) modifying
an arithmetic, structure, union, or incomplete type in a declaration (U > 64)
• 31 nesting levels of parenthesized declarators within a full declarator (U)
• 32 nesting levels of parenthesized expressions within a full expression (U
> 200)
• 31 significant characters in an external identifier (U)

440 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

• 511 external identifiers in one translation unit (U)


• 127 identifiers with block scope declared in one block (U)
• 1024 macro identifiers simultaneously defined in 1 translation unit (U)
• 31 parameters in one function declaration (U > 100)
• 31 arguments in one function call (U > 100)
• 31 parameters in one macro definition (U > 100)
• 31 arguments in one macro call (U > 100)
• 509 characters in a logical source line (U > 3000)
• 509 characters in a character string literal or wide string literal (after
concatenation) (U > 3000)
• 8 nesting levels for #include files (64)
• 257 case labels for a switch statement, excluding those for any nested
switch statements (U)
• 127 members in a single structure or union (U)
• 127 enumeration constants in a single enumeration (U)
• 15 levels of nested structure or union definitions in a single
struct-declaration-list (U)

ANSI C Implementation Defined Features


The ANSI standard for the C Programming Language (X3J11/90-013) leaves
certain details of the language unspecified. Throughout the standard, various
details are described as “undefined” or “implementation defined”. The
following definitions are taken from the standard for these and related terms:
Term Meaning
implementation-defined Behavior, for a correct program construct and correct
behavior data, that depends on the characteristics of the
implementation and that each implementation shall
document.

Green Hills Software, Inc. 441


13. Green Hills C

Term Meaning
undefined behavior Behavior, upon use of a nonportable or erroneous
program construct, of erroneous data, or of
indeterminately valued objects, for which this
International Standard imposes no requirements.
Permissible undefined behavior ranges from ignoring
the situation completely with unpredictable results, to
behaving during translation or program execution in a
documented manner characteristic of the environment
(with or without the issuance of a diagnostic message),
to terminating a translation or execution (with the
issuance of a diagnostic message).
unspecified behavior Behavior, for a correct program construct and correct
data, for which this International Standard explicitly
imposes no requirements.

The standard requires that a conforming implementation provide documentation


which describes the behavior in each case where the standard uses the phrase
“implementation defined”. This chapter describes the behavior of the ARM
compiler in each such case. Features are listed according to the sequence in
which they appear in the standard, with citations referring to the appropriate
section of the standard.

Translation F.3.1
Each non-empty sequence of whitespace characters, other than new line, is
replaced by one space character.

Diagnostic messages all have the form:


"filename", line nnn: content_of_message
offending_source_line

There are two classes of messages: warnings and errors. All warning
diagnostics have warning at the beginning of the message field.

The compiler returns one (indicating failure), if any errors were reported, and
zero (indicating success), if there were no errors.

The level of diagnostic can be controlled.

To suppress compiler warnings:

442 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

Set the Compiler Diagnostics→Warnings option to Suppress (-w).

Environment F.3.2
No further processing occurs after program termination in a stand-alone
environment.

In hosted execution environments, two arguments are passed to the function


main:
int main(int argc, char *argv[]);

The argument argc is the number of valid elements in the argv array.

The argument argv is a null-terminated array of command line words.

In a stand-alone environment, no arguments are passed to the function main.

Identifiers F.3.3
A total of 255 characters are significant in an identifier without external linkage.

A total of 255 characters are significant in an identifier with external linkage.

Case is significant in an identifier with external linkage.

Characters F.3.4
The escape sequence values are as follows.
Sequence Value
\a 7
\b 8
\f 12
\n 10
\r 13

Green Hills Software, Inc. 443


13. Green Hills C

Sequence Value
\t 9
\v 11

There are no shift states in the encoding of multi-byte characters.

There are eight bits in a character in the execution character set.

The source and execution character sets are identical and the mapping is direct.

The basic execution character set includes all possible single-byte characters and
the extended character set includes all possible 4-byte characters. Therefore,
there are no characters or escape sequences represented in these two character
sets.

An integer character constant may contain up to four characters. The value is


calculated as follows: the least significant byte of the integer is the ASCII code
for the rightmost character. The next byte of the integer is the ASCII code for
the second character from the right, and so on.

A wide character constant that contains more than one multi-byte character
has the same integer value as a wide character constant consisting only of the
rightmost multi-byte character.

The C locale is used to convert multi-byte characters into corresponding wide


characters (codes) for a wide character constant.

The character type char is unsigned by default (note that this default
varies between target processor families). To control the signedness of chars
manually:

Use the C/C++ Compiler→Data Types→Signedness of Char Type


option (--signed_chars/--unsigned_chars).

Integers F.3.5
The table below shows the storage and range of various variable types:

444 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

Size
Designation (bits) Range
char 8 0..255
signed char 8 -128..127
unsigned char 8 0..255
short 16 -32768..32767
signed short 16 -32768..32767
unsigned short 16 0..65535
int 32 -2147483648..2147483647
signed int 32 -2147483648..2147483647
unsigned int 32 0..4294967295
long 32 -2147483648..2147483647
signed long 32 -2147483648..2147483647
unsigned long 32 0..4294967295

Truncation occurs when an integer is converted to a shorter signed integer.

Conversion of an unsigned integer to a signed integer of equal length does not


modify the bit pattern of the number. Signed integers are represented in two’s
complement. Therefore such a conversion on a number with the high order
bit set produces a negative number equal to (original_value - pow(2,n)),
where n is the number of bits.

The result of bitwise operations on signed integers is a signed integer whose


two’s complement representation pattern is the result of applying the bitwise
operation on the two’s complement representation of the arguments.

The sign of the remainder of integer division will have the same sign as the
dividend, if the remainder is not zero.

The right shift of a negative-value signed integral type produces a signed


integral value, arithmetically shifted to the right.

Floating-Point F.3.6
The amount of storage and the range of various floating-point numbers are
shown below:

Green Hills Software, Inc. 445


13. Green Hills C

Size
Designation (bits) Range in bits
float 32 1.1754943635e-38 to
3.4028235e+38
double 64 2.2250738585072015e-308 to
1.7976931348623158e+308
long double 64 2.2250738585072015e-308 to
1.7976931348623158e+308

The direction of truncation when an integral number is converted to a


floating-point number that cannot exactly represent the original value is to the
nearest representable value. In other words, the value is rounded.

The direction of truncation or rounding when a floating-point number is


converted to a narrower floating-point number is to the nearest representable
value. In other words, the value is rounded.

If a floating-point value is stored in an extended precision register on a ARM


hardware floating-point target, the value will be expressed in 80 bits, but will
be rounded to the correct size for the value’s type when the value is stored to
memory.

Arrays and Pointers F.3.7


The type of the integer required to hold the maximum size of an array is
unsigned int. This is the type of size_t.

The type of integer required for a pointer to be converted to an integral type is


int; its size is 4 bytes.

Casting a pointer to an int or vice-versa has no effect on the bit pattern of


the value.

The type of the integer required to hold the difference between two pointers to
members of the same array is int. This is the type of diff_t.

446 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

Registers F.3.8
The register storage class specifier causes the compiler to give first priority to
the given variable when allocating variables to registers. Therefore, the register
storage class specifier significantly affects allocation of variables. Because the
compiler’s automatic allocation of registers is very good, the register storage
class specifier usually has a negative impact on allocation and should be used
very sparingly.

Structures, Unions, Enumerations and Bit-fields F.3.9


If a union member is accessed using a member of a different type, the result
depends upon the pair of types involved. Consider the following code fragment:
typedef signed int a_t;
typedef unsigned int b_t;
union {
a_t a;
b_t b;
} u;

a_t m;
b_t n;

main()
{
u.a = m;
n = u.b;
}

The members of the union u are declared with two different types. A value is
assigned to u.a and the other member of the union, u.b, is evaluated. Whether
the value of m will equal n depends on the types of a and b. The various cases
are described below:
If a_t and b_t are integral or pointer types and have the same size, then the value
of n will be the same as if m was assigned to n directly, as

n = (b_t) m
If a_t and b_t are integral or pointer types and a_t is larger than b_t, then the
value of n will be as if this assignment were performed:

n = (b_t)((int) m);

Green Hills Software, Inc. 447


13. Green Hills C

If a_t and b_t are integral or pointer types and a_t is smaller than b_t, then the
value of n will be as if this assignment was performed:

n = (b_t)((int) m);

except the high bytes of n would be determined by the contents of memory before
the assignment of m to u.a.
If either a_t or b_t is an integral or pointer type and the other is a floating-point
type, such that both a_t and b_t are the same size in bytes, then the value of n
will depend upon the IEEE-695 signed magnitude representation of floating-point
numbers and the two’s complement or unsigned binary representation of integer
numbers. The bit-pattern of m will be interpreted as a bit-pattern of the alternate
representation. It is possible that illegal values will result if a_t is integral and
b_t is float.
If either a_t or b_t is an integral or pointer type and the other is a floating-point
type, such that a_t is smaller than b_t, then the high bytes of b_t will be taken
from a_t and the low bytes will depend on the contents of memory before the
assignment of m to u.a.
If either a_t or b_t is an integral or pointer type and the other is a floating-point
type, such that a_t is larger than b_t, then the content of b_t will be taken from
the high bytes of a_t and the low bytes of a_t will be discarded.
If a_t and b_t are both arrays of integral or pointer types, where the elements of
each array are of the same size, then the value of n[0] will be the same as if by
direct assignment of m[0] to n[0] and so forth for the first k elements of m and
n, where k is the length of the smaller array. If n is longer than m, the elements
of n beyond the first k will be determined by the contents of memory before the
assignment of m to u.a.
If a_t and b_t are both arrays of integral or pointer types, and the elements of
a_t are larger than the elements of b_t, then the low byte or bytes of m[0] will
be used for the value of n[0], and the higher byte or bytes of m[0] will be used
for the value of n[1], and so on up to n[sizeof(m[0])/sizeof(n[0])-1].
This process continues until the elements of either m or n have been exhausted. If
there are remaining elements in n, they will depend upon the contents of memory
before the assignment of m to u.a.
If a_t and b_t are both arrays of integral or pointer types, and the elements of a_t
are smaller than the elements of b_t, then the contents of m[0] will be used for
the low byte or bytes of n[0] and the contents of m[1] will be used for the higher
byte or bytes of n[0], and so on up to n[sizeof(m[0])/sizeof(n[0])-1].
This process continues until the elements of either m or n have been exhausted. If
there are remaining elements in n, they will depend upon the contents of memory
before the assignment of m to u.a.

Other unions involving arrays and floating-point numbers may be understood


by applying the rules above for converting float to int and then from int

448 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

to an array type ([]), and so on. Members of structures are padded and aligned
as described in “ARM Characteristics” on page 84. All structure members
except bitfields begin on a byte boundary. A structure is aligned according to
the strictest alignment of any of its members. An array member is aligned
according to the alignment requirement of its elements. Padding is performed
when necessary to ensure that a member or bitfield begins on its required
alignment. There is never any padding before the first member or bitfield, but
there is padding after the last member or bitfield if it is needed to ensure that the
size of the structure is a multiple of its alignment.

Bitfields may be declared with any standard integer base type (including
signed long long and unsigned long long if supported). They
may also be declared with _Bool or enum base types. When a bitfield is
used in an integral context, its value is converted to a standard integer type in
the following way. All standard integer types with rank greater than or equal
to int are ordered from least to greatest rank with signed types preceding
unsigned types of the same rank. The value is then converted to the first type
in this ordering that can represent all of the values of the original bitfield type.
For example, on a target where the long type has the same number of bits as
the int type and the long long type is supported, a bitfield value would
be promoted as follows. If an int can represent all values of the original
type, the value is converted to an int; otherwise, if an unsigned int can
represent all values of the original type, the value is converted to an unsigned
int; otherwise, if a long long can represent all values of the original
type, the value is converted to a long long; otherwise, it is converted to an
unsigned long long.

A bitfield must be wholly contained within a storage unit meeting the size and
alignment requirements of its declared base type. Padding is inserted between
bitfields as required to satisfy this constraint. For example:
struct {
int a:20;
int b:20;
long long c:20;
};

On a target with 32-bit ints with 32-bit alignment, there will be 12 bits of
padding between a and b since b cannot cross a 32-bit aligned boundary.
On a target with 64-bit long longs with 64-bit alignment, there will also
be 12 bits of padding between b and c since c cannot cross a 64-bit aligned
boundary. On a target with 64-bit long longs with 32-bit alignment, there

Green Hills Software, Inc. 449


13. Green Hills C

will be no padding between b and c since a long long can cross one 32-bit
aligned boundary; however, if c were declared to contain more than 44 bits,
there would then be 12 bits of padding between b and c since a 32-bit aligned
long long cannot cross two 32-bit aligned boundaries.

As long as the above constraint is met, multiple bitfields, even those of different
base types, may occupy the same storage unit. Within a particular storage unit,
bitfields are allocated in increasing memory address order. This means on a
big endian target the first bitfield will occupy the most significant bits of the
storage unit, and on a little endian target the first bitfield will occupy the least
significant bits. For example:
struct {
int a:10;
char b:4;
short c:5;
};

Assuming that ints are 32 bits, shorts are 16 bits, chars are 8 bits, and
the alignment of each type matches its size, there will be no padding between a
and b, but there will be 2 bits of padding between b and c. If bytes are 8 bits,
all three fields will occupy one 4-byte storage unit, with a occupying the first
byte, a and b sharing the second byte, and c occupying the third byte.

For information about controlling the signedness of bitfields, see “Signedness


of Bitfields” on page 429. For information about controlling the size and type
of enumerations, see “Enumerated Types” on page 431.

Qualifiers F.3.10
Any dereference of a pointer, such as *p, constitutes an access to an object, x,
with volatile-qualified type if any address from the value of p up to the value of
p plus sizeof(*p) less one is greater than or equal to the address of x and less
than the sum of the address and size of x.

Declarators F.3.11
There is no specific limit on the number of declarators that may modify an
arithmetic, structure, or union type.

450 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

Statements F.3.12
There is no specific limit on the number of case values in a switch.

Preprocessing Directives F.3.13


The value of a single character constant in a constant expression that controls
conditional inclusion matches the value of the same character constant in the
execution character set.

Such a character constant can have a negative value.

If the file is included using the form #include file, the directory containing
the file in which the #include directive occurs is searched first. If the
directory does not contain the file, or if the file is using the form #include
<file>, a list of user-specified directories is searched. For information about
specifying include directories, see “Using Your Own Header Files and
Libraries” on page 96.

The include directive form #include file is supported as described above.

Quoted names are supported for source files that can be included.

In the #include directive, delimited character sequences are passed through


to the operating system unchanged.

For a list of the recognized #pragma directives, see “#pragma Directives”


on page 526.

The __DATE__ and __TIME__ macros always have a time available.

Library Functions F.3.14


NULL expands to zero.

If the following is line 15 of a file called test.c:


assert(1==2);

the program would print the following to stderr and then call abort().
Assertion failed: "1==2", file "test.c", line 15

Green Hills Software, Inc. 451


13. Green Hills C

The following table explains the return values of the listed functions for certain
characters:
Function Characters for which non-zero value is returned
isalnum ’A’..’Z’, ’a’..’z’, and ’0’..’9’
isalpha ’A’..’Z’ and ’a’..’z’
iscntrl 0..31 and 127..255
islower ’a’..’z’
isprint 32..126
isupper ’A’..’Z’

The following values are returned by math functions for domain errors:
Function(s) Input values Return value
acos,acosf |x| > 1.0 0.0
acosh x < 1.0 0.0
asin,asinf |x| > 1.0 0.0
asinh x < 1.0 0.0
atan2,atan2f x==0.0,y==0.0 0.0
atanh x==1 or x < -1 0.0
log,logf x <= 0.0 0.0
pow,powf x==0.0 and y<0.0 0.0
sqrt,sqrtf x < 0.0 0.0

Only the functions exp, pow, and tan detect underflow and set errno to
ERANGE.

The function fmod() returns 0.0 when the second argument is zero.

Additional Features

Signals
The equivalent of signal(sig, SIG_DFL) is executed prior to the call of
a signal handler.

452 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

Default handling is reset if a SIGILL signal is received by a handler specific


to the signal function.

Streams and Files


The last line of a text stream does not require a terminating new line character if
the operating system is UNIX. Other systems vary.

Space characters written out to a text stream immediately before a new line
character appear when the stream is read back on UNIX. Other systems vary.

No null characters are appended to data written to a binary stream on UNIX.


Other systems vary.

The file position indicator of an append mode stream is initially positioned


at the end of the file.

A write on a text stream does cause the associated file to be truncated beyond
that point.

Unbuffered, fully buffered, and line buffered modes are all provided in hosted
environments. Embedded environments provide a limited form of buffering
which is essentially unbuffered, but which provides the benefits of buffering
within operations such as fwrite and printf.

A zero length file can exist on UNIX. Other systems vary.

The rules for composing a valid filename differ between systems.

The same file can be opened multiple times.

Removing an open file has unpredictable results. In most cases the application
program will only have access to a portion of the file as it was before it was
deleted. Once the application exits, the file will cease to exist entirely even if
the application was writing to the file.

The effect of renaming a file to a name of a file which already exists varies
between systems. On some systems it is undetected and the old file is lost. On
others, the rename fails and all files remain unchanged.

The %p format descriptor in printf behaves exactly as %x.

The %p format descriptor in scanf behaves exactly as %x.

Green Hills Software, Inc. 453


13. Green Hills C

If the - is neither the first character nor the last character in the scan list for [
conversion in the fscanf function, all characters in the range beginning with
the character preceding the - up to and including the character following the -
are added to the scan set. If the character following the - lexically precedes the
character before the -, then the - and the character following it are ignored.

tmpfile
An open temporary file is not removed if the program terminates abnormally.

errno
The functions fgetpos() and ftell() set errno to EBADF on failure.

The function perror prints a message in this format:


argument: contents_of_message

where argument is the parameter passed to perror and contents_of_message


is a predefined message associated with the current value of errno.

Memory
The functions calloc, malloc, and realloc return NULL if the size
requested is zero. If the library libkr.a is linked into the application or if
memory checking is enabled, these functions will return a valid pointer.

abort()
When abort() is called, the buffers within the stdio library for open files are
not flushed. The files are closed and will exist. Temporary files will not be
deleted.

exit()
The low-order eight bits of the argument passed to exit are returned as the status.

454 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

getenv()
The only limitation on environment names is that they may not contain the
character = which is used to separate the name from its value.

The method to alter the environment list obtained by a call to the getenv
function is to call the function setenv(char *name, char *value).
This will set the environment variable named by the null-terminated string
name to a copy of the null-terminated string pointed to by value.

system()
The format of the string passed to system() may be of any format.

The function system() performs no operation.

strerror()
The strings returned by strerror for the various values of errno are listed
below:
00: "Error 0 (no error)" 18: "Cross-device link"
01: "Not owner" 19: "No such device"
02: "No such file or directory" 20: "Not a directory"
03: "No such process" 21: "Is a directory"
04: "Interrupted system call" 22: "Invalid argument"
05: "I/O error" 23: "File table overflow"
06: "No such device or address" 24: "Too many open files"
07: "Arg list too long" 25: "Not a typewriter"
08: "Exec format error" 26: "Text file busy"
09: "Bad file number" 27: "File too large"
10: "No children" 28: "No space left on device"
11: "No more processes" 29: "Illegal seek"
12: "Not enough core" 30: "Read-only file system"
13: "Permission denied" 31: "Too many links"
14: "Bad address" 32: "Broken pipe"
15: "Block device required" 33: "Argument too large"

Green Hills Software, Inc. 455


13. Green Hills C

16: "Mount device busy" 34: "Result too large"


17: "File exists" 35: "Non standard error"

There is little formatting style to the string returned by strerror(). The first
character is always capitalized and the string does not end with a period.

Locale Behavior (G.4)


The program is run in the local time zone and Daylight Savings Time.

The era for the clock function’s Local Specific Behavior is Midnight, January
1, 1970 (GMT).

The characters in the execution set in addition to those required by the C


standard are listed in “Characters F.3.4” on page 443.

The direction of printing is left to right.

The decimal point character is a period (.).

Character Testing and Case Mapping


The execution character set in its natural sequence is the ASCII character set.
00 nul 01 soh 02 stx 03 etx 04 eot 05 enq 06 ack 07 bel
08 bs 09 ht 0A nl 0B vt 0C np 0D cr 0E so 0F si
10 dle 11 dc1 12 dc2 13 dc3 14 dc4 15 nak 16 syn 17 etb
18 can 19 em 1a sub 1b esc 1c fs 1d gs 1e rs 1f us
20 sp 21 ! 22 " 23 # 24 $ 25 % 26 & 27 ’
28 ( 29 ) 2A * 2B + 2C , 2D - 2E . 2F /
30 0 31 1 32 2 33 3 34 4 35 5 36 6 37 7
38 8 39 9 3A : 3B ; 3C < 3D = 3E > 3F ?
40 @ 41 A 42 B 43 C 44 D 45 E 46 F 47 G
48 H 49 I 4A J 4B K 4C L 4D M 4E N 4F O
50 P 51 Q 52 R 53 S 54 T 55 U 56 V 57 W
58 X 59 Y 5A Z 5B [ 5C \ 5D ] 5E ^ 5F _
60 ‘ 61 a 62 b 63 c 64 d 65 e 66 f 67 g

456 MULTI: Building Applications for Embedded ARM


ANSI C Implementation Defined Features

68 h 69 i 6A j 6B k 6C l 6D m 6E n 6F o
70 p 71 q 72 r 73 s 74 t 75 u 76 v 77 w
78 x 79 y 7A z 7B { 7C | 7D } 7E ~ 7F del

The strftime function converts %c, %x, and %X as follows:


"%c" is equivalent to "%a %b %d %H:%M:%S %Y"
"%x" is equivalent to "%a %b %d, %Y"
"%X" is equivalent to "%H:%M:%S"

Green Hills Software, Inc. 457


13. Green Hills C

Amendment 1 Compliance
This release complies with Amendment 1 to the ANSI/ISO standard for C. The
main focus of Amendment 1 was to address the needs of foreign character sets,
primarily wide characters (for more information, see “Extended Characters”
on page 436).

Header File iso646.h


Header File iso646.h is provided, containing the following macro definitions:
#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=

Header File wchar.h


Header File wchar.h is provided, containing the following:

• The following types are defined:


wchar_t
mbstate_t
wint_t
• The following macros are defined:
WCHAR_MAX
WCHAR_MIN

458 MULTI: Building Applications for Embedded ARM


Amendment 1 Compliance

WEOF
• More than sixty new functions to operate on wide characters are declared.
These functions correspond to functions for characters in stdlib.h, stdio.h,
and string.h.

Header File wctype.h


Declares many macros and functions to classify and map wide characters similar
to the macros and functions which operate on characters declared in ctype.h.

The EILSEQ macro


The Amendment 1 EILSEQ macro, is added to errno.h. No other changes were
necessary to achieve Amendment 1 compliance in this header file.

Green Hills Software, Inc. 459


13. Green Hills C

ISO C99 Compliance


This section lists all the features of ISO C99 that are supported in this release.
Note that all the features specified by Amendment 1 were integrated into the ISO
C99 standard. Therefore the full set of ISO C99 features includes everything
listed in “Amendment 1 Compliance” on page 458, plus the items listed below.

The long long Data Type


The long long data type is supported in conformance with ISO C99,
including the following:

• long long is recognized by default as an integral type. To disable this


data type:

Set the C/C++ Compiler→Data Types→Long Long Support option


to Off (--no_long_long).

• The following predefined symbol is provided:


__LLONG_BIT (has the value 64)
• The following symbols are defined in limits.h:
LLONG_MIN
LLONG_MAX
ULLONG_MAX
• The following type is defined in stdlib.h:
lldiv_t
• The following functions are available in the C library and stdlib.h:
atoll() converts the initial portion of the string pointed to by its
argument to a long long int representation.
strtoll() and strtoull() take their string argument and convert
it to a long long int and long long unsigned int,
respectively.
llabs() returns the absolute value of its long long int argument.

460 MULTI: Building Applications for Embedded ARM


ISO C99 Compliance

lldiv() takes two long long int arguments and returns both
arg1/arg2 and arg1%arg2 in a single operation.

// Comments
Comments of the form // are supported by default in conformance with ISO
C99. To disable this feature:

Set the C/C++ Compiler→Allow C++ Style Slash Comments in C


option to Off (--no_slash_comment).

Header File math.h


The following ISO C99 functions are added to math.h and the C library:

• isnormal() returns zero if its argument value is infinite, zero, or a NaN.


• signbit() returns a non-zero value if its argument is negative.
• isnan() returns a non-zero value if its argument is a NaN.
• isinf() returns a non-zero value if its argument is infinite.
• fdim() and fdimf() return the positive difference between the
arguments. In particular, they return arg1-arg2 if arg1>arg2, or
zero otherwise.
• fmax() and fmaxf() return the maximum of their arguments.
• fmin() and fminf() return the minimum of their arguments.
• hypot() and hypotf() return the square root of the sum of the squares
of their two arguments.
• acosh() and asinh() and atanh(): return the arc hyperbolic cosine,
arc hyperbolic sine, and arc hyberbolic tangent of their double precision
argument.
• acoshf() and asinhf() and atanhf(): return the arc hyberbolic
cosine, arc hyperbolic sine, and arc hyberbolic tangent of their single
precision argument.

Green Hills Software, Inc. 461


13. Green Hills C

Header File stdio.h


The following ISO C99 functions are added to stdio.h and the C library:

• snprintf() and vsnprintf(): These functions behave in the same


way as sprintf() and vsprintf(), except that their second argument
limits the length of the buffer to be written.

The va_copy macro


The ISO C99 va_copy macro, is added to stdarg.h. No other changes were
necessary to achieve ISO C99 compliance in this header file.

Header File stdbool.h


Header File stdbool.h is provided, containing the following:

• The following type is defined:


_Bool
• The following macros are defined:
bool
true
false
__bool_true_false_are_defined

Header File stdint.h


Header File stdint.h is provided, containing the following:

• Declares numerous integral types in terms of existing types, such as short,


int, and long.
• Declares numerous macros, which provide the numeric limits of the new
types.
• Declares function-like macros, for forming integer constants with the new
types.

462 MULTI: Building Applications for Embedded ARM


Chapter 14

Green Hills C++

This Chapter Contains:


• Specifying a C++ Language Dialect
• Standard C++
• Standard C++ with ARM Extensions
• GNU C++
• Extended Embedded C++
• Embedded C++
• Template Instantiation
• Using Clearmake with Green Hills C++
• Multiple and Virtual Inheritance
• Namespace Support
• Precompiled Header Files
• Linkage
• Post Processing in C++
• The C++ decode Utility
• C++ Implementation-Defined Features
14. Green Hills C++

This chapter describes the Green Hills implementation of C++, including


aspects of the language particular to our compilers.

Specifying a C++ Language Dialect


The needs of C++ users vary widely, depending on a number of factors,
including the type of target application and environment, the foreign libraries
used, compatibility with other C++ compilers, and the trade-offs users make in
regard to the C++ feature set and library support they require. To meet such
a diverse set of needs, Green Hills Software supports a form of “scalable”
C++. You can specify language and library levels to obtain everything from
a small and efficient Embedded C++ compiler and library, to the power of
the full ISO Standard C++.

To specify a C++ dialect:


Set the C/C++ Compiler→C++ Language Dialect option to one of
the following settings:
• Standard C++ (Violations give Errors) (--STD) — The strict
International Standard ISO/IEC 14882:1998 dialect. For more
information, see “Standard C++” on page 465.
• Standard C++ (Violations give Warnings) (--std) — [default] The
International Standard ISO/IEC 14882:1998 dialect with warnings.
For more information, see “Standard C++” on page 465.
• Standard C++ with ARM Extensions (--arm) — The Annotated
C++ Reference Manual (ARM) dialect. For more information, see
“Standard C++ with ARM Extensions” on page 472.
• GNU C++ (--g++) — The GNU dialect. For more information, see
“GNU C++” on page 473.
• Extended Embedded C++ (--ee) — A scalable, efficient version
of C++ designed for large embedded applications. For more
information, see “Extended Embedded C++” on page 477.
• Embedded C++ (--e) — The smallest and most efficient version
of C++, designed for small embedded applications. For more
information, see “Embedded C++” on page 478.

464 MULTI: Building Applications for Embedded ARM


Standard C++

Standard C++
This dialect is defined by the International Standard ISO/IEC 14882:1998
(except as noted in this chapter) and includes all the latest features and changes
described in newer C++ books. All of the features of Standard C++ are enabled
by default, except for exception handling (because of the code size and speed
penalty to be paid even if EH features are not used). You can turn off many
individual C++ features by using the appropriate builder or driver options.

To specify use of this dialect:

Set the C/C++ Compiler→C++ Language Dialect option to either:


• Standard C++ (Violations give Errors) (-STD), or
• Standard C++ (Violations give Warnings) (-std) [default]

Note In order to obtain the exact dialect specified by the standard, you need to
set these additional options as follows:

• Set the C/C++ Compiler→C++ Exception Handling option to On


(--exceptions)
• Set the C/C++ Compiler→C++→Templates→Recognition of Exported
Templates option to On (--export). For more information, see “Exported
Templates” on page 490.

Standard C++ Extensions


The following features, not in the ARM but in the standard mode, are accepted:

• The dependent statement if, while, do-while, or for is a scope, and


the restriction of such a statement from being a declaration is removed.
• The expression tested in an if, while, do-while, or for, as the first
operand of a ? operator, or as an operand of the &&, ||, or ! operators
may have a pointer-to-member type or a class type that can be converted
to a pointer-to-member type in addition to the scalar cases permitted by
the ARM.
• Qualified names are allowed in elaborated type specifiers.
• A global-scope qualifier is allowed in member references of the form
x.::A::B and p->::A::B.
• The precedence of the third operand of the ? operator is changed.

Green Hills Software, Inc. 465


14. Green Hills C++

• If control reaches the end of the main() routine, and main() has an integral
return type, it is treated as if a return 0; statement were executed.
• Pointers to arrays with unknown bounds as parameter types are diagnosed
as errors.
• A functional-notation cast of the form A() can be used even if A is a class
without a (nontrivial) constructor. The temporary created gets the same
default initialization to zero as a static object of the class type.
• A cast can be used to select one out of a set of overloaded functions when
taking the address of a function.
• Template friend declarations and definitions are permitted in class definitions
and class template definitions.
• Type template parameters are permitted to have default arguments.
• Function templates can have non-type template parameters.
• A reference to const volatile cannot be bound to an rvalue.
• Qualification conversions, such as conversion from T ** to T const
* const * are allowed.
• Digraphs are recognized.
• Operator keywords (e.g., and, bitand, etc.) are recognized.
• Static data member declarations can be used to declare member constants.
• wchar_t is recognized as a keyword and a distinct type.
• bool is recognized.
• RTTI (run-time type information), including dynamic_cast and the
typeid operator, is implemented.
• Declarations in tested conditions (in if, switch, for, and while
statements) are supported.
• Array new and delete are implemented.
• New-style casts (static_cast, reinterpret_cast, and
const_cast) are implemented.
• Definition of a nested class outside its enclosing class is allowed.
• mutable is accepted on non-static data member declarations.
• Namespaces are implemented, including using declarations and directives.
Access declarations are broadened to match the corresponding using
declarations.

466 MULTI: Building Applications for Embedded ARM


Standard C++

• Explicit instantiation of templates is implemented.


• The typename keyword is recognized.
• explicit is accepted to declare non-converting constructors.
• The scope of a variable declared in the for-init-statement for a for
loop is the scope of the loop (not the surrounding scope).
• Member templates are implemented.
• The new specialization syntax (using “template <>”) is implemented.
• Cv-qualifiers are retained on rvalues (in particular, on function return
values).
• The distinction between trivial and nontrivial constructors has been
implemented, as has the distinction between PODs and non-PODs with
trivial constructors.
• The linkage specification is treated as part of the function type (affecting
function overloading and implicit conversions).
• extern inline functions are supported, and the default linkage for
inline functions is external.
• A typedef name may be used in an explicit destructor call.
• Placement delete is implemented.
• An array allocated via a placement new can be deallocated via delete.
• Covariant return types on overriding virtual functions are supported.
• enum types are considered to be non-integral types.
• Partial specialization of class templates is implemented.
• Partial ordering of function templates is implemented.
• Function declarations that match a function template are regarded as
independent functions, not as “guiding declarations” that are instances of
the template.
• It is possible to overload operators using functions that take enum types
and no class types.
• Explicit specification of function template arguments is supported.
• Unnamed template parameters are supported.
• The new lookup rules for member references of the forms x.A::B and
p->A::B are supported.

Green Hills Software, Inc. 467


14. Green Hills C++

• The notation :: template (and ->template, etc.) is supported.


• In a reference of the form f()->g(), with g a static member function, f()
is evaluated, and likewise for a similar reference to a static data member.
The ARM specifies that the left operand is not evaluated in such cases.
• enum types can contain values larger than can be contained in an int.
• Default arguments of function templates and member functions of class
templates are instantiated only when the default argument is used in a call.
• String literals and wide string literals have const type.
• Class name injection is implemented
• Argument-dependent (Koenig) lookup of function names is implemented.
• Class and function names declared only in unqualified friend declarations
are not visible except for functions found by argument-dependent lookup.
• A void expression can be specified on a return statement in a void
function.
• Function-try-blocks (i.e., try-blocks that are the top-level statements of
functions, constructors, or destructors) are implemented.
• Universal character set escapes (e.g., \uabcd) are implemented.
• On a call in which the expression to the left of the opening parenthesis
has class type, overload resolution looks for conversion functions that
can convert the class object to pointer-to-function types, and each such
pointed-to “surrogate functions” type is evaluated alongside any other
candidate functions.

Accepted Anachronisms
The following anachronisms are accepted when anachronisms are enabled:

• overload, in function declarations, is accepted and ignored.


• Definitions are not required for static data members that can be initialized
using default initialization. The anachronism does not apply to static data
members of template classes; they must always be defined.
• The number of elements in an array may be specified in an array delete
operation. The value is ignored.
• A single operator++() and operator--() function can be used to overload
both prefix and postfix operations.

468 MULTI: Building Applications for Embedded ARM


Standard C++

• The base class name may be omitted in a base class initializer if there is only
one immediate base class.
• A bound function pointer (a pointer to a member function for a given object)
can be cast to a pointer to a function.
• A nested class name may be used as a non-nested class name provided no
other class of that name has been declared. The anachronism is not applied
to template classes.
• A reference to a non-const type may be initialized from a value of a
different type. A temporary is created, it is initialized from the (converted)
initial value, and the reference is set to the temporary.
• A reference to a non-const class type may be initialized from an rvalue of
the class type or a derived class thereof. No (additional) temporary is used.
• A function with old-style parameter declarations is allowed and may
participate in function overloading as though it were prototyped. Default
argument promotion is not applied to parameter types of such functions
when the check for compatibility is done, so that the following declares the
overloading of two functions foo:
int foo(int);
int foo(x) char x; {return x;}

It will be noted that in C this code is legal but has a different meaning: a
tentative declaration of foo is followed by its definition.
• A reference to a non-const class can be bound to a class rvalue of the
same type or a derived type thereof.
struct A {
A(int);
A operator=(A&);
A operator+(const A&);
};
main() {
A b(1);
b = A(1) + A(2); // Allowed as anachronism
}

Extensions Accepted in Normal C++ Mode


The following extensions are accepted in all modes (except when strict ANSI
violations are diagnosed as errors):

Green Hills Software, Inc. 469


14. Green Hills C++

• A friend declaration for a class may omit the class keyword:


class B;
class A {
friend B; // Should be "friend class B"
};

• Constants of scalar type may be defined within classes:


class A {
const int size = 10;
int a[size];
};

• In the declaration of a class member, a qualified name may be used:


struct A {
int A::f(); // Should be int f();
};

• The preprocessing symbol __c_plusplus is defined in addition to the


standard __cplusplus.
• Anonymous unions can be introduced into a containing class by using a
typedef name – it need not be declared directly, as with a true anonymous
union. For example:
typedef union {
int i, j;
} U; // U identifies a reusable anonymous union
class A {
U; // Okay -- references to A::i and A::j
// are allowed
};

In addition, “anonymous classes” and “anonymous structures” are allowed


as long as they have no C++ features (e.g., no static data members to
member functions and no nonpublic members) and have no nested types
other than other anonymous classes, structures, or unions. For instance:
struct A {
struct {
int i, j;
}; // Okay -- references to A::i and A::j
// are allowed
};

470 MULTI: Building Applications for Embedded ARM


Standard C++

• In addition to the proposed extensions to C, type qualifier restrict


is allowed for reference and pointer-to-member types and for nonstatic
member functions.
• An assignment operator declared in a derived class with a parameter type
matching one of its base classes is treated as a “default” assignment
operator; that is, such a declaration blocks the implicit generation of a copy
assignment operator. (This is Cfront behavior that is known to be relied
upon in at least one widely used library.) For example:
struct A {};
struct B : public A {
B& operator=(A&);
};

By default, there will be no implicit declaration of B::operator=(const


B&), whereas in strict ANSI mode B::operator=(A&) is not a copy
assignment operator and B::operator=(const B&) is implicitly declared.
• Implicit type conversion between a pointer to an extern "C" function
and a pointer to an extern "C++" function is permitted. For example:
extern "C" void f(); // f’s type has
// extern "C" linkage
void (*pf)() = &f; // pf points to an
// extern "C++" function
// error unless implicit
// conversion is allowed

This extension is disabled in Strict ANSI mode.


• A ? operator whose second and third operands are string literals or wide
string literals can be implicitly converted to char * or wchar_t *.
(Recall that in C++, string literals are const. There is a deprecated implicit
conversion that allows conversion of a string literal to char *, dropping to
const. That conversion, however, applies only to simple string literals.
Allowing it for the result of a ? operation is an extension.)
char *p = x ? "abc : "def";

• Except in Strict ANSI mode, default arguments may be specified for


function parameters other than those of a top-level function declaration (e.g.,
they are accepted on typedef declarations and on pointer-to-function and
pointer-to-member-function declarations).

Green Hills Software, Inc. 471


14. Green Hills C++

Note For more information about Standard C++, we recommend Stroustrup’s


The C++ Programming Language, Third Edition.

Standard C++ with ARM Extensions


This dialect is ARM-compliant C++ as defined by The Annotated C++
Reference Manual (ARM) by Ellis and Stroustrup (Addison-Wesley, 1990),
including templates, exceptions, and the anachronisms listed in Chapter 18
of that book. This is essentially the same language defined by the language
reference for Cfront version 3.0x, with the addition of exceptions.

To specify use of this dialect:

Set the C/C++ Compiler→C++ Language Dialect option to Standard


C++ with ARM Extensions (--arm).

472 MULTI: Building Applications for Embedded ARM


GNU C++

GNU C++
This dialect closely emulates the C++ language supported by the GNU compiler.

To specify use of this dialect:

Set the C/C++ Compiler→C++ Language Dialect option to GNU C++


(--g++).

GNU C++ Extensions


This dialect enables the extensions listed below, together with those in “GNU
C/C++ Extensions” on page 416.

• If an explicit instantiation directive is preceded by the keyword extern, no


(explicit or implicit) instantiation is for the indicated specialization.
• std::type_info does not need to be introduced with a special
#pragma.
• A special keyword __null expands to the same constant as the literal “0”,
but is expected to be used as a null pointer constant.
• Names from dependent base classes are ignored only if another name would
be found by the lookup.
const int n = 0;
template <class T> struct B {
static const int m = 1; static const int n = 2;
};
template <class T> struct D : B<T> {
int f() { return m + n; } // B::m + ::n in g++ mode
};

• When doing name lookup in a base class, the injected class name of a
template class is ignored.

Green Hills Software, Inc. 473


14. Green Hills C++

namespace N {
template <class T> struct A {};
}
struct A {
int i;
};
struct B : N::A<int> {
B() { A x; x.i = 1; } // g++ uses ::A, not N::A
};

• The injected class name is found in certain contexts in which the constructor
should be found instead.
struct A {
A(int) {};
};
A::A a(1);

• A difference in calling convention is ignored when redeclaring a typedef.


typedef void F();
extern "C" {
typedef void F(); // Accepted in GNU C++ mode (error otherwise)
}

• The macro __GNUG__ is defined identically to __GNUC__ (i.e., the major


version number of the GNU compiler version that is being emulated).
• The macro _GNU_SOURCE is defined as “1”.
• Guiding declarations (a feature present in early drafts of the standard, but
not in the final standard) are disabled.
• Namespace std is predeclared.
• The definition of a member of a class template that appears outside of the
class definition may declare a nontype template parameter with a type that
is different than the type used in the definition of the class template. A
warning is issued.
template <int I> struct A { void f(); };
template <unsigned int I> void A<I>::f(){}

• A friend declaration may refer to a member typedef.

474 MULTI: Building Applications for Embedded ARM


GNU C++

class A {
class B {};
typedef B my_b;
friend class my_b;
};

• An inherited type name can be used in a class definition and later redeclared
as a typedef.
struct A { typedef int I; };
struct B : A {
typedef I J; // Refers to A::I
typedef double I; // Accepted in g++ mode
}; // (introduces B::I)

• In a catch clause, an entity may be declared with the same name as the
handler parameter.
try { }
catch(int e) {
char e;
}

• A template argument list may appear following a constructor name in


constructor definition that appears outside of the class definition:
template <class T> struct A {
A();
};
template <class T> A<T>::A<T>(){}

• A constructor need not provide an initializer for every nonstatic const data
member (but a warning is still issued if such an initializer is missing).
struct S {
int const ic;
S() {} // Warning only in GNU C++ mode (error otherwise).
};

• Exception specifications are ignored on function definitions when support


for exception handling is disabled (normally, they are only ignored on
function declarations that are not definitions).
• A friend declaration in a class template may refer to an undeclared template.

Green Hills Software, Inc. 475


14. Green Hills C++

template <class T> struct A {


friend void f<>(A<T>);}

• A function template default argument may be redeclared. A warning is


issued and the default from the initial declaration is used.
template<class T> void f(int i = 1);
template<class T> void f(int i = 2){}
int main() {
f<void>();
}

• A definition of a member function of a class template that appears outside of


the class may specify a default argument.
template <class T> struct A { coid f(T); };
template <class T> void A<T>::f(T value = T() ) {}

476 MULTI: Building Applications for Embedded ARM


Extended Embedded C++

Extended Embedded C++


This dialect is a scalable version of C++, which was created in a joint effort by
Green Hills Software and P. J. Plauger. It is often referred to as EEC++ or
ESTL (Embedded C++ with the Standard Template Library). It is not an official
standard, but is rather a compromise language, situated between Standard C++
and Embedded C++, and is intended for large embedded applications.

To specify use of this dialect:

Set the C/C++ Compiler→C++ Language Dialect option to Extended


Embedded C++ (-ee).

EEC++ offers all of the features of Standard C++ except those that adversely
affect code size or speed. Consequently, it excludes:

• Exception handling
• Multiple inheritance and virtual base classes
• Run-time type information
However it does retain the following notable but inexpensive features of C++
which are excluded by Embedded C++ (see “Embedded C++” on page 478):

• Templates
• Namespaces
• The mutable keyword
• Most new-style casts
As with Standard C++, other features can be individually controlled through
Builder and driver options.

EEC++ Library Features


The EEC++ library features include STL and namespaces. It complements
EC++, allowing users to make the most of the enhanced language.

Green Hills Software, Inc. 477


14. Green Hills C++

Embedded C++
This dialect is intended as a stable, simple, and efficient version of Standard
C++, with the ultimate intention of producing an open standard to be used
worldwide. EC++ is not a new language specification that will compete with
existing Standard C++; rather, it is a pure subset for the practical user of C++. It
is often referred to as EC++ (Embedded C++), and originated in Japan through
the efforts of the following committee members:

• Green Hills Software


• ADaC
• Toshiba
• Plum Hall
• Hitachi
• Dinkumware
• NEC
• Cygnus
To specify use of this dialect:

Set the C/C++ Compiler→C++ Language Dialect option to


Embedded C++ (-e).

EC++ is designed to meet the needs of the embedded industry. The committee
members established the following guidelines for creating EC++. The subset
fulfills the particular requirements of embedded systems designs.

• Remove complex features and specifications while retaining as many


object-oriented features as possible.
• Avoid those features and specifications that do not fulfill the requirements of
embedded system design. Three major requirements of embedded system
designs are:
1. Avoiding excessive memory consumption
2. Taking care to avoid producing unpredictable responses
3. Creating code that can be placed into read only memory (“ROM-able”)

478 MULTI: Building Applications for Embedded ARM


Embedded C++

• Non-standard extensions to C++ should be avoided.


• The founders of the EC++ committee state: “Our background is in the
semiconductor business. We mainly target 32-bit RISC MCU applications
as embedded systems. Although there are many applications using 4 or
8-bit MCUs, we cannot address them. We feel that the basic features of
C, or even assembly language, are sufficient for these processors. On the
other hand, those systems that are expandable using standard buses, such
as VME or PCI, are similar to those of PCs or workstations. We recognize
that a full version of Standard C++ is better than Embedded C++ for those
application designs.”

EC++ is similar to C++ (1990) except for the following conditions:

• Many small enhancements and clarifications are retained from ANSI C++.
• Unused keywords are retained from ANSI C++ for upward compatibility.
• A style guide is available, providing guidelines for using EC++ wisely.
New additions to the ANSI C++ language have been made. One such feature
is the mutable keyword. The mutable keyword allows the user to modify
class members even if the object has been declared const. These cannot be
placed in ROM. Previously, the object was placed in ROM, without the ability
to manipulate it.

New-style casts force you to be explicit about the type of cast being performed.
The new-style casts are self documenting, and force you to be aware when
performing a dangerous cast. The EC++ committee felt the learning curve to
use the new-style casts was too steep to justify their benefit.

The following items are language elements which have poor run-time
characteristics and have not been included in EC++:

• Exception handling: It is difficult to estimate the time between when an


exception has occurred and control has passed to a corresponding exception
handler. It is also difficult to estimate memory consumption for exception
handling.
• Multiple inheritance and virtual base classes: Designing a class hierarchy
using multiple inheritance or recognizing the overall hierarchy of it and
using it correctly is difficult. The programs are less readable, less usable,
and more difficult to maintain.

Green Hills Software, Inc. 479


14. Green Hills C++

• Run-time type information: Program size is a factor when supporting the


run-time type information facility. To support the run-time type information
(RTTI) facility, there is at least some program size overhead, because type
information for polymorphic classes is needed. The compiler automatically
generates the information, and it would be included in programs that do not
use the RTTI facility.

The following language elements are overly complex for embedded


programming and have not been included in EC++:

• Templates: Templates are complex items that increase the time of


compilation and cause unexpected code explosion.
• Namespaces: To avoid serious name conflicts, using static class members
is recommended. This removes the need for using namespaces in the first
place.

EC++ Library Features


The EC++ library is a subset of the Standard C++ library. The EC++ library is
designed to meet the needs of the embedded industry. It is much smaller and
more efficient than the full standard C++ library.

The EC++ library represents a significant addition to the typical C library


supplied with an embedded compiler. For a close approximation of the
Embedded C++ library, see P. J. Plauger, The Draft Standard C++ Library,
Prentice-Hall, 1995.

• iostream operations are supported for cin and cout, using classes
istream, ostream, ios, and streambuf.
• String operations are supported for class string.
• Math facilities are overloaded for both double and float types, in both
real and complex modes.

To enhance the EC++ library, the following features were removed:

• Standard Template Library is removed; string, complex, or iostream


(et.al.) classes are not implemented through templates.
• No exceptions implies no exception handling in function prototypes or
classes.

480 MULTI: Building Applications for Embedded ARM


Template Instantiation

• No run-time type information implies no type_info class.


The library omits support for wide character input/output, the locale type,
and long double arithmetic, because they are seldom needed in embedded
applications.

Note For more information about EC++, please visit the Embedded C++
(http://www.caravan.net/ec2plus/) web site.

Template Instantiation
The C++ language includes the concept of templates. A template is a description
of a class or function that is a model for a family of related classes or functions.
For example, you can write a template for a Stack class, and then use a
stack of integers, a stack of floats, and a stack of some user-defined type. In
the source, these might be written Stack<int>, Stack<float>, and
Stack<X>. From a single source description of the template for a stack, the
compiler can create instantiations of the template for each of the types required.

The instantiation of a class template is always done as soon as it is needed


in a compilation. However, the instantiations of template functions, member
functions of template classes, and static data members of template classes
(hereafter referred to as template entities) are not necessarily done immediately,
for several reasons:

• You would like to end up with only one copy of each instantiated entity
across all the object files that make up a program. (This of course applies to
entities with external linkage.)
• The language allows you to write a specialization of a template entity,
that is, a specific version to be used in place of a version generated from
the template for a specific data type. (You could, for example, write a
version of Stack<int>, or of just Stack<int>::push, that replaces
the template-generated version; often, such a specialization provides a
more efficient representation for a particular data type.) While compiling a
reference to a template entity, the compiler cannot know if a specialization
for that entity will be provided in another compilation. Thus, it cannot do
the instantiation automatically in any source file that references it.
• The language also dictates that template functions that are not referenced
should not be compiled, and that, in fact, such functions might contain

Green Hills Software, Inc. 481


14. Green Hills C++

semantic errors that would prevent them from being compiled. Therefore,
a reference to a template class should not automatically instantiate all the
member functions of that class.

It should be noted that certain template entities are always instantiated when
used (e.g., inline functions).

As these requirements demonstrate, if the compiler is responsible for doing all


the instantiations automatically, it can only do so on a program-wide basis. That
is, the compiler cannot make decisions about instantiation of template entities
until it has seen all the source files that make up a complete program.

The Green Hills C++ compiler provides an instantiation mechanism that does
automatic instantiation at link time. For cases where the programmer wants
more explicit control over instantiation, the Green Hills C++ compiler also
provides instantiation modes and instantiation #pragma directives, which can
be used to exert fine-grained control over the instantiation process.

Automatic Instantiation
The goal of an automatic instantiation mode is to provide trouble-free
instantiation so that you can compile source files to object code, link them and
run the resulting program, without having to worry about how the necessary
instantiations get done.

In practice, this is difficult for a compiler to achieve, and different compilers


use different automatic instantiation schemes with different strengths and
weaknesses:

• Cfront saves information about each file it compiles in a special directory


called the repository. It instantiates nothing during the normal compilations.
At link time, it looks for entities that are referenced but not defined, and
whose mangled names indicate that they are template entities. For each such
entity, it consults the repository information to find the file containing the
source for the entity, and performs a compilation of the source to generate
an object file containing object code for that entity. This object code for
instantiated objects is then combined with the “normal” object code in the
link step.

Cfront requires that you follow a particular coding convention: all templates
must be declared in .h files, and for each such file there must be a

482 MULTI: Building Applications for Embedded ARM


Template Instantiation

corresponding .C file containing the associated definitions. The compiler


is never informed of the existence of the .C files explicitly; you do not,
for example, compile them in the normal way. The link step looks for
them when and if it needs them, and does so by taking the .h filename and
replacing its suffix.

The disadvantage of this scheme is that it performs a separate compilation


for each instantiated function (or, at best, one compilation for all the member
functions of one class). Even though the function itself is often quite small,
it must be compiled along with the declarations for the types on which
the instantiation is based, and those declarations can easily run into many
thousands of lines. For large systems, these compilations can take a very
long time. The link step tries to be smart about recompiling instantiations
only when necessary, but because it keeps no fine-grained dependency
information, it is often forced to recompile everything for a minor change
in a .h file. In addition, Cfront has no way of ensuring that preprocessing
symbols are set correctly when it does these instantiation compilations, if
preprocessing symbols are set other than on the command line.
• Borland’s C++ compiler instantiates everything referenced in a compilation,
then uses a special linker to remove duplicate definitions of instantiated
functions.

Those using Borland’s compiler must make sure that every compilation sees
all the source code it needs to instantiate all the template entities referenced
in that compilation. That is, you cannot refer to a template entity in a source
file if a definition for that entity is not included by that source file. In
practice, this means that either all the definition code is put directly in the .h
files, or that each .h file includes an associated .C (actually, .CPP) file.

This scheme is straightforward, and works well for small programs.


For large systems, however, it tends to produce very large object files,
because each object file must contain object code (and symbolic debugging
information) for each template entity it references.

The Green Hills C++ approach is a little different. It requires that, for each
instantiation of a non-exported template, there is some (normal, top-level,
explicitly-compiled) source file that contains the definition of the template
entity, a reference that causes the instantiation, and the declarations of any
types required for the particular instantiation. This requirement can be met
in various ways:

Green Hills Software, Inc. 483


14. Green Hills C++

• By following the Borland convention where each .h file that declares a


template entity also contains either the definition of the entity or includes
another file containing the definition.
• By enabling the implicit inclusion. When the compiler sees a template
declaration in a .h file and discovers a need to instantiate that entity, it is
given permission to search for an associated definition file with the same
base name and a different suffix. That file is then implicitly included at the
end of the compilation. This method allows most programs written using the
Cfront convention to be compiled with Green Hills C++. For more details,
see “Implicit Inclusion” on page 488.
• By the “ad hoc” approach. The programmer ensures that the files that define
template entities also have the definitions of all the available types, and
adds code or #pragma directives in those files to request instantiation
of the entities there.

Exported templates are also supported by the Green Hills C++ automatic
instantiation method, but they require additional mechanisms explained in
“Exported Templates” on page 490.

The Green Hills C++ automatic instantiation method works as follows:

1. The first time the source files of a program are compiled, no template
entities are instantiated. However, template information files are generated
and contain information about entities that could have been instantiated in
each compilation. These template information files have a .ti suffix.
2. When the object files are linked together, a program called the prelinker is
run. It examines the object files, looking for references and definitions of
template entities, and for the added information about entities that could
be instantiated.
3. If the prelinker finds a reference to a template entity for which there is
no definition anywhere in the set of object files, it looks for a file that
indicates that it could instantiate that template entity. Upon finding such a
file, the prelinker assigns the instantiation to it. The set of instantiations
assigned to a given file is recorded in an associated instantiation request
file (with a .ii suffix).
4. The prelinker then executes the compiler again to recompile each file for
which the .ii file was changed. The original compilation options (saved in
the .ti file) are used for recompilation.

484 MULTI: Building Applications for Embedded ARM


Template Instantiation

5. When the compiler compiles a file, it reads the .ii file for that file and
obeys the instantiation requests therein. It produces a new object file
containing the requested template entities (and everything else already in
the object file). The compiler also receives a definition list file, which lists
all the instantiations for which definitions already exist in the set of object
files. If during compilation the compiler has the opportunity to instantiate
a referenced entity that is not on that list, it performs the instantiation. It
passes back to the prelinker (in the definition list file) a list of instantiations
that it has “adopted” in this way, so the prelinker can assign them to a
file. This adoption process allows rapid instantiation and assignment of
instantiations referenced from new instantiations, and reduces the need to
recompile a given file more than once during the prelinking process.
6. The prelinker repeats steps 3-5 until there are no more instantiations to
be adjusted.
7. The object files are linked together.

Once the program has been linked correctly, the .ii files contain a complete set of
instantiation assignments. From then on, whenever source files are recompiled,
the compiler will consult the .ii files and do the indicated instantiations as it
does the normal compilations. That means that, except in cases where the set of
required instantiations changes, the prelink step from then on will find that all
the necessary instantiations are present in the object files and no instantiations
assignment adjustments need be done. This is true even if the entire program is
recompiled.

If the programmer provides a specialization of a template entity somewhere in


the program, the specialization will be seen as a definition by the prelinker.
Since that definition satisfies whatever references there might be to that entity,
the prelinker will see no need to request an instantiation of the entity. If the
programmer adds a specialization to a program that has previously been
compiled, the prelinker will notice that too and remove the assignment of the
instantiation from the proper .ii file.

The .ii files should not, in general, require any manual intervention. There is
one exception. If:

• a definition is changed in such a way that some instantiation no longer


compiles (it gets errors), and
• a specialization is added in another file, and

Green Hills Software, Inc. 485


14. Green Hills C++

• the first file is being recompiled before the specialization file and is getting
errors,

the .ii file for the file getting the errors must be deleted manually to allow the
prelinker to regenerate it.

If the prelinker changes an instantiation assignment, it will issue a message


such as:
C++ prelinker: A<int>::f() assigned to file test.o
C++ prelinker: executing: /usr/green/gcx -c test.c

The automatic instantiation scheme can coexist with partial explicit


control of instantiation by the programmer through the use of the C/C++
Compiler→C++→Templates→Manual Template Instantiation Mode option
(see “Instantiation Modes” on page 486), and/or #pragma directives (see
“Instantiation #pragma Directives” on page 487).

Instantiations are normally generated as part of the object file of the translation
unit in which the instantiations are performed. But when one instantiation per
object is used, each instantiation is placed in its own object file. This mode
is useful when building libraries that need to include copies of the instances
referenced from the library. If each instance is not placed in its own object file,
it may be impossible to link the library with another library containing some
of the same instances.

Automatic instantiation may optionally be turned off. If automatic instantiation


is turned off, the template information file is not generated.

Instantiation Modes
Normally, when a file is compiled, no template entities are instantiated
(except those assigned to the file by automatic instantiation). The
overall instantiation mode can, however, be controlled using the C/C++
Compiler→C++→Templates→Manual Template Instantiation Mode
Builder option and associated driver options (see “Templates” on page 173).

486 MULTI: Building Applications for Embedded ARM


Template Instantiation

Instantiation #pragma Directives


Instantiation #pragma directives can be used to control the instantiation
of specific template entities or sets of template entities. There are three
instantiation #pragma directives:

• #pragma instantiate fn — Instructs the compiler to instantiate fn.


• #pragma can_instantiate fn — Instructs the compiler to consider
fn for instantiation. This #pragma is often used in conjunction with
automatic instantiation to indicate potential sites for instantiation if the
template entity turns out to be required.
• #pragma do_not_instantiate fn — Instructs the compiler to not
instantiate fn. This #pragma is often used to suppress the instantiation of
an entity for which a specific definition will be supplied.

Each of the above instantiation #pragma directives takes an argument, fn,


which may be one of the following:

• A template class name (e.g., A<int>)


• A template class declaration (e.g., class A<int>)
• A member function name (e.g., A<int>::f)
• A static data member name (e.g., A<int>::i)
• A static data declaration (e.g., int A<int>::i)
• A member function declaration (e.g., void A<int>::f(int, char))
• A template function declaration (e.g., char* f(int, float))
A #pragma directive in which the argument is a template class name is
equivalent to repeating the directive for each member function and static data
member declared in the class. When instantiating an entire class a given
member function or static data member may be excluded using the #pragma
do_not_instantiate directive. For example:
#pragma instantiate A<int>
#pragma do_not_instantiate A<int>::f

The template definition of a template entity must be present in the compilation


for an instantiation to occur. If an instantiation is explicitly requested by use
of the #pragma instantiate directive, and no template definition is
available, or a specific definition is provided, an error is issued.

Green Hills Software, Inc. 487


14. Green Hills C++

template <class T> void f1(T); // No body provided


template <class T> void g1(T); // No body provided
void f1(int) {} // Specific definition
void main()
{
int i;
double d;
f1(i);
f1(d);
g1(i);
g1(d);
}
#pragma instantiate void f1(int) // error - specific
// definition
#pragma instantiate void g1(int) // error - no body
// provided

f1(double) and g1(double) will not be instantiated (because no bodies were


supplied) but no errors will be produced during the compilation (if no bodies
are supplied at link time, a linker error will be produced).

A member function name (e.g., A<int>::f) can only be used as a #pragma


argument if it refers to a single user defined member function (i.e., not an
overloaded function). Compiler-generated functions are not considered, so
a name may refer to a user defined constructor even if a compiler-generated
copy constructor of the same name exists. Overloaded member functions can
be instantiated by providing the complete member function declaration. For
example:
#pragma instantiate char* A<int>::f(int, char*)

The argument to an instantiation directive may not be a compiler-generated


function, an inline function, or a pure virtual function.

Implicit Inclusion
Implicit inclusion is enabled by default, and permits the compiler to assume
that if it needs a definition to instantiate a template entity declared in a .h file
it can implicitly include the corresponding .C file to get the source code for
the definition. To disable this feature:

488 MULTI: Building Applications for Embedded ARM


Template Instantiation

Set the C/C++ Compiler→C++→Templates→Implicit Source File


Inclusion option to Off (--no_implicit_include).

For example, if a template entity ABC::f is declared in file xyz.h, and an


instantiation of ABC::f is required in a compilation but no definition of
ABC::f appears in the source code processed by the compilation, the compiler
searches for an xyz.C file; if the file is found, the compiler processes it as if the
file were included at the end of the main source file.

To find the template definition file for a given template entity, the compiler
needs to know the full pathname of the file in which the template was declared
and whether the file was included using the system include syntax (e.g.,
#include <file.h>). This information is not available for preprocessed
source code containing #line directives. Consequently, the compiler will not
attempt implicit inclusion for source code containing #line directives.

The following suffixes are searched for: .c, .C, .cpp, .CPP, .cxx, .CXX,
and .cc.

Care should be taken when writing files that may be implicitly included. For
instance, if the file xyz.C is implicitly included since it contains a definition of a
template declared in xyz.h, it is possible that more than one module will include
it. In fact, most likely any module that includes xyz.h will end up implicitly
including xyz.C. In addition, if xyz.C defines a global symbol (a non-template
function or a variable), every module which (implicitly) includes it will get that
symbol definition. This can lead to multiply defined symbol errors from the
linker. This can be averted by having only template definitions in files that can
be implicitly included. An implicitly included header file should be organized
much the same way as any other header file.

Since a file is automatically pulled in when the implicit inclusion is on, the
compiler driver or the builder do not need to separately compile it; just like a
regular header file does not need to be separately compiled.

Implicit inclusion works well alongside automatic instantiation, but the two
are independent. They can be enabled or disabled independently, and implicit
inclusion is still useful when automatic instantiation is not done.

Green Hills Software, Inc. 489


14. Green Hills C++

Exported Templates
Exported templates are templates declared with the keyword export, which is
not recognized by default. To enable this feature:

Set the C/C++ Compiler→C++→Templates→Recognition of


Exported Templates option to On (--export).

Note This option requires and will automatically enable C/C++


Compiler→C++→Templates→Dependent Name Processing (--dep_name).

Exported templates and implicit inclusion (see “Implicit Inclusion”


on page 488) are mutually exclusive. Enabling C/C++
Compiler→C++→Templates→Recognition of Exported
Templates (--export) will automatically disable C/C++
Compiler→C++→Templates→Implicit Source File Inclusion
(--no_implicit_include)

Exporting a class template is equivalent to exporting each of its static data


members and each of its non-inline member functions. An exported template is
special because its definition does not need to be present in a translation unit
that uses that template. In other words, the definition of an exported (non-class)
template does not need to be explicitly or implicitly included in a translation
unit that instantiates that template. For example, the following is a valid C++
program consisting of two separate translation units:

490 MULTI: Building Applications for Embedded ARM


Using Clearmake with Green Hills C++

// File 1:
#include <stdio.h>
static void trace() { printf("File 1\n"); }

export template <class T> T const & min(T const &, T const &);
int main() {
trace();
return min(2, 3);
}

// File 2:
#include <stdio.h>
static void trace() { printf("File 2\n"); }

export template <class T> T const & min(T const &a,


T const &b) {
trace();
return a < b ? a : b;
}

Note that these two files are separate translation units: one is not included in
the other. That allows the two functions trace() to coexist (with internal
linkage).

Using Clearmake with Green Hills C++


The Green Hills C++ compiler offers several methods of building template
code. The following sections describe these methods. This information is
provided by ClearCase of Atria, Inc.

Automatic Instantiation
The Green Hills C++ compiler performs automatic template instantiation to
build template code by default. During a prelink step, the compiler determines
the necessary template code the program requires and compiles into some of the
object files to make up the program. The compiler tracks how the program uses
template code and records this information in the .ii files in the build directory.

When using the Automatic Instantiation method, Clearmake sometimes


executes unnecessary rebuilds of program components. When the prelinker

Green Hills Software, Inc. 491


14. Green Hills C++

compiles template code into an existing object file, the dependency information
that Clearmake previously recorded for that object file is no longer updated. The
next time that Clearmake is invoked, it will rebuild the object file. After this
rebuild, the dependency information for the object file is correct once again. At
this point, Clearmake no longer executes unnecessary rebuilds of that object file.

The Automatic Instantiation method is the easiest to use because it requires no


programmer intervention and is suitable for most applications. Aside from
the unnecessary rebuilds described above, this method does not conflict with
ClearCase configuration management.

Compile-Time Demand Instantiation


The Compile-Time Demand Instantiation method instantiates templates at
compile-time, rather than during a prelink step. To use this method:

1. Set the C/C++ Compiler→C++→Templates→Auto-Instantiation


of Templates option to Off (--no_auto_instantiation).
2. Set the C/C++ Compiler→C++→Templates→Manual Template
Instantiation Mode option to None (-tused).

This option takes all the template code to which the source module refers and
compiles it into the object module. If multiple source modules refer to the
same template class or function, copies of the compiled template code appear
in multiple object modules.

The Compile-Time Demand Instantiation is easy to use, requiring only that you
specify extra compiler options. It is suitable for most applications, especially
for building archives. Also, this method does not conflict with ClearCase
configuration management. The disadvantage is that the compiler uses extra
time and disk space to perform redundant template instantiation, and the same
instantiation may appear in multiple source files, thereby causing programs
to be larger than necessary.

Explicit Instantiation
The Explicit Instantiation method is an alternate form of compile-time
instantiation. The Green Hills C++ compiler allows you to add directives to the
source code to specify which template classes to instantiate.

492 MULTI: Building Applications for Embedded ARM


Multiple and Virtual Inheritance

When it compiles a source module, the compiler instantiates all the template
classes specified by the directives in the source. The compiler instantiates each
template class completely; that is, it instantiates every member function and
static data member of the class.

To use the Explicit Instantiation method, follow these steps:

1. For each template class to instantiate, add one #pragma instantiate


directive to the source code. For example, if the program requires the
Array<String> class, then add the following directive:
#pragma instantiate Array<String>

2. In each source file that contains a #pragma instantiate directive,


include the header files that contain definitions of the templates and classes
used in the directives.
3. This step is optional:

1. Set the C/C++ Compiler→C++→Templates→Auto-Instantiation


of Templates option to Off (--no_auto_instantiation).
2. Set the C/C++ Compiler→C++→Templates→Manual Template
Instantiation Mode option to None (-tnone).

Automatic instantiation does not interfere with explicit instantiation, but


you may choose to disable it.

The Explicit Instantiation method requires more effort to use. However, it


allows you to control the placement of instantiated template code into object
modules. This control is useful in some situations, especially when building
archives of instantiated template code. Using explicit instantiation does not
conflict with Clearmake build avoidance.

Multiple and Virtual Inheritance


In situations involving multiple and/or virtual inheritance, the Green Hills C++
compiler has a limitation on the maximum byte offset of a base class within a
derived class. If the offset is larger than the maximum value that fits in the
unsigned short type, virtual function calls and RTTI might not work
properly.

Green Hills Software, Inc. 493


14. Green Hills C++

Example 1.
class BIG_BASE {
public:
char c[70000];
virtual void foo();
};

class TWO_BASE {
public:
int i;
virtual void bar();
};

// offset of TWO_BASE is sizeof(BIG_BASE), which doesn’t fit


// into ’unsigned short’ on most architectures - diagnostic is given
class DERIVED : public BIG_BASE, public TWO_BASE {
public:
// ...
};

In this type of situation, an error message is generated.

Where only single class inheritance is involved, the offset of a base class is
always 0, so this limitation does not apply.

494 MULTI: Building Applications for Embedded ARM


Namespace Support

Namespace Support
Namespaces are enabled by default. To disable this feature:

Set the C/C++ Compiler→C++→Namespaces→Namespace


Support option to Off (--no_namespaces).

Name lookup during template instantiations approximates the two-phase


lookup rule of the standard. When a name is looked up as part of a template
instantiation but is not found in the local context of the instantiation, it is looked
up in a synthesized instantiation context. The Green Hills C++ compiler follows
the new instantiation lookup rules for namespaces as closely as possible in the
absence of a complete implementation of the new template name binding rules.

For example:
namespace N {
int g(int);
int x = 0;
template <class T> struct A {
T f(T t) {return g(t);}
T f() {return x;}
};
}
namespace M {
int x =99;
double g(double);
N::A<int> ai;
int i = ai.f(0); // N::A<int>::f(int) calls
// N::g(int)
int i2 = ai.f(); // N::A<int>::f() returns 0 (=
// N::x)
N::A<double> ad;
double d = ad.f(0); // N::A<double>::f(double)
// calls M::g(double)
double d2 = ad.f(); // N::A<double>::f() also
// returns 0 (= N::x)
}

The lookup of names in template instantiations does not conform to the rules in
the working paper in the following respects:

Green Hills Software, Inc. 495


14. Green Hills C++

• Although only names from the template definition context are considered for
names that are not functions, the lookup is not limited to those names visible
at the point at which the template was defined.
• Functions from the context in which the template was referenced are
considered for all function calls in the template. Functions from the
referencing context should only be visible for “dependent” functions calls.

The lookup rules for overloaded operators are implemented as specified by the
standard. This means that the operator functions in the global scope overload
with the operator functions declared extern inside a function, instead of
being hidden by them. The old operator function lookup rules are used when
namespaces are turned off. This means a program can have different behavior,
depending on whether it is compiled with namespace support enabled or
disabled, as in the following example:
struct A {};
A operator+(A, double);
void f() {
A a1;
A operator+(A, int);
a1 + 1.0; // calls operator+(A, double) with
// namespaces enabled
} // but otherwise calls operator+(A, int);

496 MULTI: Building Applications for Embedded ARM


Precompiled Header Files

Precompiled Header Files


It is often desirable to avoid repeatedly recompiling a set of header files,
especially when they introduce many lines of code and the primary source
files that #include them are relatively small. The Green Hills C++ compiler
provides a mechanism to save to disk a copy of the compiled headers together
with a data structure recording the present state of the project. Then, when
you recompile the same source file (or others with the same set of headers),
the compiler checks that this precompiled header file (PCH) is still valid and,
if so, uses it in place of the original headers. In the right circumstances, this
can produce a dramatic improvement in compilation time. Note that PCH
files can take up a lot of disk space. For more information, see “Performance
Issues” on page 502.

Automatic PCH Processing


To enable automatic PCH processing:

Set the C/C++ Compiler→C++→Precompiled Header


Files→Precompiled Header File option to Automatically Use and/or
Create a PCH (--pch).

The compiler will search for a valid PCH file to read in, and if one is not found
will create one for use on a subsequent compilation.

The PCH file contains a snapshot of all the code preceding the header stop
point. The header stop point is typically the first token in the primary source
file that does not belong to a preprocessing directive, but it can also be specified
directly by #pragma hdrstop (see “Other Ways to Control PCHs” on page
501) if that comes first. For example:
#include "xxx.h"
#include "yyy.h"
int i;

The header stop point is int (the first non-preprocessor token) and the PCH
file will contain a snapshot reflecting the inclusion of xxx.h and yyy.h. If the
first non-preprocessor token or the #pragma hdrstop appears within a #if
block, the header stop point is the outermost enclosing #if. The following
illustrates a more complicated example:

Green Hills Software, Inc. 497


14. Green Hills C++

#include "xxx.h"
#ifndef YYY_H
#define YYY_H 1
#include "yyy.h"
#endif
#if TEST
int i;
#endif

Here, the first token that does not belong to a preprocessing directive is again
int, but the header stop point is the start of the #if block containing it. The
PCH file will reflect the inclusion of xxx.h and, conditionally, the definition
of YYY_H and inclusion of yyy.h; it will not contain the state produced by
#if TEST.

A PCH file will be produced only if the header stop point and the preceding
code (mainly, the header files themselves) meet certain requirements:

• The header stop point must appear at file scope; it may not be within an
unclosed scope established by a header file. For example, a PCH file will
not be created in this case.
// xxx.h
class A {
// xxx.C
#include "xxx.h"
int i; };

• The header stop point must not be inside a declaration started within a header
file, nor (in C++) may it be part of a declaration list of a linkage specification.
For example, in the following case the header stop point is int, but since it
is not the start of a new declaration, no PCH file will be created:
// yyy.h
static
// yyy.C
#include "yyy.h"
int i;

• Similarly, the header stop point must not be inside a #if block or a
#define started within a header file.
• The processing preceding the header stop must not have produced any
errors. Note that warnings and other diagnostics will not be reproduced
when the PCH file is reused.

498 MULTI: Building Applications for Embedded ARM


Precompiled Header Files

• There must have been no references to the predefined macros __DATE__


or __TIME__.
• There must have been no use of the #line preprocessing directive.
• #pragma no_pch (see section “Other Ways to Control PCHs” on page
501) must not have appeared.
• The code preceding the header stop point must have introduced a sufficient
number of declarations to justify the overhead associated with precompiled
headers.

When a precompiled header is produced, it contains, in addition to the snapshot


of the compiler state, some information that can be checked to determine under
what circumstances it can be reused. This includes:

• The compiler version, including the date and time the compiler was built.
• The current directory (i.e., the directory in which the compilation is
occurring).
• The command line options.
• The initial sequence of preprocessing directives from the primary source
file, including #include directives.
• The date and time of the header files specified in #include directives.
This information comprises the PCH “prefix.” The prefix information of a given
source file can be compared to the prefix information of a PCH file to determine
whether the latter is applicable to the current compilation.

As an illustration, consider two source files:


// a.C
#include "xxx.h"
// Start of code
// b.C
#include "xxx.h"
// Start of code

When a.C is compiled with automatic PCH processing enabled, a precompiled


header file named a.pch is created. Then, when b.C is compiled (or when a.C
is recompiled), the prefix section of a.pch is read in for comparison with the
current source file. If the command line options are identical, if xxx.h has not
been modified, and so forth, then, instead of opening xxx.h and processing it

Green Hills Software, Inc. 499


14. Green Hills C++

line by line, the compiler reads in the rest of a.pch and thereby establishes the
state for the rest of the compilation.

It may be that more than one PCH file is applicable to a given compilation.
If so, the largest (i.e., the one representing the most preprocessing directives
from the primary source file) is used. For instance, consider a primary source
file that begins with:
#include "xxx.h"
#include "yyy.h"
#include "zzz.h"

If there is one PCH file for xxx.h and a second for xxx.h and yyy.h together, the
latter will be selected (assuming both are applicable to the current compilation).
Moreover, after the PCH file for the first two headers is read in and the third is
compiled, a new PCH file for all three headers may be created.

When a precompiled header file is created, it takes the name of the


primary source file, with the suffix replaced by .pch. Unless a C/C++
Compiler→C++→Precompiled Header Files→PCH Search Directory
(--pch_dir) is specified (see “Other Ways to Control PCHs” on page 501), it is
created in the directory of the primary source file.

When a precompiled header file is created or used, a message such as the


following is issued:
"test.C": creating precompiled header file "test.pch"

To suppress this message:

Disable the C/C++ Compiler→C++→Precompiled Header


Files→PCH Messages option (--no_pch_messages).

When C/C++ Compiler→C++→Precompiled Header Files→Precompiled


Header File is set to Automatically Use and/or Create a PCH (--pch), the
compiler will consider a precompiled header file obsolete and delete it under
the following circumstances:

• If the precompiled header file is based on at least one out-of-date header file
but is otherwise applicable for the current compilation.

500 MULTI: Building Applications for Embedded ARM


Precompiled Header Files

• If the precompiled header file has the same base name as the source file
being compiled (e.g., xxx.pch and xxx.C) but is not applicable for the
current compilation (e.g., because of different command line options).

This handles some, but not all, common cases. Other PCH file clean-up must be
performed by the programmer.

Manual PCH Processing


To manually create a PCH file:

Set the C/C++ Compiler→C++→Precompiled Header


Files→Precompiled Header File option to Create and Use a New
PCH and enter a filename in the Value field (--create_pch file).

To manually specify an existing PCH file for use:

Set the C/C++ Compiler→C++→Precompiled Header


Files→Precompiled Header File option to Create and Use a New
PCH and enter a filename in the Value field (--use_pch file).

If the specified PCH file is invalid (i.e., if its prefix does not match the prefix for
the current primary source file), a warning will be issued and it will not be used.

By default, PCH files are created and searched for in the directory containing the
primary source file. To specify an alternate directory for writing and reading:

Specify the path in the C/C++ Compiler→C++→Precompiled Header


Files→PCH Search Directory option (--pch_dir file).

This option will not affect PCH files specified with an absolute pathname.

Other Ways to Control PCHs


There are several ways you can control and/or tune how precompiled headers
are created and used.

Green Hills Software, Inc. 501


14. Green Hills C++

• #pragma hdrstop may be inserted in the primary source file at a point


prior to the first token that does not belong to a preprocessing directive. This
enables you to specify where the set of header files subject to precompilation
ends. For example:
#include "xxx.h"
#include "yyy.h"
#pragma hdrstop
#include "zzz.h"

Here the precompiled header file will include processing states for xxx.h
and yyy.h but not zzz.h. This is useful if you decide that the information
added by what follows the #pragma hdrstop does not justify the
creation of another PCH file.
• #pragma no_pch may be used to suppress precompiled header
processing for a given source file.

Performance Issues
The relative overhead incurred in writing out and reading back in a precompiled
header file is quite small for reasonably large header files.

In general, the cost of writing out a precompiled header file is relatively low,
even if the file ends up not being used. If it is used, it almost always produces a
significant increase in compilation speed. The problem is that the precompiled
header files can be quite large (from a minimum of about 250K bytes to several
megabytes or more).

Thus, despite the faster recompilations, precompiled header processing is


not likely to be justifiable for an arbitrary set of files with nonuniform initial
sequences of preprocessing directives. Rather, the greatest benefit occurs when
a number of source files can share the same PCH file. The more sharing, the
less disk space is used. With sharing, the disadvantage of large precompiled
header files can be minimized, without giving up the advantage of a significant
speedup in compilation times.

Consequently, to take full advantage of header file precompilation, try to


reorder the #include sections of your source files and/or group #include
directives within a commonly used header file.

502 MULTI: Building Applications for Embedded ARM


Linkage

Different environments and different projects will have different needs, but in
general you will need to experiment and may need to make some minor changes
to source code in order to make the best use of this feature.

Linkage
C++ accepts the extern "language" directive in order to achieve linkage
between C++ and C. The full syntax is as follows:
extern "language" {
declarations
}

or
extern "language" declaration;

where language may be C or C++.


Language Effect on Resulting Code
C C++ does not alter the procedure name as it usually would when
confronted with an overloaded function.
C++ Uses C++ naming rules. Function names are always mangled
according to C++ linkage specifications. This is the default
linkage.

Note that the extern "language" directive only affects the external names of
functions so that the compiler will apply the appropriate function naming rules.
This directive does not modify the type or number of arguments of a function, or
its return type. Normal C++ type checking rules are not altered by this directive.

For more information about using C++ with C, see Chapter 17, “Mixing
Languages and Writing Portable Code”.

Post Processing in C++


In C or C++, global objects (or non-local static objects) are those objects which
are declared outside of the scope of any function and are available throughout
the entire program. C++ objects which are instances of a class type have
mechanisms for automatic construction/initialization and destruction/cleanup
through the use of constructors and destructors. Constructors are functions

Green Hills Software, Inc. 503


14. Green Hills C++

which are automatically called by the compiler when an object is created.


Destructors are called when an object is deleted. This implies some
implementation-specific behavior for global objects which may vary from C++
system to C++ system.

Global objects, such as those in libraries (e.g. cin, cout, and cerr) must
be constructed and initialized for the entire program. This means that the
constructor functions must be called as soon as the program begins. The
compiler has no knowledge of external global objects contained in other
modules or libraries except for an extern declaration. This is not enough
information for the compiler to be able to properly insure that these calls are
performed. For targets that use the Green Hills linkers, the linker resolves the
global constructor and destructor information. In other environments, the
cxxmunch utility assumes this responsibility. The VxWorks environment
is unique in that the module load/unload functions invoke the global
constructors/destructors, or else the user executes them manually.

After an executable has been produced, the Green Hills C++ compiler driver
calls an nm utility (such as gnm) to find all global symbols. The output of the
nm utility is sent to the post-link program cxxmunch. cxxmunch searches
for all global constructor and destructor calls and generates a C module that
will execute these calls appropriately at program startup and exit. The driver
then invokes the compiler and assembler to produce another object module.
Following that, the linker is invoked to relink the new constructor/destructor
object with the original object and libraries. This produces the fully processed
C++ executable, which has all of the appropriate constructor and destructor
calls.

The driver makes all of this processing completely transparent. However, those
who choose not to use the driver provided by Green Hills are responsible for
calling the post-link program after producing an executable; otherwise the
program may not run correctly.

The C++ decode Utility


The decode utility is provided with Green Hills C++. Its syntax is as follows:
decode [-u]

This utility is a C++ name “demangler”. It reads the input from stdin and
writes output to stdout. Anything that looks like mangled names in the input

504 MULTI: Building Applications for Embedded ARM


C++ Implementation-Defined Features

are demangled. Everything else is passed through unchanged. This makes


the program suitable, for example, as a filter for the output of a linker; error
messages in general are passed through unaltered, but mangled names are
demangled. For example:
ld: Undefined symbol
f__Fif

is changed to:
ld: Undefined symbol
f(int, float)

The decode utility takes only a single option: -u. When used, -u specifies
whether external names have an added leading underscore.

C++ Implementation-Defined Features


• 1.3.2: Diagnostic message — for a complete list of the C++ compiler
diagnostic messages, see the MULTI: C and C++ Compiler Error Messages
book (online only).
• 1.3.5: Implementation-defined behavior — Documentation is provided in
this section.
• 1.3.6: Implementation limits — none.
• 1.4: Implementation compliance — the standard Green Hills distribution
is built around a hosted implementation with the standard set of available
libraries.
• 1.7: The C++ memory model — the size of a byte is 8 bits.
• 1.9: Program execution — the minimum requirements are all fulfilled.
• 2.1: Phases of translation — Mapping of file characters to the basic source
character set is performed via identity mapping. Nonempty sequence
of white-space characters (other than new-lines) are retained through
preprocessing. Sources of translation units containing definitions of
templates that are being instantiated are required to be available.
• 2.2: Character sets — ASCII encoding is used for all characters.
• 2.8: Header names — see “Instructing the Compiler to Search for Your
Headers” on page 96.

Green Hills Software, Inc. 505


14. Green Hills C++

• 2.13.2: Character literals — the C/C++ Compiler→Special


Tokens→Host & Target Kanji Support option enables recognition of
multi-byte character Kanji sequences. When this option is disabled, or when
unrecognized sequences are encountered, up to four chars are generated,
initializing an int value, the least significant byte of which is initialized to
the rightmost c-char of the multi-byte character literal. If there are less than
four c-chars, the most significant bytes will be 0. Character literals outside
of the implementation-defined range are truncated to the [0,255] range.
Universal characters are truncated in the same way as \xhhh characters.
• 2.13.3: Floating literals — same as the C compiler (see “ANSI C
Implementation Defined Features” on page 441).
• 2.13.4: String literals — Duplicate string literals are merged by default.
Enable the C/C++ Compiler→C/C++ Data Allocation→Uniquely
Allocate All Strings option to create a unique instance of every string.
• 3.6.1: Main function — main() is required for stand-alone projects,
and all operating systems except for vxWorks. The following additional
main() definitions are supported:

int main(int argc, char *argv[], char *env[])

(where *env[] is a null-terminated array of environment variables.)


A return type of void is also permitted with a warning.

Linkage of main() is external.


• 3.6.2: Initializations of non-local objects — Dynamic initialization of
objects of namespace scope is performed by _main(), except for vxWorks
projects which use the _ctors array. All static constructors within one
compilation unit are executed in lexical order. Constructors in different
compilation units are executed in link-line order.
• 3.9: Types — for data type sizes and alignments, see “ARM Characteristics”
on page 84.
• 3.9.1: Fundamental types — char and unsigned char hold
equivalent non-negative values by default. The C/C++ Compiler→Data
Types→Signedness of Char Type option enables negative and non-negative
equivalent values. float and double are represented in the IEEE format.
The long double type is equivalent to double.
• 3.9.2: Compound types — Pointers are 4 bytes.

506 MULTI: Building Applications for Embedded ARM


C++ Implementation-Defined Features

• 4.7: Integral conversions — Unrepresentable values are truncated to a


value that fits into the destination type using modulo operation.
• 4.8: Floating-point conversions — same as the C compiler (see “ANSI C
Implementation Defined Features” on page 441).
• 4.9: Floating-integral conversions — same as the C compiler (see “ANSI
C Implementation Defined Features” on page 441).
• 5.2.8: Type identification — Typeid expression results are only of static
type std::type_info. No derived name classes are provided.
• 5.2.10: Reinterpret cast — mapping remains the same. Mapping of
pointers to addresses and vice versa uses int or larger type.
• 5.3.3: Sizeof: for information about the sizes of fundamental types, see
“ARM Characteristics” on page 84.
• 5.6: Multiplicative operators — Remainder from the division of a negative
and non-negative operand is the same sign as the first operand.
• 5.7: Additive operators — ptrdiff_t is defined as an int.
• 5.8: Shift operators — The result of E1 >> E2 where E1 has a signed
type and a negative value is negative.
• 7.1.5.2: Simple type specifiers — Types char and bitfields are unsigned
by default.
• 7.2: Enumeration declarations — Enumerations have a type of int,
unless the C/C++ Compiler→Data Types→Use Smallest Type Possible
for Enum option is enabled.
• 7.4: The asm declaration — asm declarations are unmodified by the
compiler. For more information, see Chapter 18, “Enhanced asm Macro
Facility for C and C++”.
• 7.5: Linkage specifications — routines declared with extern "C"
will not have name mangling performed on them. The default mode,
extern "C++", performs name mangling. No other language linkages
are supported. Mangling of function names, type names, and static data
member names is performed by the C++ compiler.
• 8.5.3: References — In the circumstances described, a temporary is
generated, rvalue is copied into it, and the reference is bound to the
temporary.
• 9.6: Bit-fields — a bitfield is allocated at the current offset unless it crosses
the offset (which is a multiple of the base type), in which case it is padded

Green Hills Software, Inc. 507


14. Green Hills C++

up to the first multiple of the size of the base type. Plain bitfields are
unsigned unless C/C++ Compiler→Data Types→Signedness of Bitfields
is set to Signed.
• 12.2: Temporary objects — are generated for f(X(2)), but the result will
be stored directly into ’b’.
• 14: Templates — only C and C++ linkages are supported.
• 14.7.1: Implicit instantiation — Recursive instantiations are limited to 30.
• 15.5.1: The terminate() function — the stack is unwound before
terminate() is called.
• 15.5.2: The unexpected() function — unless reset by user, will call
terminate().
• 16.1: Conditional inclusion — Numeric values for character literals in
#if / #elif controlling expressions is identical to char literals in
regular expressions.
• 16.2: Source file inclusion — (see also “Instructing the Compiler to Search
for Your Headers” on page 96):

#include <h-char-sequence> — searches the system header


directories. All identifiers in h-char-sequence will be resolved.
#include "q-char-sequence" — searches the current directory, and
then all include directories. Sequences in q-char-sequence will be treated
as a string literal, and will not be resolved.
Mapping between the sequence and the external source filename — is
performed through the identity function.
Nesting of #include preprocessor directives — can exceed 1,000
levels.
• 16.6: Pragma directive — see “#pragma Directives” on page 526.
• 16.8: Predefined macro names — for a list of the required preprocessor
macros and their values, see “Macro Names Required by ANSI C and C++”
on page 512.
• 17.4.4.5: Reentrancy — all subroutines are reentrant provided that the
target system has been configured with the appropriate lock routines in
subdirectory libsys.

508 MULTI: Building Applications for Embedded ARM


C++ Implementation-Defined Features

• 17.4.4.8: Restrictions on exception handling — see the Dinkum


C++ Library Reference (included with your distribution, at
install_dir/scxx/html/index.html)
• 18.1: Types — NULL has a value of 0.
• 18.3: Start and termination — exit() returns the value of argument
status:

EXIT_SUCCESS — has a value of 0.


EXIT_FAILURE — has a value of 1.
• 18.4.2.1: Class bad_alloc — what() returns an empty string.
• 18.5 to 18.6: Various class definitions. See Dinkum C++ Library Reference.
• 18.7: Other runtime support — we strongly recommend that all signal
handlers are POFs (plain old functions).
• 20.1.5: Allocator requirements — match those in the standard. Certain
operations on containers and algorithms will behave differently if allocator
instances compare non-equal. The class allocator always returns true
for operator ==.
• 21.1.3.1: struct char_traits<char> — types streampos and
streamoff have typedefs of fpos<mbstate_t> and long,
respectively. Type wstreampos has a typedef of streampos
• 22.2: Standard locale categories Various type definitions. See Dinkum
C++ Library Reference.
• 22.2.5.1.2: time_get virtual functions — Two-digit year numbers. 0 to 68
represent years 2000 to 2068, and 69 to 136 represent years 1969 to 2036
• 23.2 to 23.3 — Various type and class definitions. See Dinkum C++ Library
Reference.
• 26.2.8: complex transcendentals — pow(0,0)==(1,0)
• 26.3: Numeric arrays — Various type and class definitions. See Dinkum
C++ Library Reference.
• 27.1.2: Positioning Type Limitations — In Green Hills standard libraries,
traits::pos_type and traits::off_type have types of
streampos and streamoff respectively
• 27.4.1: Types — streamoff has a type long.
• 27.4.2.4: ios_base static members — The synchronization flag is ignored.
Streams are always synchronized.

Green Hills Software, Inc. 509


14. Green Hills C++

• 27.4.4.3: basic_ios iostate flags functions — Argument values are


either iosbase::badbit set, iosbase::failbit set, or
iosbase::eofbit set, depending upon which bit was set.
• 27.7.1.3: Overridden virtual functions — has no effect for
basic_streambuf. It is overridden for basic_filebuf.
• 27.8.1.4: Overridden virtual functions — calls the C library function
setvbuf with the input arguments. Buffering is performed using _IOFBF
• C.1.9.16.8: Predefined names — symbol __STDC__ has a value of 0.
• C.2.2.3: Macro NULL — has a value of 0.
• D.6: Old iostreams members — see 21.1.3 for streampos and
streamoff typedefs.

510 MULTI: Building Applications for Embedded ARM


Chapter 15

Macros, #pragmas, and


Intrinsics

This Chapter Contains:


• Predefined Macro Names
• #pragma Directives
• Intrinsic Functions
15. Macros, #pragmas, and Intrinsics

Predefined Macro Names


The preprocessor automatically defines a number of macro names based upon
the compiler and language you are using, and on the builder or driver options
that you have specified. Consequently, you can write code which will compile
differently under different circumstances by using the #ifdef preprocessor
directive.

All of the preprocessor predefined macros are listed in the following sections.

Macro Formats
The standards for C and C++ require that all macros which are predefined by
the compiler begin with one or two underscore characters. Prior to the ANSI
standard, some C preprocessors defined macros with names (such as ghs or
unix) which could conflict with macro names in the user’s program.

Each Green Hills macro is defined with two leading underscores in all language
modes, unless stated otherwise.

Macros marked with a * are also defined by default without the two leading
underscores in K&R C (and the Compatibility Mode C Compiler’s Transition C
Mode).

Recent preprocessors predefine macros with two leading underscores and two
trailing underscores. Macros marked with a ** are defined by default in all
three possible forms (for instance, ghs, __ghs, and __ghs__) in K&R C
(and the Compatibility Mode C Compiler’s Transition C Mode).

When using other C or C++ modes (except Strict ANSI C), you can instruct
the preprocessor to generate versions of macros marked as * or ** as it
would in K&R mode by enabling the Advanced→Advanced Preprocessor
Options→Definition of Unsafe Symbols (--unsafe_predefines) option.

All predefined macros have the value 1, unless stated otherwise.

Macro Names Required by ANSI C and C++


The standards for C and C++ require the preprocessor to define certain macro
names. These macro names and their values are shown in the table below. All

512 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

of them are defined in all modes of C, except __STDC__, which is defined in


C++ and ANSI C only.
__cplusplus
The value of this macro is:
• 199711L: in ANSI C++
• 1: in other modes of C++ (EC++, EEC++, ARM)
• Not defined otherwise
__DATE__
A string literal representing the date of the current compilation, which is 11
characters long, and in the form: mmm dd yyyy. For example: "Apr 01 2001"
__FILE__
A string literal representing the name of the current source file (for example,
"file.c")
__FULL_DIR__
A string literal representing the full pathname of the directory of the current source
file.
__FULL_FILE__
A string literal representing the full pathname of the current source file.
__LINE__
An integer literal representing the line number in the current source file.
__STDC__
The value of this macro is:
• 0: in C++ and ANSI C mode
• 1: in Strict ANSI C mode
• Undefined in K&R C
__STDC_VERSION__=199409L
Defined in C++ and all modes of C except K+R.
__TIME__
A string literal representing the local time of the current compilation, which is 8
characters long, and in the form: hh:mm:ss. For example: "11:46:51"

Language Identifier Macros


These macros identify the language used:

Green Hills Software, Inc. 513


15. Macros, #pragmas, and Intrinsics

Primary Language Macros


__LANGUAGE_ASM__ **
Language is assembly.
__LANGUAGE_C__ **
Language is C.
__LANGUAGE_CXX__ **
Language is C++.

C Language Macros
__EXTENDED_EMBEDDED_CXX_HEADERS
The Extended Embedded C++ header files and libraries are used (for example,
options --eel or --eele).
__Japanese_Automotive_C
Japanese Automotive C
__PROTOTYPES__
All modes of C except K&R mode. All modes of C++.
__STRICT_ANSI__
Language is Strict ANSI C. Defined only when GNU is selected as your C or
C++ dialect.

C++ Language Macros


__c_plusplus
Language is C++ (this is for backwards compatibility with some older C++
implementations).
__embedded_cplusplus
Language is Embedded or Extended Embedded C++.
__EMBEDDED_CXX
Language is Embedded C++ (for example, option --e).
__EMBEDDED_CXX_HEADERS
The Embedded C++ header files and libraries are used (for example, options
--el or --ele).

514 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

__EXTENDED_EMBEDDED_CXX
Language is Extended Embedded C++ (ESTL) (for example option --ee).
__EXTENDED_EMBEDDED_CXX_HEADERS
The Extended Embedded C++ header files and libraries are used (for example,
options --eel or --eele).
__STANDARD_CXX
Language is Standard C++.
__STANDARD_CXX_HEADERS
The Standard C++ header files and libraries are used (for example, options
--stdl or --stdle).

Green Hills Toolchain Identification Macros


__CCOM__
Compatibility Mode Compiler.
__EDG__
C++ or New Generation Compiler.
__ghs__ **
Any Green Hills Software compiler or preprocessor.
__ghs_asm
Indicates that the Green Hills assembler is in use.
__ghs_c_int__
Predefined typedef equivalent in size to int. When used in to describe a function
parameter, it requires that the parameter passed in is an integer constant.
__ghs_psinfo
Target supports the psinfo “self-aware” structure. Only defined when the
-private_defines option is passed.
__GHS_REVISION_DATE
The date of the compiler, represented as a string similar to __FILE__.
__GHS_REVISION_VALUE=n
Represents the date, n, of the compiler build in the time_t format.
__ghs_stdcall
Target uses a standard Green Hills argument passing convention.

Green Hills Software, Inc. 515


15. Macros, #pragmas, and Intrinsics

__GHS_VERSION_NUMBER=n
Represents the version, n, of the toolchain.
__gnu_asm
Indicates that the GNU assembler is in use.
__unix_asm
Indicates that the UNIX assembler is in use.

ARM-Specific Predefined Macro Names


The following table lists predefined macros specific to the ARM processor
family:
__ARM
ARM processor family
__ARM_DSP
ARM CPU variant supports enhanced DSP extensions (E variants).
__THUMB
Thumb code
__THUMB_AWARE
ARM CPU variant supports Thumb mode.

Note For a list of individual processor macros, see “ARM Processor Variants”
on page 90.

Endianness Macros
One of these symbols is always defined to specify the endianness of the target
processor.
__BIG_ENDIAN__
Big Endian byte order.
__LITTLE_ENDIAN__
*
Little Endian byte order.

516 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

Data Type Macros


These macros specify the size and signedness of certain data types.

Sizes
__CHAR_BIT=n
Specifies the size of char in bits.
__FUNCPTR_BIT=n
Specifies the size of a function pointer in bits.
__INT_BIT=n
Specifies the size of int in bits. See also __PTRDIFF_TYPE__,
__SIZE_TYPE__, and __WCHAR_TYPE__ in “GNU Compatibility Macros” on
page 522.
__LONG_BIT=n
Specifies the size of long in bits.
__LLONG_BIT=n
Specifies the size of long long in bits. Defined only if the long long type
is supported.
__NO_LONGLONG
No long long support (equivalent to the --no_long_long driver option).
__PTR_BIT=n
Specifies the size of a pointer in bits.
__REG_BIT=n
Specifies the size of an integer register in bits.
__SHRT_BIT=n
Specifies the size of short in bits.
__WCHAR_BIT=n
Specifies the size of wchar_t in bits.

Signedness
__Enum_Field_Is_Signed__
__Enum_Field_Is_Unsigned__
Bitfield enumerations are signed or unsigned.

Green Hills Software, Inc. 517


15. Macros, #pragmas, and Intrinsics

__Field_Is_Signed__
__Field_Is_Unsigned__
Bitfields are signed or unsigned
__Ptr_Is_Signed
__Ptr_Is_Unsigned
Pointers are signed or unsigned.
__SIGNED_CHARS__
__CHAR_UNSIGNED__
Type char is signed or unsigned.
__WChar_Is_Signed__
__WChar_Is_Unsigned__
Type wchar_t is signed or unsigned.

Floating-Point Macros
These macros specify the manner in which floating-point operations are
performed.
__DOUBLE_HL
Passed if the high word of a double comes at the lower address in memory. This is
usually the case for big endian targets, although certain targets behave differently.
__IeeeFloat *
IEEE-754 floating-point format. This symbol is always defined.

Floating-Point Mode Macros


One of these symbols is always defined, unless full hardware floating point is
enabled.
__NoFloat *
No floating point mode.
__SoftwareDouble
Double precision floating point uses integer instructions.
__SoftwareFloat
All floating point is done with integer instructions.

518 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

MISRA Macros
These macros relate to the MISRA C variant.
__MISRA_i=n
MISRA diagnostic levels.
i is either 8 or 118–127, and n is one of the following:
• 0: Silent
• 1: Warn
• 2: Error
For more information about the MISRA rules, see “MISRA C” on page 154.
__ONLY_STANDARD_KEYWORDS_IN_C
MISRA rule No. 1

Memory Model Macros


These macros relate to various different forms of memory model.

Position Independent Code and Data Macros


__ghs_pic=n *
Position Independent Code (PIC) is enabled. n will be set to one of the following:
• 1: Deprecated Green Hills behavior. In this mode, static or global initializers to
position-independent objects were not supported. The compiler will warn for
any unsupported position independent initializers.
• 2: Normal Green Hills behavior. Special start-up code is invoked to fix up static
or global initializers to position-independent objects.
__ghs_pid=n *
Position Independent Data (PID) is enabled. n will be set to one of the following:
• 1: Deprecated Green Hills behavior. In this mode, static or global initializers to
position-independent objects were not supported. The compiler will warn for
any unsupported position independent initializers.
• 2: Normal Green Hills behavior. Special start-up code is invoked to fix up static
or global initializers to position-independent objects.

Green Hills Software, Inc. 519


15. Macros, #pragmas, and Intrinsics

Global Register Macros


__GlobalRegisters=n
Corresponds to settings of -globalreg=n, where n is a non-negative integer.

Global Variable Macros


__GHS_NOCOMMONS
Uninitialized global variables in C do not exhibit COMMON variable behavior
(corresponds to the --no_commons driver option).

Alignment and Packing Macros


These macros specify the size of data alignment and packing.
__ghs_alignment=n
Alignment of the most-aligned type, which is either double, long, or long long.
Has a value of 1, 2, or 4.
__ghs_max_pack_value=n
Represents the largest value that may be passed to #pragma pack(n). Has a
value of 1, 2, or 4.
__ghs_packing=n
Represents value specified with the -pack=n option on the command line. Has
a value of 1, 2, or 4. If the macro name is not defined, , no -pack= option was
specified on the command line. This value is not changed by the #pragma
pack(n) directive.
__ghs_struct_min_alignment=n
The value of the minimum structure alignment in bytes. This symbol is not
defined if n is 1. Otherwise, it has the value 2, 4, or 8. Corresponds to the
--struct_min_alignment=ndriver option.

Current File and Function Macros


These macros identify the current file and function. See also __FILE__ in
“Macro Names Required by ANSI C and C++” on page 512.

520 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

__BASE__
A string literal representing the name of the current source file, without the
directory path.
__FUNCTION__
A string literal representing the current function name. (The macros
__FUNCTION__ and __PRETTY_FUNCTION__ depend on their context, and
cannot be determined by a preprocessing-only pass. Therefore, the compiler will
not resolve those two macros when options -E or -P are used.)
__PRETTY_FUNCTION__
In C++, a string literal representing the fully qualified function name. In C, behaves
the same as __FUNCTION__.

Object Format Macros


These macros specify the object format.
__BSD
Object file type is BSD.
__COFF
Object file type is COFF.
__ELF
Object file type is ELF.

Optimization Predefined Macro Names


These macros relate to the optimization strategy employed.
__GHS_Inline_Memory_Functions
Inlining of C Memory Functions (see “Inlining of C Memory Functions” on page
632).
__GHS_Inline_String_Functions
Inlining of C String Functions is enabled (see “Inlining of C String Functions”
on page 633).
__GHS_Optimize_Inline
Automatic inlining is enabled (see “Automatic Inlining” on page 625).

Green Hills Software, Inc. 521


15. Macros, #pragmas, and Intrinsics

GNU Compatibility Macros


These macros are not defined unless you select the GNU dialect in C/C++
Compiler→C Language Dialect (-gcc) or C/C++ Compiler→C++ Language
Dialect (--g++). See also __INT_BIT=n in “Data Type Macros” on page 517.
__BASE_FILE__
Similar to __FILE__ except its value always represents the name of the top level
source file, even when referenced in an include file. This macro is not available
in C++ with any option.
__OPTIMIZE__
General Optimizations are enabled.
__OPTIMIZE_SIZE__
Size Optimizations are enabled.
__PTRDIFF_TYPE__
Has the value of the appropriate type.
__SIZE_TYPE__
Has the value of the appropriate type.
__USER_LABEL_PREFIX=symbol
Has the value “_” or nothing, depending on whether an underscore is prepended
to symbols in C when generating assembly language.
__WCHAR_TYPE__
Has the value of the appropriate type.

C++ Macros
These macros relate to various features of C++.
__ARRAY_OPERATORS
Defined when array new and delete are enabled (that is, operator new[] and
operator delete[]).
_BOOL
Defined when bool is recognized as a basic type (for example, as with the option
--bool).
__EDG_IMPLICIT_USING_STD
Defined when the standard namespace std is implicitly used (as with the option
--using_std).

522 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

__EDG_RUNTIME_USES_NAMESPACES
Indicates that the C++ Run-time libraries use namespaces.
__EXCEPTION_HANDLING
__EXCEPTIONS
Indicates C++ compiler is running in a mode that allows exception handling.
__NAMESPACES
Indicates C++ namespaces are accepted.
__RTTI
Indicates Run-Time Type Identification code accepted.
_WCHAR_T
Defined if wchar_t is a keyword.

Operating System-Specific Macros


These macros identify the target operating system.

INTEGRITY Macros
__INTEGRITY
INTEGRITY real-time operating system.

ThreadX Macros
__THREADX
ThreadX real-time operating system.
TX_ENABLE_EVENT_LOGGING
ThreadX event logging enabled.

VxWorks Macros
__VXWORKS *
Wind River VxWorks.

Green Hills Software, Inc. 523


15. Macros, #pragmas, and Intrinsics

__CPU=x
CPU variants for VxWorks.

Deprecated Macros
These macros are deprecated and may not be supported in future versions of
MULTI.
__Char_Is_Signed
Type char is signed char.
__Char_Is_Unsigned
Type char is unsigned char.
__Int_Is_32
Type int is 4 bytes.
__Int_Is_64
Type int is 8 bytes. (The macro __Int_Is_64 is an old style macro, kept for
backward compatibility. The new style macros (like __INT_BIT=n) should be
used when possible.)
__msw *
Any version of Microsoft Windows (deprecated).
__LL_BIT=n
Describes the size of long long in bits.
__LL_Is_64
Type long long is 8 bytes (when long long is an allowed type).
__Long_Is_32
Type long is 4 bytes.
__Long_Is_64
Type long is 8 bytes.
__Ptr_Is_32
Pointers are 4 bytes.
__Ptr_Is_64
Pointers are 8 bytes.
__Reg_Is_32
CPU has 32-bit registers.

524 MULTI: Building Applications for Embedded ARM


Predefined Macro Names

__Reg_Is_64
CPU has 64-bit registers.
__WChar_Is_Int__
Type wchar_t are int or unsigned int.
__WChar_Is_Long__
Type wchar_t are long or unsigned long.
__WChar_Is_Short__
Type wchar_t is short or unsigned short.

Green Hills Software, Inc. 525


15. Macros, #pragmas, and Intrinsics

#pragma Directives
#pragma directives allow individual compiler implementations to add special
features to C programs without changing the C language. Programs that use
#pragma directives stay relatively portable, although they make use of features
unavailable in all ANSI C implementations.

According to the ANSI standard, the #pragma directives that are not
recognized by the compiler should be ignored. This requirement may help
when porting code between compilers because one compiler will recognize and
process a certain #pragma directive, while a different compiler (which does
not need or recognize that #pragma directive) will, by default, generate a
warning and ignore it.

If a #pragma directive which would ordinarily be recognized is misspelled,


the compiler will not recognize it and will, by default, generate a warning and
ignore it. You can increase the severity of these messages to errors, or suppress
them, as follows:

Set the Compiler Diagnostics→C/C++ Messages→Unknown


#pragmas option to Errors (--unknown_pragma_errors) or Silent
(--unknown_pragma_silent).

The majority of Green Hills proprietary #pragma directives begin with the
keyword ghs to differentiate them from other implementations. The compiler
considers any #pragma beginning with the ghs keyword to be recognized.

If the compiler recognizes a #pragma directive, it will perform some limited


syntax checking. #pragma directives that fail these checks will, by default,
generate warnings, and be ignored. You can increase the severity of these
messages to errors, or suppress them, as follows:

Set the Compiler Diagnostics→C/C++ Messages→Incorrect


#pragmas option to Errors (--incorrect_pragma_errors) or Silent
(--incorrect_pragma_silent).

526 MULTI: Building Applications for Embedded ARM


#pragma Directives

General #pragma Directives


The general #pragmas are listed in the following table:
#pragma alignvar (n)
Instructs the compiler to make the next variable n-byte aligned, where n is 1,
2, 4, 8, or 16.
#pragma asm
#pragma endasm
These #pragmas mark the beginning and end of a section of code which is to be
copied literally to the assembly language output file. Any macros or preprocessing
directives will be processed, but no processing of comments will be performed.
The construct #pragma endasm may not contain any comments or \ escapes,
although it may contain spaces or tabs before and after the # character, as long as
the total length of the line does not exceed 255 characters.
The New Generation Compiler accepts these #pragmas by default. To
use them with the Compatibility Mode Compiler, you must pass either the
-pragma_asm_inline or the -japanese_automotive_c driver option.
Note that the Compatibility Mode Compiler, inserts the text approximately into the
scope of the last statement. So, a #pragma asm placed immediately after the
end of a scope will appear inside the scope. Consider the following example:

int function(int i)
{
if (i) {
i++;
}
#pragma asm
some assembly
#pragma endasm
return i;
}

In this case, the contents of the #pragma asm will appear in the same block of
code as the i++; statement. An empty statement (such as a lone semicolon on
a line) may be used to force the contents of the pragma #asm into the same
block as the empty statement. This caveat only applies to the Compatibility Mode
compiler.

Green Hills Software, Inc. 527


15. Macros, #pragmas, and Intrinsics

#pragma hdrstop
Instructs the compiler to write the parse state to disk at this point. Later, when
the file is recompiled, parsing will begin at the point of this #pragma, with the
precompiled header information loaded.
For more information about precompiled header files, see “Precompiled Header
Files” on page 497.
#pragma ident "string"
Inserts string in the output assembly file as a comment.
#pragma inline function-list
This #pragma is deprecated.
Instructs the compiler to consider each function in the comma-separated
function-list as a candidate for inlining.
Note that you cannot force the compiler to inline any function.
#pragma instantiate fn
#pragma can_instantiate fn
#pragma do_not_instantiate fn
These #pragmas can be used to control the instantiation of a template function,
fn. For full documentation, see “Template Instantiation” on page 481.
#pragma intvect intfunc integer_constant
Instructs the compiler to insert a pointer to the function intfunc at the address
specified by integer_constant.
For more information, see “Writing Interrupt Routines” on page 120.
#pragma no_pch
Suppresses precompiled header processing for the current source file.
For more information about precompiled header files, see “Precompiled Header
Files” on page 497.
#pragma once
This #pragma is only available with the New Generation Compiler.
If this #pragma is placed at the beginning of a header file, the compiler will only
include the file once, and will ignore subsequent #include statements that
reference the file.

528 MULTI: Building Applications for Embedded ARM


#pragma Directives

#pragma pack (n)


#pragma pack ()
#pragma pack (push {, name} {, n})
#pragma pack (pop {, name} {, n})
Instructs the compiler to lay out subsequent class, struct, and union
definitions in memory with a maximum alignment of n, where n is 1, 2, or 4.
The second format, where n is not specified, reverts the maximum alignment to
the default value, or that specified by the Builder or driver.
The third and fourth formats, only available with the New Generation Compiler,
allow you to push and pop maximum alignment values, and to specify a name for
the pushed value, so that it can subsequently be popped back to by name.
#pragma __printf_args
#pragma __scanf_args
These #pragmas are available only with the New Generation Compiler.
These #pragmas should be used immediately before a function declaration or
definition.
If the function has a variable number of arguments and the last specified argument
is of type char *, the function is treated as a variadic function like printf or
scanf.
The compiler will expect that the last specified argument is a character string,
with printf or scanf formatting sequences (that is "%s"), and will check the
extra arguments to ensure that the type and number match the type and number
specified in the format string.
#pragma unknown_control_flow (function-list)
Instructs the compiler to anticipate an unexpected flow from each function in
the comma-separated function-list. Such a function would be setjmp. This
information is used in various optimizations.

Green Hills Software, Inc. 529


15. Macros, #pragmas, and Intrinsics

#pragma weak foo


Defines foo as a weak symbol. This #pragma may be used in either of the
following ways:
• If foo is declared as an external reference in filename:
#pragma weak foo
extern int foo;

and foo is not defined in any other file, then the address of foo is set to zero (or,
in the case of projects that use PIC or PID, 0 plus the adjustment for the text
or data segment offset). This will prevent an undefined symbol linker error.
• If foo is defined in filename:
#pragma weak foo
int foo = 1;

and a definition of foo appears in any other file, then that other definition
will have priority, and the definition in filename will be treated as if it were
an external reference.
#pragma weak foo = bar
This #pragma has the same effect as #pragma weak foo, except that (subject
to the same conditions) the address of foo is set to the address of bar. It
requires that foo is not defined in the current module, although it could be an
external reference. bar must be defined at the outermost level of the current
module. bar may not be a common symbol (see the C/C++ Compiler→C/C++
Data Allocation→Allocation of Uninitialized Global Variables option in
“C/C++ Data Allocation” on page 166).This #pragma may be used to provide
a backwards-compatible alias to a symbol which has been renamed in a new
version of a program, as follows:

#pragma weak oldname=name


int name()
{
return 5;
}

If any old software depends on the existence of oldname, it will continue to work as
if the function is called oldname. If there are no longer any references to oldname,
then the symbol effectively disappears and can be reused.

530 MULTI: Building Applications for Embedded ARM


#pragma Directives

Green Hills Extension #pragmas


The Green Hills extension #pragmas are listed in the following table:
#pragma ghs alias newsym oldsym
Creates a new global symbol newsym with the same address as oldsym. newsym
cannot be defined in the current module or the behavior is undefined. oldsym
must be defined at the outermost level of the current module. oldsym cannot be a
common symbol (see the C/C++ Compiler→C/C++ Data Allocation→Allocation
of Uninitialized Global Variables option in “C/C++ Data Allocation” on page 166).
#pragma ghs alias newsym oldsym is similar to #pragma weak
newsym=oldsym except that in the latter case, newsym is defined as a weak
symbol.
#pragma ghs callmode=near|far|default
#pragma ghs near
#pragma ghs far
These #pragmas control the call mode used to call subsequent functions.
For more information about these #pragmas, and other methods for controlling
function call modes, see “Near and Far Function Calls” on page 115.

Green Hills Software, Inc. 531


15. Macros, #pragmas, and Intrinsics

#pragma ghs check=(check-list)


Controls various run-time checks. This #pragma must be used at the global scope
level, and affects all functions which are defined after it.
The checks in the comma-separated check-list are drawn from the following list:
• all — All checks
• none — No checks
• revert — Revert to the checks specified by the Builder or driver (see below).
• bound or bounds — Array Bounds check
• assign or assignbound — Assignment Bounds check
• case or switch — Case Label Bounds check
• zero or zerodivide — Divide by Zero check
• return — Function Return Value check
• alloc — Memory Allocation (General) check
• memory — Memory Allocation (Intensive) check
• nil or nilderef — Nil Pointer Dereference check
• use or usevariable — Variable Read Before Write check
• watch — Write to Watchpoint check
To turn off any of these options, append the prefix no to the appropriate
pragma-item. You can use this to turn on everything except the specified check.
For example, to turn on all checks except the Divide by Zero check:

#pragma ghs check=(all,nozero)

These checks can all also be set with Builder or driver options (see the
Debugging→Run-Time Error Checks option in “Debugging Options” on page
147). Note that the driver only accepts the longer form of the check name.
These #pragmas require that the Green Hills library, libind, be linked in. All of
these checks require additional instructions to be inserted into the generated code,
and consequently will increase your code size and degrade its performance.
For information about using these run-time checks, see Chapter 14, “Viewing
Memory Allocation Information” in the MULTI: Debugging book.

532 MULTI: Building Applications for Embedded ARM


#pragma Directives

#pragma ghs includeonce


Instructs the compiler to include header files only once. If the compiler encounters
subsequent #include directives relating to the same file, it will ignore them.
The same behavior can be obtained with the Advanced→Advanced
Preprocessor Options→Duplicate #includes Builder option and associated
driver option (see “Advanced Preprocessor Options” on page 210).
This #pragma directive is not supported in the Strict ANSI C mode used with the
Compatibility Mode Compiler.
#pragma ghs interrupt
Instructs the compiler to make the encompassing function, or the next function if in
the file scope, an interrupt handling function.
#pragma ghs nofloat interrupt
Instructs the compiler to prevent the encompassing function, or next function if
in file scope (which must be separately identified as an interrupt function) from
saving and restoring floating point-registers.
#pragma ghs nowarning n
#pragma ghs endnowarning
These #pragmas are only supported with the New Generation Compiler.
Control the suppression of warning number n. You may set multiple and/or nested
nowarning directives, but each should have a matching endnowarning.
To display error and warning numbers with diagnostic messages, enable
the Compiler Diagnostics→C/C++ Messages→Varying Message
Severity→Display Error Message Numbers option (--display_error_number).
#pragma ghs Ostring
Turns on optimizations. The optional string may contain any or all of the following
letters:
• L —Loop optimizations
• M — Memory optimizations
• S — Small (but Slow) optimizations
For information about Builder and driver optimization options, see “Optimization
Options” on page 143. For descriptions of many of our optimizations, see Chapter
19, “Optimization Descriptions”.
#pragma ghs reference sym
Creates a reference to symbol sym, which can force the symbol to be pulled in
from a library. It can also be used to prevent an unused function called sym from
being deleted by the “Deletion of Unused Functions” optimization.

Green Hills Software, Inc. 533


15. Macros, #pragmas, and Intrinsics

#pragma ghs revertoptions


Disables all options set via #pragma ghs directives and returns to the defaults
specified by the Builder or driver.
#pragma ghs section sect-type="new-sect-type"
Instructs the compiler to allocate to new-sect-type, code or data that would
normally be allocated to sect-type. For more information, see “Controlling Code
Placement with #pragma ghs section” on page 107.
#pragma ghs startnoinline
#pragma ghs endnoinline
These #pragmas are only available with the New Generation Compiler.
These #pragmas mark the beginning and end of a section of code in which the
compiler cannot consider any functions for inlining. Even inlined C++ member
functions or functions marked with the keywords __inline or inline will not
be inlined. Template functions and member functions of template classes are
not affected.
For more information about controlling inlining, see “Inlining Optimizations” on
page 625.
#pragma ghs startnomisra
#pragma ghs endnomisra
These #pragmas are only available with the New Generation Compiler.
These #pragmas mark the beginning and end of a section of code in which the
compiler does not perform MISRA checking.
For more information, see “MISRA C” on page 154.
#pragma ghs struct_min_alignment(n)
Instructs the compiler to minimally align all subsequent objects of types struct,
class, and union to n bytes, where n is 1, 2, or 4.
#pragma ghs thumb
#pragma ghs nothumb
These #pragmas mark the beginning and end of a section of code to be generated
using the 16-bit Thumb instruction set (see “Thumb Mode” on page 101).
#pragma ghs ZO
Disables all optimizations, starting from the next function.

534 MULTI: Building Applications for Embedded ARM


#pragma Directives

Conditional #pragmas
Any of the Green Hills extension #pragmas can be made conditional upon
whether you are generating debugging information or are optimizing your
executable. To make a #pragma conditional, use the syntax:

#pragma ghs [condition] pragma-name

where the optional condition parameter is one of:

• ifdebug — Enable the #pragma only if debugging information is being


generated (see Debugging→Debugging Level in “Debugging Options”
on page 147).
• ifnodebug — Enable the #pragma only if debugging information is
not being generated.
• ifoptimize — Enable the #pragma only if optimizations are enabled
(see Optimization→Optimization Strategy in “Optimization Options”
on page 143).
• ifnooptimize — Enable the #pragma only if optimizations are not
enabled.

For example, to enable the Assignment Bounds and Unallocated Memory


run-time checks only if optimizations are not enabled, enter #pragma ghs
check=(check-list) as follows:
#pragma ghs ifnooptimize check=(assign,memory)

Green Hills Software, Inc. 535


15. Macros, #pragmas, and Intrinsics

Intrinsic Functions
The ARM architecture provides a number of intrinsic functions to perform
certain tasks which are difficult or inefficient to write in a high-level language.
The Green Hills C and C++ compilers support these functions.

The name of a C or C++ intrinsic function begins with two underscores (__),
which indicate to the compiler that it is a special function. It usually generates
optimized inline code, often using special instructions that do not correspond to
standard C and C++ operations.

Prototypes for the functions can be found in include/arm/arm_ghs.h.


void *__builtin_return_address(unsigned int level);
Returns the return-address of the current function. The level argument must be
set to 0. This function can be used in both normal and interrupt procedures.
void __DI();
void __EI();
These functions disable and enable interrupts and can bracket a critical section
of code that must not be interrupted.
void __RIR(unsigned int);
Takes an unsigned int key previously returned by __DIR() or __EIR() and
restores interrupts to the state represented by that key.
This function, together with __DIR() and __EIR() can be used to safely enable
or disable interrupts and later restore them to their original state when that state
is not known at compile time.
unsigned int __DIR(void);
unsigned int __EIR(void);
Like __DI() and __EI(), these functions disable and enable interrupts. In
addition, they return an unsigned int key that represents the state of interrupts
prior to their operation.
unsigned int __GETSR(void);
void __SETSR(unsigned int);
The __GETSR function returns the current value of the Current Program Status
Register (CPSR).
The __SETSR function takes a 32-bit integer argument and stores it into this
register.

536 MULTI: Building Applications for Embedded ARM


Intrinsic Functions

unsigned int __GETSSR(void);


void __SETSSR(unsigned int);
The __GETSSR function returns the current value of the Saved Program Status
Register (SPSR).
The __SETSSR function takes a 32-bit integer argument and stores it into this
register.

Arithmetic Operation Instructions


extern unsigned int __MULUH(unsigned int a, unsigned int b);
extern signed int __MULSH(signed int a, signed int b);
The __MULUH(a,b) function takes as arguments two 32-bit unsigned integers a
and b and returns the high 32-bit half of their 64-bit unsigned product.
The __MULSH(a,b) function takes as arguments two 32-bit signed integers a and
b and returns the high 32-bit half of their 64-bit signed product.
signed long long __SMLAL(signed long long Rd, signed int Rm,
signed int Rs);
unsigned long long __UMLAL(unsigned long long Rd, unsigned
int Rm, unsigned int Rs);
Uses the smlal or umlal instructions to multiply Rm by Rs and return the sum
of the 64 bit product with Rd.
unsigned int __CLZ32(unsigned int a);
Takes a 32-bit integer argument and returns the count of leading zeros, which is a
number from 0 to 32. When available, it translates to the CLZ instruction of ARM
architecture version 5 (ARM9E, ARM10, XScale, ARM11.)
unsigned long long __UMULL(unsigned int Rm, unsigned int Rs);
signed long long __SMULL(signed int Rm, signed int Rs);
Returns the full 64 bit product of the 32x32->64 bit multiply of Rm and Rs. Uses
the UMULL and SMULL instructions like __MULUH() and __MULSH(), but uses the
full 64 bit result instead of the high 32 bits.
unsigned int __CLZ32(unsigned int int level;
signed long long __SMULL(signed int Rm, signed int Rs);
Returns the full 64 bit product of the 32x32->64 bit multiply of Rm and Rs. Uses
the UMULL and SMULL instructions like __MULUH() and __MULSH(), but uses the
full 64 bit result instead of the high 32 bits.

Green Hills Software, Inc. 537


15. Macros, #pragmas, and Intrinsics

unsigned long long __MULUH64(unsigned long long Rm, unsigned


long long Rs);
Uses a series of multiply instructions to generate the high 64 bits of an unsigned
64x64->128 bit multiply.

Enhanced DSP Intrinsic Functions


Green Hills provides support for the DSP (Digital Signal Processing) additions
to the ARM instruction set, which is included in processors, such as the
ARM9E, ARM10, ARM11, and XScale, that implement the E variant of the
ARM architecture version 5. Software alternatives are not provided.

The sticky-overflow bit (Q) set by some DSP instructions can be accessed with
(__GETSR() & (1<<27)).

For prototypes for the functions, see include\arm\arm9e_ghs.h.


int __QADD(int Rm, int Rn)
Addition with signed 32-bit saturation. This function translates directly into the
QADD ARM E variant assembly instruction. Return Rm plus Rn saturated to a
signed 32-bit value.
int __QDADD(int Rm, int Rn)
Doubled addition with signed 32-bit saturation. This function translates directly into
the QDADD ARM E variant assembly instruction. Return Rm plus twice Rn. Both the
results of the doubling and addition are saturated to a signed 32-bit value.
int __QSUB(int Rm, int Rn)
Subtraction with signed 32-bit saturation. This function translates directly into
the QSUB ARM E variant assembly instruction. Return Rm minus Rn saturated to
a signed 32-bit value.
int __QDSUB(int Rm, int Rn)
Doubled subtraction with signed 32-bit saturation. This function translates directly
into the QDSUB ARM E variant assembly instruction. Return Rm minus twice Rn.
Both the results of the doubling and subtraction are saturated to a signed 32-bit
value.

538 MULTI: Building Applications for Embedded ARM


Intrinsic Functions

int __SMLAxy(int Rm, int Rs,int Rn)


16-bit signed multiply, 32-bit accumulate. These functions translate directly into
the SMLAxy ARM E variant assembly instructions. Multiply half of each Rm and
Rs, and add the result to Rn. The following xy values determine the multiplication
operands:
• BB: Bottom 16 bits of Rm, bottom 16 bits of Rs
• BT: Bottom 16 bits of Rm, top 16 bits of Rs
• TB: Top 16 bits of Rm, bottom 16 bits of Rs
• TT: Top 16 bits of Rm, top 16 bits ofRs
int __SMLAWy(int Rm, int Rs,int Rn)
32х16→48-bit signed multiply, high 32-bit accumulate. These functions translate
directly into the SMLAWy ARM E variant assembly instructions. Multiply Rm with
half of Rs and add the top 32 bits (of the 48-bit result) to Rn. The following y
values determine the second multiplication operand:
• B: Bottom 16 bits of Rs
• T: Top 16 bits of Rs
int __SMULxy(int Rm, int Rs)
16-bit signed multiply. These functions translate directly into the SMULxy ARM E
variant assembly instructions. The following xy values determine the multiplication
operands:
• BB: Bottom 16 bits of Rm, bottom 16 bits of Rs
• BT: Bottom 16 bits of Rm, top 16 bits of Rs
• TB: Top 16 bits of Rm, bottom 16 bits of Rs
• TT: Top 16 bits of Rm, top 16 bits of Rs
int __SMULWy(int Rm, int Rs)
Top 32 bits of 32х1648-bit signed multiply. These functions translate directly into
the SMULWy ARM E variant assembly instructions. Return the top 32 bits of Rm
multiplied with the value described by y:
• B: Bottom 16 bits of Rs
• T: Top 16 bits of Rs

XScale Intrinsic Functions


Green Hills provides support for certain XScale extensions to the ARM
instruction set. The instructions related to the XScale’s multiply with internal
accumulate features are currently supported. Software alternatives are not
provided.

Green Hills Software, Inc. 539


15. Macros, #pragmas, and Intrinsics

Prototypes for the functions may be found in include\arm\xscale_ghs.h.


void __MAR(unsigned int RdLo, unsigned int RdHi)
Move from registers to implicit 40-bit accumulator. This function translates directly
into the MAR XScale assembly instruction. It transfers the values of RdLo and
RdHi to the implicit parameter acc0. All 32 bits of RdLo, but only the bottom 8 bits
of RdHi, are used to generate acc0.
void __MIA(signed int Rm, signed int Rs)
32-bit signed multiply with implicit 40-bit accumulator. This function translates
directly into the MIA XScale assembly instruction. Rm and Rs are multiplied and
then accumulated to the implicit parameter acc0.
void __MIAPH(signed int Rm, signed int Rs)
Dual 16-bit signed multiply with implicit 40-bit accumulator. This function translates
directly into the MIAPH XScale assembly instruction. A first signed multiplication is
performed on the bottom 16 bits of both Rm and Rs. A second signed multiplication
is performed on the top 16 bits of both Rm and Rs. Both multiplication results are
accumulated to the implicit parameter acc0.
void __MIAxy(signed int Rm, signed int Rs)
Single 16-bit signed multiply with implicit 40-bit accumulator. These functions
translate directly into the MIAxy XScale assembly instructions. Half of Rm is
multiplied with half of Rs and the signed result is accumulated to the implicit
parameter acc0. The following xy values determine the multiplication operands:
• BB: Bottom 16 bits of Rm, bottom 16 bits of Rs
• BT: Bottom 16 bits of Rm, top 16 bits of Rs
• TB: Top 16 bits of Rm, bottom 16 bits of Rs
• TT: Top 16 bits of Rm, top 16 bits of Rs
unsigned int __MRA_LO(void)
unsigned int __MRA_HI(void)
Move from implicit 40-bit accumulator to registers. These functions translate
directly into the MRA XScale assembly instruction, the inverse of MAR. __MRA_LO
(__MRA_HI) returns the low 32 bits (high 8 bits) from acc0. Pairing calls of
__MRA_LO and __MRA_HI together will generate a single MRA instruction.

v6 Instruction Set Intrinsics


The following intrinsics are available with the ARM11 processor. Note that
only those specifically marked are available in Thumb mode.

540 MULTI: Building Applications for Embedded ARM


Intrinsic Functions

signed int __REVSH(int Rm);


Reverses the bytes of the lower 16 bits and sign extends them to 32 bits, using
the REVSH instruction.
This function is available in Thumb mode.
signed int __SADD8TO32(signed int Rn, signed int Rm,
__ghs_c_int__ rorshift);
signed int __SADD16TO32(signed int Rn, signed int Rm,
__ghs_c_int__ rorshift);
unsigned int __UADD8TO32(unsigned int Rn, unsigned int Rm,
__ghs_c_int__ rorshift);
unsigned int __UADD16TO32(unsigned int Rn, unsigned int Rm,
__ghs_c_int__ rorshift);
These functions right-rotate Rm by the immediate rorshift, then sign or zero extend
it from 8 or 16 bits to 32 bits and add it to the value in Rn.
signed int __SADD8TO16(signed int Rn, signed int Rm,
__ghs_c_int__ rorshift);
unsigned int __UADD8TO16(unsigned int Rn, unsigned int Rm,
__ghs_c_int__ rorshift);
These functions right-rotate Rm by the immediate rorshift, then sign or zero extend
each halfword from 8 to 16 bits and add it to the corresponding halfword in Rn.

Parallel Addition Intrinsics


signed int __Qoperation(signed int Rn, signed int Rm);
Performs the specified operation as a signed, saturated operation, where
operation is one of the following:
• ADD16 — Add top halfwords and bottom halfwords in parallel.
• ADD8 — Add each byte of source operands in parallel.
• ADDSUBX — Add bottom halfword of second operand to top halfword of first
operand, and subtract top halfword of second operand from bottom halfword
of first operand.
• SUB16 — Subtract top halfwords and bottom halfwords in parallel.
• SUB8 — Subtract each byte of source operands in parallel.
• SUBADDX — Subtract bottom halfword of second operand from top halfword
of first operand, and add top halfword of second operand to bottom halfword
of first operand.

Green Hills Software, Inc. 541


15. Macros, #pragmas, and Intrinsics

signed int __Soperation(signed int Rn, signed int Rm);


Performs the specified operation as a signed operation, and sets the GE bits
in cpsr based on sign of result, where operation is one of those specified in
__Qoperation(), above.
__SHoperation(signed int Rn, signed int Rm);
Performs the specified operation as a signed operation with the result shifted right
by 1, where operation is one of those specified in __Qoperation(), above.
unsigned int __Uoperation(unsigned int Rn, unsigned int Rm);
Performs the specified operation as a signed operation, and sets the GE bits in
cpsr on overflow, where operation is one of those specified in __Qoperation(),
above.
unsigned int __UHoperation(unsigned int Rn, unsigned int Rm);
Performs the specified operation as an unsigned operation with the result shifted
right by 1, where operation is one of those specified in __Qoperation(), above.
unsigned int __UQoperation(unsigned int Rn, unsigned int Rm);
Performs the specified operation as an unsigned saturated operation, where
operation is one of those specified in __Qoperation(), above.

Multiplication Intrinsics
signed int __SMLAD(signed int Rm, signed int Rs, signed int
Rn);
signed int __SMLADX(signed int Rm, signed int Rs, signed int
Rn);
signed int __SMLSD(signed int Rm, signed int Rs, signed int
Rn);
signed int __SMLSDX(signed int Rm, signed int Rs, signed int
Rn);
These functions multiply the top halfwords of Rm and Rs, and add or subtract the
result from the product of their bottom halfwords. The result of that operation is
then added to Rd.
The X variants swap the top and bottom halfwords of Rs before multiplication.

542 MULTI: Building Applications for Embedded ARM


Intrinsic Functions

signed long long __SMLALD(signed long long Rd, signed int Rs,
signed int Rn);
signed long long __SMLALDX(signed long long Rd, signed int
Rs, signed int Rn);
signed long long __SMLSLD(signed long long Rd, signed int Rs,
signed int Rn);
signed long long __SMLSLDX(signed long long Rd, signed int
Rs, signed int Rn);
These functions multiply the top halfwords of Rm and Rs, and add or subtract the
result from the product of their bottom halfwords. The result of that operation is
then added to the 64 bit Rd.
The X variants swap the top and bottom halfwords of Rs before multiplication.
signed int __SMMLA(signed int Rm, signed int Rs, signed int
Rn);
signed int __SMMLAR(signed int Rm, signed int Rs, signed int
Rn);
signed int __SMMLS(signed int Rm, signed int Rs, signed int
Rn);
signed int __SMMLSR(signed int Rm, signed int Rs, signed int
Rn);
These functions perform a signed 32x32->64 bit multiply on Rm and Rs and
add the upper 32 bits to Rn.
The R variants round the intermediate result instead of truncating it.
signed int __SMMUL(signed int Rm, signed int Rs);
signed int __SMMULR(signed int Rm, signed int Rs);
These functions perform a signed 32x32->64 bit multiply on Rm and Rs and
take the upper 32 bits.
The R variant rounds the result instead of truncating it.
signed int __SMUAD(signed int Rm, signed int Rs);
signed int __SMUADX(signed int Rm, signed int Rs);
signed int __SMUSD(signed int Rm, signed int Rs);
signed int __SMUSDX(signed int Rm, signed int Rs);
These functions multiply the top halfwords of Rm and Rs, and add or subtract the
result from the product of their bottom halfwords.
The X variants swap the top and bottom halfwords of Rs before multiplication.

Green Hills Software, Inc. 543


15. Macros, #pragmas, and Intrinsics

unsigned long long __UMAAL(unsigned int RdLo, unsigned int


RdHi, unsigned int Rm, unsigned int Rs);
Performs an unsigned 32x32->64 bit multiply on Rm and Rs and adds the two 32
bit values in RdLo and RdHi.

Bitwise Extraction
int __PKHBT(int Rn, int Rm, __ghs_c_int__ lslshift);
Returns a 32 bit value in which the bottom halfword (least significant 16 bits)
are taken from the bottom halfword of Rn, and the top halfword is taken from
the top halfword of Rm logically shifted left by the immediate lslshift. An lslshift
value of 0 specifies no shift.
int __PKHTB(int Rn, int Rm, __ghs_c_int__ asrshift);
Returns a 32 bit value in which the top halfword (most significant 16 bits) are taken
from the top halfword of Rn, and the bottom halfword is taken from the bottom
halfword of Rm arithmetically shifted right by the immediate asrshift. If asrshift is 0,
this operation is equivalent to __PKHBT().
int __SEL8 (int Rn, int Rm);
The 4 bytes of the return value, from least to most significant, are set based on
the condition of the cpsr bits from GE[0] to GE[3]. Each byte is taken from the
corresponding byte of Rn if the GE flag is true, or Rm if it is false.
int __SEL16(int Rn, int Rm);
The top and bottom halfwords of the result are set conditionally based on the value
of the GE[3] and GE[1] bits of the cpsr. If GE[3] is true, the top halfword of
the result is equal to the top halfword of the first parameter, otherwise it is set to
the top halfword of the second parameter. The bottom halfword of the result is
similarly taken from either the first or second parameter, based on the GE[1] bit.
signed int __SSAT(__ghs_c_int__ saturate, signed int Rm,
__ghs_c_int__ lslshift);
unsigned int __USAT(__ghs_c_int__ saturate, unsigned int Rm,
__ghs_c_int__ lslshift);
These functions perform a signed or unsigned saturation at the bit position
specified by the immediate saturate.
An immediate logical shift left, lslshift, may be applied to Rm before saturation.

544 MULTI: Building Applications for Embedded ARM


Intrinsic Functions

signed int __SSATR(__ghs_c_int__ saturate, signed int Rm,


__ghs_c_int__ asrshift);
unsigned int __USATR(__ghs_c_int__ saturate, unsigned int Rm,
__ghs_c_int__ asrshift);
These functions perform a signed or unsigned saturation at the bit position
specified by the immediate saturate.
An immediate arithmetic shift right, asrshift, may be applied to Rm before
saturation.
signed int __SSAT16(__ghs_c_int__ saturate, signed int Rm);
unsigned int __USAT16(__ghs_c_int__ saturate, unsigned int
Rm);
Saturates the two halfwords of Rm in parallel at the arbitrary bit position specified
by the immediate saturate.
signed int __SUNPK16TO32(signed int Rm, __ghs_c_int__
rorshift);
signed int __SUNPK8TO32 (signed int Rm, __ghs_c_int__
rorshift);
unsigned int __UUNPK16TO32(unsigned int Rm, __ghs_c_int__
rorshift);
unsigned int __UUNPK8TO32 (unsigned int Rm, __ghs_c_int__
rorshift);
Rotates Rm right by rorshift and sign or zero-extends it from 8 or 16 bits to 32 bits.
rorshift must be an immediate integer, with 0 indicating no shift.
These functions are available in Thumb mode.
signed int __SUNPK8TO16 (signed int Rm, __ghs_c_int__
rorshift);
unsigned int __UUNPK8TO16 (unsigned int Rm, __ghs_c_int__
rorshift);
Sign or zero-extends the least significant byte of each halfword of Rm rotated
right by the immediate rorshift.
unsigned int __USAD8(unsigned int Rm, unsigned int Rs);
Performs four unsigned 8 bit subtractions, subtracting each byte in Rm from the
corresponding byte in Rs, and returning the sum of the absolute values of each
subtraction.

Green Hills Software, Inc. 545


15. Macros, #pragmas, and Intrinsics

unsigned int __USADA8(unsigned int Rm, unsigned int Rs,


unsigned int Rn);
Performs four unsigned 8 bit subtractions, subtracting each byte in Rm from the
corresponding byte in Rs, and returning the sum of the absolute values of each
subtraction added to Rn.

Synchronization Primitives
int __LDREX(int *Rn);
Generates the ldrex load exclusive synchronization instruction for the address
in Rn, which attempts to mark the address for exclusive access by the current
processor, and return the result.
int __STREX(int Rm, int Rn);
Generates the strex store exclusive synchronization instruction, and attempts to
store the value in Rm to the address Rn. Returns 0 on success or 1 otherwise.

Endianness Intrinsics
int __REV(int Rm);
Reverses the bytes in a 32 bit value, using the REV instruction.
This function is available in Thumb mode.
int __REV16(int Rm);
Reverses the bytes in both the upper and lower 16 bits, using the REV16
instruction.
This function is available in Thumb mode.
void __SETEND_BE(void);
void __SETEND_LE(void);

546 MULTI: Building Applications for Embedded ARM


Chapter 16

Libraries and Header Files

This Chapter Contains:


• The Green Hills Header Files and Standard Libraries
• Advanced Library Topics
• libansi.a Data Structures and Functions
• libind.a Functions
• Customizing the Run-Time Environment Libraries and Object Modules
16. Libraries and Header Files

This chapter describes the standard language libraries provided with the Green
Hills tools for ARM. Libraries are files which contain collections of object files.

Green Hills provides libraries to implement language features, such as the


Standard C libraries, the C++ libraries, and various aspects of run-time support.
These libraries, and any libraries that you create, are linked into the program
image by the linker, elxr.

Header files provide declarations and macros that may be used while
programming. Many of the functions in the standard libraries are declared in
header files. In C and C++, header files are referenced in the source code by
using a #include directive, which is read by the compiler’s preprocessor.

By convention, libraries have a .a extension, and are named in the form


libname.a. C language header files generally have a .h extension, and C++
headers either have a .h extension or no extension.

The process for creating and maintaining libraries is documented in Chapter


10, “The ax Librarian”.

For more information, see:

• P. J. Plauger, The Standard C Library)


• B. Stroustrup, The C++ Programming Language (3rd Ed.)
• P. J. Plauger, Dinkum C++ Library Reference (included with your
distribution, at install_dir/scxx/html/index.html)
• P. J. Plauger, Dinkum Abridged Library Reference (for EC++ and EEC++;
included with your distribution, at install_dir/ecxx/html/index.html)

Note Your Green Hills compiler license permits you to make unlimited
distributions of programs linked with the Green Hills library object code
without charge. However, distribution of any Green Hills library source code or
object code is not permitted.

548 MULTI: Building Applications for Embedded ARM


The Green Hills Header Files and Standard Libraries

The Green Hills Header Files and Standard Libraries


Your Green Hills tools for ARM provide a number of directories which contain
header files and standard libraries for the C and C++ languages, together with a
number of other low-level system libraries.

C and C++ Header File Directories


Depending upon the language you are compiling, the compiler searches one
or more of the following directories for header files which are specified in
#include preprocessor directives:

• include/arm: Contains header files for ARM extensions for C and C++.
• ansi: Contains Standard C library header files.
• scxx: Contains Standard C++ library header files.
• eecxx: Contains Extended Embedded C++ library header files.
• ecxx: Contains Embedded C++ library header files.

Library Directories
Depending upon the target architecture which you specify, the driver searches
one of the following directories (inside install_dir/lib) for libraries to resolve
references in the header files. Each directory contains a library set optimized
for use with a specific type of target CPU in the ARM processor family.

• Libraries for the ARM6, ARM7, and ARM7M architectures:


arm3 (default): Little Endian
arm3b: Big Endian
arm3p: Little Endian, with PID support
arm3pb: Big Endian, with PID support
• Libraries for the ARM7TM, ARM8, ARM9, and StrongArm architectures:
arm4 (default): Little Endian
arm4b: Big Endian
arm4p: Little Endian, with PID support
arm4pb: Big Endian, with PID support

Green Hills Software, Inc. 549


16. Libraries and Header Files

• Libraries for the ARM9e or higher, ARM10, and XScale architectures:


arm5 (default): Little Endian
arm5b: Big Endian
arm5p: Little Endian, with PID support
arm5pb: Big Endian, with PID support
• Libraries for the MicroRad architecture, with FPA hardware floating-point:
armfp (default): Little Endian
armfpb: Big Endian
armfpp: Little Endian, with PID support
armfppb: Big Endian, with PID support
• Libraries for Thumb mode:
thumb (default): Little Endian
thumbb: Big Endian
thumbp: Little Endian, with PID support
thumbpb: Big Endian, with PID support
• Libraries for VFP hardware floating-point architectures:
armvfp (default): Little Endian
armvfpb: Big Endian
armvfpp: Little Endian, with PID support
armvfppb: Big Endian, with PID support

Libraries
Each library directory contains a version of the following set of libraries, built
for the particular target architecture:

• C Library:
libansi.a: Standard ANSI C library. This is the first library the linker
searches by default when you use the C driver, ccarm.
• C++ Libraries (see also “Choosing a C++ Library” on page 553):

550 MULTI: Building Applications for Embedded ARM


The Green Hills Header Files and Standard Libraries

libscnoe.a: Standard C++ Library without exceptions. This is the first


library the linker searches by default when you use the C++ driver,
cxarm, or can be explicitly specified with the --stdl driver option.
libsce.a: Standard C++ Library with exceptions. To instruct the linker to
search this library, use the --stdle driver option.
libeecnoe.a: Extended embedded C++ Library without exceptions. This
library is a subset of libscnoe.a. To instruct the linker to search this
library, use the --eel driver option.
libeece.a: Extended embedded C++ Library with exceptions. To instruct
the linker to search this library, use the --eele driver option.
libecnoe.a: Embedded C++ Library without exceptions. This library
is a subset of libeecnoe.a. To instruct the linker to search this library,
use the --el driver option.
libece.a: Embedded C++ Library with exceptions. To instruct the linker
to search this library, use the --ele driver option.
libsedgnoe.a: Run-time support for standard C++, without exceptions.
libsedge.a: Run-time support for standard C++, with exceptions.
libedgnoe.a: Run-time support for embedded and extended embedded
C++, without exceptions.
libedge.a: Run-time support for embedded and extended embedded
C++, with exceptions.
• Low-level System Libraries (These libraries are always searched unless you
pass the -nostdlib driver option):
libind.a: Language-independent library, containing the math routines
and other general purpose routines of the ANSI C library.
libstartup.a: Run-time environment startup routines. The source code
for the modules in this library is provided in the libstartup directory (see
“Low-Level Startup Library libstartup.a” on page 583).
libsys.a: Run-time environment system routines. The source code
for the modules in this library is provided in the libsys directory (see
“Low-Level System Library libsys.a” on page 584).
libarch.a: Target-specific run-time support.
• Other Libraries:

Green Hills Software, Inc. 551


16. Libraries and Header Files

libdbmem.a: Provides a version of malloc with memory-checking.


This library is linked against when you pass the -check=memory driver
option.
libmulti.a: Supports procedure calls from the MULTI Debugger
command line. This library is linked against when you pass the -G driver
option.
libnoflt.a: Provides versions of printf, scanf, and other functions,
which exclude floating point support, and so are smaller. To instruct the
linker to link against this library instead of the equivalent routines in
libansi.a, use the -fnone driver option.

552 MULTI: Building Applications for Embedded ARM


The Green Hills Header Files and Standard Libraries

Choosing a C++ Library


The Green Hills tools for ARM supports three different variants of C++.
Depending on which variant of C++ you select, different libraries will be
searched by the driver as follows:
Default Libraries
C/C++ Compiler→C++ Language Dialect Setting Standard Run-time
Standard C++ (Violations give Errors) (--STD) libscnoe.a libsedgnoe.a
Standard C++ (Violations give Warnings) (--std)
Extended Embedded C++ (--ee) libeecnoe.a libedgnoe.a
Embedded C++ (--e) libecnoe.a libedgnoe.a

By default, the linker searches libraries of the same type as the specified
language variant that do not support exceptions. You can override these defaults
by specifying an alternative library type as follows:
Libraries
C/C++ Compiler→C++ Libraries Setting Standard Run-time
Standard C++ Library without Exceptions libscnoe.a libsedgnoe.a
(--stdl)
Standard C++ Library with Exceptions (--stdle) libsce.a libsedge.a
Extended Embedded C++ Library without libeecnoe.a libedgnoe.a
Exceptions (--eel)
Extended Embedded C++ Library with libeece.a libedge.a
Exceptions (--eele)
Embedded C++ Library without Exceptions libecnoe.a libedgnoe.a
(--el)
Embedded C++ Library with Exceptions (--ele) libece.a libedge.a

Note You can only specify a different library if it is less full-featured than your
chosen language variant (and therefore appears below your default library in
the table). Thus you can write code in C++ while restricting your use of library
modules to those offered in EEC++, but not vice versa. For more information
about the differences between C++, EEC++, and EC++, see Chapter 14, “Green
Hills C++”.

Green Hills Software, Inc. 553


16. Libraries and Header Files

Automatic Searching of Libraries


The compiler chooses libraries to search based on the options which you pass.
By default it will:

• Search for header files in the directories include/arm and ansi.


• Search for libraries in the lib/arm directory, and open the following libraries
for linking against in this order:
libansi.a (the standard C library)
libind.a (to obtain necessary math routines)
libstartup.a (to obtain run-time startup routines)
libsys.a and libarch.a (to obtain run-time support routines)

When you specify a particular target to build for, or pass other options, the
compiler may change its search paths, and select additional libraries to link
against. For example:
cxarm --eel -G -fnone -bsp=at91eb01 test.cxx

This command instructs the compiler to:

• Search for header files in the directories include/arm, ansi, and eecxx
(because of the option --eel which specifies extended embedded C++).
• Search for libraries in the arm4 directory (because of the option
-bsp=at91eb01, which specifies the Atmel 91EB01 board, containing a
ARM 7TM processor).
• Open the following libraries for linking against in this order:
libmulti.a (because of the -G option)
libeecnoe.a (because of the --eel option)
libedgnoe.a (because of the --eel option)
libnoflt.a (because of the -fnone option)
libansi.a, libind.a, libstartup.a, libsys.a, and libarch.a (default lower
level libraries).

Note For information about specifying your own libraries and headers to search
for, see “Using Your Own Header Files and Libraries” on page 96.

554 MULTI: Building Applications for Embedded ARM


Advanced Library Topics

Advanced Library Topics

Linking Alternate Startup Files and Libraries


The Builder and compiler driver automatically specify default startup files and
Green Hills libraries when running the linker. To disable the linking of startup
files and Green Hills libraries:

Set the Advanced→Advanced Linker Options→Link in Standard


Libraries option to Off (-nostdlib).

Less Buffered I/O


The Green Hills ANSI C library includes a Standard I/O Package (“stdio”),
which provides formatted I/O using printf and scanf, character I/O using
getc and putc, and other features.

If I/O is completely unbuffered, every character read or written requires a


system call to ensure that I/O is not delayed until the buffer is full or lost in a
buffer if the application exits abnormally.

As a consequence, in traditional implementations, all I/O performed in stdio is


fully-buffered. This improves performance by increasing the average number of
characters written per system call, but requires additional space for the code to
manage the buffers, as well as for the buffers themselves. Often, several KB of
code are added to the application, because the stdio package invokes malloc
and other routines to manage the buffering.

In order to provide a reasonable compromise between fully-buffering and


unbuffered I/O, the Green Hills ANSI C library defaults to a less buffered I/O
mode. Rather than allocate a permanent buffer for each file (which is used as
long as the file is open), buffering is performed within fprintf, fwrite,
fputs, puts, printf, sprintf, vprints, vfprintf, vsprintf,
and their wide character forms.

During a single call, any characters written to one of these functions is buffered.
One function call often requires only one output system call. Once the function
completes, all characters are written to the file. No characters are left in a buffer

Green Hills Software, Inc. 555


16. Libraries and Header Files

after the function call, eliminating both the risk of output loss and the need to
flush buffers when a file is closed or the program exits. No input routines are
buffered by the Less Buffered I/O method. Files are not closed upon program
termination, except as noted below.

You can enable full buffering of any file by calling either setbuf() or
setvbuf(). In this case, characters are only written to a buffered file when
the buffer is full or when fflush() or fclose() is called. Upon normal
termination of the program, if setbuf() or setvbuf() has been called at
any time, all open files will be flushed and then closed.

All files are processed in exactly the same manner, whether they are opened by
default (stdin, stdout, and stderr) or by fopen().

Buffering of C++ I/O Streams


In contrast to C stdio, the Green Hills implementation of C++ I/O streams
defaults to full buffering. Consequently, if you use both C stdio calls (e.g.
printf) and C++ iostream calls (e.g. cout), you may see unexpected
buffering behavior. Performance will be optimal, but characters may be output
at different times due to the increased C++ buffering.

You can disable full buffering in favor of less-buffered I/O (with a possible
decline in performance), by calling pubsetbuf(), setbuf(), or
setvbuf() before calling stdio functions. For example:
cout.rdbuf()->pubsetbuf(0,0);
cout << "Hello" << endl;
printf("Hello\n");

or:
setbuf(stdout, NULL);
cout << "Hello" << endl;
printf("Hello\n");

Alternatively, and in order to maintain maximum performance, you can leave


full buffering enabled, and call fflush() to force output when needed. For
example:
cout << "Hello" << endl;
printf("Hello\n");
fflush(stdout);

556 MULTI: Building Applications for Embedded ARM


Advanced Library Topics

Division by Zero
Integral divide and modulus operators are implemented in software with Green
Hills library functions. When an illegal division by zero occurs, different
applications will have different requirements for handling it. The division
routines respond to division by zero by calling off to a weak function, int
__division_by_zero(), which is not defined in the libraries. By default,
if this routine is not defined, the division routines will silently ignore division
by zero and return a result of zero. If a program defines this function, it can
specify whatever behavior is desired.

64-bit Integer Arguments and printf


The type long long was an extension to ANSI C which has become official
in the ISO C99 standard. Since this type is larger than either int or long, it
requires special handling in the printf and scanf routines.

As in earlier versions of printf and scanf, a single ’l’ modifier indicates


an argument of type long. For example:
printf("large number: %ld", 0x7fffffffL);

However, when the ’l’ modifier is repeated, an argument of type long long
is indicated. For example:
printf("very large number: %lld", 0x7fffffffffffffffL);

For backwards compatibility with older implementations, printf and scanf


also allow the ’L’ modifier to indicate an argument of type long long, but
this is non-standard and is not recommended.

Thread-Safe Library Functions


The Green Hills library functions can be made completely thread-safe. A
thread is a single task running in a multitasking environment in which there is a
shared memory space for all tasks. The multitasking environment is actually
multithreaded, since it operates on a shared memory space for all threads.

A thread-safe function works properly every time it is invoked in a


multithreaded environment, even if the function is invoked by multiple threads
simultaneously or is interrupted or suspended and then resumed.

Green Hills Software, Inc. 557


16. Libraries and Header Files

All Green Hills functions can be made thread-safe if a few simple functions
are incorporated into the threading environment. The file libsys/ind_thrd.c
provides stubs for the necessary functions that must be implemented in order to
make the Green Hills libraries thread-safe.

Ensuring That Critical Code Is Thread-Safe


Code that accesses resources shared between two or more threads is critical
code or is considered critical to thread safety. These shared resources or
memory may become corrupted when two or more threads are writing to the
same data structures at the same time or when a thread is reading data that is
currently being written by another thread.

To make critical code thread-safe, you must implement a simple lock/unlock


mechanism that allows a function to completely execute critical code before that
code is accessed by a function call in another thread. Calling __ghsLock()
in front of the critical code denies access to it by any other thread. At the end of
the critical code, __ghsUnlock() makes the critical code available again.

Functions that perform I/O are another concern to thread safety. If multiple
functions are writing data to a file simultaneously, that data may be corrupted.
Similarly, if a function is reading a file while another function is writing to
it, the file may get bad data. You must also implement the file lock/unlock
mechanism to ensure that I/O functions are thread-safe. If desired, the file
locks may be implemented with calls to the general __ghsLock() and
__ghsUnlock() routines.

For applications that have demanding I/O restrictions, you may consider
substituting the quicker, non-thread-safe getc_unlocked for getc, and
putc_unlocked for putc.

The following functions, located in libsys/ind_thrd.c, should be implemented:


void __ghsLock(void);
Acquires general lock. Blocks until the lock becomes available.
void __ghsUnlock(void);
Releases general lock.
void __gh_lock_init(void);
A callback to initialize the lock data structure before it is used.

558 MULTI: Building Applications for Embedded ARM


Advanced Library Topics

void __ghs_flock_file(void *addr);


Acquires lock for file *addr.
void __ghs_funlock_file(void *addr);
Release lock for file *addr.
int __ghs_ftrylock_file(void *addr);
Non blocking acquire lock for file *addr. May return -1 if this cannot be
implemented. Returns 0 on success and nonzero on failure.
void __ghs_flock_create(void **addr);
void __ghs_flock_destroy(void *addr);
Callbacks to initialize local lock data structures before they are used.

In addition, the following functions, which may be used to save and restore
arbitrary state across setjmp() and longjmp() calls, may be implemented:
int __ghs_SaveSignalContext(jmp_buf jmpbuf)
void __ghs_RestoreSignalContext(jmp_buf jmpbuf)

Allocating Data Structures


In the C libraries, there are global and static data structures that
need to be allocated for each thread. The members of the structure
ThreadLocalStorage declared in libsys/ind_thrd.h represent the global
and static variables that must be allocated for each thread. The function
GetThreadLocalStorage() in libsys/ind_thrd.c can retrieve a pointer to
the structure representing these variables.

The global variable errno in the C library is often referenced directly in an


application. In the Green Hills libraries, errno is allocated once for each
thread and is accessed through functions.

To make errno thread-safe, include <errno.h>. In an environment that already


has a thread-safe implementation (such as INTEGRITY), referencing errno
will automatically generate references to int __gh_get_errno(void)
and void __gh_set_errno(int), which are implemented in
libsys/ind_errn.c.

Green Hills Software, Inc. 559


16. Libraries and Header Files

Tailoring Libraries for Thread Safety


Green Hills provides thread-safe versions of some library functions that are
not, inherently, thread-safe. These include asctime_r and rand_r. Some
library functions cannot be made thread-safe because they are not thread-safe
by definition. These include ecvt, fcvt, and gcvt.

Source code is provided for some low-level routines in the libsys and libstartup
directories, so you can tailor the Green Hills libraries for your particular
environment. When modified, these functions must remain thread-safe so that
functions in the Green Hills libraries that call them also remain thread-safe.

The following code letters identify the level of thread-safety of the library
functions listed in the remainder of this chapter.
Y Completely thread-safe.
P Partially thread-safe. A lock must be implemented for complete thread safety.
I Performs I/O or modifies I/O data structures. This is a special case of a
partially thread-safe function.
T Achieves thread safety by thread local storage, so long as thread
local storage is implemented. See the preceding discussion on
GetThreadLocalStorage().
E Writes to the global variable errno. See above.
N Not thread-safe.

560 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

libansi.a Data Structures and Functions


The functions documented in the ANSI C Standard are contained in the
libansi.a and libind.a libraries.

Note A number of these functions require that you provide environment-specific


information, before they will operate usefully. Where this is the case, the
low-level routines that the function depends on are listed in the right-hand
column. For information about editing and rebuilding these libsys.a functions,
see “Low-Level System Library libsys.a” on page 584. Note that the libsys.a
functions _exit() and sbrk() have default implementations that are fully
functional in most environments.

In addition, several libsys.a I/O functions are available as system calls when you
are connected to your target with the MULTI Debugger. For more information,
see “libsys.a Functions Provided through MULTI System Calls” on page 576.

The following tables list the data structures and functions in libansi.a. See
also “libind.a Functions” on page 577.
Variable Declaration
_CTYPE unsigned char _CTYPE[]
sys_errlist char *sys_errlist[]
_tolower_ short _tolower_[]
_toupper_ short _toupper_[]

Thread
Function safe? Arguments/return value
abort() Y void abort(void)
Depends On: raise()
abs() Y int abs(int x)
asctime() T char *asctime(const struct tm *t)
Depends On: __gh_timezone()
asctime_r() Y asctime_r(const struct tm *t, char
*buffer)
Depends On: __gh_timezone()

Green Hills Software, Inc. 561


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
_assert() IE void _assert(const char *problem, const
char *filename, int line)
Depends On: lseek(), raise(), write()
assert() IE void assert(int value)
Depends On: lseek(), raise(), write()
atexit() P int atexit(void (*func)(void))
atof() E double atof(const char *str)
atoi() E int atoi(const char *str)
atol() E long atol(const char *str)
atoll() E long long atoll(const char *str)
bcmp() Y bcmp(char *b1, char *b2, int length)
bcopy() Y bcopy(char *from, char *to, int n)
bsearch() Y void *bsearch(const void *key, const
void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void
*))
bufcpy() Y bufcpy(char *to, char *from, int n)
btowc() Y wint_t btowc(int c)
bzero() Y bzero(char *pt, int n)
calloc() P void *calloc(size_t num, size_t size)
Depends On: sbrk()
cfree() P void cfree(char *item)
Depends On: sbrk()
clearerr() I void clearerr(FILE *file)
clearn() Y void clearn(int n, char *pt)
clock() Y clock_t clock(void)
Depends On: times()
ctime() T char *ctime(const time_t *timer)
Depends On: __gh_timezone(), localtime()
ctime_r() T char *ctime_r(const time_t *timer, char
*buffer)
Depends On: __gh_timezone(), localtime()

562 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
difftime() Y double difftime(time_t time1, time_t
time0)
div() Y div_t div(int number, int denom)
__docvt() Y internal use only
_doprnt() I int _doprnt(const char *format, va_list
args, FILE *stream)
Depends On: lseek(), write()
_doscan() I _doscan(const char *format, va_list
args, FILE *stream)
Depends On: close(), lseek(), read(),
sbrk(), write()
ecvt() N char *ecvt(double value, int ndig, int
*decpt, int *sign)
eprintf() IE int eprintf(const char *format, ...)
Depends On: lseek(), write()
execl() Y int execl(const char *name, const char
*args, ...)
Depends On: environ(), execve()
execle() Y int execle(const char *name, const char
*args, ...)
Depends On: execve()
execv() Y int execv(const char *name, char *const
*argv)
Depends On: environ(), execve()
exit() P void exit(int val)
Depends On: _exit()
fclose() IE int fclose(FILE *file)
Depends On: close(), lseek(), write()
fcvt() N char *fcvt(double value, int ndig, int
*decpt, int *sign)
fdopen() IE FILE *fdopen(int fno,const char *mode)
Depends On: close(), creat(), lseek(),
open(), write()
feof() Y int feof(FILE *stream)

Green Hills Software, Inc. 563


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
ferror() Y int ferror(FILE *stream)
fflush() IE int fflush(FILE *file)
Depends On: lseek(), write()
ffs() Y int ffs(int i)
fgetc() IE int fgetc(FILE *file)
Depends On: read()
fgetwc() IE wint_t fgetwc(FILE *file)
Depends On: read()
fgetwc_ NE wint_t fgetwc_unlocked(FILE *file)
unlocked()
Depends On: read()
fgetpos() IE int fgetpos(FILE *file,fpos_t *pos)
Depends On: lseek()
fgets() IE char *fgets(char *str, int n, FILE
*file)
Depends On: read()
fgetws() IE wchar_t *fgetws(wchar_t *str, int n,
FILE *file)
Depends On: read()
_filbuf() IE _filbuf(FILE *file)
Depends On: read()
filln() Y void filln(int n, char *pt, int fill)
_flsbuf() IE _flsbuf(int ch, FILE *file)
Depends On: lseek(), write()
fopen() IE FILE *fopen(const char *name, const char
*mode)
Depends On: close(), creat(), lseek(),
open(), write()
fprintf() IE int fprintf(FILE *stream, const char
*format, ...)
Depends On: lseek(), write()

564 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
fwprintf() IE int fwprintf(FILE *stream, const wchar_t
*format, ...)
Depends On: lseek(), write()
fputc() IE int fputc(int ch,FILE *file)
Depends On: lseek(), write()
fputs() IE int fputs(const char *str,FILE *file)
Depends On: lseek(), write()
fputws() IE int fputws(const wchar_t *str,FILE
*file)
Depends On: lseek(), write()
fputwc() IE wint_t fputwc(wchar_t ch,FILE *file)
Depends On: lseek(), write()
fputwc_ NE wint_t fputwc_unlocked(wchar_t ch,FILE
unlocked() *file)
Depends On: lseek(), write()
fread() IE size_t fread(void *ptr,size_t
size,size_t nitems,FILE *file)
Depends On: read()
free() P void free(void *ptr)
Depends On: sbrk()
freopen() IE FILE *freopen(const char *name, const
char *mode, FILE *file)
Depends On: close(), creat(), lseek(),
open(), write()
frexp() Y double frexp(double value, int *eptr)
frexpf() Y float frexpf(float value, int *eptr)
fscanf() IE int fscanf(FILE *stream, const char
*format, ...)
Depends On: close(), lseek(), read(),
sbrk(), write()
fseek() IE int fseek(FILE *stream, long int offset,
int ptrname)
Depends On: lseek(), write()

Green Hills Software, Inc. 565


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
fsetpos() IE int fsetpos(FILE *file,const fpos_t
*pos)
Depends On: lseek(), write()
ftell() IE long ftell(FILE *stream)
Depends On: lseek()
fwrite() IE size_t fwrite(const void *ptr,size_t
size,size_t nitems, FILE *file)
Depends On: lseek(), write()
fwide() Y int fwide(FILE *stream, int orientation)
fwscanf() IE int fwscanf(FILE *stream, const wchar_t
*format, ...)
gcvt() N char *gcvt(double value, int ndig, char
*buf)
getc() IE int getc(FILE *f)
Depends On: read()
getc_ N int getc_unlocked(FILE *f)
unlocked()
Depends On: read()
getchar() IE int getchar(void)
Depends On: read()
getchar_ I int getchar_unlocked(void)
unlocked()
Depends On: read()
getenv() Y char *getenv(char *np)
Depends On: environ()
getl() IE long getl(FILE *file)
Depends On: read()
gets() IE char *gets(char *str)
Depends On: read()
getw() IE int getw(FILE *file)
Depends On: read()
getwchar() IE wint_t getwchar(FILE *file)
Depends On: read()

566 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
index() Y char *index(const char *str, const char
ch)
isalnum() Y int isalnum(int c)
isascii() Y int isascii(int c)
isalpha() Y int isalpha(int c)
iscntrl() Y int iscntrl(int c)
isdigit() Y int isdigit(int c)
isgraph() Y int isgraph(int c)
islower() Y int islower(int c)
isprint() Y int isprint(int c)
ispunct() Y int ispunct(int c)
isspace() Y int isspace(int c)
isupper() Y int isupper(int c)
iswalnum() Y int iswalnum(wint_t wc)
iswalpha() Y int iswalpha(wint_t wc)
iswblank() Y int iswblank(wint_t wc)
iswcntr() Y int iswcntrl(wint_t wc)
iswctype() Y int iswctype(wint_t wc, wctype_t index)
iswdigit() Y int iswdigit(wint_t wc)
iswgraph() Y int iswgraph(wint_t wc)
iswlower() Y int iswlower(wint_t wc)
iswprint() Y int iswprint(wint_t wc)
iswpunct() Y int iswpunct(wint_t wc)
iswspace() Y int iswspace(wint_t wc)
iswupper() Y int iswupper(wint_t wc)
iswxdigit() Y int iswxdigit(wint_t wc)
isxdigit() Y int isxdigit(int c)
labs() Y long labs(long x)
ldexp() E double ldexp(double value, int exp)
ldexpf() E float ldexpf(float value, int exp)
ldiv() Y ldiv_t ldiv(long int number, long int
denom)

Green Hills Software, Inc. 567


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
llabs() Y long long llabs(long long x)
lldiv() Y lldiv_t lldiv(long long numer, long long
denom)
localeconv() Y struct lconv *localeconv(void)
longjmp() Y void longjmp (jmp_buf env, int val)
malloc() P void *malloc(size_t size)
Depends On: sbrk()
mblen() Y int mblen(const char *s, size_t n)
mbrlen() Y size_t mbrlen(const char *s, size_t n,
mbstate_t *ps)
mbrtowc() Y size_t mbrtowc(wchar_t *pwc,const char
*s, size_t n, mbstate_t *ps)
mbsinit() Y int mbsinit(const mbstate_t *ps)
mbsrtowcs() Y size_t mbsrtowcs(wchar_t *wcs, const
char **pmbs, size_t n, mbstate_t *ps)
mbstowcs() Y size_t mbstowcs( wchar_t *pwcs, const
char *mbs, size_t n)
mbtowc() Y int mbtowc(wchar_t *pwc, const char *s,
size_t n)
memchr() Y void *memchr(const void *s, int c,
size_t n)
memcmp() Y int memcmp(const void *s1, const void
*s2, size_t length)
memmove() Y void *memmove(void *s1, const void *s2,
size_t n)
mktemp() P char *mktemp(char *str)
Depends On: getpid()
mktime() Y time_t mktime(struct tm *timeptr)
Depends On: __gh_timezone(), localtime(),
localtime_r()
modf() Y double modf(double value, double *iptr)
on_exit() P int on_exit( void (*func)(void), char *
arg)

568 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
perror() IE void perror(const char *str)
Depends On: lseek(), write()
printf() IE int printf(const char *format, ...)
Depends On: lseek(), write()
putc() IE int putc(int ch, FILE *f)
Depends On: lseek(), write()
putc_ N int putc_unlocked(int ch, FILE *f)
unlocked()
Depends On: lseek(), write()
putchar() IE int putchar(int ch)
Depends On: lseek(), write()
putchar_ N int putchar_unlocked(int ch)
unlocked()
Depends On: lseek(), write()
putl() IE long putl(long l, FILE *file)
Depends On: lseek(), write()
puts() IE int puts(const char *str)
Depends On: lseek(), write()
putw() IE putw(int w, FILE *file)
Depends On: lseek(), write()
putwc() IE wint_t putwc(wchar_t wc, FILE *f)
Depends On: lseek(), write()
putwchar() IE wint_t putwchar(wchar_t wc)
Depends On: lseek(), write()
qsort() Y void qsort(void *base, size_t nmemb,
size_t size, int (*compar)(const void *,
const void *))
rand() P int rand()
rand_r() Y int rand_r(long * seedSent)
realloc() P void *realloc(void *old, size_t
new_size)
Depends On: sbrk()
remove() Y int remove(const char *filename)
Depends On: unlink()

Green Hills Software, Inc. 569


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
rewind() IE void rewind(FILE *stream)
Depends On: lseek(), write()
rindex() Y char *rindex(const char *str, const char
ch)
scanf() IE scanf(const char *format, ...)
Depends On: close(), lseek(), read(),
sbrk(), write()
setbuf() IE void setbuf(FILE *stream, char *buf)
Depends On: close(), lseek(), write()
setjmp() Y int setjmp (jmp_buf env)
setlinebuf() Y int setlinebuf(FILE *stream)
setlocale() Y char *setlocale(int category, const char
*locale)
setvbuf() IE int setvbuf(FILE *stream, char *buf, int
mode, size_t size )
Depends On: close(), lseek(), write()
snprintf() E int snprintf(char *s, size_t size, cosnt
char *format, ...)
sprintf() E int sprintf(char *s, const char *format,
...)
srand() N void srand(int val)
sscanf() Y int sscanf(const char *str, const char
*format, ...)
strcat() Y char *strcat(char *s2, const char *str1)
strchr() Y char *strchr(const char *str, int ch)
strcmp() Y int strcmp(const char *str1, const char
*str2)
strcoll() Y int strcoll(const char *s1, const char
*s2)
strcpy() Y char *strcpy(char *s2, const char *str1)
strcspn() Y size_t strcspn(const char *s1, const
char *s2)
strerror() Y char *strerror(int errnum)

570 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
strftime() Y size_t strftime(char *start, size_t
maxsize, const char *format, const
struct tm *timeptr)
Depends On: __gh_timezone()
strindex() Y int strindex(char *str, char *sub)
strlen() Y size_t strlen(const char *str)
strncat() Y char *strncat(char *s2, const char
*str1, int n)
strncmp() Y int strncmp(const char *str1, const char
*str2, int n)
strncpy() Y char *strncpy(char *s2, char *str1, int
n)
strpbrk() Y char *strpbrk(const char *s1, const char
*s2)
strrchr() Y char *strrchr(const char *str, int ch)
strrindex() Y int strrindex(char *str, char *sub)
strsave() P char *strsave(char *str)
Depends On: sbrk()
strspn() Y size_t strspn(const char *s1, const char
*s2)
strstr() Y char *strstr(const char *str, const char
*sub)
strtod() E double strtod(const char *str, char
**endptr)
strtok() T char *strtok(char *s1, const char *s2)
strtok_r() Y char *strtok_r(char *s1, const char *s2,
char **ppLast)
strtol() E long strtol(const char *str, char **ptr,
int base)
strtoll() E long long strtoll(const char *str, char
**ptr, int base)
strtoul() E unsigned long strtoul(const char *str,
char **ptr, int base)
strtoull() E unsigned long long strtoull(const char
*str, char **ptr, int base)

Green Hills Software, Inc. 571


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
strxfrm() Y size_t strxfrm(char *s1, const char *s2,
size_t n)
swab() Y swab(char *from, char *to, int nbytes)
swprintf() E int swprintf(wchar_t *s, size_t n, const
wchar_t *format, ...)
swscanf() Y int sscanf(const wchar_t*str, const
wchar_t *format, ...)
tmpfile() IE FILE *tmpfile(void)
Depends On: access(), close(), creat(),
lseek(), open(), unlink(), write()
tmpnam() TPE char *tmpnam(char *s)
Depends On: access()
tmpnam_r() PE char *tmpnam_r(char *s)
Depends On: access()
tolower() Y int tolower(int c)
toupper() Y int toupper(int c)
towctrans() Y wint_t towctrans(wint_t wc, wctrans_t
desc)
towlower() Y wint_t towlower(wint_t wc)
towupper() Y wint_t towupper(wint_t wc)
ungetc() IE int ungetc(int ch,FILE *file)
Depends On: close(), lseek(), sbrk(),
write()
ungetwc() IE wint_t ungetwc(wint_t wc, FILE *f)
Depends On: close(), lseek(), sbrk(),
write()
ungetwc_ NE wint_t ungetwc_unlocked(wint_t wc, FILE
unlocked() *f)
Depends On: close(), lseek(), sbrk(),
write()
vfprintf() IE int vfprintf(FILE *stream, const char
*format, va_list args)
Depends On: lseek(), write()

572 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
vfscanf() IE vfscanf(FILE *stream, const char
*format, va_list args)
Depends On: close(), lseek(), read(),
sbrk(), write()
vfwscanf() IE vfwscanf(FILE *stream, const wchar_t
*format, va_list args)
Depends On: close(), lseek(), read(),
sbrk(), write()
vfwprintf() IE int vfwprintf(FILE *stream, const
wchar_t *format, va_list args)
Depends On: lseek(), write()
vprintf() IE int vprintf(const char *format, va_list
args )
Depends On: lseek(), write()
vscanf() IE vscanf(const char *format, va_list ap )
Depends On: close(), lseek(), read(),
sbrk(), write()
vsnprintf() Y int vsnprintf(char *s, size_t size,
const char *format, va_list ap)
vsprintf() E int vsprintf(char *s, const char
*format, va_list ap)
vsscanf() Y vsscanf(const char *str, const char
*format, va_list ap)
vswprintf() E int vswprintf(wchar_t *s, const wchar_t
*format, va_list ap)
vswscanf() P int vswscanf(const wchar_t *str, const
wchar_t *format, va_list args)
vwprintf() IE int vwprintf(const wchar_t *format,
va_list args)
Depends On: lseek(), write()
vwscanf() IE int vwscanf(const wchar_t *format,
va_list args)
Depends On: close(), lseek(), read(),
sbrk(), write()
wcrtomb() Y size_t wcrtomb(char *s, wchar_t wc,
mbstate_t *ps)

Green Hills Software, Inc. 573


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
wcscat() Y wchar_t *wcscat(wchar_t *s2, const
wchar_t *str1)
wcschr() Y wchar_t *wcschr(const wchar_t *str,
wchar_t ch)
wcscmp() Y int wcscmp(const wchar_t *str1, const
wchar_t *str2)
wcscoll() Y int wcscoll(const wchar_t *str1, const
wchar_t *str2)
wcscoll() Y int wcscoll(const wchar_t *str1, const
wchar_t *str2)
wcscpy() Y whcar_t *wcscpy(wchar_t *s2, const
wchar_t *str1)
wcscspn() Y size_t wcscspn(const wchar_t *s1, const
wchar_t *s2)
wcscspn() Y size_t wcscspn(const wchar_t *s1, const
wchar_t *s2)
wcsftime() Y size_t wcsftime(wchar_t *start, size_t
maxsize, const wchar_t *format, const
struct tm *timeptr)
Depends On: __gh_timezone()
wcslen() Y size_t wcslen(const wchar_t *str)
wcsncat() Y wchar_t *wcsncat(wchar_t *s2, const
wchar_t *str1, size_t n)
wcsncmp() Y int wcsncmp(const wchar_t *str1, const
wchar_t *str2, size_t n)
wcsncpy() Y wchar_t *wcsncpy(wchar_t *s2, const
wchar_t *str1, size_t n)
wcspbrk() Y wchar_t *wcspbrk(const wchar_t *s1,
const wchar_t *s2)
wcsrchr() Y wchar_t *wcsrchr(const wchar_t *str,
wchar_t wc)
wcsrtombs() Y size_t wcsrtombs(char *mbs, const
wchar_t **pwcs, size_t n, mbstate_t *
ps)
wcsspn() Y size_t wcsspn(const wchar_t *s1, const
wchar_t *s2)

574 MULTI: Building Applications for Embedded ARM


libansi.a Data Structures and Functions

Thread
Function safe? Arguments/return value
wcsstr() Y wchar_t *wcsstr(const wchar_t *str,
const wchar_t *sub)
wcstod() Y double strtod(const wchar_t *str,
wchar_t **endptr)
wcstof() Y float strtof(const wchar_t *str, wchar_t
**endptr)
wcstok() Y wchar_t wcstok(wchar_t *s1, const
wchar_t *s2, wchar_t **ppLast)
wcstol() Y long strtol(const wchar_t *str, wchar_t
**ptr, int base)
wcstoll() Y long long strtol(const wchar_t *str,
wchar_t **ptr, int base)
wcstoul() Y unsigned long strtoul(const wchar_t
*str, wchar_t **ptr, int base)
wcstoull() Y unsigned long long strtoull(const
wchar_t *str, wchar_t **ptr, int base)
wcsxfrm() Y size_t wcsxfrm(wchar_t *s1, const
wchar_t *s2, size_t n)
wctob() Y int wctob(wint_t wc)
wctomb() Y int wctomb(char *s, wchar_t wchar)
wctrans() Y wctrans_t wctrans(const char *name)
wctype() Y wctype_t wctype(const char *name)
wmemchr() Y wchar_t *wmemchr(const wchar_t *s,
wchar_t wc, size_t n)
wmemcmp() Y int wmemcmp(const wchar_t *s1, const
wchar_t *s2, size_t length)
wmemcpy() Y wchar_t *wmemcpy(wchar_t *dest, const
wchar_t *src, size_t n)
wmemmove() Y wchar_t *wmemmove(wchar_t *s1, const
wchar_t *s2, size_t n)
wmemset() Y wchar_t *wmemset(wchar_t *s, wchar_t c,
size_t n)

Green Hills Software, Inc. 575


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
wprintf() EI int wprintf(const wchar_t *format, ...)
wscanf() EI int wscanf(const wchar_t *format, ...)
Depends On: close(), lseek(), read(),
sbrk(), write()

libsys.a Functions Provided through MULTI System Calls


Some of the libsys.a functions are implemented as MULTI system calls, and so
are available when you are connected to your target via MULTI:
MULTI System Call Equivalent libsys.a libsys.a Module
Function
SYSCALL_WRITE write indio.c
SYSCALL_READ read indio.c
SYSCALL_OPEN open indio.c
SYSCALL_CLOSE close indio.c
SYSCALL_CREAT creat indio.c
SYSCALL_LSEEK lseek indio.c
SYSCALL_UNLINK unlink indio.c
SYSCALL_EXIT _exit ind_exit.c
SYSCALL_ACCESS access ind_stat.c
SYSCALL_MANTIME time ind_time.c

Note If you are working in a stand-alone environment, then you must provide
target-specific edits to these libsys.a functions if you want to use functions
in libansi.a that depend upon them.

576 MULTI: Building Applications for Embedded ARM


libind.a Functions

libind.a Functions
The libind.a library contains mathematical functions such as sqrt and sin,
which are listed in the following table:
Thread
Function safe? Arguments/return value
acos() E double acos(double x)
acosf() E float acosf(float arg)
acosh() E double acosh(double x)
asin() E double asin(double x)
asinf() E float asinf(float arg)
asinh() E double asinh(double x)
atan() E double atan(double x)
atan2() E double atan2(double y, double x)
atan2f() E float atan2f(float y, float x)
atanf() E float atanf(float x)
atanh() E double atanh(double x)
cabs() E double cabs(struct complex z)
ceil() Y double ceil(double x)
cos() Y double cos(double f0)
cosf() Y float cosf(float f0)
cosh() E double cosh(double x)
coshf() E float coshf(float x)
erf() Y double erf(double x)
erfc() Y double erfc(double x)
exp() E double exp(double x)
expf() E float expf(float x)
fabs() Y double fabs(double x)
floor() Y double floor(double x)
fmod() Y double fmod(double x,double y)
gamma() E double gamma(double x)
_gh_va_arg() Y char *_gh_va_arg(p, align, regtyp, size)
hypot() E double hypot(double x,double y)

Green Hills Software, Inc. 577


16. Libraries and Header Files

Thread
Function safe? Arguments/return value
isinf() Y int isinf(double x)
isnan() Y int isnan(double x)
j0() E double j0(double x)
j1() E double j1(double x)
jn() E double jn(int n,double x)
log() E double log(double x)
log10() E double log10(double x)
log10f() E float log10f(float x)
logf() E float logf(float x)
matherr() Y int matherr(struct exception *ex)
memcpy() Y void *memcpy(void *s1, const void *s2,
size_t n)
memset() Y void *memset(void *s, int c, size_t n)
pow() E double pow(double x, double y)
powf() E float powf(float x, float y)
rmatherr() Y int rmatherr(struct rexception *ex)
__rnerr() P int __rnerr(int num, int linenum, char
*str, void *ptr, void *al, void *a2,
void *a3, void *a4, void *a5, size_t
len)
sin() Y double sin(double f0)
sinf() Y float sinf(float f0)
sinh() E double sinh(double x)
sinhf() E float sinhf(float arg)
sqrt() E double sqrt(double f0)
sqrtf() E float sqrtf(float f0)
tan() E double tan(double x)
tanf() E float tanf(float arg)
tanh() E double tanh(double x)
tanhf() E float tanhf(float x)
y0() E double y0(double x)

578 MULTI: Building Applications for Embedded ARM


libind.a Functions

Thread
Function safe? Arguments/return value
y1() E double y1(double x)
yn() E double yn(int n, double x)

Green Hills Software, Inc. 579


16. Libraries and Header Files

Customizing the Run-Time Environment Libraries and Object


Modules
The following sections contain information about the libraries and object
modules that comprise the Green Hills run-time environment:

• crt0.o — the default startup module (see “Startup Module crt0.o” on page
581)
• libstartup.a — the startup library (see “Low-Level Startup Library
libstartup.a” on page 583)
• libsys.a — the system library (see “Low-Level System Library libsys.a”
on page 584)

Many users will be able to use the Green Hills run-time environment without
alteration. However, you may need to customize some of these underlying
routines for your particular environment. The full source files are provided in
the libstartup and libsys directories in install_dir/arm/src. To prepare a project
in which customization can be performed:

1. Click the button to create a new project with the New Project Wizard,
and select settings appropriate to your project until you reach the Link
Options screen.
2. On the Link Options screen, set the Startup Library and/or the System
Library option to “Customize” (see also “Setting Link Options” on page
26).

When you create a project in this way, the New Project Wizard creates a
subproject called startupcode inside your top-level project file, which in
turn contains the subprojects libsys.gpj, libstartup.gpj, and crt0.gpj. These
subprojects contain editable copies of the source to the Green Hills run-time
modules, which you can customize as necessary and rebuild either separately,
or as part of your project.

Note For more information about building and setting build options, see
Chapter 2, “The MULTI Builder”. Options should be changed with care, as
some of them are required for proper operation. For example, the default.gpj
project causes the preprocessor symbol EMBEDDED to be defined when
compiling; this symbol is required for some modules in the libraries.

580 MULTI: Building Applications for Embedded ARM


Customizing the Run-Time Environment Libraries and Object Modules

If you are working with the compiler driver and makefiles, then you should
still create a new project with the New Project Wizard, as described above.
When the files have been created, then edit them as appropriate, and use your
makefile to link to them as usual.

Startup Module crt0.o


The source code to crt0.o is contained in the source file crt0.arm, which is
located in install_dir/src/libtstartup. By default, your program is built with
crt0.o as the startup module. This file contains a function _start() that is
the default entry point for the program. The _start() function performs
initialization and then calls main().

crt0.arm
crt0.arm is the sole source file for the startup module crt0.o. It is a small
target-specific assembly language file and contains only a minimal amount of
code, required to set up a C program environment before calling into a high-level
language C function. This code is located in the function _start(), the
default entry point for programs in the Green Hills environment. On program
startup, an initial system call determines whether a Green Hills debug agent
(or debug server) is controlling execution of the program (as opposed to the
program running stand-alone, without being connected to a debug server). If the
system call is successful, some required register initialization is assumed to have
been accomplished by the debug server; otherwise the code in crt0.arm may do
more initialization. The source code in crt0.arm should be consulted since the
actual register manipulation varies widely across different architectures.

The register most commonly requiring initialization is the processor stack


pointer, since a valid stack is generally required before a high-level language
function can be called. Most crt0.arm modules reference the special symbol
__ghsend_stack when initializing the stack pointer. The symbols
__ghsbegin_section, __ghsend_section, and __ghssize_section
(where section is the name of your section preceded by an underscore (_) rather
than a period (.)), are special linker-defined symbols that mark the respective
start, end, and size of each user program section. In previous versions of the
Green Hills toolchain, the initial stack pointer was either set to some default
value by a Green Hills debug server or ROM monitor, set manually before
starting program execution under a Green Hills debug server, or initialized with
user-customized startup code.

Green Hills Software, Inc. 581


16. Libraries and Header Files

The .stack section is an improved method for specifying the location of the
run-time stack. You can place a .stack section into the linker directives file
to specify the location and size of the run-time stack. The Green Hills startup
code sets up the stack pointer to point to the end of this section if the stack
grows downward, or to the start if the stack grows upward. You can change the
location or size of the stack by changing the linker directives file.

Debug servers automatically detect the existence of the .stack section and
automatically initialize the stack pointer. For example:
.heap align(16) pad(0x100000) :
.stack align (16) pad(0x80000):

This specifies that the stack starts on the first 16-byte aligned address following
the .heap section in memory. The stack is configured to be 0x80000 bytes
in size. The other benefit of using .stack to specify the stack configuration
is that stack checking code is easily built into a program. Such code need
only compare the current value of the stack pointer register with the value
of __ghsbegin_stack or __ghsend_stack (depending on whether
the stack grows down or up) to determine whether the available stack area
is exhausted.

Finally, _start() calls the function __ghs_ind_crt0(), the


target-independent startup routine located in libstartup.a.

582 MULTI: Building Applications for Embedded ARM


Customizing the Run-Time Environment Libraries and Object Modules

Low-Level Startup Library libstartup.a


The source code to libstartup.a is contained in install_dir/src/libstartup. This
library contains hardware and process initialization routines. It automates the
function of copying sections of a program’s initialized data from ROM to RAM
and the relocation of initializers that are located at run time.

ind_crt0.c
This module contains machine-independent startup code. In particular,
ind_crt0.c clears the uninitialized data sections, such as .bss, and copies
initialized data sections from their locations in ROM to their final locations in
RAM. Whether or not a program requires this ROM to RAM copy depends on
the linker directives file for that program. You do not have to write code to
clear or copy sections at startup; ind_crt0.c does it automatically. If you want
to do this initialization without the aid of the Green Hills library, customize
ind_crt0.c and rebuild libstartup.a.

If your program uses PIC and/or PID, the ind_crt0.c code will relocate
initialized pointers to any position independent object. For example, consider
the following C code:
extern int foo();
int (*ptr)() = &foo;

This declares a global function pointer that is initialized to the address of the
function foo(). Since the location of foo() is not known until run time,
the compiler emits a small amount of data that describes each such relocated
initialization in the program. For example, when compiling for PIC, the
compiler generates data to inform ind_crt0.c that the initializer of the variable
ptr requires a run-time modification specifying the run-time location of the
program’s code, as desired. After ind_crt0.c finishes, all initialized pointers
contain valid run-time addresses.

Finally, ind_crt0.c calls into the user code, main().

ind_bcpy.c
This module is implemented for some targets that require special code to
initialize parts of their memory system.

Green Hills Software, Inc. 583


16. Libraries and Header Files

ind_mcpy.c, ind_mset.c
These modules contain the C run-time library functions memcpy() and
memset(), which are used during initialization to copy and clear data sections.
You can modify these routines if desired.

ind_reset.c
These modules contain low-level initialization routines. They may require
modifications to boot up on bare boards that do not have other means for
initialization.

Low-Level System Library libsys.a


The source code to libsys.a is contained in install_dir/src/libsys. This
library contains low-level system routines that implement run-time library
initialization, profiling, and system calls.

ind_alloc.c
This module returns a piece of memory of the given type and alignment from
the heap. This relies on ind_heap.c to actually get the memory, but since
sbrk() does not give alignment guarantees, this is used as a front end.

ind_call.arm, ind_dots.arm
These modules contain target-specific language and handle lowest-level system
call capability. The routine __ghs_syscall() is called from various
system call routines, such as open(), close(), read(), and write().
The __ghs_syscall() routine transfers control to the start address of the
.syscall section.

Debug servers or monitors can key in this address to accomplish the emulation
of system calls in the Green Hills environment. For example, many debug
servers set a special breakpoint on this address. Then, when the breakpoint
is encountered during execution, the debug server knows that a system call
occurred. The arguments are then retrieved and the system call is emulated on
the host by the debug server.

584 MULTI: Building Applications for Embedded ARM


Customizing the Run-Time Environment Libraries and Object Modules

ind_crt1.c
This module contains the first C function called by the standard libraries after
memory and static and global data have been initialized. It initializes the ANSI
C and other run-time libraries before jumping to the application entry point
(main).

ind_errn.c
This module handles reads and writes to errno in a thread safe manner. See
also ind_thrd.c.

ind_gpid.c
This module returns the current process number. This is used in mktemp() to
add uniqueness to the generated filenames.

ind_targ1.c
This is a hanger for user-customizable target specific functions.

ind_thrd.c
This module implements the locking mechanism needed for thread-safe
libraries. Also see ind_errn.c.

prof_960.c and prof_mip.c


These modules implement profiling support on top of certain target monitors.

ind_mcnt.arm, ind_gcnt.arm, ind_bcnt.c, ind_mprf.c,


ind_gprf.c
These modules provide profiling support. Two routines are used:
__ghs_mcount() for call count profiling and __ghs_gcount() for
call graph profiling. The module ind_bcnt.c contains the profiling routine
__ghs_bcount(), which handles calls that are emitted by the compiler to
implement code coverage analysis. The ind_mprf.c and ind_gprf.c modules

Green Hills Software, Inc. 585


16. Libraries and Header Files

contain routines that accomplish profiling functions, such as starting a profiling


timer (only on certain processors) and writing profile data to disk.

ind_heap.c
This module contains the dynamic memory allocation routines and, in particular,
the system call routine, sbrk(). The .heap section in the linker directives
file specifies the location, size, alignment, and initialization, if any, of the heap.
For example:
.heap align(16) pad(0x100000) :
.stack align (16) pad(0x80000):

This specifies that the heap starts on the first 16-byte aligned address following
the previous section in memory and is 0x100000 bytes in size. The .stack
section then follows the heap area. The pad directive instructs the linker that
the heap is uninitialized on startup. This enables you to place the run-time heap
anywhere in memory; the run-time library automatically allocates memory
where you place this section.

In addition, the ability to hard code a size for the heap assures you that the
program does not use more heap memory than is desired or expected. Any
attempt to allocate memory at an address higher than that specified by the size
in the linker directive will cause sbrk() to fail and return an error value.

ind_io.c
This module contains system routines most likely needed for a UNIX-like
implementation, including:
int open(const char *filename, int mode, . . . );
int creat(const char *filename, int prot);
int close(int fno);
int read(int fno, void *buf, int size);
int write(int fno, const void *buf, int size);
int unlink(char *name);

These system calls enable the program to open, read, write, and close files.

586 MULTI: Building Applications for Embedded ARM


Customizing the Run-Time Environment Libraries and Object Modules

Many of the Green Hills ind_io.c and related system call modules filter down
to calls to the generic system call interface routine __ghs_syscall(),
described in “ind_call.arm, ind_dots.arm” on page 584.

ind_iob.c
This module contains the default file buffer, _iob, used by the C library’s
stdio.h interface. The user may want to modify this to reduce or increase the
number of files that may be opened through this interface. The user may also
modify the default buffering by modifying __gh_iob_init().

ind_exit.c
This module contains the following routines:
Routine Description
_enter() Is called at startup and used as a separate routine to
initialize the I/O system, initialize caching options, etc.
_ghs_at_exit() Registers functions that need to be called upon
_exit() (similar to the ANSI atexit()).
_exit() Calls clean-up routines registered by the program via
__ghs_at_exit() or atexit() and allows the
program to terminate cleanly via an exit system call.

Other Low-Level Functions


The following files contain a basic set of UNIX-like operating system routines.
Each routine is commented to show the function it performs and the values
it returns. These routines allow the linker to resolve an operating system’s
symbols, referenced by the Green Hills run-time libraries.
Source file Routine(s)
ind_alrm.c unsigned int ualarm(unsigned int value, unsigned
int interval);
unsigned int alarm(unsigned int seconds);
ind_gmtm.c struct tm *gmtime(const time_t *timer);
ind_renm.c int rename(const char *old, const char *new);

Green Hills Software, Inc. 587


16. Libraries and Header Files

Source file Routine(s)


ind_sgnl.c int raise(int sig);
void (*signal(int sig, void (*func)(int)))(int);
ind_stat.c int access(char *name, int mode);
ind_syst.c int system(const char *string);
ind_time.c time_t time(time_t *tptr);
int times (struct tms *buffer);
ind_tmzn.c struct tm *localtime(const time_t *timer);
void tzset(void);
int __gh_timezone(void);

588 MULTI: Building Applications for Embedded ARM


Chapter 17

Mixing Languages and


Writing Portable Code

This Chapter Contains:


• Mixing Languages
• Writing Portable Code
17. Mixing Languages and Writing Portable Code

Mixing Languages
Green Hills compilers can combine C and C++ routines within the same
executable files, subject to certain constraints. This section provides some
basic information about using Green Hills compilers to create a mixed language
executable and describes how the compiler driver builds mixed language
executables. Additional language-specific details are provided in the subsequent
sections.

All Green Hills compiler drivers are compatible with each other. This permits a
C driver to compile a FORTRAN module, and a FORTRAN driver to compile
a C++ module. The driver uses the input filename extension to determine the
correct language, rather than assuming that the name of the driver determines
the source code language.

Though compatible during compilation, the various drivers differ during the
link phase. To link an application, the driver must determine all of the languages
in use in order to know which libraries to include. The driver assumes that
every application has modules written in C and assembly language, and that
there is at least one module written in the driver’s default language. If the
command line includes source files written in other languages (as indicated
by the file extension), then the driver recognizes that those languages exist in
the application as well.

Consequently, mixing any one language with C is easy because the driver always
assumes C is in use. To assure the correct linkage when mixing a language with
C, use the driver for the language other than C for linking the application.

590 MULTI: Building Applications for Embedded ARM


Mixing Languages

Initialization of Libraries
A multiple language application may need to perform input and output in more
than one language. With a little care to avoid conflicts between languages,
this is fully supported. If input and output will always be performed on
different files by each language, then the main program in a single language
application automatically handles the initialization and deinitialization of each
language’s run-time routines. Therefore, if the application will only perform
I/O in one language other than C, then it is easy to write the main program
for the application in that language. For more complex requirements, write
a main program in C to perform the initialization and deinitialization of the
library run-time routines. Examples of main programs in C are given in the
next section.

Examples of main() Programs


All language environments automatically perform initializations at the start
of the execution and cleanup at the termination. The initializations and
cleanup vary depending on the language. Examples of initializations and
cleanup include command line argument initialization, standard input/output
configuration, and static object creation/destruction. Since the C language
initializations and cleanup differ from that of the other languages, you must
often insert code inside the main() function to ensure proper configuration.

C main() Program for C++


If a program uses both C and C++, and the main() function is written in C,
insert a call to _main() as the first executing statement and a call to exit(0)
as the last executing statement (see example below). You must do this to ensure
that static constructors and destructors are properly configured. For more details
on using C++ in C programs refer to “Using C++ in C Programs” on page 593.
void main(void)
{
_main();/* must be first executable line */
/* rest of main goes here */
exit(0);/* must be last executable line */
}

Green Hills Software, Inc. 591


17. Mixing Languages and Writing Portable Code

Performing I/O on a Single File in Multiple Languages


Some applications benefit from performing input and output on a single file or
device from more than one language; one example of this is pre-opened files. In
C, these are stdin, stdout, and stderr. In C++, they are the same as C or,
alternatively, iostreams cin, cout, or cerr may be used.

All languages have full access to these pre-opened files, and input and output
can easily be mixed between the languages on these files. However, for the best
results, a complete input or output operation is done in a single language. In
C, any call to a library function which performs input or output is a complete
operation. If this rule is followed, all data will be output correctly and in the
intended sequence. The C library routine fflush() flushes the buffer of the
pre-opened files in all languages. In addition, to flush one of C++ iostreams,
use the notation file << flush. For example:
cout << flush

Performing input and output on a single file which is not preopened is more
difficult. It is possible to open the file once in each language and perform
input and output independently in each language. In many cases this would be
unacceptable, particularly when working with a device rather than a simple file.

C Routines and Header Files In C++


The C++ language allows much use of existing C code. Therefore, it is fairly
straightforward to call functions written in ANSI C from C++. The syntax of
the two languages is very similar and the use of header files has been continued
in C++.

By default in C++, the names of functions are encoded or mangled, whereas in


C, the names of functions are unchanged. C++ provides the extern specifier
to identify non-C++ functions so their names will not be mangled. Therefore,
this specifier allows ANSI declarations for any C functions to be included and
then linked with the compiled C object code.

To specify a C declaration:

• Specify or declare functions individually. The following example specifies


that two functions with extern "C" linkage are to be declared.

592 MULTI: Building Applications for Embedded ARM


Mixing Languages

extern "C" {
int fclose(FILE *);
FILE *fopen(const char *, const char *);
}

C++ requires prototyped declarations, as does ANSI C. It is not advisable to


include non-prototyped declarations because they mean something different
in C++. If they are used, any error messages may or may not point to the
non-prototype declaration.
• Declare entire header files with extern "C". For example:
extern "C" {
#include <stdio.h>
#include <string.h>
}

Here, all the function declarations that appear in <stdio.h> and <string.h>
are affected in the same manner as the two specific functions declared
individually in the previous example (fclose() and fopen()).
• If code contains both C and C++, then the extern constructs can be placed
within #ifdef __cplusplus statements. This practice is common
within header files. For example,
#ifdef __cplusplus
extern "C" {
#endif
void assert(int );
void _assert(const char *,const int,const char *);
#ifdef __cplusplus
}
#endif

Using C++ in C Programs


Many features in the C++ language simplify complicated tasks for most
languages. It makes little sense to attempt to call C++ from C in most cases,
because doing so would force the C programmer to reproduce work performed
by the C++ compiler. The various implementations of C++ use different
mechanisms for implementing the following details. This makes it more
difficult to port C programs that call C++.

Green Hills Software, Inc. 593


17. Mixing Languages and Writing Portable Code

C provides no support for any of the C++ extensions to the language. The C
programmer must manually perform some of the tasks that the C++ compiler
performs automatically. Some knowledge of the internal mechanics and details
of a C++ implementation is necessary, as follows:

• The C++ compiler encodes or mangles function and class member names.
Any C++ function or class members called from a C program must be
referenced by the encoded or mangled names.
• The manner in which a C++ compiler handles member functions must be
known. All member functions (except static member functions) have the
special object member pointer this inserted automatically as the first
argument in the parameter list. A C programmer must manually add the
argument this when calling any member functions from C.
• Handling constructors and destructors for static objects requires special
processing. On most systems, the main() function has special function
call to _main() inserted to insure that all static constructor/destructor
calls are made properly. If main() is not in a C++ module, then the C
programmer must manually include calls to _main() in the C main
module. The _main() code is contained in the C++ library and therefore
must be linked into the final executable.
• Virtual functions are also handled automatically by a C++ compiler, but
involve additional coding to access or use them from a C environment.

Function Prototyping in C vs. C++


In ANSI C and C++, header files provide prototypes for library functions which
enforce a standard interface between the calling program and the called function.

Function prototyping requires that the function declaration include the function
return type and the number and type of the arguments. When a prototype is
available for a function, the compiler is able to perform argument checking and
coercion on calls to that function. If a prototype is not available for a function
when it is called, ANSI C will behave like K&R C. The return type of the
function is assumed to be int, and actual arguments will be promoted to int,
long, or double types, or pointers as appropriate. In C++, however, it is an
error to call a function which has not been declared with a prototype.

Another important difference between ANSI C and C++ is that a non-prototype


declaration of a function, such as:

594 MULTI: Building Applications for Embedded ARM


Writing Portable Code

char *function_name();

has no effect on the number and type of the arguments in ANSI C. In C++ it
is understood as:
char *function_name(void)

which means that the function has no arguments at all. If the function declaration
occurs within the scope of an extern "C" declaration, the function has
non-C++ linkage, and therefore cannot be overloaded. This means that if a
traditional K&R style declaration of a function appears in a header file, and the
#include directive which accesses that header file is enclosed in extern
"C" { }, then it will be impossible to redeclare that function with arguments.

Writing Portable Code


Many compiler vendors have implemented the C and C++ languages for a wide
variety of system architectures. One important reason for this is that these
languages greatly simplify the task of building and maintaining software for
multiple platforms. However, not all features of C and C++ accommodate
this goal. In fact, both languages intentionally provide features that perform
differently on different systems. For a program to be truly portable, the
programmer must avoid these non-portable features of the C and C++
languages. This chapter discusses some of the non-portable assumptions that
can cause programs to fail and how to avoid portability problems with Green
Hills C/C++ compilers.

The C/C++ language specifications define programs in such a way that portable
programs will always work with all appropriate language compilers, including
any Green Hills C/C++ compiler. However, difficulties arise when programmers
make non-portable assumptions about the machine or compiler that they are
using. As a result, a program may appear to compile and operate correctly when
compiled with one vendor’s compiler, but not with a Green Hills compiler.

Certain differences between compilers are specific to the individual compiler


vendor. In addition, many more differences are particular to the processor and
the operating system being used. To avoid these differences when porting
between different system architectures, portable code should be consistently
written.

Green Hills Software, Inc. 595


17. Mixing Languages and Writing Portable Code

Compatibility Between Green Hills Compilers


All Green Hills C/C++ compilers follow the same interpretation of the C/C++
languages as described in this manual; however, some Green Hills C or C++
compilers do not include certain features or options.

For information about compatibility with Green Hills compilers for other
languages, see “Mixing Languages” on page 590.

Word Size Differences


Green Hills compilers support machines with 32-bit and 64-bit word size.
Porting C/C++ programs between machines of different word sizes requires
particular care because word size may affect most primary data types.

Some machines are byte addressable, meaning that their addresses refer to
8-bit bytes. Typically, byte addressable machines operate on 8, 16, 32, 64, and
128-bit quantities. Other machines are word addressable, meaning that their
addresses refer to words of a standard size varying from 16 to 64 bits. Word
addressable machines typically operate on multiples of the word size.

A program that operates on a machine of one word size may not operate on a
machine of a different word size. Thus, word size incompatibility problems
may arise if two different machines have different word sizes, or if one machine
is word addressable and the other is byte addressable. The word size affects the
range of numbers implemented by integer data types, as well as the precision
and range of single and double precision floating-point data types.

The most common word size problems are integer and floating-point
underflows, overflows, and loss of precision. The layout of bit aligned data
structures will vary with the word size, so overlaying structures in memory
makes programs difficult to port to another compiler. Address arithmetic done
in integer variables is often not portable.

Range of Representable Values


The size of each basic numeric type controls the range of values which may be
represented by that type. The header files <limits.h> and <float.h> provide
defined symbols which represent the minimum and maximum values for all
numeric data types in C/C++. A portable program should use these symbols and
never depend on the use of values outside the allowed range.

596 MULTI: Building Applications for Embedded ARM


Writing Portable Code

If arithmetic operations cause overflow, underflow, or loss of precision, the


program may not detect the error or may behave differently on different systems.

Relative Sizes of Data Types


Both C and C++ place very weak requirements on the relative size of the basic
types, though programs in either language commonly assume otherwise. For
example, both languages only require that short be no larger than int and
that int be no larger than long. It would be legal for short, int, and long
to all be the same size or for them all to be different. For instance, with some
32-bit Green Hills C/C++ compilers, short is 16 bits and both int and
long are 32 bits. The assumption that int is twice as large as short, but
the same size as long is non-portable, because, with 64-bit Green Hills C/C++
compilers, short is 16 bits, and int and long are either 32 or 64 bits.

Another common non-portable assumption is that pointers are the same size
as int or long. Neither is guaranteed. With all 32-bit Green Hills C/C++
compilers, pointers are 32 bits. But with 64-bit Green Hills C/C++ compilers,
pointers may be either 32 or 64 bits, independent of the size of int or long.

In both languages, all integer constants have type int unless marked with a
type suffix. In certain cases, the use of a plain integer constant instead of a long
integer constant may be non-portable.

Endianness Problems
Programs that overlay characters and integers in memory or that use character
pointers to integer variables and vice versa are often not portable between
machines with different byte ordering.

Programs that declare a single variable with different integer types in different
modules may fail when ported to a machine with a different byte order.

Alignment Requirements
Some systems will not load or store a two byte object unless that object is on an
even address. Other systems have a similar requirement for four or eight byte
objects. Others may allow certain accesses, but require more time to perform
them. Therefore, alignment of data is both a matter of correctness and of time

Green Hills Software, Inc. 597


17. Mixing Languages and Writing Portable Code

efficiency. Although increased alignment may improve performance, it also


consumes space, due to padding inserted to achieve alignment.

The alignment requirements on each system are chosen both to satisfy the
restrictions of the hardware and to achieve a reasonable balance between
performance and space. The alignment rules are often not configurable and they
differ for each system. Thus, programs that make assumptions about the relative
position of data objects in memory or elements within classes, structures, or
arrays are not portable—even among the Green Hills C++ compilers.

The C/C++ languages impose the following restrictions on size and alignment:

• The alignment of a structure, union, class, or array is equal to or greater than


the maximum alignment requirement of any of its members.
• The size of a structure, union, class, or array is always a multiple of the
maximum alignment requirement of any of its members.
• The offset of any member of a structure, union, class, or array is always a
multiple of its alignment requirement.
• All dynamic memory allocation routines provided with the compiler will
return a pointer aligned to the maximum alignment for any object on that
machine.

All Green Hills C/C++ compilers also satisfy these principles:

• The stack is maintained on an alignment suitable for any object.


• Parameters and local variables are allocated on the stack according to their
alignment requirement.
• Local variables are arranged on the stack to avoid unnecessary padding
due to alignment.

If a program does not use integer arithmetic for pointer computations and
ensures that all general purpose memory allocation routines return maximally
aligned pointers, then all references to dynamically allocated memory will be
properly aligned.

598 MULTI: Building Applications for Embedded ARM


Writing Portable Code

Structures, Unions, Classes, and Bitfields


The preceding issues of size, byte order, and alignment all affect the allocation
of data in memory. In particular, compound data structures such as unions,
structures, classes, bitfields, and arrays are very much affected by these issues.

Unions
A union allows the same memory location to be accessed as more than one type.
This is inherently non-portable. Suppose a union consists of an integer and an
array of four characters. Whether the first element of the array is the most or
least significant part of the integer depends on byte order. It is not even certain
that the integer and the array of characters have the same size.

These problems increase when a program combines integer, floating-point,


and pointer fields, and are even more severe when unions consist of structures
or bitfields.

Structures and Classes


Green Hills C/C++ compilers always allocate fields in a structure or class in the
order in which the program declares them.

The exact offset of each field from the base of the structure/class depends on
the size and alignment of the field itself and of those which precede it. The
offset of the first field is always 0 in C, but not necessarily in C++ (for instance
with multiple inheritance). Also, padding is inserted as necessary to satisfy the
alignment requirement of each subsequent field, and may also be added at the
end of the structure/class to make its overall size a multiple of its alignment.

Any program is non-portable if it assumes the offset of a field within


a class/structure or if it assumes that certain fields in two different
classes/structures always have the same offset.

Bitfields
The allocation of bitfields in a structure is dependent upon alignment rules.
Additionally, the exact layout of bits within a bitfield varies between systems
and cannot be assumed by a portable program.

Green Hills Software, Inc. 599


17. Mixing Languages and Writing Portable Code

Assumptions About Function Calling Conventions


Early implementations of C used a very straightforward approach to function
calls. All parameters were pushed on the stack from right to left. All integral
types smaller than int were promoted to int and float was promoted
to double. Given this implementation, it was possible to write functions
in C which handled variable parameters, even before the <varargs.h> and
<stdarg.h> facilities. But such functions are non-portable and depend on an
intimate knowledge of the calling conventions.

Many modern C/C++ compilers pass some parameters in registers and may not
evaluate parameters from right to left. Integer and floating-point variables, not
to mention structures, may have different rules. One non-portable assumption is
that a double may be passed to a function which expects two integers. Not
only does this assume a relationship between the size of the two types and a
certain ordering of bytes and words, but it assumes that doubles and integers
follow all of the same rules. Both of these assumptions are erroneous.

A much more common assumption is that pointer and integers may be


interchanged when passing parameters. Neither C nor C++ guarantee
that a pointer will be assigned to an integer and back without loss of
information—even if the pointer and the integer are the same size. The only
safe way to write a function that can correctly accept either pointer or integer
parameters is to use the <varargs.h> or <stdarg.h> facilities.

Even among integral types, a program may assume that int and long are
interchangeable. A C program can invoke printf using the %d operator to
refer to a long parameter; however, this program will fail when ported to a
system where long is larger than int. The correct way is to use %ld for
long parameters.

The same portability problems exist with respect to function return values. A
function which returns an int should never be used to return a pointer or long
or floating-point value, even though it may work reliably on a particular system.
A common mistake is to omit a declaration of a function that returns a pointer,
and then place a cast around the invocation of that function. The cast cannot fix
the error; it only prevents the compiler from reporting it.

600 MULTI: Building Applications for Embedded ARM


Writing Portable Code

Pointer Issues
Nearly all machines supported by Green Hills compilers are byte addressable,
but neither C nor C++ require this. On some machines, a pointer to an int and
a pointer to a char are not interchangeable. ANSI C requires that void pointers
handle all pointer types, but the void pointer must be cast or assigned to its
original type before being used. Similarly, C does not require that function
pointers and data pointers be interchangeable, but some C programs incorrectly
make this assumption.

C supports portable pointer arithmetic, provided it is used correctly. In ANSI C,


the difference of two pointers is only defined for cases where both pointers refer
to two elements within the same array object. Even so, in some unusual cases
the difference may be outside the range of ptrdiff_t() (which is either
int or long). Subtraction or comparison of pointers to two separate objects
may give non-portable results due to differences in memory layout or because
pointers are signed on one system and unsigned on another.

Pointer arithmetic should always be done directly on the pointers, not by casting
or assigning the pointers to integer types.

NULL Pointer
In all Green Hills C/C++ compilers, and most C compilers in general, the NULL
pointer has the value 0. But there are still two portability issues. One issue is
that some older programs depend upon the contents of memory location 0 being
0. This is now a well recognized programming error and some modern machines
purposely give a memory fault for any attempt to read or write to location 0.

A more subtle problem is the size of NULL. On a machine where pointers are
larger than int, it is incorrect to use the constant 0 as a NULL pointer, because 0
is of type int, which is smaller than a pointer. This matters when passing NULL
to a function that takes variable parameters or is not declared with a prototype.

Character Set Dependencies


Not all computer systems use the same characters. Although all computer
systems recognize letters, digits, and the standard punctuation characters,
considerable variation exists among the less commonly used characters.
Therefore, programs which use the less common characters may not be portable.

Green Hills Software, Inc. 601


17. Mixing Languages and Writing Portable Code

Green Hills compilers use the ASCII character set and the ASCII collating
sequence. Some language implementations use a different collating sequence,
such as EBCDIC. Programs which manipulate character data, especially string
sorting algorithms, may be dependent on a particular character collating
sequence (the order in which characters are defined by the implementation). If
one character appears before a second character in the collating sequence, then
the first character will be considered smaller than the second character when
they are compared. In the ASCII collating sequence, the lowercase letters ’a’
to ’z’ appear as the contiguous integer values 97 to 122 (decimal). In other
collating sequences, such as EBCDIC, the lowercase letters are not contiguous.

To make character and string sorting programs portable, dependencies on the


character collating sequence should be avoided. If a program is designed to
operate with a collating sequence other than ASCII, it may be necessary to
modify string and character comparison code in order to operate with ASCII.

Floating Point Range and Accuracy


The range, precision, accuracy, and base of floating-point arithmetic can vary
widely between machines. This can lead to many portability problems that can
only be addressed numerically. Green Hills compilers use the standard IEEE
floating-point representation.

Operating System Dependencies


The file and I/O device naming conventions vary greatly among computer
systems. Thus, programs that access operating system resources (such as
files) by their system names are often not portable. In order to write portable
programs, the use of explicit filenames in the program should be minimized.
Preferably, these names can be input to the program when the program is run.

If a program contains explicit filenames it may be necessary to change them to


names acceptable to the target system. Refer to your target operating system
documentation for a description of legal filenames for that environment.

Assembly Language Interfaces


Programs which use embedded assembly code or interface to external assembly
will require all of the assembly code to be rewritten when the program is
transported to a new machine.

602 MULTI: Building Applications for Embedded ARM


Writing Portable Code

Evaluation Order
None of the language specifications fully describe the order in which the various
components of an expression or statement must be evaluated. Additionally,
the language specifications disallow computations whose results depend upon
which permitted evaluation order is used. Many illegal programs have gone
undetected because they have only been compiled with one compiler. Because
the evaluation order may differ between compilers, some illegal programs may
not operate as expected when compiled with a Green Hills compiler.

Some language implementations may evaluate the arguments to a function from


right to left, others from left to right.

Green Hills compilers may execute expressions with side effects (such as
subroutine, procedure, or function calls) in a different order than other
compilers. When a variable is modified as a side effect of an expression, and
its value is also used at another point in the expression, it is not specified
whether the value used at either point in the expression is the value before or
after modification. Different values for the same variable could potentially be
used at different places in the expression, depending on the evaluation order
observed by the compiler.

Green Hills compilers may also execute operators with side effects (such as ++,
--, or +=) in a different order from that of other compilers.

Green Hills compilers may allocate some pointer variables not declared
register to registers. This allows the compiler to generate more efficient
sequences for post-increment operators. These sequences may involve
incrementing at a different position in the statement than that used with other
compilers. In particular, statements of the form:
*p++ = expression involving ’p’

often evaluate differently with a PCC compiler than with a Green Hills compiler.

A particular case of evaluation order dependency is the use of the ?: operator


in an expression which is an argument to a function call. Green Hills compilers
evaluate all question mark operators before any other arguments and keep the
result in temporary storage. PCC evaluates the ?: operator at its position in
the argument list. The call:
foo(b?i:i+i, i++)

Green Hills Software, Inc. 603


17. Mixing Languages and Writing Portable Code

will usually evaluate differently under PCC than it will under a Green Hills
compiler.

Machine-Specific Arithmetic
Certain arithmetic operators in C/C++ are intended to generate the most
efficient corresponding operation on the target machine. If all input values are
within the expected range, the results are portable. Out of range values may
give different results on different systems.

Shift
The shift operators in C/C++ possess machine-specific arithmetic
characteristics. If the right-hand operand is negative or exceeds the number of
bits in the left-hand operand, the behavior is undefined. In Green Hills C/C++
compilers, the operands will be given to the hardware as if the operands were
legal, and the result depends entirely on the hardware. Some systems accept a
negative shift and reverse the direction of the shift, but many do not. Shifting by
more than the number of bits is the same as shifting by one less than the number
of bits on some systems, but on others it has very different results.

If the left-hand operand of a right shift is signed, C/C++ does not require the
compiler to propagate the sign bit. Thus a correct C/C++ compiler can yield a
positive number when right shifting a negative number by one.

Division
The division operator may round up or down when applied to signed integers
if one or both of them is negative. Division by zero produces different results
on different machines.

The remainder operator always satisfies the rule:


( a / b ) * b + a % b == a

as long as b is not 0. Therefore, if a or b is negative, the sign of the remainder


may or may not match the sign of the dividend, depending on the machine.

604 MULTI: Building Applications for Embedded ARM


Writing Portable Code

Illegal Assumptions About Compiler Optimizations


Some programs illegally depend on the exact code generated by a particular
compiler. Such programs are particularly difficult to port to an advanced
optimizing compiler because the optimizer makes major changes in the code
in order to reduce the program’s size and increase the program’s speed. This
section describes some of the most common illegal assumptions made about
code generation. The optimizations referenced in this chapter are described in
greater detail in Chapter 19, “Optimization Descriptions”.

Implied Register Usage


Some programs rely on the exact register allocation scheme used by the
compiler. Such programs are illegal and will require modification before they
can be transported.

For example, C/C++ programs that rely on register variables being allocated
sequentially to pass hidden parameters will not work. Hidden returns (i.e., using
return and expecting to return the value of the last evaluated expression)
will not work either.

Memory Allocation Assumptions


Green Hills compilers allocate memory in a different manner than that of
typical compilers. To assure portability, programs compiled with a Green
Hills compiler must not make assumptions regarding the order or allocation
of variables in memory except where the language standard specifies it. If a
program depends on the illegal memory allocation peculiarities of a particular
compiler, it may experience portability problems. Note the following:

• Green Hills compilers do not necessarily allocate variables in the order of


declaration.
• Green Hills compilers may not allocate unused variables.
• Green Hills compilers allocate certain variables to registers that standard
compilers would always allocate to memory.

Green Hills Software, Inc. 605


17. Mixing Languages and Writing Portable Code

Memory Optimization Restrictions


This section is very important when the system code or application uses shared
memory or signals.

Using the Advanced→Advanced Optimization Options→Memory


Optimization option (-OM) enables the compiler to assume that memory
locations do not change asynchronously with respect to the running program
(see “Memory Optimization” on page 650). In particular, when the compiler
reads or writes to some memory location, it assumes that the same value
remains there several instructions later. To avoid the (potentially high) speed
penalties involved in re-reading memory, the compiler searches a register for a
copy of the value to use instead.

This option may cause problems for many parts of operating systems, device
drivers, memory mapped I/O locations, shared memory environments, multiple
process environments, interrupt-driven routines, and when UNIX style signals
are enabled. In C/C++, general optimizations may be used as follows.

An example of the potential problems involved with memory optimizations is


that many UNIX device drivers need to use memory locations which are really
I/O registers that can change at any time. A typical example of a loop waiting
for a device register to change is:
while (!(*TSRADDR & (1 << TXSBIT)));

If memory optimizations are enabled while compiling this loop, the compiler
may generate code that reads the value pointed to by TSRADDR only once. If the
Advanced→Advanced Optimization Options→Optimize All Appropriate
Loops option (-OL) is also enabled, it is almost certain that this will be the case.
When this happens, the loop executes either once or forever (depending on the
value of the bit when it is first tested) and will be rendered either ineffective
or fatal. Depending on the situation, the compiler may detect such loops
and generate code that operates correctly even with Advanced→Advanced
Optimization Options→Memory Optimization option (-OM) enabled.
However, if the loop body were to test more than one bit at the same address,
the compiler may distort the loop in an attempt to read memory as few times
as possible.

The compiler assumes that the volatile type qualifier is used when it is
available. This means that any Optimization→Optimization Strategy implies
Advanced→Advanced Optimization Options→Memory Optimization

606 MULTI: Building Applications for Embedded ARM


Writing Portable Code

in C++ or in the ANSI modes of C. If circumstances prevent the use of


volatile, you should disable the Advanced→Advanced Optimization
Options→Memory Optimization option (-Onomemory). Note that this will
leave the other general optimizations enabled (see “Optimization Options”
on page 143).

Problems with Source Level Debuggers

Variable Allocation
Once a variable is allocated to a register it will always reside in that register.
However, because other variables may share the register, it may not always
contain the current value of the variable. This may cause a source level
debugger to give incorrect results. If a variable is looked at outside the range
of its use, the compiler may have temporarily allocated that register for some
other purpose. The best strategy is to check results just after they are assigned,
or when the current value is going to be used later. Near the end of a function,
most of the local variables will no longer be in use, so it is more likely that the
register has been re-allocated.

Advanced Optimizations
In general, it is advantageous to disable some optimizations if source level
debugging is to be performed. The following examples illustrate some specific
types of problems caused when using optimizations in conjunction with source
level debuggers.

• The common sub-expression elimination optimization causes the compiler to


attempt precalculation of expressions the program uses more than once and
then save the result in a register. During a debug session, the programmer
will not find the expression itself, because it was evaluated and saved at
an earlier time.
• Various loop and branch optimizations rearrange entire statements or blocks
of statements. This causes difficulties with source level debugging because
a direct correlation between source lines and executable instructions will
no longer exist.

Green Hills Software, Inc. 607


17. Mixing Languages and Writing Portable Code

Problems with Compiler Memory Size


The compiler primarily uses memory for the program, static data structures,
global declarations, parse trees, and generated machine code. Global
declarations consist of the global constant, type, variable, and function
declarations. Memory usage increases when a compilation includes large
numbers of declarations. Even unused global declarations must be stored
throughout the compilation. If memory size problems exist, reduce the size of
the include files by including only the necessary declarations.

Basic blocks also require memory. Every possible branch creates a new block.
Memory usage may increase on machine-generated programs with very large
switch statements or with a very large number of small if statements.

Green Hills compilers read the source program only once. The C++ and the
New Generation C compiler store the entire program into a parse tree before
proceeding with optimization and code generation. The Compatibility Mode
C compiler performs optimization and code generation as it reads in each
function. The optimizer modifies the parse tree and then passes it on to the
code generator. The code generator produces an internal representation of the
machine code to be output for the function. Another optimization phase is then
called to modify this machine code. Finally, the optimized machine code for the
function is output. After the machine code is output, the memory being used
for the parse tree, optimization, and machine code generation is released for
use in processing the next function.

Usually, the size of the largest function in the program determines the maximum
memory usage for parse trees and machine code. If memory size problems
exist, turn off the optimizer and reduce the size of the largest function. A
simple function of less than 100 lines should not cause memory size problems.
However, procedures containing very complex statements, or more than 1000
lines of code, may require several megabytes of memory in order to compile.

Detection of Portability Problems


Many of the problems associated with porting programs to a Green Hills C/C++
compiler from other compilers can be detected with the UNIX utility program
lint(1). Look for variables used before definition, routines using return and
return(x), non-portable character operations, evaluation order undefined,
and routines whose value is used but not set. The UNIX utility program lint is
not able to detect code that relies on the allocation order of memory variables,

608 MULTI: Building Applications for Embedded ARM


Writing Portable Code

or on the arithmetic characteristics of short data types. Furthermore, because


lint does not do actual data flow analysis, the absence of a message does not
imply the absence of a problem.

Green Hills Software, Inc. 609


17. Mixing Languages and Writing Portable Code

610 MULTI: Building Applications for Embedded ARM


Chapter 18

Enhanced asm Macro Facility


for C and C++

This Chapter Contains:


• Definition of Terms
• Example
• Using asm Macros
• ARM asm Macros
• Writing asm Macros
18. Enhanced asm Macro Facility for C and C++

Although having the ability to write portable code is an advantage of using the
C language, sometimes it is necessary to introduce machine-specific assembly
language instructions into C code. This need arises most often within operating
system code that must deal with hardware registers that would otherwise be
inaccessible from C. You can use the asm facility to include this assembly code.

In earlier versions of C, the asm facility included a line that looked like a call
on the function asm that took one argument, a string:
asm("assembly instruction here");

Unfortunately, this technique has shortcomings when the assembly instruction


needs to reference C language operands. The user has to guess the register or
stack location into which the compiler would put the operand and encode that
location into the instruction. If the compiler’s allocation scheme changes or,
more likely, if the C code surrounding the asm changes, the correct location
for the operand in the asm also changes. The user has to be aware that the C
code would affect the asm and change it accordingly.

The new facility presented here is upward-compatible with old code, since it
retains the old capability. In addition, you can define asm macros that describe
how machine instructions should be generated when their operands take
particular forms that the compiler recognizes, such as register or stack variables.

Although this enhanced asm facility is easier to use than before, the user is
still strongly discouraged from using it for routine applications, because those
applications will not be portable to different machines. The asm facility helps
implement operating systems in a clean way.

The optimizer (ccarm -O) may work incorrectly on C programs that use
the asm macro facility, leading to run-time errors. This is more likely when
the asm macros contain instructions or labels that are unlike those that the C
compiler generates. No compiler warning or error messages will be issued.
Furthermore, the user may need to rewrite asm code in the future, in order
to maximize its benefits as new optimization technology is introduced into
the compilation system.

Wherever possible, consider using intrinsic functions instead of asm macros.


Asm macros act as an optimization barrier to the compiler, since the compiler is
unable to interpret the actions or understand the instructions in the asm macro.
Intrinsic functions, on the other hand, are understood by the compiler, so the
compiler need not make worst-case assumptions about the behavior of the

612 MULTI: Building Applications for Embedded ARM


Definition of Terms

instructions. Intrinsic functions are also easier to use since the compiler takes
care of loading and storing the operands automatically, as necessary.

Definition of Terms
The following terms are used when describing the asm macro facility.
Term Definition
asm macro The mechanism by which programs use the enhanced
asm facility. An asm macro has a definition and uses. The
definition includes a set of pattern/body pairs. Each pattern
describes the storage modes that the actual arguments must
match for the asm macro body to be expanded. The uses
resemble C function calls.
storage mode The compiler’s idea of where the argument can be found at
run time. Examples are “in a register” or “in memory.”
pattern Specifies the modes for each of the arguments of an asm
macro. When the modes in the pattern all match those of the
use, the corresponding body is expanded.
asm macro body The portion of code that will be expanded by the compiler
when the corresponding pattern matches. The body may
contain references to the formal parameters, in which
case the compiler substitutes the corresponding assembly
language code.

Example
The following is a general example intended to demonstrate how to define
and use an asm macro. For an example specific to ARM, see “ARM asm
Macros” on page 619.

Suppose your machine has an spl instruction for setting machine interrupt
priority levels. spl takes one operand, which must be in a register.
Nevertheless, it would be convenient to have a function that produces inline
code to set priority levels, uses the spl instruction, and works with register
variables or constants.

This example consists of two parts: the definition of the asm macro and its use.

Green Hills Software, Inc. 613


18. Enhanced asm Macro Facility for C and C++

Definition
Define an asm macro, called spl:
asm void SPL(newpri)
{
%reg newpri
spl newpri
%con newpri
movw newpri, %r0
spl %r0
}

The lines that begin with % are patterns. If the arguments at the time the macro
is called match the storage modes in a pattern, the code that follows the pattern
line will expand.

Use
The table below shows the (assembly) code that the compiler will generate with
two different uses of spl. It uses the following introductory code (along with
the above definition):
f() {
register int i;
SPL(i);
SPL(3);
}

Code Matches Generates


SPL(i); % reg spl %r8
SPL(3); % con movw &3,%r0
spl %r0

The first use of spl has a register variable as its argument (assuming that
i actually gets allocated to a register). This argument has a storage mode
that matches reg, the storage mode in the first pattern. Therefore, the
compiler expands the first code body. newpri, the formal parameter in the
definition, has been replaced in the expanded code by the compiler’s idea of
the assembly-time name for the variable i, namely %r8. Similarly, the second
use of spl has a constant as its argument, which leads to the compiler’s

614 MULTI: Building Applications for Embedded ARM


Using asm Macros

choosing the second pattern. Here again newpri has been replaced by the
assembly-time form for the constant &3.

Using asm Macros


You can use the enhanced asm facility to define constructs that behave
syntactically like static C functions. Each asm macro has one definition and
zero or more uses per source file. The definition must appear in the same file
with the uses (or be included with #include). The same asm macro may be
defined multiply (and differently) in several files.

The asm macro definition declares a return type for the macro code, specifies
patterns for the formal parameters, and provides bodies of code to expand
when the patterns match. When it encounters an asm macro call, the compiler
replaces uses of the formal parameters with its idea of the assembly language
locations of the actual arguments as it expands the code body. This constitutes
an important difference between C functions and asm macros. An asm macro
can have the effect of changing the value of its arguments, whereas a C function
can only change a copy of its argument values.

Calls to asm macros look exactly like normal C function calls. They may be
used in expressions and they may return values. The arguments to an asm
macro may be arbitrary expressions, except that they may not contain uses
of the same or other asm macros. Return values are passed according to the
target-specific calling convention.

Structures contained in registers and stand-alone variables are passed directly


to the asm macro as arguments, and may be directly modified by the macro
as well as read. When the argument to an asm macro is a function name or
a structure contained in memory, the compiler generates code to compute a
pointer to the structure or function, and the resulting pointer is used as the
actual argument to the macro. Elements of a structure or array, or the value of a
compound expression must be evaluated to a temporary variable which is then
passed as the argument to the macro. Addresses are loaded into a temporary
variable before being passed along. In cases where the value of an expression
is passed as an argument through a temporary variable, modifying the value
directly will not affect the value of the expression, so any result must be passed
by the return value of the asm macro. Temporary variables will usually be
allocated to registers.

The following example shows how passing addresses work:

Green Hills Software, Inc. 615


18. Enhanced asm Macro Facility for C and C++

asm void make10(addr)


{
%reg addr
li r3, 10
stw r3, 0(addr)
%nearmem addr
lwz r4, addr
li r3, 10
stw r3, 0(r4)
%error
}
void func()
{
int i, array[10];
make10(&i);
make10(array);
make10(&array[3]);
}

Definition
The syntactic classes type_specifier, identifier, and parameter_list are presented
in the style used in C-language compilers. A syntactic description enclosed in
square brackets ([ ]) is optional, unless the right bracket is followed by +. A +
means “one or more repetitions” of a description. Similarly, * means “zero or
more repetitions.” For example:
asm [type_specifier]identifier ([parameter_list])
{
[storage_mode_specification_line
asm_body] *
}

An asm macro consists of the keyword asm followed by what looks like a C
function declaration. Inside the macro body there are one or more pairs of
storage_mode_specification_lines (patterns) and corresponding asm_bodies.
If the type_specifier is other than void, the asm macro should return a value
of the declared type.

storage_mode_specification_line
% [storage_mode [identifier [, identifier]* ] ]*

616 MULTI: Building Applications for Embedded ARM


Using asm Macros

A storage_mode_specification_line consists of a single line (no continuation


with the backslash character (\) is permitted) that begins with a percent
sign (%) and contains the names (identifiers) and storage modes of the
formal parameters. Modes for all formal parameters must be given in each
storage_mode_specification_line (except for error). The percent sign (%) must
be the first character on a line (including whitespace). If an asm macro has no
parameter_list, the storage_mode_specification_line may be omitted.

Storage Modes
These are the storage modes that the compiler recognizes in asm macros:
Storage Description
mode
con A compile-time constant.
error Generates a compiler error. You can use this mode to flag errors at
compile time if no appropriate pattern exists for a set of actual arguments.
farsprel A location on the stack that is too far away to be accessed in a single
instruction.
lab A compiler-generated unique label. The identifier(s) that are specified
as being of mode lab do not appear as formal parameters in the asm
macro definition, unlike the preceding modes. Such identifiers will be
expanded to be unique.
Example:

asm void check_for_bit_set(r)


{
%reg r %lab endlab
b_if_not_bit_set r, endlab
software_trap
endlab:
%error
}
void check_status(int i, int j)
{
/* Using the macro twice would cause the "endlab" label to be
defined twice if it was not specified as unique with %lab */
check_for_bit_set(i);
check_for_bit_set(j);
}

mem Matches any allowed machine addressing mode, with the exception
of reg and con.

Green Hills Software, Inc. 617


18. Enhanced asm Macro Facility for C and C++

Storage Description
mode
farmem A location in memory that cannot be accessed with a single-load
instruction. These may need to be broken up into multiple-load
instructions, and the steps for doing this may depend on the compilation
mode.
nearmem A location in memory that can be accessed with a single-load instruction
(such as nearby stack variables or variables in a Small Data Area).
reg A treg or ureg.
treg A compiler-selected temporary register.
ureg A C register variable that the compiler has allocated in a machine
register.

asm Body
The asm body represents the (presumed) assembly code that the compiler will
generate when the modes of all of the formal parameters match the associated
pattern. Syntactically, the asm body consists of the text between two pattern
lines that begin with a percent sign (%) or between the last pattern line and the
right curly brace (}) that ends the asm macro. C-language comment lines are
not recognized as such in the asm body. Instead, they are simply considered
part of the text to be expanded.

Formal parameter names may appear in any context in the asm body, delimited
by non-alphanumeric characters. For each instance of a formal parameter in the
asm body the compiler substitutes the appropriate assembly language operand
syntax that will access the actual argument at run time. As an example, if one
of the actual arguments to an asm macro is x, an automatic variable, a string
like 4(%fp) would be substituted for occurrences of the corresponding formal
parameter. An important consequence of this macro substitution behavior is
that asm macros can change the value of their arguments. This differs from
standard C semantics.

For lab parameters, a unique label is chosen for each new expansion.

If an asm macro is declared to return a value, it must be coded to return a


value of the proper type in the machine register that is appropriate for the
implementation.

618 MULTI: Building Applications for Embedded ARM


ARM asm Macros

An implementation restriction requires that no line in the asm body may start
with a percent sign (%).

ARM asm Macros


The following example demonstrates how to use asm macros correctly:
#if defined(__THUMB)
asm int mulword(a,b)
{
%con a %con b
mov r0,a
mov r1,b
mul r0,r1
%con a %reg b
mov r0,a
mul r0,b
%reg a %con b
mov r0,b
mul r0,a
%reg a %reg b
mul r0,a,b
%con a %mem b
mov r0,a
ldr r1,b
mul r0,r1
%mem a %con b
ldr r0,a
mov r1,b
mul r0,r1
%mem a %mem b
ldr r0,a
ldr r1,b
mul r0,r1
%error
}
#elif defined(__ARM)
asm int mulword(a,b)
{
%con a %con b
mov r0,a
mov r1,b
mul r0,r1,r0
%con a %reg b
mov r0,a
mul r0,b,r0
%reg a %con b
mov r0,b
mul r0,a,r0
%reg a %reg b
mul r0,a,b

Green Hills Software, Inc. 619


18. Enhanced asm Macro Facility for C and C++

%con a %mem b
mov r0,a
ldr r1,b
mul r0,r1,r0
%mem a %con b
ldr r0,a
mov r1,b
mul r0,r1,r0
%mem a %mem b
ldr r0,a
ldr r1,b
mul r0,r1,r0
%error
}
#endif
short x = 30;
short y = 2;
int z=10;
func()
{
int tmp1 = x, tmp2 = y;
int ztmp = z;
return mulword(10,20) + mulword(tmp1,tmp2) + mulword(ztmp,30) +
mulword(ztmp,ztmp) + mulword(10,ztmp);
}
func2()
{
int tmp1 = x, tmp2 = y;
int ztmp = z;
return (10*20) + (tmp1*tmp2) + (ztmp*30) +
(ztmp*ztmp) + (10*ztmp);
}
main()
{
if (func() == func2())
printf("Everything is just peachy.\n");
return 0;
}

Do not pass relocatable parameters (global or static variables, for example) to


asm macros since these will cause the assembler to load the address instead
of the contents at that address. For example, in the example above, adding a
mulword(x,y) would be incorrect, since x and y are both relocatable.

Writing asm Macros


Here are some guidelines for writing asm macros.

620 MULTI: Building Applications for Embedded ARM


Writing asm Macros

• Use intrinsic functions preferentially over asm macros. Intrinsic functions


do not inhibit optimizations the same way that asm macros may, and they
are easier to use.
• Know the implementation. You must be familiar with the C compiler and
assembly language with which you are working. You can consult the
Application Binary Interface for your machine for the details of function
calling and register usage conventions.
• Observe register conventions. You should be aware of which registers the C
compiler normally uses for temporary registers (also known as caller-saved
or volatile registers) and permanent registers. An asm macro may alter
temporary registers at will, but the values in permanent registers must be
preserved. You must know in which register or registers the compiler returns
function results.
• Handle return values. asm macros may “return” values. That means they
behave as if they were actually functions that had been called via the usual
function call mechanism. asm macros must therefore mimic C’s behavior
in that respect, returning values in the same way as normal C functions.
Float and double results sometimes get returned in different registers from
integer results. On some machine architectures, C functions return pointers
in different registers from those used for scalars. Finally, structures may be
returned in a variety of implementation-dependent ways.
• Cover all cases. The asm macro patterns should cover all combinations of
storage modes of the parameters. The compiler attempts to match patterns in
the order of their appearance in the asm macro definition. If the compiler
encounters a storage mode of error while attempting to find a matching
pattern, it generates a compile-time error for that particular asm macro call.
• Beware of argument handling. asm macro arguments are used for macro
substitution. Thus, unlike normal C functions, asm macros can alter the
underlying values to which their arguments refer. Altering argument values
makes it impossible to substitute an equivalent C function call for the asm
macro call.
• asm macros are inherently non-portable and implementation-dependent.
Although they make it easier to introduce assembly code reliably into C
code, the process cannot be made foolproof. You will always need to verify
correct behavior by inspection and testing.
• Debuggers will generally have difficulty with asm macros. You cannot
set breakpoints in the macro code.

Green Hills Software, Inc. 621


18. Enhanced asm Macro Facility for C and C++

622 MULTI: Building Applications for Embedded ARM


Chapter 19

Optimization Descriptions

This Chapter Contains:


• Inlining Optimizations
• Loop Optimizations
• General Optimizations
• Default Optimizations
19. Optimization Descriptions

This chapter provides detailed descriptions of many of the optimizations


available with the Green Hills ARM compiler. It is provided for users who are
interested in detailed information about the code transformations that these
optimizations perform, and for advanced users who may want individually to
control them. Most users, however, are encouraged to allow the compiler to
choose which optimizations to set for their particular purpose, by specifying an
Optimization Strategy:
Set the Optimization→Optimization Strategy option to one of the
following settings:
• Optimize for Size (-Ospace).
• Optimize for General Use (-O).
• Optimize for Speed (-Ospeed).

For further details about this and other high-level optimization options, see
“Optimization Options” on page 143.

624 MULTI: Building Applications for Embedded ARM


Inlining Optimizations

Inlining Optimizations
The term inlining refers to the process of substituting a call to a function or
subroutine with the actual content of that function or subroutine. This eliminates
the overhead of a subroutine call and results in faster code.

Typically, the best candidate for inlining is a small, frequently executed function
or subroutine that the program calls from only a few locations. Inlining increases
efficiency in high usage areas without significantly increasing program size.

The Green Hills implementation of inlining is language independent within


the Green Hills family of compilers. Routines of one language may be freely
inlined into programs of another language. Additionally, the Green Hills
compilers perform inlining across modules. Therefore, if a program defines a
function within one module, and several modules use that same function, the
compiler can inline the function within all the appropriate modules.

What Can Be Inlined


Although the user can request that any number of functions be considered for
inlining using the methods described below, the compiler will not necessarily
inline all such functions. The overall size of the function to be inlined,
the calling function, and other factors are always taken into consideration.
Recursive functions cannot be inlined under any circumstances.

Automatic Inlining
To enable this optimization, set the Optimization→Optimization
Strategy option to Optimize for Speed (-Ospeed).
To disable this optimization, set the Advanced→Advanced
Optimization Options→Inline Tiny Functions option to Off
(--no_inline_tiny_functions).

The compiler automatically inlines the following types of function:

• Static functions which are referenced only once in a file.


• Very small functions (for example, single simple assignments).

Green Hills Software, Inc. 625


19. Optimization Descriptions

Manual Inlining
With manual inlining, the user indicates in the source code which functions
should be considered for inlining. The method for doing this differs for each
language:

• In C, the keyword inline or __inline is placed immediately before the


declaration of each function to be inlined. Such functions are given the
internal linkage, as though they were declared static.
• In C++, only inline is available. C++ member functions that are defined
inside class or struct type definitions are also considered inline, even if
the inline keyword is omitted. Such routines are known as implicitly
inlined member functions. Inline member functions and functions declared
extern inline are given the external linkage. All other inline functions
are given the internal linkage.

Functions declared inline are considered to be of static scope; therefore, they are
not exported or available to be inlined in other modules. If all calls to a function
are inlined, and if the address of the function is never taken, the compiler will
not generate any out-of-line code for that function.

Single-pass Inlining
This optimization is enabled by default and cannot be disabled.

Only those functions manually indicated by the user in the source code will be
considered for inlining. In the Compatibility Mode C compiler, only those
functions which are defined before they are called will be inlined.

Example 1.

The following program illustrates the basic principles of inlining. The main
program in this case contains a simple loop that calls the function sub(). The
call itself occurs only once in the program code, but the function is executed
for each iteration of the loop. The call is easily replaced by the routine code
for sub() itself, eliminating both the need for parameter passing and the
overhead of a jump-to-subroutine. The reduced overhead per execution results
in a major increase in program speed.

626 MULTI: Building Applications for Embedded ARM


Inlining Optimizations

Initial C source code Optimized C source code

__inline void sub(x) { main() {


printf("x=%d\n",x); int i;
return; for (i=1;i<10;i++)
} printf("x=%d\n",i);
main() { }
int i;
for (i=1;i<10;i++)
sub(i);
}

Inline functions are given the internal linkage (as though they were declared
static). Therefore, it is safe to remove the body unless the address of the
inline function is taken. Note that in the example above, the body of sub()
is eliminated following this strategy.

It is important to note that each module which calls an inline function must
“see” its entire definition (including the body). If only a declaration is available,
all symbols might not get resolved, leading to linker errors. Also, be cautious
when taking an address of an inline function from two different modules—this
will result in two different values (since each module will treat the inline
function as its own local copy). Comparing the two values will not result in
equality (which one might expect for non-inline functions).

Note If a function is declared in a header file with the __inline or inline


keyword, a unique instance of the function will be generated for every source
file. In particular, if such a function has its address taken in two different source
files, the address will be different in those two source files. In this aspect, inline
functions behave differently from normal functions.

Two-Pass Inlining (Intermodule Inlining)


Two-pass inlining involves a special precompilation pass over all of the source
files to generate intermediate code for all of the functions to be inlined. This
code is stored in files with the same name as the original source file but with
the .inf extension. On the second pass, each source file is compiled normally,
but the compiler is given all of the .inf files as additional input. In this way, the
compiler is able to inline functions across source files and across programming
languages.

Green Hills Software, Inc. 627


19. Optimization Descriptions

In two-pass inlining, compiler warnings are suppressed on the first pass so that
duplicate warnings will not be issued.

Since two-pass inlining requires significant additional compilation time, it must


be enabled specifically with one of the -OI option variants. The -OI option
variants offer different ways of selecting functions as candidates for two-pass
inlining, and each is described below.

Automatic Two-Pass Inlining

To control this optimization, use the Optimization→Intermodule


Inlining option (-OI/-Onoinline).

This optimization instructs the compiler to consider all small functions as


candidates for inlining. There is no need for the user to determine which
functions to inline, or to modify the source code.

Any functions that have been manually specified will also be considered for
inlining.

Inlining Specific Functions


To specify particular functions for consideration for inlining:

Specify the functions to consider for inlining in the


Optimization→Individual Functions→Inline Specific
Functions option (-OI=fn1[,fn2…]).

This optimization allows you to specify a list of functions to be considered for


inlining. This is similar to manual two-pass inlining in that the user determines
whether or not each function will be inlined, but does not require modification
of the source code.

Any functions that have been manually specified (see “Manual Inlining” on
page 626) will also be considered for inlining.

628 MULTI: Building Applications for Embedded ARM


Inlining Optimizations

Note The Optimization→Individual Functions→Inline Specific Functions


option (-OI=fn1[,fn2…]) does not enable automatic two-pass inlining. You
can enable both this option and Optimization→Intermodule Inlining (-OI)
in order to enable all three forms (manual, automatic, and function name) of
two-pass inlining.

Example 2. Two-Pass Inlining: Combining the Inlining Option


Variants

Given the following contents of file_a.c and file_b.c:


file_a.c:
int a_very_big_function()
{
/* lots of code in here, not shown for brevity... */
return 0;
}
int b()
{
return 2;
}

file_b.c:
extern int a_very_big_function(), b();
__inline int c()
{
return 3;
}
int main()
{
return a_very_big_function() + b() + c();
}

there are several ways to use the inlining option variants.

Given the command line:


ccarm -OI file_a.c file_b.c:

• The function a_very_big_function() will not be inlined, even


though Optimization→Intermodule Inlining (-OI) is enabled, because the
compiler deems it to be too large.
• The function b() will be inlined because Optimization→Intermodule
Inlining (-OI) is enabled and b() is small.

Green Hills Software, Inc. 629


19. Optimization Descriptions

• The function c() will be inlined because it was declared with __inline
in the same module as the caller.
• The functions a_very_big_function() and b() will be generated in
closed form in module a. c() will not be generated in closed form because
it is declared with __inline and it was successfully inlined everywhere.

Given the command line:


ccarm -OI=a_very_big_function file_a.c file_b.c

• The function a_very_big_function() will be inlined because it was


specified with Optimization→Individual Functions→Inline Specific
Functions (-OI=a_very_big_function).
• The function b() will not be inlined because Optimization→Intermodule
Inlining (-OI) was not enabled.
• The function c() will be inlined because it was declared with __inline
in the same module as the caller.
• The functions a_very_big_function() and b() will be generated
in closed form in module a. The function c() will not be generated in
closed form.

Given the command line:


ccarm file_a.c file_b.c

• The functions a_very_big_function() and b() will not be inlined


because Optimization→Intermodule Inlining (-OI) was not enabled.
• The function c() will be inlined because it was declared with __inline
in the same module as the caller.
• The functions a_very_big_function() and b() will be generated in
closed form in module a. c() will not be generated in closed form.

Varying Inlining Thresholds


To increase the size threshold beneath which the compiler will consider
functions for inlining:

630 MULTI: Building Applications for Embedded ARM


Inlining Optimizations

Set the Optimization→Optimization Scope→Inline Larger


Functions option to On (-OB).

The compiler will still not consider very large functions for inlining unless
they are specified using the Optimization→Individual Functions→Inline
Specific Functions option (-OI=fn1[,fn2…]). For example, if
Optimization→Intermodule Inlining (-OI) is not inlining sufficiently large
functions for your needs, pass:
ccarm -OI -OB

If you need even larger functions to be inlined, then you must specify them
individually using Optimization→Individual Functions→Inline Specific
Functions option (-OI=fn1[,fn2…]). For example, to enable automatic
two-pass inlining with the higher Optimization→Optimization Scope→Inline
Larger Functions (–OB) threshold, and to additionally inline the function
a_very_big_function(), pass:
ccarm -OI -OB -OI=a_very_big_function

Advantages of Inlining
Inlining is traditionally considered an optimization that improves program
speed at the cost of increasing program size. However, although inlining creates
more code (because the compiler may generate a single function multiple
times within the program), it may actually decrease the overall program size.
When a call is replaced by inlined code, the compiler can usually avoid saving
and restoring several registers before and after the call. Parameters which
normally must be passed on the stack to a called routine can be accessed
directly by the inlined routine in their original location. Furthermore, because
Green Hills compilers perform inlining before most global optimizations, the
process of inlining may significantly enhance the opportunities for additional
optimizations. This results in very efficient code.

For example, if one or more parameter values are constant, large portions of the
inlined routine may be reduced or eliminated at compile time, and loops which
normally execute a variable number of times may become constant.

Green Hills Software, Inc. 631


19. Optimization Descriptions

Register allocation may improve because inlining eliminates the overhead


associated with a call. On most architectures, a call to a routine that exists
within a routine reduces the number of registers available for local variables
and temporaries. If all routine calls can be eliminated by inlining, the number of
registers available for variables and temporaries increases.

Pessimistic assumptions made by the compiler when compiling the caller may
not be necessary if no call is made. Normally the compiler must assume that
when a call is performed, global variables may be changed. This prevents the
compiler from optimizing the values of expressions containing global variables
across a call to a function. When the function is inlined, the call is eliminated
and the global variables can be optimized freely.

Limitations of Inlining
Inlining is subject to the following limitations:

• Source line number information related to inlined routines is deleted. When


a program is executed under the control of a source debugger, no source
code is available for the inlined routine. Single stepping by source line will
cause the entire inlined call to be executed as a single statement. You can,
however, debug the inlined call by stepping through the sequence of inlined
machine instructions at the point of the source-level call.
• Routines written in assembly language cannot be inlined because they are
only assembled (and not compiled) to produce an object file.

Inlining of C Memory Functions


To disable this optimization:

Set the Advanced→Advanced Optimization Options→Inline C


Memory Functions option to Off (-Onomemfuncs).

This optimization enables automatic inlining of calls to C memory functions


(if string.h is included). If a memory function has its address taken from
within a module that is compiled with memory inlining, a static copy of the
function will be produced and its address used in place of the function from the
C libraries. This is, strictly speaking, not C compliant because the address of

632 MULTI: Building Applications for Embedded ARM


Inlining Optimizations

the function from within the module will differ from the address taken in other
modules. You should not use memory (or string) inlining when the addresses
of such functions are taken.

Note This optimization will not be enabled by default if you set


Optimization→Optimization Strategy to Optimize for Size (-Ospace).
To invoke it in this situation, set the Advanced→Advanced Optimization
Options→Inline C Memory Functions option to On (-Omemfuncs).

Inlining of C String Functions


To disable this optimization:

Set the Advanced→Advanced Optimization Options→Inline C


String Functions option to Off (-Onostrfuncs).

This optimization enables automatic inlining of calls to C string functions


(if string.h is included). If one of the string functions has its address taken
from within a module that is compiled with string inlining, a static copy of the
function will be produced and its address used in place of the function from the
C libraries. This is, strictly speaking, not C compliant because the address of
the function from within the module will differ from the address taken in other
modules. You should not use string (or memory) inlining when the addresses
of such functions are taken.

Note This optimization will not be enabled by default if you set


Optimization→Optimization Strategy to Optimize for Size (-Ospace).
To invoke it in this situation, set the Advanced→Advanced Optimization
Options→Inline C Memory Functions option to On (-Ostrfuncs).

Green Hills Software, Inc. 633


19. Optimization Descriptions

Additional C++ Inlining Information


The C++ standard dictates that all member functions defined inside class
definitions are implicitly declared inline. Thus, one would expect that the
compiler will consider all such functions for inlining, even in the absence
of any of the two-pass inlining option variants. However, apparently small
bodies in C++ can often expand into dozens of lines in assembly code. In such
cases, inlining every function that is implicitly declared inline might lead to
unacceptably bloated code (especially when size is more important than speed).
As a consequence, in C++, only functions which are composed entirely of
straightline code will be inlined by default.

If such default C++ inlining is unsatisfactory, either because it generates


an unacceptable increase in code size or because it does not inline enough
functions, you can override the default behavior as follows:
Set the Advanced→Advanced C/C++ Compiler Options→C++
Inlining Level option to one of the following settings:
• Maximum (--max_inlining) — Instructs the compiler to consider all
functions (whether containing control flow statements or not) for
inlining, subject to its usual restraints in the case of excessively
large or complicated functions
• Maximum Unless Debugging (--max_inlining_unless_debug)
— Behaves the same as Maximum, but disables inlining if
debugging is enabled. The debugger can only debug inlined
functions at the assembly level. The option avoids having to
change the inlining options when debugging the application.
• Standard (--inlining) — [default] Applies standard C++ inlining
rules as described above.
• Standard Unless Debugging (--inlining_unless_debug) —
Behaves the same as Standard but disables inlining if debugging
is enabled.
• None (--no_inlining) — Disables all C++ inlining. Any functions
which are declared inline (whether explicitly with the inline
keyword, or implicitly) will be given file-local closed copies. If a
function is used in more than one module, each module will get
its own file-local closed copy.

You can use these options to control C++ inlining for all modules that make up
an executable, or at a local module-by-module level. You can also use them
together, perhaps enabling maximum inlining for modules that contain only
small functions and disabling all inlining for modules containing large functions.

634 MULTI: Building Applications for Embedded ARM


Inlining Optimizations

To control C++ inlining within a module, you should use the #pragma ghs
startnoinline and #pragma ghs endnoinline constructs and/or
the __noinline keyword. These #pragmas bracket off functions which
should not, even if they are member functions defined inside a class, be inlined.
This feature has no effect on template functions or member functions of
template classes.

You can use the __noinline keyword when declaring template member
functions or direct member functions of template classes, by adding it to the
source code in the same place where inline is ordinarily accepted. The
__noinline keyword treats an inline member function as though it were
defined outside of the class body. This has the effect of generating a single
externally visible closed copy for that template instantiation. This is preferable
to disabling all inlining, since it does not generate duplicate copies in different
modules.

For the __noinline keyword to be recognized and to take effect:

Set the C/C++ Compiler→C++→Keyword Support→Support


__noinline Keyword option to On (--enable_noinline).

Note This option is automatically enabled when you set the


Optimization→Optimization Strategy option to Optimize for Size
(-Ospace).

Consequently, you can combine the same source code differently without
having to remove the __noinline keyword. To suppress recognition of
the __noinline keyword, set the C/C++ Compiler→C++→Keyword
Support→Support __noinline Keyword option to Off (--disable_noinline).

The Green Hills C++ library header files make use of the __noinline
keyword on member functions which are known to cause large code bloats.

Green Hills Software, Inc. 635


19. Optimization Descriptions

Loop Optimizations
The compiler uses most of its resources to optimize code in the innermost loops
in your source files. Therefore, this optimization is most effective for code
containing many loop structures that are executed frequently.

This optimization includes:

• strength reduction
• loop invariant analysis
• loop unrolling

Automatic Loop Optimization

To control this optimization, use the Advanced→Advanced


Optimization Options→Optimize All Appropriate Loops option
(-OL/-Onoloop).

If code size is a priority, you should set Advanced→Advanced Optimization


Options→Loop Unrolling to Off (-Onounroll).

Loop Optimizing Specific Functions


To specify particular functions for consideration for loop optimizations:

Specify the functions to consider for loop optimization in the


Optimization→Individual Functions→Loop Optimize Specific
Functions option (-OL=fn1[,fn2…]).

For example, the following command line specifies that loop optimizations will
be applied to sub and sub2:
ccarm -OL=sub,sub2 main.c prog1.c prog2.c

636 MULTI: Building Applications for Embedded ARM


Loop Optimizations

Strength Reduction
This optimization is applied to arrays subscripted with the loop index. Most
compilers access the array element by multiplying the size of the element by the
loop index. The Green Hills compilers store the address of the array in a register
and add the size of the array element to the register on each iteration of the loop.

Example 1.
Initial C source code Optimized C source code

subr() subr()
{ {
int i; int i;
int q[4]; int q[4];
for (i=0;i<4;i++) int *_ptr;
q[i]=i; for (i=0, _ptr=q; i<4; i++)
} *_ptr++ = i;
}

Strength reduction also applies to multiplying a loop invariant with the loop
index. The optimizer replaces a multiply instruction or a call to the mul()
library function with add and shift instructions.

Green Hills Software, Inc. 637


19. Optimization Descriptions

Loop Invariant Analysis


This optimization examines loops for expressions or address calculations that
do not change within the loop. Where such computations are identified, they
are relocated to outside the loop and their values are stored in registers.

This optimization is especially useful for reducing code generated to access an


array element when the array index does not change within the loop.

Example 2.
Initial C source code Optimized C source code

subr() subr()
{ {
int i,j; int i,j;
int q[4],p[4]; int q[4],p[4];
for (i=3;i>=0;i--) { int *_ptr;
q[i]=i; for (i=3; i>=0; i--) {
for (j=0;j<4;j++) q[i] = i;
p[j]=q[i]; for (j=0, _ptr = &q[i]; j<4; j++)
} p[j] = *_ptr;
} }
}

638 MULTI: Building Applications for Embedded ARM


Loop Optimizations

Loop Unrolling
This optimization duplicates the code in innermost loops up to a maximum of
four times to produce more straightline code. This removes much of the loop
overhead required for testing for stop condition and branching, and allows for
more instruction pipelining and better use of the register allocator . It is most
effective when the innermost loop is relatively short, causing minimal increase
in code size. The following options allow further control over loop unrolling:
To decrease from 8 to 4 the number of times that a loop may be
unrolled:
Set the Optimization→Optimization Scope→Unroll Loops Up To 8
Times option to Off (-Onounroll8).
To increase the maximum size of loops that may be unrolled:
Set the Optimization→Optimization Scope→Unroll Larger Loops
option to On (-Ounrollbig).
To disable loop unrolling (recommended when code size is a priority):
Set the Advanced→Advanced Optimization Options→Loop
Unrolling option to Off (-Onounroll).

Example 3.

This simple example uses a loop with a constant iteration count of 100 and a
maximum loop index of 4. If the number of iterations (n) is large (auxiliary
loop execution time is negligible), then the loop takes n*(4 cycles per iteration)
= 4n cycles to complete. The unrolled loop takes n/ 4 *(10 cycles per iteration)
= 2.5n cycles to complete. If n is large, unrolling makes the loop execute in
only 63% of the original time.

Green Hills Software, Inc. 639


19. Optimization Descriptions

Initial C source code Optimized C source code

subr(a) subr(a)
int a[]; int a[];
{ {
int i; int i;
for (i=0;i<100;i++) for (i=0;i<100;i+=4) {
a[i]=i; a[i]=i;
} a[i+1]=i+1;
a[i+2]=i+2;
a[i+3]=i+3;
}
}

640 MULTI: Building Applications for Embedded ARM


General Optimizations

General Optimizations
To enable all of the optimizations in this section:
Set the Optimization→Optimization Strategy option to one of the
following settings:
• Optimize for Size (-Ospace).
• Optimize for General Use (-O).
• Optimize for Speed (-Ospeed).

Peephole Optimization
This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:
Use the Advanced→Advanced Optimization Options→Peephole
Optimization option (-Opeep/-Onopeephole).
When debugging, you may find it helpful to select the Restrict
peephole optimization scope to increase debuggability setting
of the Optimization→Optimization Scope→Pipeline & Peephole
Scope option (-Olimit=peephole).

This optimization identifies common code patterns and replaces them with more
efficient code. This includes optimizations such as flow of control, algebraic
simplifications, and removal of unreachable code. The compiler only performs
this optimization when local code analysis ensures that the results will be
correct without further analysis of the surrounding code.

Example 1.
Initial Assembly code Optimized Assembly code

mul r1 <- r2, r3 mac r4 <- r2, r3


add r4 <- r1, r4

Green Hills Software, Inc. 641


19. Optimization Descriptions

Pipeline Instruction Scheduling


This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:
Use the Advanced→Advanced Optimization Options→Pipeline
Instruction Scheduling option (-Opipeline/-Onopipeline).
When debugging, you may find it helpful to select the Restrict
pipeline optimization scope to increase debuggability setting of the
Optimization→Optimization Scope→Pipeline & Peephole Scope
option (-Olimit=pipeline).

This is a low-level time optimization from which a majority of architectures


benefit. These architectures (which include all RISC implementations,
most new CISC implementations, many DSP processors, and even new
application-specific cores) are pipelined, and usually expose at least certain
aspects of that pipeline to users.

Instruction scheduling involves reordering instructions for these architectures


to make the most efficient use of the associated pipelines. The optimizer uses
three methods for pipeline instruction scheduling:

• branch scheduling
• basic block scheduling
• superscalar scheduling (for certain architecture implementations only)
These are among the most important optimizations for many architectures, and
can increase code speed by 10% or more for the majority of applications.

Example 2. Branch Scheduling and Basic Block Scheduling

For this generic machine example, assume that:

• there is one delay slot after a branch


• at least one instruction is required between a load into a register and the use
of that register
• the last register of a three operand instruction is the destination

642 MULTI: Building Applications for Embedded ARM


General Optimizations

(a) Before Scheduling (b) After Scheduling


1 load r0, 0(r5) load r0, 0(r5)
2 load r1, 4(r6) load r1, 4(r6)
3 add r0, r1, r2 add r7, r8, r9
4 add r7, r8, r9 add r0, r1, r2
5 sub r0, r3, r4 branch L2
6 branch L2 sub r0, r3, r4
7 nop

Branch scheduling consists of two different areas: filling branch delay slots and
filling a delay between a comparison and a branch based on that comparison.

In this example, the branch delay slot is filled when instruction 5 from sequence
(a) is placed in the nop slot after the branch at instruction 6 in sequence (b).
This causes the normally unused cycles after the branch to be used on the
sub instruction.

Certain architectures require a number of cycles to elapse between a comparison


and branch based on that comparison. The method shown above is used to
move one or more instructions between the compare and the branch to make
use of those cycles.

Basic block scheduling is performed within a basic block (a sequence of


instructions which always executes as a group). There are no branches into the
block and only one branch out of the block at the end. The instructions within a
single basic block are sorted so that the new sequence produces the same result
as the original sequence, while minimizing its execution time.

In this example, this change is made by reversing the order of the two add
instructions at lines 3 and 4 between sequence (a) and sequence (b) to allow
for the load delay in instruction 2. This will prevent a stall after the load and
instead use those cycles on the add instruction.

Example 3. Superscalar Scheduling

Scheduling for superscalar implementations involves taking into account the


existence of multiple execution units. Many architectures are now designed with
multiple integer, floating-point, or load-store units in a single implementation.
The compiler can schedule the instructions of these architectures so that the

Green Hills Software, Inc. 643


19. Optimization Descriptions

instructions associated with multiple execution units can execute at the same
time.

For this generic superscalar machine example, assume the same architecture
characteristics as in the previous example and, also, that:

• one integer and one floating-point instruction can be issued in the same cycle
• the floating-point instruction must follow the integer instruction with which
it is paired

This example uses the same instructions as the last example, with the addition
of a floating-point add instruction and a floating-point sub instruction at lines
6 and 7.
(a) Before Scheduling (b) After Scheduling
1 load r0, 0(r5) load r0, 0(r5)
2 load r1, 4(r6) load r1, 4(r6)
3 add r0, r1, r2 add r7, r8, r9
4 add r7, r8, r9 addd f0, f1, f2
5 sub r0, r3, r4 add r0, r1, r2
6 addd f0, f1, f2 subd f3, f2, f4
7 subd f3, f2, f4 branch L2
8 branch L2 sub r0, r3, r4
9 nop

In this example, the two floating-point instructions at lines 6 and 7 from


sequence (a) have been moved to lines 4 and 6 in sequence (b), making the
most efficient use of the multiple instruction issue capability of the integer and
floating-point execution units.

Conditional Instructions
This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→Conditional


Instructions option (-Ocond/-Onocond).

644 MULTI: Building Applications for Embedded ARM


General Optimizations

This optimization is used in situations where blocks of unconditionally executed


instructions are skipped with conditional branches. The compiler may instead
eliminate the branch and execute those instructions conditionally.

Example 4.
Initial Assembly code Optimized Assembly code

equal r0, r1 equal r0, r1


branchtrue L2 loadtrue r3, 12(sp)
load r3, 12(sp) addtrue r2, r3, r2
add r2, r3, r2 addfalse r2, r1, r2
branch L3 load r4, 0(r2)
L2:
add r2, r1, r2
L3:
load r4, 0(r2)

Green Hills Software, Inc. 645


19. Optimization Descriptions

Data Definition Movement


This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→Data


Definition Movement option (-Oinitializers/-Onoinitializers).

This optimization instructs the compiler to take objects which would otherwise
be allocated to uninitialized sections (such as .bss) and put them into
initialized sections (such as .data) when it determines that this will improve
performance and reduce program size.

Example 5.
Initial C source code Optimized C source code

static int a = 1; static int a = 1;


static int b; static int b = 0;

int f() int f()


{ {
int *p = &a int *t = &a
int *q = &b return *t + *(t+1);
return *p + *q; }
}

The optimized code is able to access and load the required data using fewer
instructions.

646 MULTI: Building Applications for Embedded ARM


General Optimizations

Common Subexpression Elimination/Partial Redundancy Elimination


This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→Common


Subexpression Elimination option (-Ocse/-Onocse).

This optimization is implemented when the compiler determines that a


previously calculated expression is part of a later expression and none of the
variable values in the subexpression have changed. The compiler retains the
value of the subexpression in a register for reuse.

Example 6.
Initial C source code Optimized C source code

int subr(int x, int y) int subr(int x, int y)


{ {
int a, b; int a, b, _v6;
x += a+b; x+=(_v6=a+b);
y += a+b; y+=_v6;
if (y < 0) if (y<0)
return (y); return (y);
return (x); return (x);
} }

Partial redundancy elimination is similar to common subexpression elimination,


except that code may be moved in order to make partially redundant expressions
fully redundant. The compiler will choose between these two optimizations as
appropriate.

Green Hills Software, Inc. 647


19. Optimization Descriptions

Tail Recursion
This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→Tail


Recursion option (-Otailrecursion/-Onotailrecursion).

A procedure is considered tail recursive if the last statement executed is a


procedure call to itself followed by a return statement. This optimization
replaces the procedure call with a branch instruction and eliminates the return
statement.

Example 7.
Initial C source code Optimized C source code

int sum(int n) int sum(int n)


{ {
if (n <= 1) int _v3=0;
return (1); L1:
else if (n <= 1)
return (n+ sum(n-1)); return _v3+1;
} _v3 += n;
_n--;
goto L1;
}

648 MULTI: Building Applications for Embedded ARM


General Optimizations

Constant Propagation
This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→Constant


Propagation option (-Oconstprop/-Onoconstprop).

This optimization replaces a variable with a constant, where the compiler


determines that the value of the variable does not change.

Example 8.
Initial C source code Optimized C source code

main() main()
{ {
int i,a,b; int i,b;
a = 3; b = 0;
b = 0; for (i=0; i<1000; i++)
b+=3;
for (i=0;i<1000;i++) { printf("%d\n", b);
b += a; }
/* a is constant over the
lifetime of the loop */
}
printf("%d\n", b);
}

Green Hills Software, Inc. 649


19. Optimization Descriptions

C/C++ Minimum/Maximum Optimization


This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→C/C++


Minimum/Maximum Optimization option (-Ominmax/-Onominmax).

This optimization generates special code for minimum, maximum, and absolute
value expressions of the form:
(i < j) ? i : j
(i > j) ? i : j
(i < 0) ? -i : i

Memory Optimization
This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. To control it individually:

Use the Advanced→Advanced Optimization Options→Memory


Optimization option (-OM/-Onomemory).

Note This optimization assumes that memory locations only change with
explicit store instructions and thus are not affected by any external sources.
Hence, it is not recommended for applications such as device drivers, and
operating systems, in which memory could be externally affected, or for shared
memory or a non-virtual memory environment when interrupts are enabled.

This optimization instructs the compiler to optimize repeated memory reads by


placing the value in a register. Subsequent read operations then refer to the
register rather than the actual memory location.

Note This optimization is only enabled through the


Optimization→Optimization Strategy option for ANSI C and C++. To enable
it when compiling K&R C code, you must set the Advanced→Advanced
Optimization Options→Memory Optimization option to On (-OM).

650 MULTI: Building Applications for Embedded ARM


General Optimizations

To disable memory optimization in ANSI C or C++, use the volatile


keyword to explicitly declare any object that may change without the
compiler’s knowledge or control (see “Type Qualifiers” on page 427), or set
the Advanced→Advanced Optimization Options→Memory Optimization
option to Off (-Onomemory).

Dead Code Elimination


This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. It cannot be controlled
individually. It removes code that computes values which are never used and
eliminates blocks that are determined to be unreachable.

In the following example, after the expression 0*x is constant folded and the
value 0 is constant propagated into the if conditional, this optimization is able
to determine that the then block is unreachable and removes the call foo()
and the return c. Then, it can determine that the value of variable c is no
longer used, and is able to eliminate the expression c = 3 * x.

Example 9.
Initial C source code Optimized C source code

int subr(int x) int subr(int x)


{ {
int a, b, c; int b;
a = 0 * x; b = 2 * x;
b = 2 * x; bar();
c = 3 * x; return b;
if (a) { }
foo();
return c;
} else {
bar();
return b;
}
}

Green Hills Software, Inc. 651


19. Optimization Descriptions

Static Address Elimination


This optimization is generally controlled by the setting you specify in the
Optimization→Optimization Strategy option. It cannot be controlled
individually. It instructs the optimizer to assign frequently used static variables
to registers within the scope of the function. This eliminates the loads and
stores required with memory allocation.

In these examples, the address of the static variable x is maintained in a register.

Example 10.
Initial C source code Optimized C source code

int subr(int q) int subr(int q)


{ {
static int x=0; static int x=0;
x++; register int x_ = x;
q+=x; x_++;
return(q); q+=x_;
} x=x_;
return(q);
}

Note This optimization is performed not only for locally defined static
variables, but also for global variables, as shown in the following example.

Example 11.
Initial C source code Optimized C source code

int x = 0; int x=0;


int subr(int q) int subr(int q)
{ {
x++; register int x_ = x;
q+=x; x_++;
return q; q+=x_;
} x=x_;
return(q);
}

652 MULTI: Building Applications for Embedded ARM


Default Optimizations

Default Optimizations
The optimizations in this section are very basic and are enabled even if no
Optimization→Optimization Strategy is specified.

Register Allocation by Coloring


This optimization is enabled by default. To disable it:

Set the Advanced→Advanced Optimization Options→Register


Allocation by Coloring option to Off (-nooverload).

This optimization permanently maintains a selected set of local scalar variables


in registers, based on their frequency of reference and their lifetimes. The
compiler uses data flow analysis to determine the lifetime of each variable.
The register allocator uses this information to assign different variables within
a function to the same register if the lifetimes of the variables do not overlap.
This increases the opportunity for allocating variables to registers, which in
turn enables the compiler to significantly optimize the code, (since additional
memory load and store instructions are not required to reference the variables).

In the following example, the variables a and b are both assigned to the same
register because their lifetimes do not overlap (note that the code could be
optimized further, but is not here in order to simplify the example).

Example 1.
Initial C source code Optimized C source code

int subr(int x) int subr(int x)


{ {
int a,b; int a;
a=x; a=x;
b=x*2; a=x*2;
return b; return a;
} }

For small functions, the compiler maintains all local variables in registers.
Scalars are generally considered for register allocation unless their values are
accessed with the address operator (&).

Green Hills Software, Inc. 653


19. Optimization Descriptions

Automatic Register Allocation


This optimization is enabled by default. To disable it:

Set the Advanced→Advanced Optimization Options→Automatic


Register Allocation option to Off (-noautoregister).

This optimization enables the automatic allocation of local variables to registers.

Example 2.
Initial C source code Optimized C source code

extern int global; extern int global;


int foo(int e) int foo(int e)
{ {
int local = e; register int local = e;
if (global) if (global)
local = local * 2; local = local * 2;
return local; return local;
} }

Register Coalescing
This optimization is enabled by default and cannot be disabled. It eliminates the
additional register-to-register copies required when using a temporary register.
When evaluating an expression, the compiler uses the destination register as
a work register and organizes the instruction sequence so that the result ends
up in that register.

Example 3.
Initial C source code Optimized C source code

int fun(int a,int b,int c) int fun(int a,int b,int c)


{ {
int ret = a+b+c; return a+b+c;
return ret; }
}

654 MULTI: Building Applications for Embedded ARM


Default Optimizations

Constant Folding
This optimization is enabled by default, and cannot be disabled. If the compiler
determines that an expression is a constant, it substitutes the constant in place
of any reference to the expression. In the following example, the expression
SHRT_MAX/2 is a constant with a value of 16383.

Example 4.
Initial C source code Optimized C source code

#define SHRT_MAX 32767 short subr()


short subr() {
{ int x;
int x; x = 16383;
x=SHRT_MAX/2; return(x);
return(x); }
}

Loop Rotation
This optimization is enabled by default and cannot be disabled. It locates
the termination test and a conditional branch at the bottom of the loop. This
causes the loop to process only one branch instruction on each iteration. Most
compilers place the termination test and an unconditional branch at the top of
the loop and an additional unconditional branch at the bottom.

Example 5.
Initial C source code Optimized C source code

int subr(int i) int subr(int i)


{ {
while (i < 10) goto L7;
i *= i; do {
return(i); i *= i;
} L7:
} while (i < 10);
return(i);
}

Green Hills Software, Inc. 655


19. Optimization Descriptions

If the compiler determines that the loop is executed at least once, it is entered
at the top. If not, the compiler generates an unconditional branch before the
loop to the termination test.

656 MULTI: Building Applications for Embedded ARM


Chapter 20

The ELF File Format

This Chapter Contains:


• Formats of Relocatable and Executable Files
• 32-Bit ELF Data Types
• ELF Headers
• ELF Identification
• ELF Sections
• Symbol Tables
• String Tables
• Program Headers
20. The ELF File Format

This chapter explains the formats of ELF (Executable and Linking Format)
files. Sections of this chapter have been reproduced with permission from
UNIX System Laboratories, Inc. For more information about ELF files, see
System V Application Binary Interface, 1993, UNIX System Laboratories, Inc.,
published by Prentice-Hall, Inc.

Formats of Relocatable and Executable Files


ELF object files are the standard output of the compiler, assembler, and linker.
An ELF file can be either of the following:

• a relocatable object file — which contains program code and data and is
suitable for linking with other object files.
• an executable file — which contains a program suitable for execution.
The following diagram shows the differences in format between these kinds
of ELF files:

Relocatable file Executable file


ELF Header ELF Header
Program Header Program Header
Table (optional) Table
Section 1 Segment 1
. . .
Section n Segment 2
. . .
. . . . . .
Section Header Table Section Header Table
(optional)

Both forms of ELF file begin with an ELF Header, which serves as the table of
contents. All other data and tables in the file may appear in any order.

An executable file must have a Program Header Table, which tells the system
how to load the program. This component is optional in a relocatable file.

658 MULTI: Building Applications for Embedded ARM


32-Bit ELF Data Types

A relocatable file requires a Section Header Table, containing information about


its sections in order to be subsequently linked. Each section has an entry in the
table, giving information such as the section’s name and size. Sections form
the majority of the relocatable object file, and comprise such information as
instructions, data, symbol table, and relocation information.

32-Bit ELF Data Types


The ELF file format supports 32-bit architectures with 8-bit bytes. It must be
modified for 64-bit architectures. ELF files represent some control data with a
machine-independent format to identify object files and interpret their contents.
Part of an ELF file uses the encoding of the target processor, regardless of the
machine on which the file was created:
Type name Size Alignment Purpose
Elf32_Addr 4 4 Unsigned program address
Elf32_Half 2 2 Unsigned medium integer
Elf32_Off 4 4 Unsigned file offset
Elf32_Sword 4 4 Signed large integer
Elf32_Word 4 4 Unsigned large integer
unsigned char 1 1 Unsigned small integer

All data structures that the ELF file format defines follow the usual size and
alignment guidelines for the relevant class. If necessary, data structures contain
explicit padding to ensure 4-byte alignment for 4-byte objects in order to force
structure sizes to a multiple of 4. Data also have suitable alignment from the
beginning of the file. For example, a structure containing Elf32_Addr will
be aligned on a 4-byte boundary within the file.

For portability, ELF data structures use no bitfields.

Green Hills Software, Inc. 659


20. The ELF File Format

ELF Headers
Some ELF file control structures can grow because the ELF header contains
their actual sizes. If the ELF file format changes, a program may encounter
control structures that are larger or smaller than expected. An ELF header is set
by the following C structure declaration:
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;

The fields of struct Elf32_Ehdr are as follows.


e_ident
Identifies the file as an ELF file and provides machine-independent data to decode
the contents. For more information, see “ELF Identification” on page 663.
e_type
Identifies the ELF file type. Permitted values are as follows:
• 0 (ET_NONE): No file type
• 1 (ET_REL): Relocatable file
• 2 (ET_EXEC): Executable file
• 0xFF00 (ET_LOPROC): Begin processor-specific range
• 0xFFFF (ET_HIPROC): End processor-specific range

660 MULTI: Building Applications for Embedded ARM


ELF Headers

e_machine
Specifies the target architecture for an individual file. Permitted values are as
follows:
• 0 (EM_NONE): Invalid machine
• 2 (EM_SPARC): Sun SPARC
• 3 (EM_386): Intel 80386
• 4 (EM_68K): Motorola 68000
• 6 (EM_486): Intel 80486
• 8 (EM_MIPS): MIPS
• 19 (EM_960): Intel i960
• 20 (EM_PPC): PowerPC
• 36 (EM_V800): NEC V800 series
• 37 (EM_FR20): Fujitsu FR
• 40 (EM_ARM): ARM
• 42 (EM_SH): Hitachi SH
• 44 (EM_TRICORE): Infineon TriCore
• 52 (EM_COLDFIRE): Motorola ColdFire
• 54 (EM_MCORE): Motorola MCore
• 58 (EM_STARCORE): Motorola StarCore
• 60 (EM_ST100): STMicroelectronics ST100
• 78 (EM_FIREPATH): Broadcom FirePath
• 79 (EM_ZSP): LSI ZSP
• 88 (EM_M32R): Renesas M32R
• 106 (EM_BLACKFIN): ADI Blackfin
e_version
Identifies the ELF file version. Permitted values are as follows:
• 0 (EV_NONE): Invalid version
• 1 (EV_CURRENT): Current version
The value 1 (one) signifies the original file format; extensions will create new
versions with higher numbers.
e_entry
Specifies the virtual address to which the system first transfers control upon
starting the process. If the file has no associated entry point, this field contains
the value zero.

Green Hills Software, Inc. 661


20. The ELF File Format

e_phoff
Specifies the program header table’s file offset in bytes. If the file has no program
header table, this field contains the value zero.
e_shoff
Specifies the section header table’s file offset in bytes. If the file has no section
header table, this field contains the value zero.
e_flags
Specifies processor-specific flags associated with the file. Flag names take the
form EF_machine_flag.
• 0x00080000 (EF_ARM_FHARD): Hardware floating point
• 0x00040000 (EF_ARM_THUMB): Thumb instruction encoding
• 0x00020000 (EF_ARM_V4): Version 4 instruction architecture
• 0x00010000 (EF_ARM_V5): Version 5 instruction architecture
• 0x0000ff000 (EF_ARM_CPU_MASK): Processor variant mask
e_ehsize
Specifies the ELF header size in bytes.
e_phentsize
Specifies the size in bytes of one entry in the file’s program header table; all
entries are the same size.
e_phnum
Specifies the number of entries in the program header table. The product of
e_phentsize and e_phnum specifies the table’s size in bytes. If a file has no
program header table, e_phnum contains the value zero.
e_shentsize
Specifies the section header’s size in bytes. A section header is one entry in the
section header table; all entries are the same size.
e_shnum
Specifies the number of entries in the section header table. The product of
e_shentsize and e_shnum specifies the section header table’s size in bytes. If
a file has no section header table, this field contains the value zero.
e_shstrndx
Specifies the index of the section containing the string table used for section
names. By convention, this is the section .shstrtab. If the file has no section
name string table, this field contains the value SHN_UNDEF.

662 MULTI: Building Applications for Embedded ARM


ELF Identification

ELF Identification
ELF provides a file framework to support multiple processors, multiple data
encodings, and multiple classes of machines. To support this file family, the
initial bytes of the file specify how to interpret the file, independent of the
processor on which the inquiry is made and independent of the file’s remaining
contents.

The initial bytes of an ELF header correspond to the e_ident member. The
identification indexes are tabulated below:
Index name Value Meaning
EI_MAG0 to 0 to 3 File identification
EI_MAG3
EI_CLASS 4 File class
EI_DATA 5 Data encoding
EI_VERSION 6 File version
EI_PAD 7 Start of padding bytes
EI_NIDENT 16 Size of e_ident[]

These indexes access bytes that contain the following values:


EI_MAG0 to EI_MAG3
A file’s first 4 bytes identify the file as ELF as follows:
• e_ident[EI_MAG0]: 0x7F (ELFMAG0)
• e_ident[EI_MAG1]: ’E’ (ELFMAG1)
• e_ident[EI_MAG2]: ’L’ (ELFMAG2)
• e_ident[EI_MAG3]: ’F’ (ELFMAG3)
EI_CLASS
This byte identifies the file’s class, or capacity. The file format is portable among
machines of various sizes; it does not impose the size of the largest machine on
the smallest. Permitted values are as follows:
• 0 (ELFCLASSNONE): Invalid class
• 1 (ELFCLASS32): 32-bit objects. Supports machines with files and virtual
address spaces up to 4 Gigabytes. It uses the basic types defined above.
• 2 (ELFCLASS64): 64-bit objects. Reserved for 64-bit architectures. Its
appearance here shows how the file format may change, but the 64-bit
format is otherwise unspecified. Other classes are defined as necessary, with
different basic types and sizes for file data.

Green Hills Software, Inc. 663


20. The ELF File Format

EI_DATA
This byte specifies the data encoding of the processor-specific data in the file.
Permitted values are as follows:
• 0 (ELFDATANONE): Invalid data encoding
• 1 (ELFDATA2LSB): Specifies 2’s complement values, with the least significant
byte occupying the lowest address.
• 2 (ELFDATA2MSB): Specifies 2’s complement values, with the most significant
byte occupying the lowest address.
Other values are reserved and are assigned to new encodings as necessary.
EI_VERSION
This byte specifies the ELF header version number. Currently, this value must be
EV_CURRENT, as explained above for e_version.
EI_PAD
This value marks the beginning of the unused bytes in e_ident. These bytes are
reserved and set to zero; programs that read ELF files should ignore them. The
value of EI_PAD changes if currently unused bytes are given meanings.
EI_NIDENT
This value specifies the size of e_ident[].

ELF Sections

Section Headers
You can use an ELF file’s section header table to locate all the file’s sections.
The section header table is an array of Elf32_Shdr structures. A section
header table index is a subscript into this array. The ELF header e_shoff
specifies the byte offset from the beginning of the file to the section header
table; e_shnum tells how many entries the section header table contains; and
e_shentsize specifies the size in bytes of each entry.

Sections contain all information in a file except the ELF header, the program
header table, and the section header table. Sections satisfy several conditions:

• Every section in an ELF file has exactly one section header describing it.
Section headers may exist that do not have an associated section.
• Each section occupies one contiguous (possibly empty) sequence of bytes
within a file.

664 MULTI: Building Applications for Embedded ARM


ELF Sections

• Sections in a file may not overlap. No byte in a file resides in more than
one section.
• An ELF file may have inactive space. The various headers and the sections
might not account for every byte in a file. The contents of the inactive space
are unspecified.

A section header has the following structure:


typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;

The fields of struct Elf32_Shdr are as follows.


sh_name
Specifies the name of the section. Its value is an index into the section header
string table section and specifies the location of a null-terminated string.
sh_type
Specifies the section’s contents and semantics. For more information, see
“Section Attribute Flags” on page 667.
sh_flags
Specifies 1-bit flags that describe miscellaneous attributes of the section.
sh_addr
Specifies the address at which the section’s first byte should reside if the section
appears in the memory image of a process. Otherwise, this field contains zero.
sh_offset
Specifies the byte offset from the beginning of the file to the first byte in the section.
sh_size
Specifies the section’s size in bytes. Unless the section type is SHT_NOBITS, the
section occupies sh_size bytes in the file. A section of type SHT_NOBITS may
have a non-zero size, but it occupies no space in the file.

Green Hills Software, Inc. 665


20. The ELF File Format

sh_link
Contains a section header table index link, whose interpretation depends on the
section type.
sh_info
Contains extra information, whose interpretation depends on the section type.
sh_addralign
Some sections have address alignment constraints. For example, if a section
contains a doubleword, the system may need to ensure doubleword alignment
for the entire section. That is, the value of sh_addr must be equal to 0 (zero),
modulo the value of sh_addralign. Currently, only 0 (zero) and positive integral
powers of two are allowed. The values 0 (zero) and 1 (one) mean the section
has no alignment constraints.
sh_entsize
Some sections contain a table of fixed-size entries, such as a symbol table. For
such sections, this field specifies the size in bytes of each entry. This structure
contains zero if the section does not contain a table of fixed-sized entries.

Special Section Indexes


Symbol table entries index the section table through the st_shndx field. See
“Symbol Tables” on page 674.
Name Value Meaning
SHN_UNDEF 0 A meaningless section. A symbol “defined”
relative to this section is an undefined
symbol.
SHN_COMMON -14 Common, or .bss, symbols are allocated
space in this section.
SHN_ABS -15 Contents of the section are absolute values;
they are not affected by relocation.
SHN_GHS_SMALLCOMMON -256 Not available for all processors. Similar to
SHN_COMMON, but for a limited number of
small variables allocated to SDA.
SHN_GHS_ZERO_COMMON -255 Not available for all processors. Similar to
SHN_COMMON, but for a limited number of
small variables allocated to ZDA.
SHN_GHS_TINYCOMMON -254 Not available for all processors. Similar to
SHN_COMMON, but for a limited number of
small variables allocated to TDA.

666 MULTI: Building Applications for Embedded ARM


ELF Sections

Note Although index 0 is reserved as an undefined value, the section header


table does contain an entry for it.

Section Types
A section header’s sh_type specifies the section’s semantics as follows:
Name Value Meaning
SHT_NULL 0 Marks the section header as inactive. It does not
have an associated section. Other members of the
section header have undefined values.
SHT_PROGBITS 1 Contains information defined by the program that
created the ELF file, whose format and meaning
are determined solely by the program.
SHT_SYMTAB 2 Contains a symbol table. An object file may have
only one section of this type, but this restriction
may be relaxed in the future. The table provides
symbols for link editing, though it may also be
used for dynamic linking. As a complete symbol
table, it may contain many symbols unnecessary
for dynamic linking.
SHT_STRTAB 3 Contains a string table. A file may have multiple
string table sections.
SHT_RELA 4 Contains relocation entries with explicit addends,
such as type Elf32_Rela for the 32-bit class
of ELF files. A file may have multiple relocation
sections.
SHT_NOTE 7 Contains notes that flag this ELF file indicating
certain properties.
SHT_NOBITS 8 Occupies no space in the file but otherwise
resembles SHT_PROGBITS.
SHT_REL 9 Contains relocation entries without explicit
addends, such as type Elf32_Rel for the
32-bit class of ELF files. A file may have multiple
relocation sections.

Section Attribute Flags


A section header’s sh_flags field contains 1-bit flags that describe the
section’s attributes.

Green Hills Software, Inc. 667


20. The ELF File Format

Name Value Meaning


SHF_WRITE 0x1 Contains data that should be writable during
process execution.
SHF_ALLOC 0x2 Occupies memory during process execution.
Some control sections do not reside in the
memory image of the final application; this
attribute is off for those sections.
SHF_EXECINSTR 0x4 Contains execution machine instructions.
SHF_GHS_ABS 0x400 Has an absolute, non-relocatable address.
SHF_GHS_BSS 0x800 Contains uninitialized data.
SHF_FIREPATH 0x10000000 Contains FNSC compressed machine
_FNSC instructions (only meaningful when
SHF_EXECINSTR is also present)

Two structures in the section header, sh_link and sh_info, contain special
information, depending on section type as follows:
sh_type sh_link sh_info
SHT_REL The section header index of the The section header index of the
associated symbol table. section to which the relocation
SHT_RELA
applies.
SHT_SYMTAB The section header index of the One greater than the symbol
associated string table. table index of the last local
symbol (binding STB_LOCAL).
other SHN_UNDEF 0

Section Names
Section names beginning with a period (.) are not meant for general use by
application programs, although application programs may use these sections if
their existing meanings are satisfactory. Application programs may use names
without the leading period to avoid conflicts with predefined section names.

Frequently Used Sections


Some sections contain program and control information. Sections in the
following list have predefined meanings, with the indicated types and attributes.

668 MULTI: Building Applications for Embedded ARM


ELF Sections

.bss
Contains uninitialized data that contributes to the program’s memory image. The
system initializes the data with zeros when the program begins to run.
Type: SHT_NOBITS
Attributes: SHF_ALLOC | SHF_WRITE
.data
Contains initialized data that contributes to the program’s memory image.
Type: SHT_PROGBITS
Attributes: SHF_ALLOC | SHF_WRITE
.linfix
When using Code Factoring or fixing “out of range relocations” inline, the assembly
becomes out of sync with the debugging information. The linker notes the changes
to the program that require updates to the debugging information in the .linfix
section. MULTI merges the information in the .dla file and the .linfix section
when debugging the program.
The .linfix section is not downloaded to the target.
Type: SHT_PROGBITS
Attributes: None
.relname
.relaname
These sections contain relocation information. If the file has a loadable segment
that includes relocation, the attributes of the sections include the SHF_ALLOC bit;
otherwise, that bit will be off. Conventionally, name is supplied by the section
to which the relocations apply. A relocation section for .text has the name
.rel.text or .rela.text.
Types: SHT_REL and SHT_RELA
Attributes: SHF_ALLOC or none
.rodata
Read-only data area. Similar to the .data section, but comprised of constant data.
Type: SHT_PROGBITS
Attributes: SHF_ALLOC
.shstrtab
Contains section names.
Type: SHT_STRTAB
Attributes: None

Green Hills Software, Inc. 669


20. The ELF File Format

.strtab
Contains strings, most commonly the strings that represent the names associated
with symbol table entries. If the file has a loadable segment that includes the
symbol string table, the section’s attributes include the SHF_ALLOC bit; otherwise,
that bit will be off.
Type: SHT_STRTAB
Attributes: SHF_ALLOC or none
.symtab
Contains a symbol table. If the file has a loadable segment that includes the
symbol table, the section’s attributes include the SHF_ALLOC bit; otherwise, that
bit will be off.
Type: SHT_SYMTAB
Attributes: SHF_ALLOC or none
.text
Contains the text, or executable instructions, of a program.
Type: SHT_PROGBITS
Attributes: SHF_ALLOC | SHF_EXECINSTR

Some sections are specific to Green Hills ELF; these are listed in the following
table. Target processors may support some or all of these sections.
.syscall
A program code section to support the Green Hills system call mechanism.
Type: SHT_PROGBITS
Attributes: SHF_EXECINSTR | SHF_ALLOC
.secinfo
A table, created by the linker, that describes actions to be taken on sections as
they are loaded for program execution (sections to be cleared, copied from ROM
to RAM, and so on).
Type: SHT_PROGBITS
Attributes: SHF_ALLOC

670 MULTI: Building Applications for Embedded ARM


ELF Sections

.fixaddr
.fixtype
Tables created by the compiler for position independent code (PIC) and position
independent data (PID) static pointer adjustments to be made when the program
is loaded for execution.
Type: SHT_PROGBITS
Attributes: SHF_ALLOC
.sdabase
If not in PID mode, the run-time system initializes the Small Data Area (SDA) base
register to be the address of this section (.sdabase).
Type: SHT_NULL
Attributes: SHF_ALLOC
.sdata
.zdata
Initialized Small Data Area and Zero Data Area. Similar to the .data section, but
of limited size and more efficiently addressed.
Type: SHT_PROGBITS
Attributes: SHF_ALLOC | SHF_WRITE
.sbss
.zbss
Uninitialized Small Data Area and Zero Data Area. Similar to the .bss section,
but of limited size and more efficiently addressed.
Type: SHT_PROGBITS
Attributes: SHF_ALLOC | SHF_WRITE
.heap
Section describing the area of memory for dynamic allocations through malloc
and related functions.
Type: SHT_NOBITS
Attributes: SHF_ALLOC | SHF_WRITE
.stack
Section describing the area of memory that the program stack will occupy.
Type: SHT_NOBITS
Attributes: SHF_ALLOC | SHF_WRITE

Green Hills Software, Inc. 671


20. The ELF File Format

Relocation Types
Relocation is the process of connecting symbolic references with symbolic
definitions. For example, when a program calls a function, the associated call
instruction must transfer control to the proper destination address at execution.
Relocatable files must have information that describes how to modify their
section contents, thus allowing executable files to contain the right information
for a process’s program image. Relocation entries contain this information. In
the code below, example 2 is preferred:

Example 1.
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;

Example 2.
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;

r_offset
Specifies the location at which to apply the relocation action. For a relocatable file,
the value is the byte offset from the beginning of the section to the storage unit
affected by the relocation. For an executable file or a shared object, the value of
which is the virtual address of the storage unit affected by the relocation.
r_info
Specifies both the symbol table index with respect to which the relocation must
be made and the type of relocation to apply information for a process’s program
image. For example, a call instruction’s relocation entry contains the symbol table
index of the function being called. You may find the following macros helpful when
reading from or writing to the r_info field:

#define ELF32_R_SYM(i) ((i) >> 8)


#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s)<<8) + (unsigned char) (t))

r_addend
Specifies a constant value used to compute the final value to be stored into the
relocatable field.

672 MULTI: Building Applications for Embedded ARM


ELF Sections

A relocation section references two other sections: a symbol table and a section
to modify. The section header’s sh_link and sh_info specify these
sections.

Green Hills Software, Inc. 673


20. The ELF File Format

Symbol Tables
The symbol table of an ELF file contains information to locate and relocate
a program’s symbolic definitions and references. A symbol table index is a
subscript into this array. Index 0 (zero) both designates the first entry in the
table and serves as the undefined symbol index. The contents of the initial entry
are specified below. A symbol table entry has the following format:
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
} Elf32_Sym;

where:
st_name
Contains an index into the file’s symbol string table. The string table contains the
character representations of the symbol names. If this field is non-zero, then it
represents a string table index that specifies the symbol name. Otherwise, the
symbol table entry has no name.
st_value
Specifies the associated symbol’s value. Depending on the context, this may be
an absolute value, an address, and so on.
st_size
Many symbols have associated sizes. For example, a data object’s size is the
number of bytes contained in the object. This field is zero if the symbol has no
size or an unknown size.
st_info
Specifies the symbol’s binding attributes and type, as explained in the symbol
binding and symbol type sections below. The values and meanings are defined
below:

#define ELF32_ST_BIND(i) ((i)>>4)


#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))

st_other
The least significant bit is set to indicate thumb mode functions, and clear for
ARM mode.

674 MULTI: Building Applications for Embedded ARM


Symbol Tables

st_shndx
Every symbol table entry is “defined” in relation to some section; this field contains
the relevant section header table index. Some section indexes indicate special
meanings. For more information, see “Special Section Indexes” on page 666.

Symbol Binding
A symbol’s binding determines the linkage visibility and behavior.
Name Value Attributes
STB_LOCAL 0 Local symbols are not visible outside the object file
containing their definition. Local symbols of the same
name may exist in multiple files without interfering with
each other.
STB_GLOBAL 1 Global symbols are visible to all object files being
combined. One file’s definition of a global symbol will
satisfy another file’s undefined reference to the same
global symbol.
STB_WEAK 2 Weak symbols resemble global symbols, but their
definitions have lower precedence.
STB_LOPROC 13 Values in this inclusive range (from STB_LOPROC to
STB_HIPROC) are reserved for processor-specific
STB_HIPROC 15
semantics. If meanings are specified, the processor
supplement explains them.

Symbol Type
A symbol’s type provides a general classification for the associated entity.
Name Value Attributes
STT_NOTYPE 0 The symbol’s type is not specified.
STT_OBJECT 1 The symbol is associated with a data object, such as a
variable, array, and so on.
STT_FUNC 2 The symbol is associated with a function or other
executable.
STT_SECTION 3 The symbol is associated with a section. Symbol table
entries of this type exist primarily for relocation and
normally have STB_LOCAL binding.

Green Hills Software, Inc. 675


20. The ELF File Format

Name Value Attributes


STT_FILE 4 By convention, this symbol names the source file
associated with the object file. For this symbol, the
binding is STB_LOCAL and the section index is SHN_ABS.
All STT_FILE symbols precede any other STB_LOCAL
symbols.
STT_LOPROC 13 Values in this inclusive range (from STT_LOPROC to
STT_HIPROC) are reserved for processor-specific
STT_HIPROC 15
semantics. If meanings are specified, the processor
supplement explains them.

Symbol Values
Symbol table entries for different ELF file types have slightly different
interpretations for the st_value member:

• In relocatable files, st_value contains alignment constraints for a symbol


whose section index is SHN_COMMON.
• In relocatable files, st_value contains a section offset for a defined
symbol. That is, st_value is an offset from the beginning of the section
that st_shndx identifies.
• In executable files, st_value contains a virtual address. To make
these symbols more useful for the dynamic linker, the section offset (file
interpretation) gives way to a virtual address (memory interpretation) for
which the section number is irrelevant.

Although the symbol table values have similar meanings for different file types,
the information allows efficient access by the appropriate programs.

676 MULTI: Building Applications for Embedded ARM


String Tables

String Tables
String table sections contain null-terminated character sequences or strings.
These strings are used to represent symbol and section names. An empty
string table section is permitted; its section header’s sh_size contains zero.
Non-zero indexes are invalid for an empty string table. If the string table is
not empty, you can reference a string as an index into the string table section.
The first byte, which is index 0 (zero), contains a null character. Likewise, a
string table’s last byte contains a null character to ensure null termination for
all strings. A string whose index is 0 (zero) specifies either no name or a null
name, depending on the context.

A section header’s sh_name contains an index into the section header string
table (See the e_shstrndx field in “ELF Headers” on page 660). The
following figures show a string table with 25 bytes and the strings associated
with various indexes:
Index +0 +1 +2 +3 +4 +5 +6 +7 +8 +9
0 \0 n a m e . \0 V a r
10 i a b l e \0 a b l e
20 \0 \0 x x \0

The string table indexes are:


Index String
0 none
1 name.
7 Variable
11 able
16 able
24 null string

A string table index may refer to any byte in the section. A string may appear
more than once; references to substrings may exist, and a single string may be
referenced multiple times. Strings that are not referenced are also allowed.

Green Hills Software, Inc. 677


20. The ELF File Format

Program Headers
An ELF executable file’s program header table is an array of structures, each
describing a segment or other information the system needs to prepare the
program for execution. A file segment contains one or more sections. Program
headers are defined only for executable files. A file specifies its own program
header size with the ELF header’s e_phentsize and e_phnum.
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;

p_type
The kind of segment this array element describes and how to interpret the array
element’s information. For more information, see “Program Types” on page 679.
p_offset
Offset from the beginning of the file at which the first byte of the segment resides.
p_vaddr
Address at which the first byte of the segment resides in memory.
p_paddr
This field is currently unused and is set to zero by the linker.
p_filesz
Number of bytes in the file image of the segment; it may be zero.
p_memsz
Number of bytes in the memory image of the segment; it may be zero.
p_flags
Flags relevant to the segment. For more information, see “Program Attribute
Flags” on page 680.

678 MULTI: Building Applications for Embedded ARM


Program Headers

p_align
Loadable process segments must have congruent values for p_vaddr and
p_offset, modulo the page size. This field specifies the value to which the
segments are aligned in memory and in the file. Values 0 and 1 mean no
alignment is required. Otherwise, p_align should be a positive, integral power of
2, and p_vaddr should equal p_offset, modulo p_align.

Program Types
A program header’s p_type specifies the program’s semantics as follows:
Name Value Meaning
PT_NULL 0 The array element is unused; other member values
are undefined. This type lets the program header
table have ignored entries.
PT_LOAD 1 The array element specifies a loadable segment,
described by p_filesz and p_memsz. The bytes
from the file are mapped to the beginning of the
memory segment. If the segment’s memory size
(p_memsz) is larger than the file size (p_filesz),
the “extra” bytes are defined to hold the value 0
and to follow the segment’s initialized area. The
file size may not be larger than the memory size.
Loadable segment entries in the program header
table appear in ascending order, sorted on the
p_vaddr member.
PT_DYNAMIC 2 The array element specifies dynamic linking
information.
PT_INTERP 3 The array element specifies the location and size
of a null-terminated pathname to invoke as an
interpreter. This segment type is meaningful only
for executable files (though it may occur for shared
objects); it may not occur more than once in a file. If
it is present, it must precede any loadable segment
entry.
PT_NOTE 4 The array element specifies the location and size
of auxiliary information.
PT_SHLIB 5 This segment type is reserved but has unspecified
semantics.

Green Hills Software, Inc. 679


20. The ELF File Format

Name Value Meaning


PT_PHDR 6 The array element, if present, specifies the location
and size of the program header table itself, both in
the file and in the memory image of the program.
This segment type may not occur more than once
in a file. Moreover, it may occur only if the program
header table is part of the memory image of the
program. If it is present, it must precede any
loadable segment entry.
PT_LOPROC 0x70000000 Reserved for processor-specific semantics.
to to
PT_HIPROC 0x7fffffff

Program Attribute Flags


A program to be loaded by the system must have at least one loadable segment
(although this is not required by the file format). When the system creates
loadable segment memory images, it gives access permissions as specified
in the p_flags member. All bits included in the PF_MASKPROC mask are
reserved for processor-specific semantics.
Name Value Meaning
PF_X 0x1 Execute
PF_W 0x2 Write
PF_R 0x4 Read
PF_MASKPROC 0xf0000000 Unspecified

If a permission bit is 0, that type of access is denied. Actual memory


permissions depend on the memory management unit, which may vary from
one system to another. Although all flag combinations are valid, the system may
grant more access than requested. However, a segment will never have write
permission unless it is specified explicitly. The following table shows both the
exact flag interpretation and the allowable flag interpretation.
Flag Value Exact Allowable
(none) 0 All access denied All access denied
PF_X 1 Execute only Read, execute
PF_W 2 Write only Read, write, execute

680 MULTI: Building Applications for Embedded ARM


Program Headers

Flag Value Exact Allowable


PF_W+PF_X 3 Write, execute Read, write, execute
PF_R 4 Read only Read, execute
PF_R+PF_X 5 Read, execute Read, execute
PF_R+PF_W 6 Read, write Read, write, execute
PF_R+PF_W+PF_X 7 Read, write, execute Read, write, execute

For example, typical text segments have read and execute - but not write -
permissions. Data segments normally have read, write, and execute permissions.

Green Hills Software, Inc. 681


20. The ELF File Format

682 MULTI: Building Applications for Embedded ARM


Index

* (asterisk) wildcard character, 35 Additional Linker Options (after .ld


* (pointer) data type files) Builder option, 185, 278
signedness, 164 Additional Linker Options (before .ld
= assignment operator, 471 files) Builder option, 184
! not operator, 465 Additional Output Files Builder
? operator, 465, 471 option, 201
? wildcard character, 35 addr linker expression function, 296
-# driver option, 76 address operator
&& logical and operator, 465 assembler, 263
|| logical or operator, 465 Advanced Build Builder menu item, 229
64-bit integer arguments, 86, 557 Advanced Builder menu item, 227
.align assembler directive, 266
A align linker expression function, 296
-a driver option, 93, 147 alignment
-A driver option, 188 bitfields, 430
.a file extension, 32, 70, 314 requirements, 597
-a linker option, 280 type double, 520
-A linker option, 280 -allabsolute linker option, 280
About MULTI Project Builder Builder Allocation of Uninitialized Global
menu item, 237 Variables Builder option, 166, 530 to
ABS linker section attribute, 292 531
absolute expressions, 252 Allow C++ Style Slash Comments in C
absolute linker expression Builder option, 153, 461
function, 296 -allow_bad_relocations linker option, 280
Add File After selected file Builder menu Alternate Assembler Directory Builder
item, 225 option, 202
Add File Into selected file Builder menu Alternate Compiler Directory Builder
item, 226 option, 202
Additional Assembler Options Builder Alternate Library Directory Builder
option, 181, 243 option, 202
Additional Intex Options Builder Alternate Linker Directory Builder
option, 139 option, 202

Green Hills Software, Inc. 683


Index
Alternate Tools Directory Builder arithmetic
option, 202 machine specific, 604
Alternative C++ Tokens Builder ARM
option, 167 mixed with thumb mode, 102
--alternative_tokens driver option, 167 __ARM, 516
-alttools driver option, 202 ARM compliant C++, 472
Anachronism Support Builder --arm driver option, 152, 464, 472
option, 170 ARM DSP extensions
--anachronisms driver option, 170 using intrinsic functions, 538
and operator, 466 .arm file extension, 32, 70
Annotated C++ Reference Manual, The ARM Ltd. assembler directives
(ARM), 472 AREA, 260
ANSI Aliasing Rules Builder option, 153 MACRO, 263
ANSI C ARM Ltd. assembly compatibility, 256
extensions, 407 directive support, 259
implementation-defined features, 441 expression support, 258
to 447, 450 to 456 invoking with the assembler, 256
library, 436 invoking with the driver, 256
limitations, 429 syntax support, 257
required macro names, 512 variable support, 258
ANSI C and Standard C++ Extensions ARM UK Assembler Compatibility
Builder option, 212 Builder option, 181, 256
-ansi driver option, 151, 406 to 407, 427 ARM UK Assembler Predefines Builder
-ANSI driver option, 151, 212, 406, 409, option, 181
427 ARM UK Internal Variables Builder
ansi header file directory, 549 option, 181
-ansi_alias driver option, 153 __ARM_DSP, 516
--any_output_suffix driver option, 199 -arm_uk_asm driver option, 181, 256
-apcs assembler option, 257 arm3 library directory, 549
-apcs driver option, 181, 257 arm3b library directory, 549
Append Default Extension to Output arm3p library directory, 549
Filename Builder option, 200 arm3pb library directory, 549
-append linker option, 280 arm4 library directory, 549
Append String to Every Section Name arm4b library directory, 549
Builder option, 217 arm4p library directory, 549
:appendExtension Builder option, 200 arm4pb library directory, 549
-archive driver option, 72 to 73, 314 arm5 library directory, 550
archiver, see librarian arm5b library directory, 550
archives, see libraries arm5p library directory, 550
argument field, 249 arm5pb library directory, 550
argument-dependent lookup, 468 armfp library directory, 550

684 MULTI: Building Applications for Embedded ARM


Index
armfpb library directory, 550 #pragma, 527
armfpp library directory, 550 asm statements
armfppb library directory, 550 overview, 434
-armuk assembler option, 256 Asm Statements Builder option, 193, 426,
armvfp library directory, 550 435
armvfpb library directory, 550 --asm_errors driver option, 193, 435
armvfpp library directory, 550 --asm_silent driver option, 193, 426, 435
armvfppb library directory, 550 --asm_warnings driver option, 193, 435
array -asmcmd driver option, 182, 243
new and delete, predefined assembler, 242
macro, 522 assignment statements, 250
--array_new_and_delete driver command line options for, 244
option, 170 escape sequences, 248
__ARRAY_OPERATORS, 522 introduction to, 10
asarm, see assembler invoking with the Builder, 99
.ascii assembler directive, 268 invoking with the driver, 99
.asciiz assembler directive, 268 passing options to compiler driver, 243
-asm driver option, 181, 243 running with compiler driver, 242
asm facility, 612 syntax, 245
asm body, 618 Assembler Command File Builder
asm macro, 613 option, 182, 243
con, 617 assembler directives
error, 617 .align, 266
examples, 613 .ascii, 268
farmem, 618 .asciiz, 268
farsprel, 617 .byte, 268
lab, 617 .comm, 274
macro body, 613 .data, 272
mem, 617 .double, 268
nearmem, 618 .dsect, 274
pattern, 613 .else, 267
reg, 618 .elseif, 267
storage mode, 613 .end, 274
treg, 617 to 618 .endif, 267
ureg, 618 .endm, 271
using asm macros, 615 .endr, 272
writing asm macros, 620 .equ, 274
.asm file extension, 32, 70 .exitm, 271
asm keyword, see asm statements .export, 274
__asm keyword, see asm statements .file, 275
asm statement .float, 268

Green Hills Software, Inc. 685


Index
.ghsnote, 309 -source, 244
.global, 274 -stack_debug, 244
.half, 268 -v, 244
.ident, 276 -w, 244
.if, 267 Assembler Warnings Builder option, 216
.import, 274 --assembler_warnings driver option, 216
.include, 269 assembly language, 245
.lcomm, 274 assignment statements, 250
.lsbss, 274 character set for, 245
.ltorg, 272 comments, 249
.macro, 271 constants for, 247
.macrolabel, 271 continuation lines, 250
.need, 276 escape sequences for, 248
.nodebug, 275 expression types, 252
.note, 272 expressions, 250
.nothumb, 276 identifiers for, 246
.org, 272 interface, 602
.previous, 272 interleaving with source code, 180
.rept, 272 labels, 253
.rodata, 273 line terminators, 250
.sbss, 275 linker requirements, 102
.section, 273 operator precedence, 251
.set, 250, 275 operators, 251
.size, 275 source statement syntax, 249
.space, 268 type combinations, 252
.string, 268 assignment statements, assembler, 250
.text, 273 Atmel AT91
.thumb, 276 establishing interrupt vectors, 121
.weak, 275 Atria, Inc., 491
.word, 269 --auto_instantiation driver option, 174
assembler options Auto-Instantiation of Templates Builder
-apcs, 257 option, 174, 177, 492 to 493
-armuk, 256 Auto-Interrupt Table Builder option, 131
-cpu, 244 -auto_interrupt_table driver option, 131
@file, 244 Automatic Register Allocation Builder
-fpu, 244 option, 204, 654
-help, 244 automatic register allocation
-I, 244 optimization, 654
-list, 244 automatic two-pass inlining, 628
-o, 244 -autoregister driver option, 204
-pd, 256 ax, see librarian

686 MULTI: Building Applications for Embedded ARM


Index
B Build Settings window, 231
__BASE__, 521 building projects, 62
__BASE_FILE__, 522 Connect menu, 232
__BIG_ENDIAN__, 516 controlling the assembler with, 99
-bigendian driver option, 131 controlling the linker with, 100
-bigswitch driver option, 197 creating a new project, 24
binary code generation, 10, 198 Debug menu, 233
Binary Code Generation Builder Edit menu, 225
option, 198 File menu, 224
binary operators, 251 File Shortcut Bar, 63
Binary Output Directory Relative to Help menu, 237
This File Builder option, 199 libraries, 36
Binary Output Directory Relative to linker directives files, working with, 43
Top-Level Project Builder option, 199 main window, 20
:binDir Builder option, 199 option types, 50
:binDirRelative Builder option, 199 Options window, 50 to 58
bitand operator, 466 overview, 23
bitfields, 85, 429, 599 searching for options in, 58
alignment and size, 430 setting options in, 50
code efficiency, 429 Source pane, 31
portability, 599 starting, 20, 22
signedness, 164 Target Selector dialog box, 228
signedness of, 429 Tools menu, 234
.bmon Output File Types, 74 Utility Program Launcher dialog
_BOOL, 522 box, 236
bool data type, 466, 522 Windows menu, 236
--bool driver option, 169, 522 working with project files, 31
Bool Type Support Builder option, 169 Builder menu items
Brief Error Message Mode Builder About MULTI Project Builder, 237
option, 192 Add File After selected file, 225
--brief_diagnostics driver option, 192 Add File Into selected file, 226
__BSD, 521 Advanced, 227
-bsp driver option, 89 Advanced Build, 229
.bss program section, 106, 669 Build Ignoring Errors selected
Build Ignoring Errors selected file file, 229
Builder menu item, 229 Build selected file, 229
Build selected file Builder menu item, 229 Check In, 234
Builder Check In + Out, 234
Advanced Build window, 230 Check Out, 234
Build menu, 229 Checkout Browser, 234
Build Progress window, 62 Clean all output before building, 230

Green Hills Software, Inc. 687


Index
Clean selected file, 229 Print Current View, 224
Clear Default Configuration, 234 Print Expanded Project, 224
Close Project, 224 Rebuild selected file, 229
CodeBalance selected program, 235 Recent Files, 224
Configuration, 234 Recent Projects, 224
Connect, 232 Remove selected file, 226
Connection Organizer, 232 Retrieve, 234
Contract All Within selected file, 227 Revert to Saved Project, 224
Convert Legacy project, 235 Save Configuration, 234
Create File, 225 Save Configuration as Default, 234
Create Subproject, 225 Save Project, 224
Debug Other Executable, 233 Search in selected file, 226
Debug selected program, 233 Set Build Macros, 226
Discard Changes, 234 Set Build Target, 226
Disconnect Target, 232 Set Imported Environment
Edit, 225 Variables, 227
Editor, 235 Set Options, 225
Execute tools at low priority, 231 to Set Options in Parent, 227
232 Set Type, 225
Exit, 225 Settings, 229
Expand All Within selected file, 227 Show build without execution, 231
Flash selected program, 235 Show Full Paths, 226
Force link, 230 Show History, 234
Graphically Edit, 225 Show internal commands, 231
Highlight Selections, 226 Show tool commands, 231 to 232
Ignore build errors, 230 Simplify All Filenames, 227
Ignore dependencies, 231 Start Launcher, 235
Load Configuration, 234 Stop after cleaning output, 230
Load Module, 232 Task Window, 232
Manuals, 237 Troubleshooting Info, 237
MULTI Project Builder Help, 237 Use lock files, 231 to 232
New Project, 224 Use Utilities, 235
New Window, 225 Version Control, 234
Number of parallel processes, 231 View Build Details, 229
Only remove intermediate Write Expanded Project to File, 224
output, 230 Builder options
Open Project, 224 Additional Assembler Options, 181,
Options, 235 243
Other VC Command, 234 Additional Intex Options, 139
Place Under VC, 234 Additional Linker Options (after .ld
Preprocess selected file, 229 files), 185, 278

688 MULTI: Building Applications for Embedded ARM


Index
Additional Linker Options (before .ld Bool Type Support, 169
files), 184 Brief Error Message Mode, 192
Additional Output Files, 201 .c Files are C++, 153
Allocation of Uninitialized Global C Include Directories, 211
Variables, 166, 530 to 531 C Japanese Automotive
Allow C++ Style Slash Comments in Extensions, 151, 426 to 427
C, 153, 461 C Language Dialect, 151, 212, 406 to
Alternate Assembler Directory, 202 407, 413, 420, 427, 429, 435, 522
Alternate Compiler Directory, 202 C++ Exception Handling, 153, 465
Alternate Library Directory, 202 C++ Include Directories, 98, 211
Alternate Linker Directory, 202 C++ Inlining Level, 213, 634
Alternate Tools Directory, 202 C++ Language Dialect, 152, 212, 464
Alternative C++ Tokens, 167 to 465, 472 to 473, 477 to 478, 522,
Anachronism Support, 170 553
ANSI Aliasing Rules, 153 C++ Libraries, 152, 553
ANSI C and Standard C++ C++ Linking Method, 214
Extensions, 212 C++ Standard Include
Append Default Extension to Output Directories, 212
Filename, 200 C/C++ Minimum/Maximum
Append String to Every Section Optimization, 205, 650
Name, 217 Call Graph Generation, 190
:appendExtension, 200 Change Assembler, 219
ARM UK Assembler Checksum, 111, 190
Compatibility, 181, 256 Code Factoring, 186, 307
ARM UK Assembler Predefines, 181 Commands to Execute After
ARM UK Internal Variables, 181 Associated Command, 201
Asm Statements, 193, 426, 435 Commands to Execute After
Assembler Command File, 182, 243 Associated Command (via
Assembler Warnings, 216 Shell), 201
Auto-Instantiation of Templates, 174, Commands to Execute Before
177, 492 to 493 Associated Command, 200
Auto-Interrupt Table, 131 Commands to Execute Before
Automatic Register Allocation, 204, Associated Command (via
654 Shell), 201
Binary Code Generation, 198 Common Subexpression
Binary Output Directory Relative to Elimination, 204, 647
This File, 199 Conditional Instructions, 206, 644
Binary Output Directory Relative to Constant Propagation, 204, 649
Top-Level Project, 199 Convert DWARF Files to MULTI
:binDir, 199 (.dbo) Format, 209
:binDirRelative, 199

Green Hills Software, Inc. 689


Index
Convert Stabs Files to MULTI (.dbo) EDG Front End Options, 219
Format, 209 End Files, 187, 312
Create Raw Binary Image, 139 Endianness, 131
Cross-Reference Information, 208 Error Style, 192
Data Definition Movement, 205, 646 Event Logging, 136
Data Model, 134 to 135 Executable Stripping, 100, 184
Dbo File Version, 219 Explicit Specifier Support, 170
Debug Information (.dbo) Tracing :extraOutputFile, 201
Diagnostics, 219 Far Calls, 116, 134
Debugging Information, 208 Files to Pre-Include, 210
Debugging Level, 91 to 92, 147, 203, Floating-Point Coprocessor, 127, 132
206, 209, 535 For-Loop Initialization Scope, 214
Define Preprocessor Symbol, 150 Force Frame Pointer, 149, 207
Definition of Standard Symbols, 210 Force Undefined Symbol, 188
Definition of Unsafe Symbols, 211, Full POSIX-2001 Compilation
512 Support, 138
Delete Unused Kernel Calls, 138 Functions Without Prototypes, 193
Deletion of Unused Functions, 186 to 194
Demangling of Names in Linker Generate Additional Output, 73, 183
Messages, 214 Generate MULTI and Native
Dependencies Relative to Source Information, 209
Directory, 199 Generate Target-Walkable
Dependencies Relative to This Stack, 206
File, 200 Global Registers, 118, 134
Dependencies Relative to Top-Level GNU Compatibility
Project, 200 Optimizations, 206
Dependent Name Processing, 178, Guiding Declarations of Template
490 Functions, 175
:depends, 199 Host & Target Kanji Support, 168,
:dependsNonRelative, 200 439, 506
:dependsRelative, 200 Hybrid One Instantiation Per
Display #includes Listing, 150 Object, 176 to 177
Display BootTable, 138 Identifier Definition, 216
Display Error Message Identifier Support, 216
Numbers, 195 to 196, 533 Ignore #include Directives, 213
Display Error Message Paths, 192 Implicit Int Return Type, 194
Display Version Information, 191 Implicit Source File Inclusion, 175,
Distinct C and C++ Functions, 215 178, 489 to 490
Distinct Template Signatures, 175 Implicit Use of ’std’ Namespace, 169
Duplicate #includes, 210, 533 Import Symbols, 188
Dynamic Download Project, 138 Include Directories, 59, 96 to 98, 141

690 MULTI: Building Applications for Embedded ARM


Index
Include libbsp.a, 137 Loop Optimize Specific
Incorrect #pragmas, 193, 526 Functions, 146, 636
inheriting, 61 Loop Unrolling, 203, 636, 639
Initialization of PIC Pointers, 197 Macro Debugging Information, 208
Inline C Memory Functions, 203, Manual Template Instantiation
632 to 633 Mode, 174, 486, 492 to 493
Inline C String Functions, 203, 633 Map File Cross-Referencing, 189
Inline Larger Functions, 144, 631 Map File Generation, 189
Inline Specific Functions, 146, 628 Map File Page Length, 189
to 631 Map File Retention, 189
Inline Tiny Functions, 203, 625 Map File Sorting, 189
Input Languages, 70 Maximize Optimizations, 145
Instantiate Extern Inline, 170 Maximum Number of Errors to
INTEGRITY Application Display, 191
Stripping, 139 Memory Description File, 131
Interleaved Source and Memory Optimization, 205, 427, 606
Assembly, 180 to 607, 650 to 651
Intermediate Output Directory Minimum Structure Alignment, 165
Relative to This File, 199 MISRA C - Advisory Rules
Intermediate Output Directory Level, 163
Relative to Top-Level Project, 142 MISRA C - Required Rules
Intermodule Inlining, 95, 144, 628 to Level, 163
631 MISRA C - Run-Time Checks, 163
Kernel Project, 137 MISRA C Rules - Character Set, 155
Libraries, 99, 141 MISRA C Rules - Comments, 156
Library Directories, 99, 141 MISRA C Rules - Constants, 156
Line Wrap Messages, 192 MISRA C Rules - Control Flow, 159
Link in Standard Libraries, 217, 555 MISRA C Rules - Conversions, 158
Link Map Method, 218 MISRA C Rules - Declarations &
Link Mode, 217 Definitions, 157
Link-Time Constant MISRA C Rules - Environment, 155
Propagation, 186 MISRA C Rules - Expressions, 158
Linker Command File, 185, 278 MISRA C Rules - Functions, 160
Linker Directives Directory, 184 MISRA C Rules - Identifiers, 156
Linker Optimizations, 144, 186 MISRA C Rules - Initialization, 157
Linker Warnings, 184 MISRA C Rules - Operators, 158
Linker-Based Far Call Patching, 134 MISRA C Rules - Pointers and
Long Long Support, 164, 460 Arrays, 161
longjmp() does not restore local MISRA C Rules - Preprocessor, 161
vars, 213 MISRA C Rules - Standard
Library, 162

Green Hills Software, Inc. 691


Index
MISRA C Rules - Structs and Pass Through Arguments, 201
Unions, 162 :passThrough, 201
MISRA C Rules - Types, 156 PCH Messages, 179, 500
Multi-Byte Characters, 167 PCH Search Directory, 179, 500 to
Multiply-Defined Symbols, 188 501
Namespace Support, 169, 495 Peephole Optimization, 205, 641
’new’ and ’delete’ Keyword Pipeline & Peephole Scope, 144, 641
Support, 170 to 642
New-Style ’for-init’ Code, 193 Pipeline Instruction Scheduling, 205,
New-Style Cast Support, 171 642
:nodepends, 200 Placement of Class Constructor Call
Non-Standard Output Suffix, 199 to New, 172
:noselfdepend, 200 Placement of Zero-Initialized
Object File Output Directory, 140, Data, 106, 134
177, 179 Position Independent Code, 112, 133
One Instantiation Per Object, 176 to Position Independent Data, 114, 133
177 :postexec, 201
Optimization Strategy, 95, 143, 145 :postexecShell, 201
to 146, 203, 427, 535, 606, 624 to Pre-link with Instantiations, 177
625, 633, 635, 641 to 642, 644, 646 Precompiled Header File, 179, 497,
to 653 500 to 501
Optimize All Appropriate :preexec, 200
Loops, 205, 606, 636 :preexecShell, 201
Optimize Specific Functions for PreLink File to Create Template
Size, 146 Instances, 178
Optimize Specific Functions for Prepend String to Every Section
Speed, 146 Name, 217
OS Directory, 136 Preprocess Assembly Files, 180, 242
Output File Size Analysis, 190 Preprocess Linker Directives
Output File Type, 183 Files, 184
Output Filename, 120, 140 Preprocess Special Assembly
Output Filename for Generic Files, 180
Types, 200 printf & scanf Argument Type
:outputDir, 142 Checking, 194
:outputDirRelative, 199 Profiling - Call Count, 93, 147
:outputName, 200 Profiling - Coverage, 93, 147
Overloading of enums, 215 Profiling - Target-Based Timing, 94,
Packing (Maximum Structure 148
Alignment), 87, 165 Quit Building if Warnings are
Parse Templates in Generic Generated, 191
Form, 178

692 MULTI: Building Applications for Embedded ARM


Index
Recognition of Exported Source Directories Relative to
Templates, 178, 465, 490 Top-Level Project, 199
Redirect Error Output to File, 191 Source Listing Generation, 99, 180
Register Allocation by Coloring, 204, Source Root, 140
653 :sourceDir, 141
Register Description File, 131 :sourceDirNonRelative, 199
Relative Xof Path, 207 Standard Include Directories, 211
Relocatable Module, 138 Start Address Symbol, 120, 184
Relocatable Module Base Image, 138 Start File Directory, 187
Remarks, 191 Start Files, 187
’restrict’ Keyword Support, 170 Start of .data Section, 218
Retain Comments During Start of .text Section, 218
Preprocessing, 211 Support __noinline Keyword, 170,
Retain Symbols for Unused 635
Statics, 167 Support for ’typename’
Run-Time Error Checks, 148, 532 Keyword, 178
Run-Time Memory Checks, 149, 207 Support for
Run-Time Type Information Constructors/Destructors, 172
Support, 172 Support for Friend Injection, 215
Search for DBA, 207 Support for Implicit Extern C Type
Search Path for .dbo Files, 207 Conversion, 171
Section Overlap Checking, 190 Support for Implicit Typenames, 176
:select, 201 Support for Inline Functions with
’Select One’ Project Extension Extern, 171
List, 201 Support for Nonstd Qualifier
Self-Dependency, 200 Deduction, 176
Set Message to Error, 195 Support for Old-Style
Set Message to Remark, 195 Specializations, 175 to 176
Set Message to Silent, 195 Support For Very Large Switch
Set Message to Warning, 195 Statements, 197
Shadow Declarations, 194 Suppress Dependencies, 200
Shared Libraries, 135 System Include Directories, 212
Signedness of Bitfields, 164, 426, 429, Tail Recursion, 204, 648
508 Target Processor, 197
Signedness of Char Type, 163, 426, Template Instantiation Output
444, 506 Directory, 177
Signedness of Enum Type, 164 Temporaries’ Lifetime, 215
Signedness of Pointers, 164 Temporary Output, 199
Similar Pool Merging, 186 Temporary Output Directory, 198
Source Directories Relative to This ThreadX Demo Library
File, 141 Directory, 136

Green Hills Software, Inc. 693


Index
Thumb Code Generation, 101, 135 -C driver option, 211
Thumb Libraries, 101, 135 .c file extension, 32, 69
Tiebreaker Processing Time, 215 .C file extension, 32, 70
Treat .bss as Commons, 214 .c Files are C++ Builder option, 153
Treatment of RTTI as ’const’, 172 C Include Directories Builder option, 211
Treatment of Virtual Tables as C Japanese Automotive Extensions
’const’, 173 Builder option, 151, 426 to 427
Trigraphs, 194 C language
Undefine Preprocessor Symbol, 150 Amendment 1 compliance, 458
Undefined Preprocessor and memory-mapped I/O, 122
Symbols, 195 ANSI dialect, 407, 429, 441 to 447,
Undefined Symbols, 188 450 to 456
Uniquely Allocate All Strings, 166, asm statements, 434
506 bitfields, 429 to 430
Unknown #pragmas, 193, 526 building an executable, 68
Unroll Larger Loops, 145, 639 compiler driver, 67
Unroll Loops Up To 8 Times, 145, compiler limitations, 440
639 const keyword, 428
Use Before ’Set’, 194 enum data type, 431
Use Debug Library List (.dli) extended characters, 436
Files, 207 GNU dialect, 413, 416
Use Floating-Point in stdio Green Hills implementation of, 406
Routines, 133 ISO C99 compliance, 458, 460 to 462
Use Smallest Type Possible for Japanese Automotive, 514
Enum, 85, 164, 426, 431, 507 Japanese Automotive C, 426
Use ThreadX Demo Library, 136 K&R dialect, 420 to 421
Use ViewPath as Source Root, 207 Kernighan & Ritchie conformance, 151
Virtual Function Definition, 173 library, 436
Warnings, 191, 443 MISRA C, 154, 426
X-Switches, 219 preprocessing, 435
building, see Builder reentrant functions in run-time
built-in functions, see intrinsics libraries, 557
__builtin_return_address() run-time libraries, 548
intrinsic function, 536 run-time library, 436
byte addressable, 601 specifying a dialect of, 406
.byte assembler directive, 268 <stdarg.h>, 433
byte order, see endianness struct data type, 428
type qualifiers, 427
C union data type, 428
C, see C language <varargs.h>, 432
-c driver option, 71, 73, 177 variable arguments, 432

694 MULTI: Building Applications for Embedded ARM


Index
volatile keyword, 427 specifying a dialect of, 464
C Language Standard, 465
division by zero, 557 See also Standard C++
C Language Dialect Builder option, 151, standard extensions, 465
212, 406 to 407, 413, 420, 427, 429, Strict ANSI, 471
435, 522 templates, 173 to 178, 466, 481, 484 to
-C linker option, 280 488, 490 to 491
C++, see C++ language C++ Language Dialect Builder
Thumb compiler driver, 67 option, 152, 212, 464 to 465, 472 to
C++ Exception Handling Builder 473, 477 to 478, 522, 553
option, 153, 465 C++ Libraries Builder option, 152, 553
C++ Include Directories Builder C++ Linking Method Builder option, 214
option, 98, 211 C++ Programming Language, Third
C++ Inlining Level Builder option, 213, Edition, The, 472
634 C++ Standard Include Directories
C++ language Builder option, 212
alignment and size limitations, 598 --c_and_cpp_functions_are_distinct
anachronisms, 468 driver option, 215
ARM compliant, 472 C/C++ minimum/maximum
building an executable, 68 optimization, 650
C main(), with, 591 C/C++ Minimum/Maximum
compiler driver, 67 Optimization Builder option, 205, 650
data types, 597 -c_include_directory driver option, 211
decode utility, 504 __c_plusplus, 470, 514
Embedded, 464 call analysis, 105
Embedded dialect, 478 Call Graph Generation Builder
Extended Embedded dialect, 477 option, 190
extensions, 469 -call_shared driver option, 135
GNU dialect, 473 -callgraph driver option, 190
implementation-defined features, 505 -callgraph linker option, 280
in C programs, 593 calling conventions, 9
inlining, 634 casts, 466, 479
International Standard, 465 EEC++ and, 477
linkage, 503 .cc file extension, 32, 70
namespaces, 495 ccarm, 67
post processing, 503 ccthumb, 67
precompiled header files, 179, 497 to cerr, 592
502 Change Assembler Builder option, 219
predefined macro, 514 char data type
predefined macros for, 470 signedness, 163
required macro names, 512 variable arguments, 432

Green Hills Software, Inc. 695


Index
char type explicit instantiation, 492
signedness, 518, 524 Close Project Builder menu item, 224
size, 517 __CLZ32() intrinsic function, 537
__CHAR_BIT=n, 517 -cmd linker option, 281
__Char_Is_Signed, 524 Code Factoring Builder option, 186, 307
__Char_Is_Unsigned, 524 code factoring optimization
__CHAR_UNSIGNED__, 518 controlling the scope of, 307
character incremental linking, 308
encoding, 84 invoking, 307
character constants, 248 overview, 307
character set dependencies, 601 partial, 308
character set for assembler, 245 -code_model=large driver option, 135
-check driver option, 148 to 149 -code_model=small driver option, 135
Check In + Out Builder menu item, 234 CodeBalance optimization wizard, 11
Check In Builder menu item, 234 CodeBalance optimizing wizard, 396
Check Out Builder menu item, 234 CodeBalance selected program Builder
Checkout Browser Builder menu menu item, 235
item, 234 -codefactor driver option, 186, 307
Checksum Builder option, 111, 190 -codefactor linker option, 281
-checksum driver option, 190 __COFF, 521
-checksum linker option, 281 collating sequence, 602
cin, 480, 592 .comm assembler directive, 274
class, 599 command line
name injection, 468 for assembler, 244
template, 481 for gdump utility, 254
class type command line utilities, see utility programs
portability, 599 Commands to Execute After Associated
classes, 479 Command (via Shell) Builder
anonymous, 470 option, 201
EC++ and, 480 Commands to Execute After Associated
Clean all output before building Builder Command Builder option, 201
menu item, 230 Commands to Execute Before Associated
Clean selected file Builder menu item, 229 Command (via Shell) Builder
Clear Default Configuration Builder option, 201
menu item, 234 Commands to Execute Before Associated
CLEAR linker section attribute, 293 Command Builder option, 200
ClearCase , Atria Inc., 491 .comment section, 283
Clearmake comments, in assembler source, 249
building templates with, 491 Common Subexpression Elimination
compile-time demand Builder option, 204, 647
instantiation, 492

696 MULTI: Building Applications for Embedded ARM


Index
common subexpression elimination conditional assembly directives, 267
optimization, 647 Conditional Instructions Builder
--common_implicit_initialization driver option, 206, 644
option, 214 Configuration Builder menu item, 234
--commons driver option, 166 Connect Builder menu item, 232
Compatibility Mode Compiler, 406 Connection Organizer Builder menu
compiler driver, 66 item, 232
See also driver options const keyword, 421, 428
building a C executable with, 68 constant data in ROM, 297
building a C++ executable with, 68 constant folding optimization, 655
controlling the assembler with, 99 Constant Propagation Builder
controlling the linker with, 100 option, 204, 649
creating libraries with, 72 constant propagation optimization, 649
file extensions recognized by, 69 CONSTANTS linker directive, 287
for C source files, 67 constants, in assembler, 247
for C++ source files, 67 constructors, 503
generating assembly files with, 71 constructors and destructors, 591, 594
generating debugging information context-sensitive help, 13
with, 91 continuation lines, in assembler, 250
generating object files with, 71 Contract All Within selected file Builder
input file types, 69 menu item, 227
introduction to, 9 conventions, typographical, 15
linker directives files, passing to, 70 Convert DWARF Files to MULTI (.dbo)
optimizing your code with, 95, 143 Format Builder option, 209
output file types, 71 Convert Legacy project Builder menu
passing multiple files to, 70 item, 235
renaming output of, 120 Convert Stabs Files to MULTI (.dbo)
running assembler with, 242 Format Builder option, 209
setting optimization options for, 143 copyright banner, generating, 191
specifying a target for, 89 cout, 480, 592
syntax, 67 coverage analysis, 105
updating libraries with, 72 __cplusplus, 470, 513
using a driver options file with, 76 .cpp file extension, 32, 70
using files with, 67 CPSR
using options with, 67 accessing sticky overflow flag, 538
compiler mode -cpu assembler option, 244
Compatibility Mode, 406 -cpu driver option, 89 to 90
New Generation, 406 -cpu=cpu driver option, 197
complex, C++ class -crc linker option, 281
EC++, 480 Create File Builder menu item, 225
.con file extension, 33

Green Hills Software, Inc. 697


Index
Create Raw Binary Image Builder __DATE__, 421, 513
option, 139 precompiled header files and, 499
Create Subproject Builder menu .dba Output File Types, 74
item, 225 -dbg_source_root driver option, 140
--create_pch driver option, 179, 501 Dbo File Version Builder option, 219
CROM linker section attribute, 293 to 294 .dbo Output File Types, 74
cross compilers, 9 -dbo_trace driver option, 219
Cross-Reference Information Builder --dbo_version driver option, 219
option, 208 -dbopath driver option, 207
crt0.arm, 581 dead code elimination optimization, 651
crt0.o startup module, 299, 581 Debug Information (.dbo) Tracing
custom example Diagnostics Builder option, 219
Run-Time Error Checks, 149 Debug Other Executable Builder menu
customizing item, 233
run-time environment, 119 Debug selected program Builder menu
cxarm, 67 item, 233
cxthumb, 67 debugger
.cxx file extension, 32, 70 displaying memory-mapped I/O, 122
--cxx_include_directory driver PIC and, 113
option, 98, 211 PID and, 114
cxxmunch utility, 504 debugging
limitations with inlining, 632
D source level, 607
-D driver option, 150 symbolic, 275
-d librarian command, 315 debugging information
-D linker option, 281 Builder and driver options for, 147
.data assembler directive, 272 controlling level of, 208
Data Definition Movement Builder files containing, 92
option, 205, 646 generating, 91
data definition movement generating DWARF information, 209
optimization, 646 maintaining, 92
data initialization Debugging Information Builder
assembler directives, 268 option, 208
Data Model Builder option, 134 to 135 Debugging Level Builder option, 91 to
.data program section, 106, 298, 669 92, 147, 203, 206, 209, 535
data type size, 597 decode utility, 504
data types -default_lnk driver option, 218
void, 421 Define Preprocessor Symbol Builder
-data_model=large driver option, 134 option, 150
-data_model=small driver option, 134 #defined(id), 421

698 MULTI: Building Applications for Embedded ARM


Index
Definition of Standard Symbols Builder --disable_ctors_dtors driver option, 172
option, 210 --disable_noinline driver option, 170, 635
Definition of Unsafe Symbols Builder Discard Changes Builder menu item, 234
option, 211, 512 -discard_zero_initializers driver
delete option, 134
array, predefined macro, 522 Disconnect Target Builder menu
-delete driver option, 186 item, 232
-delete linker option, 281 --discretionary_errors driver option, 212
Delete Unused Kernel Calls Builder --discretionary_warnings driver
option, 138 option, 212
-deletedebug linker option, 281 Display #includes Listing Builder
deleting option, 150
unused functions, 305 Display BootTable Builder option, 138
Deletion of Unused Functions Builder Display Error Message Numbers Builder
option, 186 option, 195 to 196, 533
demangler, 504 Display Error Message Paths Builder
Demangling of Names in Linker option, 192
Messages Builder option, 214 Display Version Information Builder
--dep_name driver option, 178, 490 option, 191
Dependencies Relative to Source -display_boot driver option, 138
Directory Builder option, 199 --display_error_number driver
Dependencies Relative to This File option, 196, 533
Builder option, 200 Distinct C and C++ Functions Builder
Dependencies Relative to Top-Level option, 215
Project Builder option, 200 Distinct Template Signatures Builder
Dependent Name Processing Builder option, 175
option, 178, 490 --distinct_template_signatures driver
:depends Builder option, 199 option, 175
:dependsNonRelative Builder option, 200 division
:dependsRelative Builder option, 200 operators, 604
destructors, 503 .dla Output File Types, 74
__DI() intrinsic function, 536 .dlo Output File Types, 74
--diag_error driver option, 195 .dnm Output File Types, 74
--diag_remark driver option, 195 do-while statement, 465
--diag_suppress driver option, 195 document set, 6
--diag_warning driver option, 195 -dotciscxx driver option, 153
digraphs, 466 .double assembler directive, 268
__DIR() intrinsic function, 536 __DOUBLE_HL, 518
-directive_dir driver option, 184 driver options
directories -#, 76
library, 549 -a, 93, 147

Green Hills Software, Inc. 699


Index
-A, 188 -cpu=cpu, 197
--alternative_tokens, 167 --create_pch, 179, 501
-alttools, 202 --cxx_include_directory, 98, 211
--anachronisms, 170 -D, 150
-ansi, 151, 406 to 407, 427 -data_model=large, 134
-ANSI, 151, 212, 406, 409, 427 -data_model=small, 134
-ansi_alias, 153 -dbg_source_root, 140
--any_output_suffix, 199 -dbo_trace, 219
-apcs, 181, 257 --dbo_version, 219
-archive, 72 to 73, 314 -dbopath, 207
--arm, 152, 464, 472 -default_lnk, 218
-arm_uk_asm, 181, 256 -delete, 186
--array_new_and_delete, 170 --dep_name, 178, 490
-asm, 181, 243 --diag_error, 195
--asm_errors, 193, 435 --diag_remark, 195
--asm_silent, 193, 426, 435 --diag_suppress, 195
--asm_warnings, 193, 435 --diag_warning, 195
-asmcmd, 182, 243 -directive_dir, 184
--assembler_warnings, 216 --disable_ctors_dtors, 172
--auto_instantiation, 174 --disable_noinline, 170, 635
-auto_interrupt_table, 131 -discard_zero_initializers, 134
-autoregister, 204 --discretionary_errors, 212
-bigendian, 131 --discretionary_warnings, 212
-bigswitch, 197 -display_boot, 138
--bool, 169, 522 --display_error_number, 196, 533
--brief_diagnostics, 192 --distinct_template_signatures, 175
-bsp, 89 -dotciscxx, 153
-c, 71, 73, 177 -dual_debug, 209
-C, 211 -dwarf_to_dbo, 209
--c_and_cpp_functions_are_distinct, 215 -dyload, 138
-c_include_directory, 211 -dynamic, 138
-call_shared, 135 -e, 120, 184, 478
-callgraph, 190 --e, 152, 464, 514, 553
-check, 148 to 149 -E, 73, 177, 436
-checksum, 190 --early_tiebreaker, 215
-code_model=large, 135 -ee, 464, 477
-code_model=small, 135 --ee, 152, 553
-codefactor, 186, 307 --eel, 152, 514 to 515, 551, 553
--common_implicit_initialization, 214 --eele, 152, 514 to 515, 551, 553
--commons, 166 --el, 152, 514, 551, 553
-cpu, 89 to 90 --ele, 152, 514, 551, 553

700 MULTI: Building Applications for Embedded ARM


Index
--enable_ctors_dtors, 172 -ident, 216
--enable_noinline, 170, 635 -identoutput, 216
-endfile, 187, 312 --implicit_extern_c_type_conversion, 171
--enum_overloading, 215 --implicit_include, 175
-errmax, 191 --implicit_typename, 176
-error_basename, 192 -include, 210
-error_fortran_style, 192 --include_never, 213
-event_logging, 136 -include_once, 210
--exceptions, 153, 465 --incorrect_pragma_errors, 193, 526
--explicit, 170 --incorrect_pragma_silent, 193, 526
--export, 178, 465, 490 --incorrect_pragma_warnings, 193
--extern_inline, 171 --initpipointers, 197
-farcallpatch, 134 --inline_tiny_functions, 203
-farcalls, 116, 134 --inlining, 213, 634
--fast, 146 --inlining_unless_debug, 213, 634
-fhard, 132 --instantiate_extern_inline, 170
@file, 76 --instantiation_dir, 177
-floatio, 133 --integrity_posix, 138
-fnone, 127, 132, 552 -intexoption, 139
--for_init_diff_warning, 193 -irel, 138
--force_vtbl, 173 -japanese_automotive_c, 151, 426 to
--friend_injection, 215 427
-fsoft, 132 -k+r, 151, 406, 420
-full_debug_info, 208 -kanji, 168, 439
-full_macro_debug_info, 208 --keep_static_symbols, 167
-g, 147 -keepmap, 189
-G, 91 to 92, 147, 552 -keeptempfiles, 199
--g++, 152, 464, 473 -kernel, 137
-ga, 207 -kernel=kernel_checked, 137
-gcc, 151, 406, 413 -kernel=kernel_fast, 137
-generatemonolithdeletions, 138 -kernel=kernel_nommu, 137
-globalreg, 118, 134, 520 -kernel=kernel_novirt, 137
-gnu, 151 to 152 -kernel=kernel_opt, 137
-gs, 147 -kernel=kernel_small, 137
-gsize, 190 -l, 99, 141
-gtws, 206 -L, 99, 141
--guiding_decls, 175 --late_tiebreaker, 215
-H, 81, 150 -libbsp, 137
-help, 76 --link_constprop, 186
--hybrid_one_instantiation_per_object, 177 --link_filter, 214
-I, 96 to 98, 141 --link_output_mode_linksafe, 217

Green Hills Software, Inc. 701


Index
--link_output_mode_reuse, 217 --no_assembler_warnings, 216
--link_output_mode_safe, 217 --no_auto_instantiation, 174, 177,
--link_output_mode_unlink, 217 492 to 493
--link_similar_pools, 186 -no_auto_interrupt_table, 131
--linker_link, 214 --no_bool, 169
-linker_warnings, 184 --no_brief_diagnostics, 192
-list, 99, 180 --no_c_and_cpp_functions_are_distinct, 215
-littleendian, 131 -no_callgraph, 190
-lnk, 185, 278 -no_codefactor, 186
-lnkcmd, 185, 278 --no_comments, 211
-locals_unchanged_by_longjmp, 213 --no_common_implicit_initialization, 214
-locatedprogram, 183 --no_commons, 166
--long_lifetime_temps, 215 --no_coverage_analysis, 147
--long_long, 164 --no_debug, 147
-Ma, 189 -no_default_lnk, 218
-map, 189 -no_delete, 186
-maplines, 189 --no_dep_name, 178
--max_inlining, 213, 634 -no_discard_zero_initializers, 134
--max_inlining_unless_debug, 213, -no_display_boot, 138
634 --no_display_error_number, 196
-MD, 81 --no_distinct_template_signatures, 175
-memory, 139, 183 -no_dual_debug, 209
--memory_description_file, 131 -no_dwarf2dbo, 209
-Mn, 189 -no_dynamic, 138
--multibyte_chars, 167 --no_enum_overloading, 215
-multiple, 188 -no_error_basename, 192
--munch, 214 -no_error_fortran_style, 192
-Mx, 189 -no_event_logging, 136
--namespaces, 169 --no_exceptions, 153
-new_assembler, 219 --no_explicit, 170
--new_for_init, 214 --no_export, 178
--new_inside_of_constructor, 172 --no_extern_inline, 171
--new_outside_of_constructor, 172 --no_for_init_diff_warning, 193
--new_style_casts, 171 --no_friend_injection, 215
--no_additional_output, 183 -no_full_debug_info, 208
--no_alternative_tokens, 167 -no_full_macro_debug_info, 208
--no_anachronisms, 170 -no_gsize, 190
-no_ansi_alias, 153 --no_guiding_decls, 175
--no_any_output_suffix, 199 --no_hybrid_one_instantiation_per_object, 177
-no_arm_uk_asm, 181 --no_implicit_extern_c_type_conversion, 171
--no_array_new_and_delete, 170

702 MULTI: Building Applications for Embedded ARM


Index
--no_implicit_include, 175, 489 to --no_rtti, 172
490 --no_saferc_runtime, 163
--no_implicit_typename, 176 -no_search_for_dba, 207
--no_include_never, 213 --no_short_enum, 164, 426
-no_include_once, 210 --no_slash_comment, 153, 461
--no_initpipointers, 197 -no_stabs2dbo, 209
--no_inline_tiny_functions, 203, 625 -no_strip_application, 139
--no_inlining, 213, 634 -no_timer_profile, 148
--no_instantiate_extern_inline, 170 --no_trace_includes, 150
--no_integrity_posix, 138 --no_typename, 178
-no_irel, 138 -no_undefined, 188
-no_japanese_automotive_c, 151 --no_unique_strings, 166
--no_keep_static_symbols, 167 --no_unsafe_predefines, 211
-no_kernel, 137 --no_use_before_set_warnings, 194
-no_libbsp, 137 -no_use_demo_library, 136
--no_link_constprop, 186 -no_use_dli_files, 207
--no_link_filter, 214 -no_use_vp_as_dbg_source_root, 207
--no_link_similar_pools, 186 --no_using_std, 169
-no_linker_warnings, 184 --no_version, 191
-no_list, 180 --no_wrap_diagnostics, 192
-no_locals_unchanged_by_longjmp, 213 -noautoregister, 204, 654
--no_long_long, 164, 460 -nobigswitch, 197
--no_multibyte_chars, 167 -nochecksum, 190
-no_multiple, 188 --nocpp, 214
--no_namespaces, 169, 495 -nodotciscxx, 153
--no_new_style_casts, 171 -noentry, 184
--no_old_specializations, 176 -nofarcallpatch, 134
--no_one_instantiation_per_object, 176 -nofarcalls, 134
--no_parse_templates, 178 -nofloatio, 133
--no_pch, 179 -noga, 207
--no_pch_messages, 179, 500 -nogtws, 206
--no_prelink_objects, 177 -noidentoutput, 216
-no_preprocess_assembly_files, 180 -nokeepmap, 189
--no_preprocess_linker_directive, 184 -nokeeptempfiles, 199
-no_preprocess_special_assembly_files, 180 -nomap, 189
--no_quit_after_warnings, 191 -non_shared, 135
--no_readonly_typeinfo, 172 --nonstd_qualifier_deduction, 176
--no_readonly_virtual_tables, 173 -noobj, 198
--no_relative_xof_path, 207 -nooverlap, 190
--no_remarks, 191 -nooverload, 204, 653
--no_restrict, 170 -nopasssource, 180

Green Hills Software, Inc. 703


Index
-nopic, 133 -Onolink, 144
-nopid, 133 -Onoloop, 205, 636
-nostartfiles, 187 -Onomax, 145
-nostddef, 210 -Onomemfuncs, 203, 632
-nostdinc, 211 -Onomemory, 205, 607, 650
-nostdlib, 217, 551, 555 -Onominmax, 205, 650
-nostrip, 184 -Onone, 143
-nothumb, 135 -Onopeephole, 205, 641
-nothumb_lib, 135 -Onopipeline, 205, 642
-o, 72, 120, 140 -Onostrfuncs, 203, 633
-O, 95, 143, 624, 641 -Onotailrecursion, 204, 648
-O1, 206 -Onounroll, 203, 636, 639
-O2, 206 -Onounroll8, 145, 639
-O3, 206 -Opeep, 205, 641
-OB, 144, 631 -Opipeline, 205, 642
-obj, 198 --option, 219
-object_dir, 140 -os_dir, 136
-Ocond, 206, 644 -Ospace, 95, 143, 624, 635, 641
-Oconstprop, 204, 649 -Ospeed, 95, 143, 624 to 625, 641
-Ocse, 204, 647 -Ostrfuncs, 203
-OI, 95, 144, 146, 628 -Otailrecursion, 204, 648
-Oinitializers, 205, 646 -Ounroll, 203
-OL, 146, 205, 606, 636 -Ounroll8, 145
-old_assembler, 219 -Ounrollbig, 145, 639
--old_for_init, 214 -overlap, 190
--old_specializations, 176 -overlap_warn, 190
-Olimit, 641 to 642 -overload, 204
-Olimit=peephole, 144 -p, 93, 147
-Olimit=pipeline, 144 -P, 177, 436
-Olink, 144 -pack, 87, 165
-OM, 205, 427, 606, 650 --parse_templates, 178
-Omax, 145 -passsource, 180
-Omemfuncs, 203 --pch, 179, 497, 500
-Ominmax, 205, 650 --pch_dir, 179, 500 to 501
--one_instantiation_per_object, 176 --pch_messages, 179
-Onobig, 144 -pd, 181
-Onocond, 206, 644 -pg, 93, 147
-Onoconstprop, 204, 649 -pic, 112, 133
-Onocse, 204, 647 -pid, 114, 133
-Onoinitializers, 205, 646 -pnone, 147
-Onoinline, 144, 628 -predefine, 256

704 MULTI: Building Applications for Embedded ARM


Index
-prelink_against, 178 -std, 465
--prelink_objects, 177 --std, 152, 212, 464, 553
-preprocess_assembly_files, 180, 242 -STD, 465
--preprocess_linker_directive, 184 --STD, 152, 212, 409, 464, 553
-preprocess_special_assembly_files, 180, -std_cxx_include_directory, 212
256 --std_qualifier_deduction, 176
--prototype_errors, 193 -stderr, 191
--prototype_silent, 193 -stdinc, 211
--prototype_warnings, 193 --stdl, 152, 515, 553
-Q, 73 --stdle, 152, 515, 551, 553
--quit_after_warnings, 191 -stdlib, 217
--readonly_typeinfo, 172 -strict_overlap_check, 190
--readonly_virtual_tables, 173 -strip, 100, 184
--register_definition_file, 131 -strip_application, 139
--relative_xof_path, 207 --struct_min_alignment, 165
-relobj, 183 --struct_min_alignment=1, 165
-relprog, 183 --struct_min_alignment=2, 165
--remarks, 191 --struct_min_alignment=4, 165
--restrict, 170 --struct_min_alignment=8, 165
--rtti, 172 --suppress_vtbl, 173
-S, 71, 73, 177, 243 synonyms for, 220
--saferc, 155 to 162 -syntax, 73
--saferc_adv, 163 -sys_include_directory, 212
--saferc_req, 163 -tall, 174
--saferc_runtime, 163 -Tdata, 218
-search_for_dba, 207 -threadx_demo_dir, 136
--section_prefix, 217 -thumb, 101, 135
--section_suffix, 217 -thumb_lib, 101, 135
--short_enum, 85, 164, 431 -timer_profile, 94, 148
--short_lifetime_temps, 215 -tlocal, 174
--signed_chars, 163, 444 -tmp, 198
--signed_enum_fields, 164 -tnone, 174, 493
--signed_fields, 164, 429 -Ttext, 218
--signed_pointer, 164 -tused, 174, 492
--slash_comment, 153 --typename, 178
--small, 146 -u, 188
-srec, 183 -U, 150
-stabs_to_dbo, 209 -undefined, 188
--standard_vtbl, 173 --unique_strings, 166
-startfile_dir, 187 --unknown_pragma_errors, 193, 526
-startfiles, 187 --unknown_pragma_silent, 193, 526

Green Hills Software, Inc. 705


Index
--unknown_pragma_warnings, 193 -dwarf_to_dbo driver option, 209
--unsafe_predefines, 211, 512 -dyload driver option, 138
--unsigned_chars, 163, 426, 444 Dynamic Download Project Builder
--unsigned_enum_fields, 164 option, 138
--unsigned_fields, 164, 426, 429 -dynamic driver option, 138
--unsigned_pointer, 164 dynamic initialization, 503
--use_before_set_warnings, 194 dynamic_cast, 466
-use_demo_library, 136 See also RTTI
-use_dli_files, 207
--use_pch, 179, 501 E
-use_vp_as_dbg_source_root, 207 -e driver option, 120, 184, 478
--using_std, 169, 522 --e driver option, 152, 464, 514, 553
-v, 76 -E driver option, 73, 177, 436
-V, 191 -e linker option, 281
-w, 191, 443 e_ehsize ELF header field, 662
--warnings, 191 e_entry ELF header field, 661
-Wformat, 194 e_flags ELF header field, 662
-Wimplicit-int, 194 e_ident ELF header field, 660
-Wl,, 184 e_machine ELF header field, 661
-Wno-format, 194 e_phentsize ELF header field, 662,
-Wno-implicit-int, 194 678
-Wno-shadow, 194 e_phnum ELF header field, 662, 678
-Wno-trigraphs, 194 e_phoff ELF header field, 662
-Wno-undef, 195 e_shentsize ELF header field, 662,
--wrap_diagnostics, 192 664
-Wshadow, 194 e_shnum ELF header field, 662, 664
-Wtrigraphs, 194 e_shoff ELF header field, 662, 664
-Wundef, 195 e_shstrndx ELF header field, 662, 677
-X, 219 e_type ELF header field, 660
--xref=declare, 208 e_version ELF header field, 661
--xref=full, 208 --early_tiebreaker driver option, 215
--xref=global, 208 -earlyabsolute linker option, 281
--xref=none, 208 EC++, see Embedded C++
-Y0,, 202 references, 481
-Ya,, 202 ecxx header file directory, 549
-Yl,, 202 EDG Front End Options Builder
-YL,, 202 option, 219
.dsect assembler directive, 274 __EDG__, 515
-dual_debug driver option, 209 __EDG_IMPLICIT_USING_STD, 522
Duplicate #includes Builder option, 210, __EDG_RUNTIME_USES_NAMESPACES, 523
533

706 MULTI: Building Applications for Embedded ARM


Index
Edit Builder menu item, 225 section header fields, 664
Editor Builder menu item, 235 section types, 667
--ee, 515 special section indexes, 666
-ee driver option, 464, 477 string tables, 677
--ee driver option, 152, 553 symbol bindings, 675
EEC++, see Extended Embedded C++ symbol table entries, 674
eecxx header file directory, 549 symbol types, 675
--eel driver option, 152, 514 to 515, 551, symbol values, 676
553 ELF files
--eele driver option, 152, 514 to 515, 551, printing with gdump utility, 254
553 #elif, 421
__EI() intrinsic function, 536 .else assembler directive, 267
EI_CLASS ELF identification index, 663 .elseif assembler directive, 267
EI_DATA ELF identification index, 663 elxr, see linker
to 664 Embedded C++
EI_MAGn ELF identification index, 663 features of, 478
EI_NIDENT ELF identification library, 480
index, 663 to 664 limitations, 479
EI_PAD ELF identification index, 663 to predefined macro, 514
664 embedded development
EI_VERSION ELF identification and memory-mapped I/O, 122
index, 663 to 664 and multiple-section programs, 107
__EIR() intrinsic function, 536 and ROM, 297
--el driver option, 152, 514, 551, 553 reducing program size, 127
--ele driver option, 152, 514, 551, 553 symbolic memory-mapped I/O, 122
__ELF, 521 __EMBEDDED_CXX, 514
ELF file format __EMBEDDED_CXX_HEADERS, 514
data types, 659 --enable_ctors_dtors driver option, 172
header fields, 660 --enable_noinline driver option, 170, 635
identification indexes, 663 .end assembler directive, 274
introduction, 658 End Files Builder option, 187, 312
object and executable file formats, 658, -endfile driver option, 187, 312
672 endianness
optional header output, 678 portability problems, 597
program attribute flags, 680 predefined macros for, 516
program section names, 668 specifying, 24, 131, 353, 358, 382
program sections, 668 Endianness Builder option, 131
program types, 679 .endif assembler directive, 267
relocation directories, 672 .endm assembler directive, 271
relocation fields, 672 .endr assembler directive, 272
section attribute flags, 667 enum data type, 421, 431, 467 to 468

Green Hills Software, Inc. 707


Index
signedness, 164 --export driver option, 178, 465, 490
size, 164 expressions
__Enum_Field_Is_Signed__, 517 linker, 295
__Enum_Field_Is_Unsigned__, 517 expressions, assembler, 250, 252
--enum_overloading driver option, 215 extended characters, 436 to 437
.equ assembler directive, 274 Extended Embedded C++
-errmax driver option, 191 exceptions, 477
#error, 421 features of, 477
error linker expression function, 296 library features, 477
Error Style Builder option, 192 predefined macro, 515
-error_basename driver option, 192 __EXTENDED_EMBEDDED_CXX, 515
-error_fortran_style driver option, 192 __EXTENDED_EMBEDDED_CXX_HEADERS, 514
escape sequences, in assembler, 248 to 515
evaluation order, 603 extensions
Event Logging Builder option, 136 ARM9E, 538
-event_logging driver option, 136 XScale, 539
__EXCEPTION_HANDLING, 523 extern, 421, 592
exceptions, 472 "C", 471
EC++ and, 479 "C++", 471
predefined macro, 523 extern directive, 503
__EXCEPTIONS, 523 --extern_inline driver option, 171
--exceptions driver option, 153, 465 -extractall linker option, 281
executable files, 183 -extractweak linker option, 281
ELF format, 658, 672 :extraOutputFile Builder option, 201
position independent, 112, 114
reducing size of, 127 F
executable output file, 280 F1 key, for help, 13
Executable Stripping Builder option, 100, Far Calls Builder option, 116, 134
184 __farcall, 117
Execute tools at low priority Builder -farcallpatch driver option, 134
menu item, 231 to 232 -farcalls driver option, 116, 134
Exit Builder menu item, 225 --fast driver option, 146
.exitm assembler directive, 271 -fhard driver option, 132
Expand All Within selected file Builder __Field_Is_Signed__, 518
menu item, 227 __Field_Is_Unsigned__, 518
--explicit driver option, 170 .file assembler directive, 275
explicit keyword, 467 @file assembler option, 244
Explicit Specifier Support Builder @file driver option, 76
option, 170 file extensions, 69
-explicit_padding linker option, 281 file inclusion directives, 269
.export assembler directive, 274

708 MULTI: Building Applications for Embedded ARM


Index
@file linker option, 280 -fsoft driver option, 132
__FILE__, 421, 513, 522 Full POSIX-2001 Compilation Support
files Builder option, 138
searching for in project, 40 -full_debug_info driver option, 208
Files to Pre-Include Builder option, 210 __FULL_DIR__, 513
final linker expression function, 296 __FULL_FILE__, 513
.fixaddr program section, 299, 671 -full_macro_debug_info driver
.fixtype program section, 299, 671 option, 208
Flash selected program Builder menu __FUNCPTR_BIT=n, 517
item, 235 function declaration, far function call, 117
.float assembler directive, 268 __FUNCTION__, 521
float data type functions
variable arguments, 432 calling conventions, 600
<float.h> header file, 596 compiler generated, 488
floating-point deleting unused, 305
I/O, disabling, 133 extern inline, 467
language-independent library, 577 inline, 488, 528
libraries, removing, 127 inline, linkage of, 627
limitations with thumb code, 105 interrupt, 533
predefined macros for, 518 keeping unused, 305
range, 602 mixed ARM/thumb requirements.
values, 84 symbols
Floating-Point Coprocessor Builder mixed ARM/thumb
option, 127, 132 requirements, 102
-floatio driver option, 133 name lookup, 468
-fnone driver option, 127, 132, 552 overloading, 467
for statement, 465 to 467 pointers to, 469, 471
--for_init_diff_warning driver prototype, C versus. C++, 594
option, 193 pure virtual, 488
For-Loop Initialization Scope Builder return values, 600
option, 214 variable argument, 432
Force Frame Pointer Builder option, 149, Functions Without Prototypes Builder
207 option, 193 to 194
Force link Builder menu item, 230
Force Undefined Symbol Builder G
option, 188 -g driver option, 147
--force_vtbl driver option, 173 -G driver option, 91 to 92, 147, 552
-fpu assembler option, 244 --g++ driver option, 152, 464, 473
friend -ga driver option, 207
class, 470 gasmlist utility, 321
--friend_injection driver option, 215

Green Hills Software, Inc. 709


Index
gbin2c utility, 325 GHS_VP_DEBUG, 125
gbincmp utility, 333 GHS_VP_NONE, 125
gbldconvert utility, 335 GHS_VP_SLOW, 125
gbuild utility, 336 __ghsbegin symbol, 106, 302
-gcc driver option, 151, 406, 413 __ghsend symbol, 106, 302
gcolor utility, 342 .ghsnote assembler directive, 309
gcompare utility, 346 __ghstable_[tablename],
gdump utility, 254, 349 __ghsentry_[tablename][entryname]
Generate Additional Output Builder Linker generated tables, 304
option, 73, 183 .global assembler directive, 274
Generate MULTI and Native global objects, 504
Information Builder option, 209 Global Registers Builder option, 118, 134
Generate Target-Walkable Stack Builder -globalreg driver option, 118, 134, 520
option, 206 __GlobalRegisters=n, 520
-generatemonolithdeletions driver gmemfile utility, 363
option, 138 .gmon Output File Types, 74
__GETSR() intrinsic function, 536 gnm utility, 370, 504
__GETSSR() intrinsic function, 537 GNU C
gfile utility, 356 extensions, 413, 416
gfunsize utility, 357 GNU C++
ghexfile utility, 358 extensions, 473
ghide utility, 362 GNU Compatibility Optimizations
__ghs__, 515 Builder option, 206
__ghs_alignment=n, 520 -gnu driver option, 151 to 152
__ghs_asm, 515 __gnu_asm, 516
__ghs_c_int__, 515 .gpj file extension, 20, 32
.ghs_info program section, 309 See also project files
__GHS_Inline_Memory_Functions, 521 .graph Output File Types, 74
__GHS_Inline_String_Functions, 521 Graphically Edit Builder menu item, 225
__ghs_max_pack_value=n, 520 grep utility
__GHS_NOCOMMONS, 520 licensing, 41
__GHS_Optimize_Inline, 521 grep window, see Search in Files Results
__ghs_packing=n, 520 window
__ghs_pic=n, 519 grouping program variables, 107
__ghs_pid=n, 519 grun utility, 378
__ghs_psinfo, 515 -gs driver option, 147
__GHS_REVISION_DATE, 515 -gsize driver option, 190
__GHS_REVISION_VALUE=n, 515 gsize utility, 380
__ghs_stdcall, 515 gsrec utility, 382
__ghs_struct_min_alignment=n, 520 gstack utility, 387
__GHS_VERSION_NUMBER=n, 516 gstrip utility, 389

710 MULTI: Building Applications for Embedded ARM


Index
-gtws driver option, 206 I
Guidelines For the Use Of The C -I assembler option, 244
Language In Vehicle Based Software, -I driver option, 96 to 98, 141
Motor Industry Software Reliability .i file extension, 69
Association, April 1998, 154 I/O
Guiding Declarations of Template mixing languages, 592
Functions Builder option, 175 I/O, memory-mapped, 122
--guiding_decls driver option, 175 #ident, 421
gversion utility, 390 .ident assembler directive, 276
gwhat utility, 392 -ident driver option, 216
Identifier Definition Builder option, 216
H Identifier Support Builder option, 216
-H driver option, 81, 150 identifiers, 245
.h file extension, 33 in assembler, 246
.H file extension, 33 -identoutput driver option, 216
.half assembler directive, 268 .idep Output File Types, 74
header file directories __IeeeFloat, 518
ansi, 549 #if
ecxx, 549 precompiled header files and, 497
eecxx, 549 .if assembler directive, 267
include/arm, 549 if statement, 465 to 466
scxx, 549 Ignore #include Directives Builder
header files, 37, 592 option, 213
header stop point, 497 to 498, 502 Ignore build errors Builder menu
See also precompiled header files item, 230
.heap program section, 300, 671 Ignore dependencies Builder menu
help, see online help item, 231
-help assembler option, 244 .ii files, 484 to 485
-help driver option, 76 .ii Output File Types, 74
-help linker option, 281 illegal assumptions
-Help linker option, 282 implied register usage, 605
Help menu, 13 memory allocation, 605
.hh file extension, 33 Implicit Int Return Type Builder
Highlight Selections Builder menu option, 194
item, 226 Implicit Source File Inclusion Builder
Host & Target Kanji Support Builder option, 175, 178, 489 to 490
option, 168, 439, 506 Implicit Use of ’std’ Namespace Builder
Hybrid One Instantiation Per Object option, 169
Builder option, 176 to 177 --implicit_extern_c_type_conversion
--hybrid_one_instantiation_per_object driver option, 171
driver option, 177 --implicit_include driver option, 175

Green Hills Software, Inc. 711


Index
--implicit_typename driver option, 176 ind_mcpy.c startup code, 584
.import assembler directive, 274 ind_mprf.c run-time code, 585
Import Symbols Builder option, 188 ind_mset.c startup code, 584
#include ind_reset.c run-time code, 584
precompiled header files and, 497 ind_reset.c startup code, 584
.include assembler directive, 269 ind_targ1.c run-time code, 585
#include directive, 141 ind_thrd.c run-time code, 585
Include Directories Builder option, 59, .inf Output File Types, 74
96 to 98, 141 Initialization of PIC Pointers Builder
-include driver option, 210 option, 197
include files initialized data, in ROM, 297
directive for, 269 --initpipointers driver option, 197
directory for assembler, 244 Inline C Memory Functions Builder
list of directories searched for, 141 option, 203, 632 to 633
Include libbsp.a Builder option, 137 Inline C String Functions Builder
include/arm header file directory, 549 option, 203, 633
--include_never driver option, 213 inline keyword
-include_once driver option, 210 extern keyword, 467
Incorrect #pragmas Builder option, 193, Inline Larger Functions Builder
526 option, 144, 631
--incorrect_pragma_errors driver Inline Specific Functions Builder
option, 193, 526 option, 146, 628 to 631
--incorrect_pragma_silent driver Inline Tiny Functions Builder
option, 193, 526 option, 203, 625
--incorrect_pragma_warnings driver --inline_tiny_functions driver option, 203
option, 193 inlining
ind_bcnt.c run-time code, 585 advantages of, 631
ind_bcpy.c startup code, 583 automatic two-pass, 628
ind_call.arm run-time code, 584 C memory functions, 632
ind_crt0.c startup code, 583 C string functions, 633
ind_crt1.c run-time code, 585 C++, 634
ind_dots.arm run-time code, 584 description, 625
ind_errn.c run-time code, 585 limitations of, 632
ind_exit.c run-time code, 587 manual, 626
ind_gcnt.arm run-time code, 585 __noinline, 635
ind_gpid.c run-time code, 585 single-pass, 626
ind_gprf.c run-time code, 585 specific functions, 628
ind_heap.c run-time code, 586 template function, 635
ind_io.c run-time code, 586 two-pass, 627
ind_iob.c run-time code, 587 --inlining driver option, 213, 634
ind_mcnt.arm run-time code, 585 inlining optimizations, 625

712 MULTI: Building Applications for Embedded ARM


Index
--inlining_unless_debug driver __DI(), 536
option, 213, 634 __DIR(), 536
Input Languages Builder option, 70 __EI(), 536
Instantiate Extern Inline Builder __EIR(), 536
option, 170 __GETSR(), 536
--instantiate_extern_inline driver __GETSSR(), 537
option, 170 __LDREX(), 546
--instantiation_dir driver option, 177 __MAR, 540
int type __MIA, 540
size, 517, 524 __MIAPH, 540
__INT_BIT=n, 517, 522 __MIAxy, 540
__Int_Is_32, 524 __MRA_HI, 540
__Int_Is_64, 524 __MRA_LO, 540
Integrated Development Environment __MULSH(), 537
(IDE), see MULTI Integrated __MULUH(), 537
Development Environment (IDE) __PKHBT(), 544
__INTEGRITY, 523 __PKHTB(), 544
INTEGRITY Application Stripping __QADD, 538
Builder option, 139 __QDADD, 538
--integrity_posix driver option, 138 __QDSUB, 538
.intercall program section, 300 __Qoperation(), 541
.interfunc program section, 300 __QSUB, 538
Interleaved Source and Assembly Builder __REV(), 546
option, 180 __REV16(), 546
Intermediate Output Directory Relative __REVSH(), 541
to This File Builder option, 199 __RIR(), 536
Intermediate Output Directory Relative __SADD16TO32(), 541
to Top-Level Project Builder __SADD8TO16(), 541
option, 142 __SADD8TO32(), 541
Intermodule Inlining Builder option, 95, __SEL16(), 544
144, 628 to 631 __SEL8(), 544
interrupt __SETEND_BE(), 546
functions, 120, 533 __SETEND_LE(), 546
processing, 120 __SETSR(), 536
routine and optimizations, 427 __SETSSR(), 537
vectors, 121 __SHoperation(), 542
__interrupt keyword, 120 __SMLAD(), 542
-intexoption driver option, 139 __SMLADX(), 542
intrinsic functions __SMLALD(), 543
__builtin_return_address(), 536 __SMLALDX(), 543
__CLZ32(), 537 __SMLAWy, 539

Green Hills Software, Inc. 713


Index
__SMLAxy, 539 __MULUH64(), 538
__SMLSD(), 542 __SMLAL(), 537
__SMLSDX(), 542 __SMULL(), 537
__SMLSLD(), 543 __UMLAL(), 537
__SMLSLDX(), 543 __UMULL(), 537
__SMMLA(), 543 ios, 480
__SMMLAR(), 543 iostream
__SMMLS(), 543 EC++, 480
__SMMLSR(), 543 -irel driver option, 138
__SMMUL(), 543 isdefined linker expression
__SMMULR(), 543 function, 296
__SMUAD(), 543 ISO/IEC 14882:1998, 465
__SMUADX(), 543 istream, 480
__SMULWy, 539
__SMULxy, 539 J
__SMUSD(), 543 Japanese Automotive C, 426
__SMUSDX(), 543 builder and driver options for, 426 to
__Soperation(), 542 427
__SSAT(), 544 predefined macro, 514
__SSAT16(), 545 __Japanese_Automotive_C, 514
__SSATR(), 545 -japanese_automotive_c driver
__STREX(), 546 option, 151, 426 to 427
__SUNPK16TO32(), 545
__SUNPK8TO16(), 545
__SUNPK8TO32(), 545
K
__UADD16TO32(), 541 K&R C
__UADD8TO16(), 541 asm statements, 421
__UADD8TO32(), 541 const keyword, 421
__UHoperation(), 542 #defined(id), 421
__UMAAL(), 544 #elif, 421
__Uoperation(), 542 #error, 421
__UQoperation(), 542 extensions, 421
__USAD8(), 545 extern, 421
__USADA8(), 546 #ident, 421
__USAT(), 544 signed keyword, 421
__USAT16(), 545 struct data type, 421
__USATR(), 545 union data type, 421
__UUNPK16TO32(), 545 variable arguments, 432
__UUNPK8TO16(), 545 volatile keyword, 421
__UUNPK8TO32(), 545 -k+r driver option, 151, 406, 420
intrinsics Kanji, 438 to 439

714 MULTI: Building Applications for Embedded ARM


Index
-kanji driver option, 168, 439 libarch.a library, 551
-keep linker option, 282 -libbsp driver option, 137
--keep_static_symbols driver option, 167 libdbmem.a library, 552
-keepmap driver option, 189 libece.a library, 551, 553
-keepmap linker option, 282 libecnoe.a library, 551, 553
-keeptempfiles driver option, 199 libedge.a library, 551, 553
-kernel driver option, 137 libedgnoe.a library, 551, 553
Kernel Project Builder option, 137 libeece.a library, 551, 553
-kernel=kernel_checked driver libeecnoe.a library, 551, 553
option, 137 libind.a
-kernel=kernel_fast driver option, 137 functions, 577
-kernel=kernel_nommu driver language-independent library, 577
option, 137 libind.a library, 551
-kernel=kernel_novirt driver option, 137 libmulti.a library, 552
-kernel=kernel_opt driver option, 137 libnoflt.a library, 552
-kernel=kernel_small driver option, 137 librarian
Koenig lookup, see argument-dependent commands, 315
lookup examples of using, 316
introduction to, 10
L overview, 314
-l driver option, 99, 141 librarian commands
-L driver option, 99, 141 -d, 315
-l linker option, 282 options for, 316
-L linker option, 282 -p, 315
labels -q, 315
assembly, 249, 253 -r, 315
__LANGUAGE_ASM__, 514 -t, 316
__LANGUAGE_C__, 514 -x, 316
__LANGUAGE_CXX__, 514 libraries, 436
language-independent library, 577 building with your project, 36
--late_tiebreaker driver option, 215 deleting files from, 315
Launcher, see MULTI Launcher EC++, 480, 514
.lcomm assembler directive, 274 EEC++, 477, 514
.lcp Output File Types, 74 examples of creating and using, 316
.ld file extension, 33, 70 incorporating changes, 580
See also linker directives files (*.ld) initialization, 591
__LDREX() intrinsic function, 546 libansi.a, 550
less buffered I/O, 555 libarch.a, 551
libansi.a, 436 libdbmem.a, 552
data structures, 561 libece.a, 551, 553
libansi.a library, 550 libecnoe.a, 551, 553

Green Hills Software, Inc. 715


Index
libedge.a, 551, 553 thumbpb, 550
libedgnoe.a, 551, 553 Library Directories Builder option, 99,
libeece.a, 551, 553 141
libeecnoe.a, 551, 553 libsce.a library, 551, 553
libind.a, 532, 551 libscnoe.a library, 551, 553
libmulti.a, 552 libsedge.a library, 551, 553
libnoflt.a, 552 libsedgnoe.a library, 551, 553
libsce.a, 551, 553 libstartup.a library, 299, 551, 583
libscnoe.a, 551, 553 libsys.a library, 299, 551, 584
libsedge.a, 551, 553 limit(), 311
libsedgnoe.a, 551, 553 limitations
libstartup.a, 551 alignment and size, 598
libsys.a, 551 C compiler, 440
linking to, 37 memory optimization, 606
searching, 282 thumb code generator, 104
setting options for, 61 <limits.h> header file, 596
Libraries Builder option, 99, 141 #line
library directories precompiled headers, and, 499
arm3, 549 line terminators
arm3b, 549 in assembler source statements, 250
arm3p, 549 Line Wrap Messages Builder option, 192
arm3pb, 549 __LINE__, 421, 513
arm4, 549 .linfix program section, 669
arm4b, 549 Link in Standard Libraries Builder
arm4p, 549 option, 217, 555
arm4pb, 549 Link Map Method Builder option, 218
arm5, 550 Link Mode Builder option, 217
arm5b, 550 --link_constprop driver option, 186
arm5p, 550 --link_filter driver option, 214
arm5pb, 550 --link_output_mode_linksafe driver
armfp, 550 option, 217
armfpb, 550 --link_output_mode_reuse driver
armfpp, 550 option, 217
armfppb, 550 --link_output_mode_safe driver
armvfp, 550 option, 217
armvfpb, 550 --link_output_mode_unlink driver
armvfpp, 550 option, 217
armvfppb, 550 --link_similar_pools driver option, 186
thumb, 550 Link-Time Constant Propagation Builder
thumbb, 550 option, 186
thumbp, 550 linkage, 503

716 MULTI: Building Applications for Embedded ARM


Index
inline functions, 627 standalone_ram.ld, 43
linker standalone_romcopy.ld, 43
advanced features, 307 standalone_romrun.ld, 43
assembly language requirements, 102 directory, specifying, 184
compressed ROM, 293 to 294, 309 editing with the Linker Directives File
ELF optional header output, 678 Editor, 45 to 47, 49
expressions, 295 example, 286
introduction to, 11 expressions, 295
invoking directly, 279 linker options for, 283
invoking with the Builder, 100 locating program sections in ROM and
invoking with the driver, 100, 278 RAM, 110
memory maps, 288 maximizing speed, 297
See also linker directives files (*.ld) MEMORY directive, 288
overview, 278 memory maps, 288
passing options to, 280 minimizing RAM usage, 297
porting guide, 311 New Project Wizard, specifying
program entry point, 284 with, 26
section maps, 289 opening in graphical editor, 39
symbols for, 106 OPTION directive, 287
syntax, 279 overview, 285
Linker Command File Builder preprocessing, 184
option, 185, 278 ROM and CROM, 294
Linker Directives Directory Builder section attributes, 292
option, 184 section maps, 289
Linker Directives File Editor SECTIONS directive, 289
editing expressions, 49 sections, including and renaming, 291
editing memory regions, 46 specifying options after, 185
editing sections, 47 specifying options before, 184
Hierarchy pane, 45 using, 70
Layout pane, 45 linker expression functions
overview, 45 absolute, 296
linker directives files (*.ld) addr, 296
associating with a Builder project, 44 align, 296
Builder and driver options for, 184 to error, 296
185 final, 296
CONSTANTS directive, 287 isdefined, 296
customizing run-time sections, 299 max, 296
defaults min, 296
standalone_pic.ld, 43 pack_or_align, 296
standalone_picpid.ld, 44 sizeof, 296
standalone_pid.ld, 43 Linker generated tables

Green Hills Software, Inc. 717


Index
__ghstable_[tablename], -o, 283
__ghsentry_[tablename][entryname], 304-overlap, 283
Linker Optimizations Builder -prog2, 283
option, 144, 186 -Q, 283
linker options -r, 283
-a, 280 -R, 283
-A, 280 -saferc, 283
-allabsolute, 280 -saferc_adv, 283
-allow_bad_relocations, 280 -saferc_req, 283
-append, 280 -skip_layout, 283
-C, 280 -stderr, 283
-callgraph, 280 -T, 283 to 284
-checksum, 281 -tvec, 284
-cmd, 281 -u symbol, 284
-codefactor, 281 -unalign_debug_sections, 284
-crc, 281 -undefined, 284
-D, 281 -underscore, 284
-delete, 281 -v, 284
-deletedebug, 281 -V, 284
-e, 281 -w, 284
-earlyabsolute, 281 -Y, 284
-explicit_padding, 281 linker section attributes
-extractall, 281 ABS, 292
-extractweak, 281 CLEAR, 293
@file, 280 CROM, 293 to 294
-help, 281 NOCLEAR, 293
-Help, 282 PAD, 293
-keep, 282 ROM, 293 to 294
-keepmap, 282 Linker Warnings Builder option, 184
-l, 282 Linker-Based Far Call Patching Builder
-L, 282 option, 134
-M, 282 --linker_link driver option, 214
-many_segments, 282 -linker_warnings driver option, 184
-map, 282 -list assembler option, 244
-maplines, 282 -list driver option, 99, 180
-merge_threshold, 282 little endian mode, 84
-multiple, 282 __LITTLE_ENDIAN__, 516
-no_crom, 282, 295 -littleendian driver option, 131
-no_strict_overlap_check, 283 __LL_BIT=n, 524
-nochecksum, 281 __LL_Is_64, 524
-nocpp, 282 __LLONG_BIT=n, 517

718 MULTI: Building Applications for Embedded ARM


Index
-lnk driver option, 185, 278 macro
.lnk file extension, 33 definition directives, 269
-lnkcmd driver option, 185, 278 MACRO, 524
Load Configuration Builder menu macro assembler, 242
item, 234 .macro assembler directive, 271
Load Module Builder menu item, 232 Macro Debugging Information Builder
local scalar variables, 653 option, 208
-locals_unchanged_by_longjmp driver .macrolabel assembler directive, 271
option, 213 macros
-locatedprogram driver option, 183 defining, 269
long long data type, 164, 460 main()
Long Long Support Builder option, 164, mixing languages, 591
460 _main(), 591, 594
long long type manifest expressions, 252
size, 517, 524 manual inlining, 626
long type Manual Template Instantiation Mode
size, 517, 524 Builder option, 174, 486, 492 to 493
__LONG_BIT=n, 517 Manuals Builder menu item, 237
__Long_Is_32, 524 -many_segments linker option, 282
__Long_Is_64, 524 -map driver option, 189
--long_lifetime_temps driver option, 215 map file
--long_long driver option, 164 generating, 282
longjmp() does not restore local vars Map File Cross-Referencing Builder
Builder option, 213 option, 189
loop invariant analysis optimization, 638 Map File Generation Builder option, 189
loop optimizations, 636 Map File Page Length Builder
Loop Optimize Specific Functions option, 189
Builder option, 146, 636 Map File Retention Builder option, 189
loop rotation optimization, 655 Map File Sorting Builder option, 189
Loop Unrolling Builder option, 203, 636, -map linker option, 282
639 .map Output File Types, 75
loop unrolling optimization, 639 -maplines driver option, 189
.lsbss assembler directive, 274 -maplines linker option, 282
.lst Output File Types, 75 .mar file extension, 70
.ltorg assembler directive, 272 __MAR intrinsic function, 540
math library, 577
M EC++ and, 480
-M linker option, 282 max linker expression function, 296
-Ma driver option, 189 max_endaddress(), 311
machine-specific arithmetic, 604 --max_inlining driver option, 213, 634

Green Hills Software, Inc. 719


Index
--max_inlining_unless_debug driver introduction to, 154
option, 213, 634 linker options for, 283
max_size(), 311 #pragma directives, 534
Maximize Optimizations Builder predefined macros for, 519
option, 145 MISRA C - Advisory Rules Level Builder
Maximum Number of Errors to Display option, 163
Builder option, 191 MISRA C - Required Rules Level Builder
.mbs file extension, 33 option, 163
-MD driver option, 81 MISRA C - Run-Time Checks Builder
.mdf file extension, 33 option, 163
.mem Output File Types, 75 MISRA C Rules - Character Set Builder
memory, 84 option, 155
alignment, 428 MISRA C Rules - Comments Builder
defining, 288 option, 156
leak reporting, 105 MISRA C Rules - Constants Builder
optimization option, 156
restrictions, 606 MISRA C Rules - Control FlowBuilder
problems with size, 608 option, 159
Memory Description File Builder MISRA C Rules - ConversionsBuilder
option, 131 option, 158
-memory driver option, 139, 183 MISRA C Rules - Declarations &
MEMORY linker directive, 288 Definitions Builder option, 157
memory maps, 288 MISRA C Rules - Environment Builder
See also linker directives files (*.ld) option, 155
memory optimization, 650 MISRA C Rules - ExpressionsBuilder
Memory Optimization Builder option, 158
option, 205, 427, 606 to 607, 650 to MISRA C Rules - FunctionsBuilder
651 option, 160
--memory_description_file driver MISRA C Rules - Identifiers Builder
option, 131 option, 156
memory-mapped I/O, 122 MISRA C Rules - Initialization Builder
-merge_threshold linker option, 282 option, 157
__MIA intrinsic function, 540 MISRA C Rules - OperatorsBuilder
__MIAPH intrinsic function, 540 option, 158
__MIAxy intrinsic function, 540 MISRA C Rules - Pointers and Arrays
min linker expression function, 296 Builder option, 161
Minimum Structure Alignment Builder MISRA C Rules - Preprocessor Builder
option, 165 option, 161
MISRA C, 426 MISRA C Rules - Standard Library
builder and driver options for, 154 to Builder option, 162
163

720 MULTI: Building Applications for Embedded ARM


Index
MISRA C Rules - Structs and Unions N
Builder option, 162 name lookup
MISRA C Rules - Types Builder template instantiation, 495
option, 156 name mangling, 503 to 504
__MISRA_i=n, 519 named labels, 253
mixed ARM/thumb, 102 Namespace Support Builder option, 169,
mixed language executable, 590 495
-Mn driver option, 189 namespaces, 466, 495
.mon Output File Types, 74 EC++ and, 480
Motor Industry Software Reliability EEC++ and, 477
Association C Rules, see MISRA C predefined macro for, 523
__MRA_HI intrinsic function, 540 std, 522
__MRA_LO intrinsic function, 540 template instantiation, and, 495
__msw, 524 __NAMESPACES, 523
__MULSH() intrinsic function, 537 --namespaces driver option, 169
MULTI Integrated Development near and far function calls, 115
Environment (IDE) __nearcall, 117
document set, 6 .need assembler directive, 276
online help, 13 new
overview, 2 array, predefined macro, 522
MULTI Launcher New Generation Compiler, 406
overview, 4 New Project Builder menu item, 224
MULTI Project Builder Help Builder New Project Wizard, 24 to 29
menu item, 237 New Window Builder menu item, 225
Multi-Byte Characters Builder ’new’ and ’delete’ Keyword Support
option, 167 Builder option, 170
--multibyte_chars driver option, 167 -new_assembler driver option, 219
-multiple driver option, 188 --new_for_init driver option, 214
multiple inheritance --new_inside_of_constructor driver
EC++ and, 479 option, 172
-multiple linker option, 282 --new_outside_of_constructor driver
multiple-section programs, 107 option, 172
Multiply-Defined Symbols Builder New-Style ’for-init’ Code Builder
option, 188 option, 193
__MULUH() intrinsic function, 537 New-Style Cast Support Builder
__MULUH64() intrinsic, 538 option, 171
--munch driver option, 214 --new_style_casts driver option, 171
mutable keyword, 466 nm utility, 504
EC++ and, 479 --no_additional_output driver
EEC++, and, 477 option, 183
-Mx driver option, 189

Green Hills Software, Inc. 721


Index
--no_alternative_tokens driver -no_dynamic driver option, 138
option, 167 --no_enum_overloading driver
--no_anachronisms driver option, 170 option, 215
-no_ansi_alias driver option, 153 -no_error_basename driver option, 192
--no_any_output_suffix driver -no_error_fortran_style driver
option, 199 option, 192
-no_arm_uk_asm driver option, 181 -no_event_logging driver option, 136
--no_array_new_and_delete driver --no_exceptions driver option, 153
option, 170 --no_explicit driver option, 170
--no_assembler_warnings driver --no_export driver option, 178
option, 216 --no_extern_inline driver option, 171
--no_auto_instantiation driver --no_for_init_diff_warning driver
option, 174, 177, 492 to 493 option, 193
-no_auto_interrupt_table driver --no_friend_injection driver option, 215
option, 131 -no_full_debug_info driver option, 208
--no_bool driver option, 169 -no_full_macro_debug_info driver
--no_brief_diagnostics driver option, 192 option, 208
--no_c_and_cpp_functions_are_distinct -no_gsize driver option, 190
driver option, 215 --no_guiding_decls driver option, 175
-no_callgraph driver option, 190 --no_hybrid_one_instantiation_per_object
-no_codefactor driver option, 186 driver option, 177
--no_comments driver option, 211 --no_implicit_extern_c_type_conversion
--no_common_implicit_initialization driver option, 171
driver option, 214 --no_implicit_include driver option, 175,
--no_commons driver option, 166 489 to 490
--no_coverage_analysis driver --no_implicit_typename driver
option, 147 option, 176
-no_crom linker option, 282, 295 --no_include_never driver option, 213
--no_debug driver option, 147 -no_include_once driver option, 210
-no_default_lnk driver option, 218 --no_initpipointers driver option, 197
-no_delete driver option, 186 --no_inline_tiny_functions driver
--no_dep_name driver option, 178 option, 203, 625
-no_discard_zero_initializers driver --no_inlining driver option, 213, 634
option, 134 --no_instantiate_extern_inline driver
-no_display_boot driver option, 138 option, 170
--no_display_error_number driver --no_integrity_posix driver option, 138
option, 196 -no_irel driver option, 138
--no_distinct_template_signatures driver -no_japanese_automotive_c driver
option, 175 option, 151
-no_dual_debug driver option, 209 --no_keep_static_symbols driver
-no_dwarf2dbo driver option, 209 option, 167

722 MULTI: Building Applications for Embedded ARM


Index
-no_kernel driver option, 137 --no_saferc_runtime driver option, 163
-no_libbsp driver option, 137 -no_search_for_dba driver option, 207
--no_link_constprop driver option, 186 --no_short_enum driver option, 164, 426
--no_link_filter driver option, 214 --no_slash_comment driver option, 153,
--no_link_similar_pools driver 461
option, 186 -no_stabs2dbo driver option, 209
-no_linker_warnings driver option, 184 -no_strict_overlap_check linker
-no_list driver option, 180 option, 283
-no_locals_unchanged_by_longjmp -no_strip_application driver option, 139
driver option, 213 -no_timer_profile driver option, 148
--no_long_long driver option, 164, 460 --no_trace_includes driver option, 150
_NO_LONGLONG, 517 --no_typename driver option, 178
--no_multibyte_chars driver option, 167 -no_undefined driver option, 188
-no_multiple driver option, 188 --no_unique_strings driver option, 166
--no_namespaces driver option, 169, 495 --no_unsafe_predefines driver
--no_new_style_casts driver option, 171 option, 211
--no_old_specializations driver --no_use_before_set_warnings driver
option, 176 option, 194
--no_one_instantiation_per_object driver -no_use_demo_library driver option, 136
option, 176 -no_use_dli_files driver option, 207
--no_parse_templates driver option, 178 -no_use_vp_as_dbg_source_root driver
--no_pch driver option, 179 option, 207
--no_pch_messages driver option, 179, --no_using_std driver option, 169
500 --no_version driver option, 191
--no_prelink_objects driver option, 177 --no_wrap_diagnostics driver option, 192
-no_preprocess_assembly_files driver -noautoregister driver option, 204, 654
option, 180 -nobigswitch driver option, 197
--no_preprocess_linker_directive driver -nochecksum driver option, 190
option, 184 -nochecksum linker option, 281
-no_preprocess_special_assembly_files NOCLEAR linker section attribute, 293
driver option, 180 --nocpp driver option, 214
--no_quit_after_warnings driver -nocpp linker option, 282
option, 191 .nodebug assembler directive, 275
--no_readonly_typeinfo driver :nodepends Builder option, 200
option, 172 -nodotciscxx driver option, 153
--no_readonly_virtual_tables driver -noentry driver option, 184
option, 173 -nofarcallpatch driver option, 134
--no_relative_xof_path driver option, 207 -nofarcalls driver option, 134
--no_remarks driver option, 191 __NoFloat, 518
--no_restrict driver option, 170 -nofloatio driver option, 133
--no_rtti driver option, 172 -noga driver option, 207

Green Hills Software, Inc. 723


Index
-nogtws driver option, 206 -O driver option, 95, 143, 624, 641
-noidentoutput driver option, 216 .o file extension, 32, 70
__noinline, 635 -o linker option, 283
-nokeepmap driver option, 189 -O1 driver option, 206
-nokeeptempfiles driver option, 199 -O2 driver option, 206
-nomap driver option, 189 -O3 driver option, 206
non-local static objects, 503 -OB driver option, 144, 631
non-portable features, 595 -obj driver option, 198
-non_shared driver option, 135 Object File Output Directory Builder
Non-Standard Output Suffix Builder option, 140, 177, 179
option, 199 object files
--nonstd_qualifier_deduction driver ELF format, 658, 672
option, 176 -object_dir driver option, 140
-noobj driver option, 198 -Ocond driver option, 206, 644
-nooverlap driver option, 190 -Oconstprop driver option, 204, 649
-nooverload driver option, 204, 653 -Ocse driver option, 204, 647
-nopasssource driver option, 180 -OI driver option, 95, 144, 146, 628
-nopic driver option, 133 -Oinitializers driver option, 205, 646
-nopid driver option, 133 -OL driver option, 146, 205, 606, 636
:noselfdepend Builder option, 200 -old_assembler driver option, 219
-nostartfiles driver option, 187 --old_for_init driver option, 214
-nostddef driver option, 210 --old_specializations driver option, 176
-nostdinc driver option, 211 -Olimit driver option, 641 to 642
-nostdlib driver option, 217, 551, 555 -Olimit=peephole driver option, 144
-nostrip driver option, 184 -Olimit=pipeline driver option, 144
.note assembler directive, 272 -Olink driver option, 144
.nothumb assembler directive, 276 -OM driver option, 205, 427, 606, 650
.thumb directive, 276 -Omax driver option, 145
-nothumb driver option, 135 -Omemfuncs driver option, 203
-nothumb_lib driver option, 135 -Ominmax driver option, 205, 650
NULL pointer one instantiation per object, 486
size of, 601 One Instantiation Per Object Builder
Number of parallel processes Builder option, 176 to 177
menu item, 231 --one_instantiation_per_object driver
numeric constants, 247 option, 176
NVPATH, 125 online help
Help menu, 13
O overview, 13
-o assembler option, 244 UNIX systems, 14
-o driver option, 72, 120, 140 Windows systems, 13

724 MULTI: Building Applications for Embedded ARM


Index
Only remove intermediate output Builder advanced, 607
menu item, 230 automatic register allocation, 654
__ONLY_STANDARD_KEYWORDS_IN_C, 519 Builder and driver options for, 143 to
-Onobig driver option, 144 146
-Onocond driver option, 206, 644 C/C++ minimum/maximum, 650
-Onoconstprop driver option, 204, 649 code factoring, 307
-Onocse driver option, 204, 647 CodeBalance optimization wizard, 11
-Onoinitializers driver option, 205, 646 CodeBalance optimizing wizard, 396
-Onoinline driver option, 144, 628 common subexpression
-Onolink driver option, 144 elimination, 647
-Onoloop driver option, 205, 636 constant folding, 655
-Onomax driver option, 145 constant propagation, 649
-Onomemfuncs driver option, 203, 632 data definition movement, 646
-Onomemory driver option, 205, 607, 650 dead code elimination, 651
-Onominmax driver option, 205, 650 inlining, 625
-Onone driver option, 143 loop, 636
-Onopeephole driver option, 205, 641 loop invariant analysis, 638
-Onopipeline driver option, 205, 642 loop rotation, 655
-Onostrfuncs driver option, 203, 633 loop unrolling, 639
-Onotailrecursion driver option, 204, 648 memory, 650
-Onounroll driver option, 203, 636, 639 partial redundancy elimination
-Onounroll8 driver option, 145, 639 optimization, 647
-Opeep driver option, 205, 641 peephole, 641
Open Project Builder menu item, 224 pipeline instruction scheduling, 642
operating system dependencies, 602 portability and, 605
operator register allocation by coloring, 653
delete[], 522 register coalescing, 654
new[], 522 static address elimination, 652
operator field, 249 strength reduction, 637
operator++, 468 tail recursion, 648
operator--, 468 Optimize All Appropriate Loops Builder
operators option, 205, 606, 636
precedence, 251 Optimize Specific Functions for Size
scalar expression, 251 Builder option, 146
type combinations and, 252 Optimize Specific Functions for Speed
-Opipeline driver option, 205, 642 Builder option, 146
Optimization Strategy Builder option, 95, __OPTIMIZE__, 522
143, 145 to 146, 203, 427, 535, 606, __OPTIMIZE_SIZE__, 522
624 to 625, 633, 635, 641 to 642, 644, optimizing compilers, 9
646 to 653 --option driver option, 219
optimizations OPTION linker directive, 287

Green Hills Software, Inc. 725


Index
Options Builder menu item, 235 Output Filename Builder option, 120,
order of evaluation, 603 140
.org assembler directive, 272 Output Filename for Generic Types
OS Directory Builder option, 136 Builder option, 200
-os_dir driver option, 136 :outputDir Builder option, 142
-Ospace driver option, 95, 143, 624, 635, :outputDirRelative Builder option, 199
641 :outputName Builder option, 200
-Ospeed driver option, 95, 143, 624 to -overlap driver option, 190
625, 641 -overlap linker option, 283
ostream, 480 -overlap_warn driver option, 190
-Ostrfuncs driver option, 203 -overload driver option, 204
-Otailrecursion driver option, 204, 648 overload keyword, 468
Other VC Command Builder menu Overloading of enums Builder
item, 234 option, 215
-Ounroll driver option, 203
-Ounroll8 driver option, 145 P
-Ounrollbig driver option, 145, 639 -p driver option, 93, 147
Output File Size Analysis Builder -P driver option, 177, 436
option, 190 -p librarian command, 315
Output File Type Builder option, 183 p_align ELF program header field, 679
Output File Types, 74 p_filesz ELF program header
.bmon.out, 74 field, 678
.dba, 74 p_flags ELF program header field, 678,
.dbo, 74 680
.dla, 74 p_memsz ELF program header field, 678
.dlo, 74 p_offset ELF program header
.dnm, 74 field, 678
.gmon.out, 74 p_paddr ELF program header field, 678
.graph, 74 p_type ELF program header field, 678
.idep, 74 p_vaddr ELF program header field, 678
.ii, 74 -pack driver option, 87, 165
.inf, 74 -pack=n, 520
.lcp, 74 pack_or_align linker expression
.lst, 75 function, 296
.map, 75 packing, 87
.mem, 75 Packing (Maximum Structure
.mon.out, 74 Alignment) Builder option, 87, 165
.run, 75 PAD linker section attribute, 293
.ti, 74 padding, 86
.time, 75

726 MULTI: Building Applications for Embedded ARM


Index
Parse Templates in Generic Form Builder Placement of Class Constructor Call to
option, 178 New Builder option, 172
--parse_templates driver option, 178 Placement of Zero-Initialized Data
partial redundancy elimination Builder option, 106, 134
optimization, 647 -pnone driver option, 147
Pass Through Arguments Builder POD, plain old data, 467
option, 201 pointer
-passsource driver option, 180 information, 518
:passThrough Builder option, 201 pointer arithmetic, 601
PCC (Portable C Compiler), 420, 603 pointer type
PCH, see precompiled header files size, 524
--pch driver option, 179, 497, 500 pointer-to-member, 465
PCH Messages Builder option, 179, 500 position independent code
PCH Search Directory Builder ABS linker section attribute and, 292
option, 179, 500 to 501 builder and driver options for, 112,
--pch_dir driver option, 179, 500 to 501 114, 133
--pch_messages driver option, 179 combining with non-PIC modules, 113
-pd assembler option, 256 debugger and, 113
-pd driver option, 181 .fixaddr program section and, 671
.pdf file extension, 33 ind_crt0.c and, 583
peephole optimization, 641 introduction to, 112
Peephole Optimization Builder linker directives file for, 43
option, 205, 641 predefined macros for, 519
permanent registers simulator and, 112
in interrupt processing, 120 Position Independent Code Builder
-pg driver option, 93, 147 option, 112, 133
-pic driver option, 112, 133 position independent data
PID ABS linker section attribute and, 292
modules builder and driver options for, 133
and non-PID modules, 115 debugger and, 114
-pid driver option, 114, 133 .fixaddr program section and, 671
Pipeline & Peephole Scope Builder ind_crt0.c and, 583
option, 144, 641 to 642 initializing the base register, 115
Pipeline Instruction Scheduling Builder introduction to, 114
option, 205, 642 linker directives file for, 43
pipeline instruction scheduling predefined macros for, 519
optimization, 642 simulator and, 114
__PKHBT() intrinsic function, 544 Position Independent Data Builder
__PKHTB() intrinsic function, 544 option, 114, 133
Place Under VC Builder menu item, 234 post processing, 503
:postexec Builder option, 201

Green Hills Software, Inc. 727


Index
:postexecShell Builder option, 201 startnoinline, 534,
#pragma __printf_args, 529 635
#pragma __scanf_args, 529 #pragma ghs startnomisra, 534
#pragma alignvar (n), 527 #pragma ghs
#pragma asm, 527 struct_min_alignment(n), 534
#pragma can_instantiate #pragma ghs thumb, 103, 534
fn, 487, 528 #pragma ghs ZO, 534
#pragma directives #pragma hdrstop, 497, 502, 528
#pragma ghs section, 107 #pragma ident "string", 528
#pragma intvect, 121 #pragma inline function-list, 528
#pragma do_not_instantiate #pragma instantiate, 177, 493
fn, 487, 528 #pragma instantiate fn, 487, 528
#pragma endasm, 527 #pragma intvect intfunc
#pragma ghs alias newsym integer_constant, 528
oldsym, 531 #pragma no_pch, 499, 502, 528
#pragma ghs #pragma once, 528
callmode=default, 117 #pragma pack, 87
#pragma ghs callmode=far, 117 #pragma pack (), 529
#pragma ghs callmode=near, 117 #pragma pack (n), 165, 529
#pragma ghs #pragma pack (pop {, name} {,
callmode=near|far|default, 531 n}), 529
#pragma ghs #pragma pack (push {, name}
check=(check-list), 532 {, n}), 529
#pragma ghs endnoinline, 534, #pragma unknown_control_flow
635 (function-list), 529
#pragma ghs endnomisra, 534 #pragma weak foo, 530
#pragma ghs endnowarning, 533 #pragma weak foo = bar, 530
#pragma ghs far, 117, 531 Pre-link with Instantiations Builder
#pragma ghs includeonce, 533 option, 177
#pragma ghs interrupt, 533 Precompiled Header File Builder
#pragma ghs near, 117, 531 option, 179, 497, 500 to 501
#pragma ghs nofloat precompiled header files, 497
interrupt, 533 automatic processing of, 497
#pragma ghs nothumb, 103, 534 builder and driver options for, 179,
#pragma ghs nowarning, 533 497, 500 to 501
#pragma ghs Ostring, 533 file contents, 499
#pragma ghs reference sym, 533 manual processing, 501
#pragma ghs revertoptions, 534 performance issues, 502
#pragma ghs section #pragma directives, 499, 502, 528
sect="name", 534 requirements, 498
#pragma ghs -predefine driver option, 256

728 MULTI: Building Applications for Embedded ARM


Index
predefined macro names __ghs_c_int__, 515
__ARM, 516 __GHS_Inline_Memory_Functions, 52
__ARM_DSP, 516 __GHS_Inline_String_Functions, 52
__ARRAY_OPERATORS, 522 __ghs_max_pack_value=n, 520
__BASE__, 521 __GHS_NOCOMMONS, 520
__BASE_FILE__, 522 __GHS_Optimize_Inline, 521
__BIG_ENDIAN__, 516 __ghs_packing=n, 520
_BOOL, 522 __ghs_pic=n, 519
__BSD, 521 __ghs_pid=n, 519
__c_plusplus, 514 __ghs_psinfo, 515
__CHAR_BIT=n, 517 __GHS_REVISION_DATE, 515
__Char_Is_Signed, 524 __GHS_REVISION_VALUE=n, 515
__Char_Is_Unsigned, 524 __ghs_stdcall, 515
__CHAR_UNSIGNED__, 518 __ghs_struct_min_alignment=n, 520
__COFF, 521 __GHS_VERSION_NUMBER=n, 516
__cplusplus, 513 __GlobalRegisters=n, 520
__DATE__, 421, 499, 513 __gnu_asm, 516
__DOUBLE_HL, 518 __IeeeFloat, 518
__EDG__, 515 __INT_BIT=n, 517, 522
__EDG_IMPLICIT_USING_STD, 522 __Int_Is_32, 524
__EDG_RUNTIME_USES_NAMESPACES, 523 __Int_Is_64, 524
__ELF, 521 __INTEGRITY, 523
__EMBEDDED_CXX, 514 introduction to, 512
__EMBEDDED_CXX_HEADERS, 514 __Japanese_Automotive_C, 514
__Enum_Field_Is_Signed__, 517 __LANGUAGE_ASM__, 514
__Enum_Field_Is_Unsigned__, 517 __LANGUAGE_C__, 514
__EXCEPTION_HANDLING, 523 __LANGUAGE_CXX__, 514
__EXCEPTIONS, 523 __LINE__, 421, 513
__EXTENDED_EMBEDDED_CXX, 515 __LITTLE_ENDIAN__, 516
__EXTENDED_EMBEDDED_CXX_HEADERS, 514
__LL_BIT=n, 524
to 515 __LL_Is_64, 524
__Field_Is_Signed__, 518 __LLONG_BIT=n, 517
__Field_Is_Unsigned__, 518 __LONG_BIT=n, 517
__FILE__, 421, 513, 522 __Long_Is_32, 524
___FULL_DIR__, 513 __Long_Is_64, 524
___FULL_FILE__, 513 MACRO, 524
__FUNCPTR_BIT=n, 517 __MISRA_i=n, 519
__FUNCTION__, 521 __msw, 524
__ghs__, 515 __NAMESPACES, 523
__ghs_alignment=n, 520 _NO_LONGLONG, 517
__ghs_asm, 515 __NoFloat, 518

Green Hills Software, Inc. 729


Index
:preexec Builder option, 200
__ONLY_STANDARD_KEYWORDS_IN_C, 519
__OPTIMIZE__, 522 :preexecShell Builder option, 201
__OPTIMIZE_SIZE__, 522 PreLink File to Create Template
__PRETTY_FUNCTION__, 521 Instances Builder option, 178
__PROTOTYPES__, 514 -prelink_against driver option, 178
__PTR_BIT=n, 517 --prelink_objects driver option, 177
__Ptr_Is_32, 524 Prepend String to Every Section Name
__Ptr_Is_64, 524 Builder option, 217
__Ptr_Is_Signed, 518 Preprocess Assembly Files Builder
__Ptr_Is_Unsigned, 518 option, 180, 242
__PTRDIFF_TYPE__, 522 Preprocess Linker Directives Files
__REG_BIT=n, 517 Builder option, 184
__Reg_Is_32, 524 Preprocess selected file Builder menu
__Reg_Is_64, 525 item, 229
__RTTI, 523 Preprocess Special Assembly Files
__SHRT_BIT=n, 517 Builder option, 180
__SIGNED_CHARS__, 518 -preprocess_assembly_files driver
__SIZE_TYPE__, 522 option, 180, 242
__SoftwareDouble, 518 --preprocess_linker_directive driver
__SoftwareFloat, 518 option, 184
__STANDARD_CXX, 515 -preprocess_special_assembly_files
__STANDARD_CXX_HEADERS, 515 driver option, 180, 256
__STDC__, 513 preprocessor
__STDC_VERSION__=199409L, 513 Builder and driver options for, 150
__STRICT_ANSI__, 514 overview, 435
__THREADX, 523 __PRETTY_FUNCTION__, 521
__THUMB, 516 .previous assembler directive, 272
__THUMB_AWARE, 516 Print Current View Builder menu
__TIME__, 421, 499, 513 item, 224
TX_ENABLE_EVENT_LOGGING, 523 Print Expanded Project Builder menu
__unix_asm, 516 item, 224
__USER_LABEL_PREFIX=symbol, 522 printf & scanf Argument Type Checking
__VXWORKS, 523 Builder option, 194
__WCHAR_BIT=n, 517 printf function, 557
__WChar_Is_Int__, 525 processor characteristics, 84
__WChar_Is_Long__, 525 processor supported, 90
__WChar_Is_Short__, 525 prof_960.c run-time code, 585
__WChar_Is_Signed__, 518 prof_mip.c run-time code, 585
__WChar_Is_Unsigned__, 518 profiling
_WCHAR_T, 523 Builder and driver options for, 147 to
__WCHAR_TYPE__, 522 148

730 MULTI: Building Applications for Embedded ARM


Index
call count, 147 .symtab, 670
coverage, 147 .syscall, 302, 584, 670
limitations with thumb code, 105 .text, 106, 298, 670
timing, 148 user-defined, 106
Profiling - Call Count Builder option, 93, .zbss, 671
147 .zdata, 671
Profiling - Coverage Builder option, 93, program variables, grouping, 107
147 project files
Profiling - Target-Based Timing Builder changing type of, 34, 38
option, 94, 148 creating, 34
-prog2 linker option, 283 editing, 39
program data, position-independent, 114 inheriting options in, 61
program entry point, 281, 284 rearranging order of, 38
program headers, 678 searching for, 40
program sections searching in, 40
begin, end, and size symbols for, 302 types of, 32, 34
.bss, 106, 669 projects
.data, 106, 298, 669 adding headers to, 37
ELF indexes, 666 adding libraries to, 36
ELF program types, 679 adding source files to, 35
ELF section attribute flags, 667 building, 62
ELF section types, 667 creating files in, 34
.fixaddr, 299, 671 creating source files for, 35
.fixtype, 299, 671 editing file hierarchy of, 38
header conditions, 664 introduction to, 20
.heap, 300, 671 linking libraries to, 37
.intercall, 300 searching for files in, 40
.interfunc, 300 setting options for, 61
.linfix, 669 --prototype_errors driver option, 193
names, 668 --prototype_silent driver option, 193
.rel, 669 --prototype_warnings driver option, 193
.rela, 669 prototypes
.rodata, 106, 298, 300, 669 predefined macro, 514
.ROM, 300 __PROTOTYPES__, 514
.sbss, 671 PT_DYNAMIC ELF program type, 679
.sdabase, 301, 671 PT_HIPROC ELF program type, 680
.sdata, 671 PT_INTERP ELF program type, 679
.secinfo, 301, 310, 670 PT_LOAD ELF program type, 679
.shstrtab, 669 PT_LOPROC ELF program type, 680
.stack, 301, 671 PT_NOTE ELF program type, 679
.strtab, 670 PT_NULL ELF program type, 679

Green Hills Software, Inc. 731


Index
PT_PHDR ELF program type, 680 Recent Projects Builder menu item, 224
PT_SHLIB ELF program type, 679 Recognition of Exported Templates
__PTR_BIT=n, 517 Builder option, 178, 465, 490
__Ptr_Is_32, 524 Redirect Error Output to File Builder
__Ptr_Is_64, 524 option, 191
__Ptr_Is_Signed, 518 reentrant functions, in C run-time
__Ptr_Is_Unsigned, 518 libraries, 557
__PTRDIFF_TYPE__, 522 __REG_BIT=n, 517
__Reg_Is_32, 524
Q __Reg_Is_64, 525
-Q driver option, 73 Register Allocation by Coloring Builder
-q librarian command, 315 option, 204, 653
-Q linker option, 283 register allocation by coloring
__QADD intrinsic function, 538 optimization, 653
__QDADD intrinsic function, 538 register coalescing optimization, 654
__QDSUB intrinsic function, 538 Register Description File Builder
__Qoperation() intrinsic function, 541 option, 131
__QSUB intrinsic function, 538 register usage, 85
Quit Building if Warnings are Generated --register_definition_file driver
Builder option, 191 option, 131
--quit_after_warnings driver option, 191 registers
quoted string expressions, 252 allocator, 639
I/O, 122
implied usage of, 605
R size of, 524 to 525
-r librarian command, 315 .rel program section, 669
-r linker option, 283 .rela program section, 669
-R linker option, 283 relative position of data objects, 598
r_addend ELF relocation field, 672 Relative Xof Path Builder option, 207
r_info ELF relocation field, 672 --relative_xof_path driver option, 207
r_offset ELF relocation field, 672 -relobj driver option, 183
RAM, placing variables in, 107 relocatable expressions, 252
.rc file extension, 33 Relocatable Module Base Image Builder
--readonly_typeinfo driver option, 172 option, 138
--readonly_virtual_tables driver Relocatable Module Builder option, 138
option, 173 relocatable object files, 183, 658, 672
Rebuild selected file Builder menu relocatable output file, 280
item, 229 relocation directories
rebuilding for ELF object files, 672
Green Hills libraries, 580 relocation information, 283
Recent Files Builder menu item, 224 relocation types, 672

732 MULTI: Building Applications for Embedded ARM


Index
-relprog driver option, 183 EEC++ and, 477
Remarks Builder option, 191 __RTTI, 523
--remarks driver option, 191 --rtti driver option, 172
Remove selected file Builder menu .run Output File Types, 75
item, 226 run-time
repeat block directives, 271 copy and clear sections, 310
.rept assembler directive, 272 environment, 119
reserved symbols, 246 error checking, 148, 532
--restrict driver option, 170 libraries, 548
restrict keyword, 471 library, 436
’restrict’ Keyword Support Builder memory checking, 149
option, 170 type information
restrictions predefined macro, 523
memory optimization, 606 run-time code
ret pseudo instruction, 103 customizing, 299
Retain Comments During Preprocessing ind_bcnt.c, 585
Builder option, 211 ind_call.arm, 584
Retain Symbols for Unused Statics ind_crt1.c, 585
Builder option, 167 ind_dots.arm, 584
Retrieve Builder menu item, 234 ind_errn.c, 585
__REV() intrinsic function, 546 ind_exit.c, 587
__REV16() intrinsic function, 546 ind_gcnt.arm, 585
Revert to Saved Project Builder menu ind_gpid.c, 585
item, 224 ind_gprf.c, 585
revision tracking, 275 ind_heap.c, 586
__REVSH() intrinsic function, 541 ind_io.c, 586
__RIR() intrinsic function, 536 ind_iob.c, 587
.rodata assembler directive, 273 ind_mcnt.arm, 585
.rodata data section, 297 ind_mprf.c, 585
.rodata directive, 300 ind_reset.c, 584
.rodata program section, 106, 298, 300, ind_targ1.c, 585
669 ind_thrd.c, 585
ROM libsys.a, 299, 584
putting data in, 297 prof_960.c, 585
ROM linker section attribute, 293 to 294 prof_mip.c, 585
.ROM program section, 300 special program sections, 299
routines run-time error checking
mixed ARM/thumb requirements, 102 Builder and driver options for, 148
RTTI, 172, 466 #pragma, 532
EC++, 481 Run-Time Error Checks
EC++ and, 480 custom example, 149

Green Hills Software, Inc. 733


Index
Run-Time Error Checks Builder Search Path for .dbo Files Builder
option, 148, 532 option, 207
run-time memory checking -search_for_dba driver option, 207
Builder and driver options for, 149 searching
#pragma, 532 for Builder options, 58
Run-Time Memory Checks Builder for files in your project, 40
option, 149, 207 in files, 40 to 41
run-time type information, see RTTI __secinfo, 111
Run-Time Type Information Support .secinfo program section, 301, 310,
Builder option, 172 670
.section assembler directive, 273
S section maps, 289
-S driver option, 71, 73, 177, 243 See also linker directives files (*.ld)
.s file extension, 32, 70 Section Overlap Checking Builder
__SADD16TO32() intrinsic option, 190
function, 541 --section_prefix driver option, 217
__SADD8TO16() intrinsic function, 541 --section_suffix driver option, 217
__SADD8TO32() intrinsic function, 541 sections
--saferc driver option, 155 to 162 attributes, 311
-saferc linker option, 283 control directives, 272
--saferc_adv driver option, 163 defining, 289
-saferc_adv linker option, 283 #pragma directive, 107
--saferc_req driver option, 163 run-time information, 310
-saferc_req linker option, 283 SECTIONS linker directive, 289
--saferc_runtime driver option, 163 __SEL16() intrinsic function, 544
Save Configuration as Default Builder __SEL8() intrinsic function, 544
menu item, 234 :select Builder option, 201
Save Configuration Builder menu ’Select One’ Project Extension List
item, 234 Builder option, 201
Save Project Builder menu item, 224 Self-Dependency Builder option, 200
.sbss assembler directive, 275 .set assembler directive, 250, 275
.sbss program section, 671 Set Build Macros Builder menu item, 226
scalar variables, 653 Set Build Target Builder menu item, 226
scxx header file directory, 549 Set Imported Environment Variables
.sdabase program section, 301, 671 Builder menu item, 227
.sdata program section, 671 Set Message to Error Builder option, 195
Search for DBA Builder option, 207 Set Message to Remark Builder
Search in Files dialog box, 40 option, 195
Search in Files Results window, 41 Set Message to Silent Builder option, 195
Search in selected file Builder menu Set Message to Warning Builder
item, 226 option, 195

734 MULTI: Building Applications for Embedded ARM


Index
Set Options Builder menu item, 225 SHF_WRITE ELF section attribute
Set Options in Parent Builder menu flag, 668
item, 227 shift operators, 604
Set Type Builder menu item, 225 SHN_ABS ELF section index, 666
__SETEND_BE() intrinsic function, 546 SHN_COMMON ELF section index, 666
__SETEND_LE() intrinsic function, 546 SHN_GHS_SMALLCOMMON ELF section
__SETSR() intrinsic function, 536 index, 666
__SETSSR() intrinsic function, 537 SHN_GHS_TINYCOMMON ELF section
Settings Builder menu item, 229 index, 666
sh_addr ELF section header field, 665 SHN_GHS_ZERO_COMMON ELF section
sh_addralign ELF section header index, 666
field, 666 SHN_UNDEF ELF section index, 666, 668
sh_entsize ELF section header __SHoperation() intrinsic function, 542
field, 666 short data type
sh_flags ELF section header field, 665, size of, 517
667 variable arguments, 432
sh_info ELF section header field, 666, --short_enum driver option, 85, 164, 431
668, 673 --short_lifetime_temps driver option, 215
sh_link ELF section header field, 666, shortcut commands
668, 673 backward, 40
sh_name ELF section header field, 665, forward, 40
677 Show build without execution Builder
sh_offset ELF section header menu item, 231
field, 665 Show Full Paths Builder menu item, 226
sh_size ELF section header field, 665, Show History Builder menu item, 234
677 Show internal commands Builder menu
sh_type ELF section header field, 665, item, 231
668 Show tool commands Builder menu
Shadow Declarations Builder option, 194 item, 231 to 232
Shared Libraries Builder option, 135 __SHRT_BIT=n, 517
SHF_ALLOC ELF section attribute .shstrtab program section, 669
flag, 668 SHT_NOTE ELF section type, 667
SHF_EXECINSTR ELF section attribute SHT_NULL ELF section type, 667
flag, 668 SHT_PROGBITS ELF section type, 667
SHF_FIREPATH_FNSC ELF section SHT_REL ELF section type, 667 to 668
attribute flag, 668 SHT_RELA ELF section type, 667 to 668
SHF_GHS_ABS ELF section attribute SHT_STRTAB ELF section type, 667
flag, 668 SHT_SYMTAB ELF section type, 667 to
SHF_GHS_BSS ELF section attribute 668
flag, 668 signed keyword, 421
--signed_chars driver option, 163, 444

Green Hills Software, Inc. 735


Index
__SIGNED_CHARS__, 518 __SMMUL() intrinsic function, 543
--signed_enum_fields driver option, 164 __SMMULR() intrinsic function, 543
--signed_fields driver option, 164, 429 __SMUAD() intrinsic function, 543
--signed_pointer driver option, 164 __SMUADX() intrinsic function, 543
Signedness of Bitfields Builder __SMULL() intrinsic, 537
option, 164, 426, 429, 508 __SMULWy intrinsic function, 539
Signedness of Char Type Builder __SMULxy intrinsic function, 539
option, 163, 426, 444, 506 __SMUSD() intrinsic function, 543
Signedness of Enum Type Builder __SMUSDX() intrinsic function, 543
option, 164 software floating point, 84
Signedness of Pointers Builder __SoftwareDouble, 518
option, 164 __SoftwareFloat, 518
Similar Pool Merging Builder option, 186 __Soperation() intrinsic function, 542
Simplify All Filenames Builder menu -source assembler option, 244
item, 227 source code
simulator interleaving with assembly code, 180
PIC and, 112 Source Directories Relative to This File
PID and, 114 Builder option, 141
single-pass inlining, 626 Source Directories Relative to Top-Level
.size assembler directive, 275 Project Builder option, 199
size(), 311 source files
__SIZE_TYPE__, 522 adding and creating, 35
sizeof linker expression function, 296 setting options for, 61
-skip_layout linker option, 283 source files for customization, 119
--slash_comment driver option, 153 source level debugging
--small driver option, 146 problems, 607
__SMLAD() intrinsic function, 542 source listing, 244
__SMLADX() intrinsic function, 542 Source Listing Generation Builder
__SMLAL() intrinsic, 537 option, 99, 180
__SMLALD() intrinsic function, 543 Source Root Builder option, 140
__SMLALDX() intrinsic function, 543 :sourceDir Builder option, 141
__SMLAWy intrinsic function, 539 :sourceDirNonRelative Builder
__SMLAxy intrinsic function, 539 option, 199
__SMLSD() intrinsic function, 542 .space assembler directive, 268
__SMLSDX() intrinsic function, 542 specifying individual functions to
__SMLSLD() intrinsic function, 543 inline, 628
__SMLSLDX() intrinsic function, 543 spl instruction, 613
__SMMLA() intrinsic function, 543 -srec driver option, 183
__SMMLAR() intrinsic function, 543 __SSAT() intrinsic function, 544
__SMMLS() intrinsic function, 543 __SSAT16() intrinsic function, 545
__SMMLSR() intrinsic function, 543 __SSATR() intrinsic function, 545

736 MULTI: Building Applications for Embedded ARM


Index
st_info ELF symbol table entry, 674 constructors and destructors, 503, 591,
st_name ELF symbol table entry, 674 594
st_other ELF symbol table entry, 674 static address elimination
st_shndx ELF symbol table entry, 675 optimization, 652
to 676 STB_GLOBAL ELF symbol binding, 675
st_size ELF symbol table entry, 674 STB_HIPROC ELF symbol binding, 675
st_value ELF symbol table entry, 674, STB_LOCAL ELF symbol binding, 675
676 STB_LOPROC ELF symbol binding, 675
-stabs_to_dbo driver option, 209 STB_WEAK ELF symbol binding, 675
stack -std driver option, 465
generating frame to support traces, 206 --std driver option, 152, 212, 464, 553
stack characteristics, 84 -STD driver option, 465
.stack program section, 301, 671 --STD driver option, 152, 212, 409, 464,
-stack_debug assembler option, 244 553
Standard C++, 465 std namespace, 522
standard I/O package, 555 -std_cxx_include_directory driver
Standard Include Directories Builder option, 212
option, 211 --std_qualifier_deduction driver
__STANDARD_CXX, 515 option, 176
__STANDARD_CXX_HEADERS, 515 <stdarg.h>, 432 to 433, 600
--standard_vtbl driver option, 173 __STDC__, 513
Start Address Symbol Builder __STDC_VERSION__=199409L, 513
option, 120, 184 stderr, 592
Start File Directory Builder option, 187 -stderr driver option, 191
Start Files Builder option, 187 -stderr linker option, 283
Start Launcher Builder menu item, 235 stdin, 592
Start of .data Section Builder option, 218 -stdinc driver option, 211
Start of .text Section Builder option, 218 stdio, 555
start-up module --stdl driver option, 152, 515, 553
rebuilding, 580 --stdle driver option, 152, 515, 551, 553
-startfile_dir driver option, 187 -stdlib driver option, 217
-startfiles driver option, 187 stdout, 592
startup code Stop after cleaning output Builder menu
crt0.o, 299, 581 item, 230
ind_bcpy.c, 583 streambuf, 480
ind_crt0.c, 583 strength reduction optimization, 637
ind_mcpy.c, 584 __STREX() intrinsic function, 546
ind_mset.c, 584 __STRICT_ANSI__, 514
ind_reset.c, 584 -strict_overlap_check driver option, 190
libstartup.a, 299, 583 string, 480
static .string assembler directive, 268

Green Hills Software, Inc. 737


Index
string constants, 247 Support for ’typename’ Keyword Builder
string literals, 468, 471 option, 178
string tables, 677 Support for Constructors/Destructors
string, C++ class Builder option, 172
EC++, 480 Support for Friend Injection Builder
strings not referenced, 677 option, 215
-strip driver option, 100, 184 Support for Implicit Extern C Type
-strip_application driver option, 139 Conversion Builder option, 171
.strtab program section, 670 Support for Implicit Typenames Builder
struct data type, 421, 428, 470 option, 176
alignment, 534 Support for Inline Functions with Extern
packing, 520 Builder option, 171
portability, 599 Support for Nonstd Qualifier Deduction
--struct_min_alignment driver Builder option, 176
option, 165 Support for Old-Style Specializations
--struct_min_alignment=1 driver Builder option, 175 to 176
option, 165 Support For Very Large Switch
--struct_min_alignment=2 driver Statements Builder option, 197
option, 165 Suppress Dependencies Builder
--struct_min_alignment=4 driver option, 200
option, 165 --suppress_vtbl driver option, 173
--struct_min_alignment=8 driver switch statement, 466
option, 165 symbol tables, 674
structure packing, 87 symbolic
STT_FILE ELF symbol type, 676 debugging directives, 275
STT_FUNC ELF symbol type, 675 memory-mapped I/O, 122
STT_HIPROC ELF symbol type, 676 symbols
STT_LOPROC ELF symbol type, 676 bindings, 675
STT_NOTYPE ELF symbol type, 675 definition directives, 273
STT_OBJECT ELF symbol type, 675 definition of, 302
STT_SECTION ELF symbol type, 675 types, 675
subprojects values, 676
setting options for, 61 .symtab program section, 670
__SUNPK16TO32() intrinsic -syntax driver option, 73
function, 545 -sys_include_directory driver option, 212
__SUNPK8TO16() intrinsic .syscall program section, 302, 584,
function, 545 670
__SUNPK8TO32() intrinsic System Include Directories Builder
function, 545 option, 212
Support __noinline Keyword Builder
option, 170, 635

738 MULTI: Building Applications for Embedded ARM


Index
T parameters, 466 to 467
-t librarian command, 316 partial specialization of, 467
-T linker option, 283 to 284 #pragma directives, 487
Tail Recursion Builder option, 204, 648 prelinker, 177, 484
tail recursion optimization, 648 specialization, 481, 485
-tall driver option, 174 specialization syntax, 467
target typename keyword, 178
specifying, 228 Temporaries’ Lifetime Builder
Target Processor Builder option, 197 option, 215
Task Window Builder menu item, 232 Temporary Output Builder option, 199
-Tdata driver option, 218 Temporary Output Directory Builder
template option, 198
automatic instantiation of, 484 .text assembler directive, 273
Template Instantiation Output Directory -text option, 113
Builder option, 177 .text program section, 106, 298, 670
templates, 467 The Draft Standard C++ Library, 480
automatic instantiation of, 174, 482 .thm file extension, 32, 70
builder and driver options for, 173 to __THREADX, 523
178 ThreadX Demo Library Directory
building with Clearmake, 491 Builder option, 136
class, 481 -threadx_demo_dir driver option, 136
default arguments, 468 thumb
dependent name processing, 178 characteristics, 101
distinct signatures, 175 chips that support, 101
EC++ and, 480 code generator limitations, 104
EEC++ and, 477 mixed with ARM code, 102
entity, 481 switching between ARM, 102
explicit instantiation of, 467 __THUMB, 516
exported templates, 178, 484, 490 .thumb assembler directive, 276
friend declarations, 466 thumb code
function, 481 floating-point limitations, 105
function inlining, 635 Thumb Code Generation Builder
function templates, 466 to 467 option, 101, 135
guiding declarations, 175 -thumb driver option, 101, 135
implicit inclusion of, 175, 484, 488 Thumb Libraries Builder option, 101,
instantiation and namespaces, 495 135
instantiation directory, 177 thumb library directory, 550
instantiation modes, 486 __THUMB_AWARE, 516
instantiation of, 481 -thumb_lib driver option, 101, 135
manual instantiation of, 174 thumbb library directory, 550
member templates, 467

Green Hills Software, Inc. 739


Index
thumbp library directory, 550 U
thumbpb library directory, 550 -u driver option, 188
.ti file, 484 -U driver option, 150
.ti Output File Types, 74 -u symbol linker option, 284
Tiebreaker Processing Time Builder __UADD16TO32() intrinsic
option, 215 function, 541
.time Output File Types, 75 __UADD8TO16() intrinsic function, 541
__TIME__, 421, 513 __UADD8TO32() intrinsic function, 541
precompiled header files and, 499 __UHoperation() intrinsic function, 542
-timer_profile driver option, 94, 148 __UMAAL() intrinsic function, 544
-tlocal driver option, 174 __UMLAL() intrinsic, 537
-tmp driver option, 198 __UMULL() intrinsic, 537
-tnone driver option, 174, 493 -unalign_debug_sections linker
Toyota Motor Corporation, 426 option, 284
Transition C unary, 251
variable arguments, 432 Undefine Preprocessor Symbol Builder
Treat .bss as Commons Builder option, 150
option, 214 undefined behavior, 442
Treatment of RTTI as ’const’ Builder -undefined driver option, 188
option, 172 undefined expressions, 252
Treatment of Virtual Tables as ’const’ -undefined linker option, 284
Builder option, 173 Undefined Preprocessor Symbols Builder
Trigraphs Builder option, 194 option, 195
Troubleshooting Info Builder menu undefined symbol references, 284
item, 237 Undefined Symbols Builder option, 188
try -underscore linker option, 284
function block, 468 union data type, 421, 428, 470
-Ttext driver option, 218 portability, 599
-tused driver option, 174, 492 --unique_strings driver option, 166
-tvec linker option, 284 Uniquely Allocate All Strings Builder
two-pass inlining, 627 option, 166, 506
TX_ENABLE_EVENT_LOGGING, 523 __unix_asm, 516
.txt file extension, 33 Unknown #pragmas Builder option, 193,
type combinations, 252 526
type qualifiers, 427 --unknown_pragma_errors driver
treatment in GNU C, 416 option, 193, 526
typeid, 466 --unknown_pragma_silent driver
See also RTTI option, 193, 526
--typename driver option, 178
typename keyword, 467
typographical conventions, 15

740 MULTI: Building Applications for Embedded ARM


Index
--unknown_pragma_warnings driver --use_pch driver option, 179, 501
option, 193 -use_vp_as_dbg_source_root driver
Unroll Larger Loops Builder option, 145, option, 207
639 user-defined variable, 298
Unroll Loops Up To 8 Times Builder __USER_LABEL_PREFIX=symbol, 522
option, 145, 639 --using_std driver option, 169, 522
--unsafe_predefines driver option, 211, utility programs, 320
512 gasmlist, 321
--unsigned_chars driver option, 163, 426, gbin2c, 325
444 gbincmp, 333
--unsigned_enum_fields driver gbldconvert, 335
option, 164 gbuild, 336
--unsigned_fields driver option, 164, 426, gcolor, 342
429 gcompare, 346
--unsigned_pointer driver option, 164 gdump, 349
unspecified behavior, 442 gfile, 356
__Uoperation() intrinsic function, 542 gfunsize, 357
__UQoperation() intrinsic function, 542 ghexfile, 358
__USAD8() intrinsic function, 545 ghide, 362
__USADA8() intrinsic function, 546 gmemfile, 363
__USAT() intrinsic function, 544 gnm, 370
__USAT16() intrinsic function, 545 grun, 378
__USATR() intrinsic function, 545 gsize, 380
Use Before ’Set’ Builder option, 194 gsrec, 382
Use Debug Library List (.dli) Files gstack, 387
Builder option, 207 gstrip, 389
Use Floating-Point in stdio Routines gversion, 390
Builder option, 133 gwhat, 392
Use lock files Builder menu item, 231 to __UUNPK16TO32() intrinsic
232 function, 545
Use Smallest Type Possible for Enum __UUNPK8TO16() intrinsic
Builder option, 85, 164, 426, 431, 507 function, 545
Use ThreadX Demo Library Builder __UUNPK8TO32() intrinsic
option, 136 function, 545
Use Utilities Builder menu item, 235
Use ViewPath as Source Root Builder V
option, 207 -v assembler option, 244
--use_before_set_warnings driver -v driver option, 76
option, 194 -V driver option, 191
-use_demo_library driver option, 136
-use_dli_files driver option, 207

Green Hills Software, Inc. 741


Index
-v linker option, 284 _WCHAR_T, 523
-V linker option, 284 wchar_t data type, 466
values wchar_t type
representable range, 596 predefined macro, 523
<varargs.h>, 432, 600 predefined macros, 518
variable size, 517
alignment, 527 __WCHAR_TYPE__, 522
not used checking, 532 .weak assembler directive, 275
variable arguments, 432 -Wformat driver option, 194
variables while statement, 465 to 466
allocation, 607 whitespace, 250
local, automatic allocation, 654 -Wimplicit-int driver option, 194
placement of for embedded -Wl, driver option, 184
development, 107 -Wno-format driver option, 194
Version Control Builder menu item, 234 -Wno-implicit-int driver option, 194
version number -Wno-shadow driver option, 194
generating from compiler driver, 191 -Wno-trigraphs driver option, 194
View Build Details Builder menu -Wno-undef driver option, 195
item, 229 .word assembler directive, 269
viewpathing, 123 word size, 596
virtual base class workspaces
EC++ and, 479 overview, 5
Virtual Function Definition Builder --wrap_diagnostics driver option, 192
option, 173 Write Expanded Project to File Builder
void data type, 421, 468 menu item, 224
volatile keyword, 421, 427, 606, 651 -Wshadow driver option, 194
__VXWORKS, 523 -Wtrigraphs driver option, 194
-Wundef driver option, 195
W
-w assembler option, 244 X
-w driver option, 191, 443 -X driver option, 219
-w linker option, 284 -x librarian command, 316
Warnings Builder option, 191, 443 X-Switches Builder option, 219
--warnings driver option, 191 --xref=declare driver option, 208
__WCHAR_BIT=n, 517 --xref=full driver option, 208
__WChar_Is_Int__, 525 --xref=global driver option, 208
__WChar_Is_Long__, 525 --xref=none driver option, 208
__WChar_Is_Short__, 525 XScale extensions
__WChar_Is_Signed__, 518 using intrinsic functions, 539
__WChar_Is_Unsigned__, 518

742 MULTI: Building Applications for Embedded ARM


Index
Y -YL, driver option, 202
-Y linker option, 284
-Y0, driver option, 202 Z
-Ya, driver option, 202 .zbss program section, 671
-Yl, driver option, 202 .zdata program section, 671

Green Hills Software, Inc. 743

You might also like