     [file version.texi not included]

This file documents the use of PRC-Tools, version version.

Using PRC-Tools
***************

This manual documents the extra tools and particular caveats associated with using the GNU Compiler Collection, GCC, to compile programs for Palm OS. It corresponds to prc-tools version version, and was last modified on updatedfull.

Palm OS-specific GCC features
*****************************

The modifications to GCC to support Palm OS programming add several new command line options and function attributes to GCC.  Additionally, a few standard GCC features are not supported.

Palm OS-specific GCC options
============================

GCC for Palm OS supports the following options, in addition to all the usual target-independent and M68K-specific options.

-mpcrel
     Activate Palm OS-specific code generation patterns.  This is turned on by default in the specs file; don't ever turn it off!

-mdebug-labels
     Put each function's name into the text section immediately after the function's code, in MacsBug format.

-mextralogues
     Activate extralogue attributes.  See Entry points.

-mown-gp
     Access global data via the A4 register, and activate owngp attributes.  By default, global data are accessed via A5, and owngp attributes have no effect.  See Global data.

     This option implies -mextralogues.

-palmosN
     Select system header files and libraries for Palm OS SDK version N. By default, the SDK selected as the default SDK the last time palmdev-prep was run will be used (see palmdev-prep).

-palmos-none
     Don't add any Palm OS SDK directories or other directories from any PalmDev trees to the include and library search paths.

There is also a -mno-X option corresponding to each of the -mX options, but you shouldn't ever need to use them.

Function attributes
===================

You specify a function attribute in the declaration of the function. In addition to the standard ones (see Declaring Attributes of Functions (Using and Porting GCC)), Palm OS defines the following function attributes:

callseq (INSNS)
     A function with a callseq attribute is called using the assembly language instructions in INSNS, which may implement a Palm OS systrap or something more esoteric.  The argument INSNS must be a string literal.

     Generally you won't use the callseq attribute directly; instead, there are macros defined in PalmTypes.h.

systrap (VECTOR)
     The systrap attribute specifies that the function should be called using the Palm OS systrap mechanism.  The integer VECTOR may be either a literal such as 0xa000 or a constant value such as an enumeration constant.  More complicated expressions are not permitted.

     This attribute is deprecated and will be removed from a future version of prc-tools.  New code should use callseq instead.

     You shouldn't use the systrap attribute directly; instead, you should use the SYS_TRAP macro defined in CoreTraps.h.

owngp
     When -mown-gp is used, the owngp attribute causes the function to save the A4 register on entry, and restore it on exit.

     You shouldn't use owngp directly; instead, you should use the macros defined in EntryPoints.h.

extralogue (PROLOGUE, EPILOGUE,...)
     When -mextralogues is used, the extralogue attribute causes the function to add code to its prologue and epilogue according to the arguments given.  See Entry points, for details.

     You shouldn't use extralogue directly; instead, you should use the macros defined in EntryPoints.h.

section (SECTION-NAME)
     This attribute is a standard one, and is used on Palm OS to indicate functions which should be placed in a code resource other than the default code #1.

In theory, the commonly used attributes differ in their ``required visibilities'':

  * A systrap or callseq attribute is only important to anyone calling the function.  (You don't usually define such functions yourself anyway.)

  * Callers don't care that a function has an extralogue or saves its owngp; these really only have effects when the code for that function is generated.

  * On Palm OS, a function's section is important both to itself (it determines what section the code is put in) and to other functions calling it (it can cause a special cross-section calling sequence to be emitted).

In practice, probably the best policy is to have exactly one declaration for each function that needs one, in a header file somewhere, and to use -Wimplicit (which is implied by -Wall), and possibly also -Wmissing-declarations, to ensure that the declaration is visible when it needs to be (see Options to Request or Suppress Warnings (Using and Porting GCC)).

Unsupported GCC features
========================

The following GCC options are not currently supported on Palm OS:

-p
-pg
-a
-ax
-fprofile-arcs
-fbranch-probabilities
     Probably profiling is unsupported.  Certainly the support functions in libgcc aren't being included, because they depend on non-existent stdio support.

-ftest-coverage
     A similar comment applies to the gcov data file.

-ffunction-sections
     This option sets each function's section after function calls are generated.  This is too late to be effective because we need to emit special code for cross-section function calls.

-mbitfield
-m68020
-m68881
     These and other M68K hardware selection options will cause your programs to fail horribly.

-mrtd
     This selects code generation patterns which disagree with the conventions used by the Palm OS API functions, so will fail horribly.

There are also the following caveats:

  * While describing the section attribute, the GCC manual suggests using the linker to split an executable into sections.  Just like -ffunction-sections, this doesn't work.

  * The __complex__ extension doesn't work.

  * The -Wmultichar warning is off by default, even if you use -Wall.

  * If -mpcrel is on, as it always is, any -fpic or -fPIC options are ineffective: -mpcrel always implies -fpic.

  * Because we care about code size (and don't have an instruction cache), too much of the following is probably counter-productive: -ffunction-cse, -funroll-loops, -funroll-all-loops.  Hence these options are not implied by the -O flags, but must be selected explicitly.

  * If you use 64K code resources, the linker -r option will not always work. Fortunately, these are both unnecessary.

  * Changing the specs file with -specs=FILE or invoking m68k-palmos-as or m68k-palmos-ld directly should be done with caution: proper operation is quite dependent on options set in the default specs file.

Include files
=============

NewTypes.h
----------

With Palm OS SDKs prior to the 3.5 SDK, programmers were encouraged to use typedefs such as DWord and VoidHand rather than the built-in types.  In the 3.5 SDK, the names of these typedefs have been changed to the somewhat more mnemonic UInt32 (etc) and the rather more functional MemHandle.  (Previously there were two ``handle'' datatypes, VoidHand and Handle, with no real reason for a distinction between them, and programmers were continually casting between them.  MemHandle corrects this historical accident.)

People wanting to write library header files capable of interacting with any SDK have a dilemma:  which to use, old- or new-style type names?

You can use old-style names by instructing developers to include PalmCompatibility.h before including your header file if they are using the 3.5 SDK.  But this is not very satisfactory:  the onus shouldn't be on developers to get this right, and you might prefer to use new-style names.

You can ensure new-style names are available simply by including NewTypes.h at the top of your header file, and instructing developers to include at least Common.h/PalmTypes.h before your header. (They are probably including Pilot.h/PalmOS.h anyway.)

Including NewTypes.h provides the following:

  * The identifiers UInt8, Int8, UInt16, Int16, UInt32, Int32, MemPtr, and MemHandle are all typedeffed appropriately.

  * The macro SDK_VERSION is defined to one of 10, 20, 30, 31, 35, 40, and so on, indicating the SDK version which is in use.

Standalone.h
------------

Including Standalone.h provides the macros listed below, which facilitate building stand-alone code resources. See Stand-alone code.

  STANDALONE_CODE_RESOURCE_ID (RES_ID)

  STANDALONE_CODE_RESOURCE_TYPE_ID (RES_TYPE, RES_ID)

  STANDALONE_CODE_RESOURCE_TYPESTR_ID (RES_TYPE, RES_ID)

  HACKMASTER_TRAP (VECTOR)

Global data
***********

An application's variables can be divided into three classes according to where they are stored.  Automatic variables local to functions are stored on the stack, and have lifetimes corresponding to the duration of the function invocation with which they are associated.  Some data are explicitly allocated on the heap via malloc(), MemPtrNew(), or MemHandleNew(), and live until they are explicitly freed.  The remainder---global and static variables---constitute an application's global data, and have lifetimes corresponding to the complete runtime of the application.

Shared libraries can also have global data:  GLibs automatically have globals just as applications do, while system libraries don't by default, but could set up their own globals manually, if desired.

Currently, both C++ virtual tables and the support data for multiple code resources are stored as global data.  This means that these features can only be used when global data is available.

Accessing global data
=====================

How global data should be accessed depends on what you are building:

  * Depending on its launch code, a Palm OS application may or may not have access to its global data (see the Palm OS Reference manual). If global data is available, it is accessed via the A5 register (which points to the end of the global data).

  * A GLib accesses its global data via the A4 register.

  * A SysLib must set up global data in its Open vector if it wants any, and then can access it via A4.

  * A Hack has no global data. (But it could use similar tricks to a SysLib if it really wanted to.)

By default, or with -mno-own-gp, compiled code will access global data via (a negative offset from) A5.  Shared libraries and other special purpose programs should be compiled with -mown-gp, and will use (a positive offset from) A4 (see New options).

Initialising A4
===============

In the following discussion, we use the term ``executable'' to refer to either an application or a shared library of either type.

There are two ways a function can be called: either directly, or when its address is taken and a call is subsequently made through that pointer. An executable can construct a pointer to a function within itself, or to a function in a GLib it uses (this will really be a pointer to the relevant stub), but not to a SysLib or operating system API function (since you can't construct a pointer to a systrap).

In simple cases, access to globals isn't a major problem:

  * When an executable E calls another function within E, it's just a direct subroutine call, and of course E's globals are still available.

  * When an executable E calls a function in a GLib L, it calls via a stub linked into E whose job is to set up access to L's globals, call the function proper, and then restore E's globals afterwards. Again, the appropriate globals are available.

  * When an executable calls a function in a SysLib, it calls via a system trap, which merely finds the library routine and calls it.  Thus, in this case, it is the library routine's responsibility to arrange access to its globals.

  * When an executable constructs a pointer to a function, and then itself calls through that pointer, it's again just a direct subroutine call, so its globals are available.

However, the situation gets more complex when an executable constructs a pointer to a function and then gives it to someone else, perhaps by passing it as an argument or by returning it to its caller.  ``Someone else'' may be either another executable or the operating system (so the pointer is a ``callback function'').

The rules here are:

  * Any pointer constructed by an application will work anywhere.

  * A pointer constructed by a shared library to a function within that library will work if that function takes steps to initialise its global pointer (Note entrypoints.).  Feature and trampoline entrypoints are most suitable.

  * A pointer constructed by a shared library to a function in a separate GLib will never work at all, because it is impossible to specify a special entrypoint sequence for a GLib stub.  Fortunately, this can be worked around by adding a function to the other GLib which returns the required function pointer.

In previous versions of prc-tools, applications also accessed their globals via the A4 register, and their function pointers were therefore subject to the same restrictions as shared library function pointers.  The appropriate steps to initialise the global pointer are much simpler for an application than a shared library, and were available via the macros CALLBACK_PROLOGUE and CALLBACK_EPILOGUE.  This is no longer necessary.  However, if you really want to use -mown-gp when building an application, you can use APP_ENTRYPOINT as a more convenient equivalent of the CALLBACK_* macros.

The extralogue attribute and entry points
=========================================

An extralogue attribute allows you to add arbitrary code to a function's prologue and epilogue.  Typically, it is used in conjunction with an owngp attribute to initialise a separate globals pointer for the duration of the function.  The ENTRYPOINT macro is defined in EntryPoints.h for precisely this purpose:

     #define ENTRYPOINT(EXTRAS)  \
       __attribute__ ((__owngp__, __extralogue__ EXTRAS))

It takes between zero and eight parameters, each of which is a string with the same syntax as an asm template string (see Assembler Instructions with C Expression Operands (Using and Porting GCC)):

     extralogue (PROLOGUE, EPILOGUE, SINGLE-EPILOGUE, VOID-EPILOGUE,
                 FAR-PROLOGUE, FAR-EPILOGUE, FAR-SINGLE-EPILOGUE, FAR-VOID-EPILOGUE)

This looks daunting, but often most of the parameters are unneeded. A replacement will be chosen, as described below, for each argument you leave empty (i.e., "").  If all arguments beyond a certain point would be empty, you can omit them entirely.  Generally you only need to specify one or two parameters because:

  * The far- variants are only used if functions in non-default sections need special treatment.  Such `special treatment' is likely to involve the global variables used to implement multiple sections.  Hence an extralogue used to arrange access to global variables had better not require such special treatment!

  * The main epilogue is capable of handling all epilogues.  The single- and void- variants allow you to supply more efficient code in most cases, but are not truly necessary.

  * In fact, you often won't need any special epilogue at all.

Thus, in practice, extralogue is often only used with one argument. For example, an ENTRYPOINT equivalent to the CALLBACK_* macros looks like this:

     ENTRYPOINT (("move.l %%a5,%%a4; sub.l #edata,%%a4"))

Note that ENTRYPOINT, being a macro, requires two sets of parentheses to emulate varargs.

See EntryPoints.h for more examples of the use of this attribute.

Prologues
.........

The function prologue first emits code to save the current A4 value on the stack.  It then emits the first one of the following which is non-empty and whose condition, if any, is satisfied:

FAR-PROLOGUE
if FUNCTION has a section attribute
PROLOGUE

The string selected can use %0 to refer to the address of the function's first parameter.  %0 will be a Mode 5 EA of the form OFFSET(fp) or OFFSET(sp).

Your prologue must not leave any extra data on the stack!  If your prologue and epilogue need to communicate with each other and their needs aren't satisfied by A4, your function should declare some local variables for storage space, and your templates may access them at appropriate offsets from FP.

However, if you use -fomit-frame-pointer, this won't work.  In this case, you would need to fake your extra epilogue with asm, thus letting the compiler figure out the correct offsets from SP.  As with the old CALLBACK_EPILOGUE, you would need to ensure that execution couldn't escape from your function without going through your `epilogue'.

Epilogues
.........

The function epilogue emits the first one of the following which is non-empty and whose condition, if any, is satisfied:

FAR-VOID-EPILOGUE
if FUNCTION has a section attribute and needs no return
register
FAR-SINGLE-EPILOGUE
if FUNCTION has a section attribute and needs at most a single
return register
FAR-EPILOGUE
if FUNCTION has a section attribute
VOID-EPILOGUE
if FUNCTION needs no return register
SINGLE-EPILOGUE
if FUNCTION needs at most a single return register
EPILOGUE

The string selected can use %0 to refer to the function's return value, if any.  If the function requires several registers to return its value (e.g., long longs are returned in D0 and D1), then %0 will be a register list suitable for a movem instruction.  If the function returns its value in a single register, then %0 denotes that register, and is either %%d0 or %%a0 depending on whether the return type is a pointer.  Otherwise the function is either void or it returns a large struct; in this case, %0 will always be %%a0.

The epilogue then emits code to restore the old value of A4 from the stack.

The far- variants
.................

You need to supply a far- variant when the normal template won't work properly when included in a function in a non-default section.  (This is not a question of optimization, as is the case for the epilogue variants, because the far- variants generally won't work for a single code resource executable.  Usually such variants are needed because they need to use the __text__ symbols, which would lead to link errors in a single code resource executable.)

Two extra operands are available to far- templates: %a1 is the function's section's __text__SECTION symbol, and %2 is the address of the main text section's base pointer global, i.e., it is __text__(%%pic), where %%pic is either A4 or A5. (This shows dramatically why far- variants are unlikely to be used with ENTRYPOINT: it's not much use accessing the text section's base pointer via A4 when that register hasn't been set up yet!)

There are other possible uses of extralogue for which the far- variants are necessary.  For example, you could arrange for a profiling function to be called at the start of a function like this:

     #define CALL_PROFILER \
       __attribute__ ((extralogue ("bsr.w __count", "", "", "",
                                   "move.l %2,%%a0; jsr __count(%%a0)")))
     int f() CALL_PROFILER;

If you couldn't tell the compiler to use a cross-section jump when needed, you would need to supply a separate version of the CALL_PROFILER macro for use with functions with section attributes.  This would lead to mysterious errors: the program would crash if the programmer used the wrong version.

Alternatively, you could just call the profiling function like this:

     int f() {
       __count();
       ...
       }

So this isn't a good example, but hopefully it serves to demonstrate the issues.  Perhaps someone will find a good use for all this flexibility!

Special projects
****************

When you compile and link using the default options, the size of your application's code is limited to 32K.  The 68000 DragonBall processor can only make a relative jump if it is of a distance of 32K or less, and you will get errors from the assembler and/or linker if your code attempts to jump further than that.  The default size limit, enforced at link time, is such that it is possible to jump arbitrarily within a maximally sized code resource without risking attempting an impossibly long jump.

While the default is limited, it is certainly possible to create larger applications; the choices and issues involved are discussed in this chapter.

Also discussed are other types of projects: shared libraries and various flavours of stand-alone code resources, particularly HackMaster Hacks and Palm OS 5 armlets.

Size limitations for a single code resource
===========================================

Even though the processor is unable to make a relative jump directly between the extremities of a code section larger than 32K, it is still possible to use such a code section if you are willing to indulge in manual heroics to help the compiler avoid needing to make such an extreme function call.

Note that a code section corresponds to a code resource in your project's final Palm OS database, and the maximum size for any kind of resource is still limited to approximately 64K by the Palm OS memory manager and the HotSync protocol.

Some of the heroic techniques are:

  * Rearrange functions within source codes and object files on the link command line so that function calls are only between ``nearby'' functions.

  * When rearrangements are insufficient, insert ``jump islands'':  proxy functions foo_aux() that just call the real function foo() with the same arguments and which can be placed anywhere, thus effectively giving each such foo() two entry points and loosening the constraints on the arrangement problem.  Or use the assembly language equivalent of a proxy function, which can avoid remarshalling the arguments and really be a jump.

  * Others are up to your imagination.

The maximum size of the main code section is specified in the linker script and enforced during linking (see Linker Scripts (Using ld)).  You can override the default script's 32K size by using the -T SCRIPT linker option. Two suitable linker scripts, which can be used as is or copied and modified, are already provided, both allowing a .text section of up to approximately 64K:

-T text_64k
     Up to 64720 bytes, the maximum resource size supported by all versions of Palm OS to date.

-T text_64k_palmos3
     Up to 65505 bytes, the maximum supported by Palm OS version 3.0 and higher.

There is, of course, some risk in going right up to the maximum resource size limits.  In practice, the limit has typically been increasing with each new version of Palm OS, and has never decreased.  Nonetheless, it may be wise to use text_64k even if you plan to target only Palm OS 3.0 and higher devices.

Multiple code resources
=======================

Theoretically, the heroics required to make functions calls over a distance of more than 32K are applicable for an arbitrarily large code resource. Unfortunately each resource is still limited to only 64K by the HotSync protocol, at least on Palm OS versions up to and including Palm OS 4.1. Thus the gain compared to a hassle-free 32K code resource is not great, and the best way to allow an application to increase beyond 32K of code is to allow it to have multiple separate code resources.

One simple technique for producing multiple code resources is to map distinct GCC code sections into distinct Palm OS code resources.  This version of prc-tools implements a limited form of that: functions may be marked as being in particular sections via the standard GCC section attribute (see Declaring Attributes of Functions (Using and Porting GCC)). (These markings are used quite early in the compiler, so other ways of putting functions into different sections, such as -ffunction-sections and rearrangements at link time, don't work.)

A project definition file (see Definition files) must be used, with a multiple code clause to inform build-prc of the new sections. You also need to define the pointer variables mentioned above in an assembly language stub file linked into your executable, and should use a linker script to place the new sections at appropriate addresses. The easiest way to do these things is to use multigen to generate them from the same definition file clause (see multigen).

Multiple code resources and global data
---------------------------------------

The current implementation puts pointers to the code resources into the application's global data, and uses those pointers in the code emitted for each call in which the calling function and the called function are in different sections.  This means that you must not attempt to call between different sections when globals are not available.

In particular, all functions in your application called while processing a launch code that doesn't give you globals must be in the main code section. This always includes PilotMain, which is always called by the startup code for all launch codes.

Read-only data
..............

Read-only data, such as string literals and other constant data, are put into code sections rather than the global data section.  This saves global data space, which is in short supply, and is valid since the data, just like the code resources that contain them, are read-only.

When an item of read-only data has file or global scope, it will be placed in the main code section.  When it is local to a function, it will mostly, but not always, be placed in the same code section as that function.

GCC's optimizer will usually notice when a string literal (or other constant) is identical to one which has been previously emitted, and will reuse the storage previously emitted rather than reserving more space for a duplicate.

Thus, in the following example, when optimisation is on, the string literal referenced from bar may well be in the foosec section, while bar itself is in the main code section:

     const char *foo () __attribute__ ((section ("foosec")));
     const char *foo () { return "hello world"; }
     const char *bar () { return "hello world"; }

The code emitted for such a reference is similar to that emitted for an inter-section function call: when there is a data reference in which the referring function and the referenced item of read-only data are in different sections, the code emitted uses the item's code resource's pointer, which is located in the application's global data.

This means that you must ensure that this sort of reference doesn't occur when globals are not available.  Because this compiler optimisation (of course) occurs only within a single translation unit, a sufficient (but not necessary) way to ensure this is by placing functions which are in different sections in different translation units (e.g., in separate .c files).

In particular, all read-only data referenced while processing a launch code that doesn't give you globals must be in the main code section.  (Thus, in the example above, bar is likely to crash if it is called during a no-globals launch.)

This can be arranged in the following ways, amongst others:

  * Write functions used during no-globals launches so that they use read-only data with file or global scope:

          const char greeting[] = "hello world";
          const char *bar () { return greeting; }

  * Order the functions within a translation unit so that all functions in the main code section are defined before any functions in other code sections. Then any shared read-only data will be in the main code section.

     (When an item of read-only data is reused, it will have been placed in the same section as the function from which it was first referenced. Thus, if the functions are ordered as described, all read-only data referenced from the functions in the main code section will themselves be in the main code section.  Any inter-section references to read-only data must then be from functions in other named code sections.  But in order for such a function to have been called, globals must be available; hence the inter-section reference will be safe too.)

Breaking up an existing application
-----------------------------------

To use multiple code resources in an existing application, you need to do the following:

 1. If your Makefile uses obj-res, change it to use build-prc directly on your bfd executable.  For example, from an original

          myapp.prc: code0000.myapp.grc ...
                  build-prc ... *.myapp.grc ...

          code0000.myapp.grc: myapp
                  m68k-palmos-obj-res myapp

     remove references to .grc files, and delete the obj-res rule altogether:

          myapp.prc: myapp ...
                  build-prc ... myapp ...

 2. Choose functions to be placed in other code sections, and annotate their declarations:

          #define EDIT_SECTION  __attribute__ ((section ("editfns")))

          void EditFormHandler (...) EDIT_SECTION;
          void DrawEditForm () EDIT_SECTION;

     (This also demonstrates using a macro to ease moving several functions at once.)

     Make very sure that the relevant annotated declaration is visible when you define such a function, and especially everywhere you call it. If there is a call to a non-default sectioned function from which the annotated declaration is not visible, the call will be generated as a call to the default code section.  When such a call is executed, it jumps to effectively a random location in the wrong code section and almost certainly crashes.  (Warning options which can detect these mistakes at compile time are noted in the discussion of required visibilities in Function attributes.)

     Note that COFF only stores eight character of a section name:  if your section names are any longer than this, they will be truncated, leading to trouble.

 3. Add a multiple code clause to your definition file:

          multiple code { "editfns" }

     Or, if you're not already using a definition file, write one including such a clause and use it in your build-prc command:

          myapp.prc: myapp.def myapp ...
                  build-prc ... myapp.def myapp ...

 4. Add rules to your Makefile to generate and build the assembler stub and linker script.

          myapp-sections.o: myapp-sections.s
                  m68k-palmos-gcc -c myapp-sections.s

          myapp-sections.s myapp-sections.ld: myapp.def
                  m68k-palmos-multigen myapp.def

 5. Link the assembler stub into your bfd executable, and use the linker script to place the extra code sections at appropriate addresses.

          OBJS = ...list of object files... myapp-sections.o

          myapp: $(OBJS) myapp-sections.ld
                  m68k-palmos-gcc -o myapp $(OBJS) myapp-sections.ld

Shared libraries
================

(This section has not yet been written; see stubgen, and also the library projects in the sample code collection.)

Stand-alone code resources
==========================

Normally build-prc processes a bfd executable as a full-blown executable, converting its .data, .bss, and .text and any other code sections into the corresponding Palm OS resources, as appropriate.

However if the bfd executable contains certain sections that are special to build-prc, its .text section will be converted into a stand-alone code resource instead, and the other sections listed above will be discarded (producing warnings) if present.

These ``special sections'' are .disposn (which is an abbreviation of disposition) and .trap.  They are interpreted as follows:

  * The first two bytes of a .disposn section, if present, specify the generated resource's ID, while (if the section is at least six bytes in length) the next four bytes specify its type.  If the .disposn section is only two bytes in length, the generated resource's type will be a suitable default dependent on the architecture of the bfd executable: code for 68000 or armc for ARM.

  * The first two bytes of a .trap section, if present, are converted into a TRAP resource.  If a .disposn section is also present, the TRAP resource will have the ID specified by that section; otherwise (when the project definition file specifies the Hack project kind), TRAP and code resources converted from successive bfd executables are numbered consecutively from 1000.

Note that these two-byte integer fields are interpreted according to the native endianness of the bfd executable in which they occur.

Producing a stand-alone code resource
-------------------------------------

There is nothing special about compiling code that is to become stand-alone, other than that you must not use global data or any extra code resources, because stand-alone code, by definition, cannot have such things.

There are considerations at link time, related to the lack of startup code:

  * Stand-alone code needs to be called directly; in particular, the startup code for a Palm OS application or GLib shared library is certainly not appropriate. Hence you should link using GCC's -nostartfiles option (see Options for Linking (Using and Porting GCC)).

  * If the bfd executable's entry point is not at offset 0 within its .text section, build-prc will insert an appropriate jump instruction at the start of the generated code resource.  Thus a stand-alone code resource can always be jumped to by jumping to its beginning.

     You specify the entry point at link time:  in short, it is a function named start() by default, or you can set it with the -e option (see Setting the entry point (Using ld)).

You can easily set up the special sections marking your code as stand-alone by using the following macros, provided in Standalone.h:

STANDALONE_CODE_RESOURCE_ID (ID)
     Mark the executable as a stand-alone code resource with the specified ID and a suitable resource type depending on the resulting compiled executable's architecture: code for 68000 or armc for ARM.

STANDALONE_CODE_RESOURCE_TYPE_ID (TYPE, ID)
STANDALONE_CODE_RESOURCE_TYPESTR_ID (TYPE, ID)
     Mark the executable as a stand-alone code resource with the specified resource TYPE and ID. If you specify TYPE with a multicharacter char constant ('TYPE'), use the ...TYPE... macro; if you use a string ("TYPE"), use the ...TYPESTR... version.

HACKMASTER_TRAP (VECTOR)
     Mark the executable as a stand-alone code resource, and add a TRAP resource containing VECTOR, which may be any C constant expression, for example, a numeric constant or even a sysTrapFOO constant as defined in a Palm OS SDK's CoreTraps.h.

Definition files
****************

A project may optionally contain a definition file, which is read by build-prc and also by several other utilities.  This file is used to specify various miscellaneous properties of the project, such as database header flags, names of multiple sections, and exported library functions.

General syntax
==============

A definition file should have the extension .def, and is a freely formatted file consisting of numbers, strings, comments, keywords, and various punctuation.

  * Numbers may be in decimal (37), octal (045), or hexadecimal (0x25).

  * Strings are enclosed in either single ('Hello') or double ("world") quotes, and may contain the usual C escape sequences (\t, \n, \', \", \\, \177, \x7F, ...).  If a string contains only alphanumeric characters and does not conflict with a keyword, the quotes may be omitted.

  * Both C style (/* comment */) and C++ style (// until end of line) comments may appear anywhere white space could occur, and are ignored.

A definition file consists of several clauses, which generally have syntax like the following:

     CLAUSE-KIND { SPECIFIC-DATA... }

For example, here is a complete definition file for a (hypothetical) fairly large non-beamable application:

     application { "Dr McCoy" DAFp copy-prevention }

     /* This app has three code resources: code #1 with all unannotated
        functions, #2 with functions placed in the "editfns" section,
        and #3 with "viewfns" functions.  */

     multiple code { editfns viewfns }

Specifying the kind of project
==============================

You can specify the database header attributes which appeared in an old-style build-prc command line along with the kind of project being built in this clause:

     PROJECT-KIND [ TYPE ] { DBNAME CRID MISCELLANEOUS... }

This clause must appear exactly once, and must be first in the file, before any other clauses.  DBNAME, CRID, and TYPE specify the database's name, creator id, and type.  Except when PROJECT-KIND is database, type can be omitted and a type suitable for the project kind will be used.  PROJECT-KIND controls the processing of the bfd executable, and should be one of the following:

app
application
     Build a Palm OS application, with a default type of appl. Code and data sections in the bfd executable are converted into Palm OS code, data, and rloc resources, and code #0 and pref #0 resources are synthesised.

glib
     Build a GLib shared library, with a default type of GLib.  Code and data sections in the bfd executable are converted into GLib code, data, and rloc resources.

syslib
     Build a system shared library, with a default type of libr. Code sections in the bfd executable are converted into libr code resources.  Since system libraries typically don't have their own global data, data sections in the bfd executable will produce a warning rather than being converted, unless you also use the data miscellaneous flag.

hack
     Build a HackMaster hack, with a default type of HACK.  All bfd executables given should be marked as stand-alone code sections, and any data sections or extra code sections present will elicit warnings from build-prc (see Stand-alone code).

database
     This implies no special handling of the bfd executable, and so builds a generic database.  In this case, TYPE must not be omitted.

The database name and creator id must come first within the braces, and may be followed by any number of the following, in any order:

read-only
appinfo-dirty
backup
ok-to-install-newer
reset-after-install
copy-prevention
stream
hidden
launchable-data
recyclable
bundle
     Set the corresponding database header attribute, adding to any attributes specified as options to build-prc.  These may also be spelt with the hyphens replaced by underscores or omitted altogether (readonly, appinfo_dirty, etc).

modification=NUM
modnum=NUM
modno=NUM
     Set the modification number in the database header to NUM.

version=NUM
     Set the database header version number to NUM.

stack=SIZE
     For an application, make the pref #0 resource request SIZE bytes of stack space.  By default, 4K is requested.

data
     For a system shared library, convert any data sections in input bfd executables into Palm OS data resources.  Without this flag, when build-prc is building a system shared library, any data sections will cause warnings instead of being converted.

Declaring multiple code sections
================================

Each section name that you use in a function section attribute in your project needs to be listed in your definition file in a multiple code clause:

     multiple code { SECTIONNAME... }

This is used by multigen to produce an assembly language list of the section names which needs to be linked into your executable, and also by build-prc to map named code sections to numbered code resources in the .prc file.

Build-prc will emit warnings if there are sections in your executable which are omitted from this clause, or vice versa.

Listing exported library entry point functions
==============================================

Both system shared libraries and GLibs require a dispatch table and a small amount of other assembler support code.  You can write this by hand, or you can use stubgen to generate the needed code from an export clause:

     export { FUNCTION-NAME... }

Dispatch table entries are generated in the order in which function names are listed in the export clause.  Thus, for the sake of binary compatibility between releases of your library, it is important to avoid changing the ordinal positions of function names.  For example, new functions being added to an existing library should be added at the end of the export clause, after the existing functions names.

Using a debugger
****************

Building an application with debugging enabled
==============================================

As on any other platform, you instruct GCC to produce debugging information by compiling with the -g option.

Some debuggers targeting Palm OS, notably GDB, also need your application to have a special stub (called StartDebug) in its startup code so that they can attach to the running application successfully.

To include this stub, you also need to link with -g.

By default, the stub is disabled and your application runs normally. When the stub sees that a gdbS #0 feature exists and has the value 0x12BEEF34, it is enabled and will converse with the debugger, telling it where in memory to find the application.

There are two convenient ways to set this feature and enable the stub:

  * The Palm OS Emulator (version 2.1d22 or greater) sets the feature automatically whenever there is a debugger connected to its debugger port. Thus there is no need to do anything yourself to enable debugging on Poser.

  * GDB Panel, in the prc-tools samples (http://sourceforge.net/project/showfiles.php?group_id=4429), is a small Palm OS application which sets this feature.  You need to use it or something similar when debugging on a real device or on the Palm OS Simulator.

Palm OS-specific GDB features
=============================

To debug Palm OS applications, GDB needs to load symbolic information from the bfd executable corresponding to your application, and to be connected to the Palm OS device where the application is running.  You generally specify the bfd executable on the command line (for example, to debug an application myapp.prc)

     $ m68k-palmos-gdb myapp

and connect using the target command.

target palmos PORT
target pilot PORT
     Connects the GDB host environment to a Palm OS device via PORT, using the Palm debugger protocol.  The argument PORT may be a device such as /dev/ttyS0 (Unix) or COM1 (Windows) to connect to a real device over a serial line, or a socket such as localhost:2000 to connect to the Palm OS Emulator.

     Using pilot is equivalent to palmos, and is provided for compatibility with earlier releases.  If PORT is omitted, GDB will attempt to connect to localhost:2000 by default.

     (The prc-tools 2.0 release only supported the pilot keyword, and PORT was not optional.)

After you have connected to the device, you should enable the debugger stub (see Enabling debugging), which is done automatically if you are connecting to Poser, and start your application, which you've compiled and linked with -g.

When your application starts up, GDB receives data from the debugger stub telling it how to correlate the bfd executable's debugging information with where in memory the application has been loaded.  Because of this, you need to ensure that the debugging information has been loaded before the breakpoint is received---hence typically the bfd file of debugging information is specified on the GDB command line.

The debugger stub also causes execution to stop as if at a breakpoint at the start of PilotMain, giving you a chance to interact with the debugger before your program runs but after you're connected to it. However, PilotMain can be entered multiple times---for example, if your application is sublaunched with another launch code or if you (or a gremlin) switch to another application and back again---and you may not want to break into the debugger every time.  You can control whether the debugger stops at this implicit breakpoint by changing the way GDB handles the SIGSTOP signal (see Signals (Debugging with GDB)).

There are some other features and limitations:

  * As a last resort before printing ?? for a function name, GDB will try to get the (mangled) name by querying the target for a MacsBug symbol. For example, this makes backtraces containing the stack frames of functions in the Palm OS ROM more informative.

  * At present, GDB won't work well with applications with multiple code resources.

Post-linker and other tools
***************************

On most platforms, you compile and link your programs, and the resulting executable is the program you run.  (The GNU linker produces an executable using a library named ``bfd''---hence the term ``bfd executable''). On Palm OS, however, this bfd executable is not, in fact, executable: its format must be changed from bfd COFF to a .prc database file, and, for all but the most trivial programs, UI resources must be bound in.

The post-linker tools are build-prc, which reads a definition file and various resource sources to generate a Palm OS .prc file, and obj-res, which converts a bfd executable into resources. (Build-prc can now read bfd executables directly, so there is no need to use obj-res anymore, but it is still supported for backwards compatibility.)  There are also multigen and stubgen, which generate various support files; and trapfilt, which decodes Palm OS trap vectors.

Other miscellaneous tools include palmdev-prep, which informs GCC of the locations of Palm OS SDKs and the like.  You should run it whenever you upgrade prc-tools or install new SDKs or modify existing ones.

build-prc
=========

     [file build-prc.texi not included]

multigen
========

     multigen [ -b BASE | --base BASE ] DEFFILE.def

The multigen utility generates an assembly language source file and a linker script for use in projects with multiple code resources (see Multiple code resources).  The assembly stub file must be compiled in with your application, and the linker script should be added to your link command.

You can write the required assembly language definitions and linker script yourself if you wish, but it is easier to have multigen generate them for you from the relevant clause in your project's definition file (see Definition files).

multigen reads from DEFFILE.def and by default writes the assembler stub file to DEFFILE-sections.s and the linker script to DEFFILE-sections.ld.

-b BASE
--base BASE
     Write the assembly language output to BASE.s and the linker script to BASE.ld.

stubgen
=======

     stubgen [ -b BASE | --base BASE ] DEFFILE.def

The stubgen utility generates assembly language stub files for a GLib or an assembly language dispatch table for a SysLib (see Shared libraries).  You can write these stub files yourself, but, particularly for a GLib, it is easier to have stubgen generate them for you from the relevant clause in your library's definition file (see Definition files).

stubgen reads from DEFFILE and by default writes its output to DEFFILE-stubs.c and DEFFILE-jumps.s, or to DEFFILE-dispatch.s, depending on the PROJECT-KIND specified in DEFFILE.

-b BASE
--base BASE
     Write the GLib output to BASE-stubs.c and BASE-jumps.s, or the SysLib output to BASE-dispatch.s.

     (This is inconsistent with the way multigen handles the -b option.  One or the other is likely to change.)

obj-res
=======

     obj-res [ -l ] [ -L EXPORTFILE ] [ -z N ] BFDFILE

The obj-res utility reads a file in a BFD supported object file format (most usually COFF) and generates the raw binary resource files necessary to make up a Palm OS executable in the current directory.  These files can be bound together into a Palm OS resource data file using build-prc.

This utility is deprecated.  It is provided only for use in existing legacy build scripts and makefiles.  In new projects it is more convenient to present the same object file directly to build-prc, thus enabling better error checking, avoiding a separate obj-res step, and avoiding the clutter of separate .grc files.

In particular, if you are using multiple code resources or the stand-alone code facilities then you must not use obj-res.  Such projects require information that is thrown away by obj-res, and your build will fail or, worse, silently produce invalid results.

But if you nonetheless choose to use it: obj-res reads from BFDFILE and writes to a number of files with names of the form TYPENNNN.BFDFILE.grc.  By default it generates resources for a Palm OS application.

-l
     Generate resources for a GLib shared library.

-L EXPORTFILE
     Generate resources for a Palm OS version 2 system shared library.

     Unlike previous versions of obj-res, this version cannot generate an offset table in EXPORTFILE.  You should use build-prc directly with a definition file instead.

-z N
     Compress the data resource, data0000.BFDFILE.grc, similarly to the corresponding build-prc option.

palmdev-prep
============

     [file palmdev-prep.texi not included]

trapfilt
========

     trapfilt [ -q | --quiet | --silent ] [ VECTOR... ]

On the 68000, calls to Palm OS system API functions are compiled into a trap instruction followed by a trap vector, which is a 16-bit number in a range starting at 0xA000.  The mapping between particular system functions and numeric trap vectors is given in the CoreTraps.h header in a Palm OS SDK (or SysTraps.h in older SDKs).

A disassembly listing of a Palm OS program displays only the trap instructions and the raw trap vectors.  The trapfilt utility decodes trap vectors using the mapping given by the header from the default SDK selected with palmdev-prep.  Typically you use it in conjunction with a disassembly listing from objdump:

     m68k-palmos-objdump -d myapp | m68k-palmos-trapfilt

If any VECTOR arguments are given, trapfilt decodes them and outputs the results on standard output.  Otherwise, when no such arguments are given, it acts as a filter: copying from standard input to standard output, annotating each line that matches the syntax of a trap vector (i.e., the syntax as printed by objdump) with the name of the corresponding system function, if any.

-q
--quiet
--silent
     In non-filter mode, output only the system function name for each VECTOR given.  The default output format in non-filter mode is similar to that used in filter mode.