1 Peal: Palm ELF ARM Loader
4 Peal is a simple ELF postlinker and loader for Palm OS. It allows ARM
5 code to use global variables and function pointers without restriction.
7 http://www.sealiesoftware.com/peal/
12 Features supported by Peal and Peal-loaded ARM code:
18 * Automatic handling of code segments larger than 64 KB
20 * Multiple entry point functions
22 * Access to global variables from m68k code
24 * Minimum memory usage - code and read-only data are not copied to
25 feature memory or the heap
27 * Thumb and ARM/Thumb interworking
32 * Peal is substantially UNTESTED. It may crash, generate incorrect
33 ARM global data, or modify random memory locations at runtime.
35 * Peal has some support for C++ code, but it is even less tested.
37 * Peal does not provide support for arbitrary ARM-ELF code. Only
38 code built with Peal's postlinker can be loaded by Peal.
40 * Peal does not provide support for ELF shared libraries.
42 * Peal uses the stack space provided by PceNativeCall(), which is
43 only 4 KB by default. There are ways to increase the ARM stack size,
44 but Peal does not use any of them.
49 A synopsis of Peal usage follows. See the example/ directory for a simple
50 demonstration, and the rest of this README for complete details.
52 0. Build the peal-postlink program in the postlink/ directory:
55 1. Write ARM code that uses global data or function pointers. ARM
56 functions intended to be called by m68k code may take a single
57 parameter. ARM functions that need to call back into m68k code should
58 use the variables gEmulStateP and gCall68KFuncP from arm/pealstub.h.
59 unsigned long MyArmFunction(void *arg) { ... }
61 2. Write m68k code that uses the API in m68k/peal.h to load ARM code
62 and call ARM functions:
63 PealModule m = PealLoadFromResources('armc', 1000);
64 void *address = PealLookupSymbol(m, "MyArmFunction");
65 unsigned long result = PealCall(m, address, myArg);
68 3. Compile m68k/peal.c along with other m68k code.
70 4. Add -fPIC when compiling to compile all ARM code as position-independent:
71 `arm-palmos-gcc -fPIC ...`
72 Compile arm/pealstub.c along with other ARM code.
74 5. Add --emit-relocs when linking ARM code to preserve relocation information:
75 `arm-palmos-ld --emit-relocs ...`
76 or `arm-palmos-gcc -Wl,--emit-relocs ...`
78 6. Run the Peal postlinker to generate ARM code resources:
79 `peal-postlink -s 1000 -t armc -o postlinked-rsrcs.ro linked-binary.bin`
81 7. Add the resources generated by peal-postlink to your Palm program as usual.
86 Palm OS limits resources to somewhat less than 64 KB each. There are
87 two ways to use Peal with code or initialized data larger than 64 KB.
89 1. Use ld's `--split-by-file` option to split the code into segments
90 smaller than 64 KB each. Then use `peal-postlink -s ...`
91 to place each segment into its own Palm resource. Finally, load
92 the code with PealLoadFromResources().
94 `arm-palmos-ld --split-by-file=64000 ...`
95 or `arm-palmos-gcc -Wl,--split-by-file=64000`
97 This method is fully automatic with Peal. No manual segmentation
98 or code reassembly is needed. This method also takes the minimum
99 amount of memory, because PealLoadFromResources() does not need
100 to copy the code into feature memory or the heap.
102 Cross-segment function calls are somewhat less efficient that
103 intra-segment calls. For maximum performance, order the files on
104 the link line so files that call each other are close together.
105 Alternatively, use __attribute__((section(...))) to segment by hand.
107 For very large source files or large data segments, `--split-by-file`
108 may still generate segments larger than 64000 bytes. In this case,
109 Peal automatically splits the segment across multiple resources,
110 and reassembles it during PealLoadFromResources(). Note that
111 peal-postlink will warn you that the large segment will require
112 more memory at runtime, because the reassembled section is
113 allocated on the dynamic heap and the reassembly process
114 itself temporarily uses additional heap memory.
116 2. Build the code and data as one big binary, using peal-postlink
117 without the -s option. Split the binary into multiple code resources.
118 Then reassemble the code resources into a single block in feature
119 memory or on the heap. Finally, load the code with PealLoad().
121 This method consumes twice as much memory, and Peal provides no
122 special support for this reassembly.
127 Peal provides support for C++ static constructors and destructors.
128 By default, the static constructors are run during the first
129 PealCall(), and the static destructors are run during PealUnload().
130 If the C++ static constructors need to use m68K callbacks, you
131 can set up the callback pointers before the first PealCall().
133 If you need to force constructors or destructors to run earlier,
134 use PealCxxConstruct() and PealCxxDestruct(). The constructors
135 and destructors are run only once, even if you call these functions
138 Support for other C++ code has received little testing.
139 It may or may not work correctly.
144 Peal can be used with Thumb code and interworked ARM/Thumb code.
145 Thumb code is usually substantially smaller than equivalent ARM code,
146 but may run more slowly.
148 PealCall() may be used with ARM functions or Thumb functions.
149 Note that PealLookupAddress(myModule, "MyThumbFunction") returns
150 &MyThumbFunction + 1. This address may be used as a function pointer
151 in Thumb code or interworking-enabled ARM code. However, this address
152 may not be passed to PceNativeCall(). Use PealCall() instead.
154 PealArmStub() in pealstub.c may be compiled in ARM mode or in Thumb mode:
156 If your code is ARM-only:
157 Compile pealstub.c in ARM mode as usual.
159 If your code is Thumb-only:
160 Compile pealstub.c with `-mthumb -mcallee-super-interworking`.
161 The latter option is necessary to allow PceNativeCall() to call
162 PealArmStub() without crashing.
164 If your code is mixed ARM and Thumb:
165 Compile pealstub.c with either `-mno-thumb -mthumb-interwork` (ARM mode)
166 or `-mthumb -mcallee-super-interworking` (Thumb mode).
169 COMPATIBLITY WITH OTHER COMPILER OPTIONS
171 Peal can be used with ARM or Thumb code compiled with `-msingle-pic-base`.
172 PealArmStub() sets up register R10 as the PIC register. This option is
173 recommended because it reduces code size and relocation count.
175 Peal cannot be used with `-msingle-pic-base -mpic-register=<reg>`,
176 unless the register used is R10. If you need -mpic-register with some
177 other value, modify PealArmStub() in arm/pealstub.c to use the register
180 Peal cannot be used with default stack checking, because Peal sets
181 the stack limit register (R10) as the PIC register. If you need
182 stack checking, specify a register other than R10 as the stack limit,
183 or modify PealArmStub() in arm/pealstub.c to use a different PIC
184 register or no PIC register.
189 The Peal postlinker transforms compiled and linked ARM code into
190 the relocatable format expected by Peal, and then optionally
191 packages the code into Palm OS resources.
193 peal-postlink expects a single input file that
194 * is an ELF executable. This is the usual format for ARM code built for Palm.
195 * is position-independent. Compile with `arm-palmos-gcc -fPIC ...`.
196 * still contains relocation information. Link with
197 `arm-palmos-ld --emit-relocs ...` or `arm-palmos-gcc -Wl,--emit-relocs`.
199 peal-postlink generates output in two formats: a resource file with
200 each ELF section in its own resource (`peal-postlink -s ...`), or
201 an unpackaged ELF relocatable object file (`peal-postlink ...`).
204 Generates a PRC-format resource file, with each ELF section in its
206 Each code and data section must be less than 64 KB. See LARGE CODE above.
207 "resID" is the first resource ID to use. A typical program will occupy
208 resources resID..resID+9. The default resource type is 'armc'.
209 This format matches the .ro or .prc formats used by build-prc.
210 Use PealLoadFromResources(resType, resID) to load this code.
213 Generates a single ELF relocatable object file.
214 Unlike -s, this format has no section size limit. However, if the entire
215 file is larger than 64 KB, then it will not fit in a Palm OS resource.
216 In this case, the binary must be split and reassembled in feature memory
217 or on the heap. See LARGE CODE above.
218 Use PealLoad(address) to load this code.
223 Keeps only symbols listed in the given file, and strips the rest.
224 By default, all non-static functions and data get a symbol name and
225 a symbol table entry. This can occupy large amounts of memory.
226 The `strip` command can remove unwanted entries, but it is also
227 likely to remove information needed by Peal. The -K option is safer.
228 Functions and data intended to be used by m68k code must have symbol table
229 entries. These functions and data should be listed in the keep file.
230 The symbol "PealArmStub" is required for Peal's operation and will not
231 be stripped, even if it is not listed in the keep file.
234 Sets the output file name.
235 Typical file name extensions are ".ro" or ".prc" (when using -s),
236 or ".bin" (when not using -s).
237 If no -o option is given, peal-postlink overwrites the input file.
240 With -s, sets the resource type for generated resources.
241 This option is silently ignored when not using -s.
244 Verbose output. Lists the sections and resources written.
247 Prints peal-postlink version, copyright, and lack of warranty.
249 peal-postlink silently removes any sections named ".disposn", ".comment",
250 ".got.plt", ".debug*", and ".debu.*". Other sections are copied to the
253 Peal's relocatable image format is similar to an ELF-ARM relocatable
254 object file, but it does not fully conform to any ELF ABI.
259 PealModule *PealLoad(void *mem)
260 Loads ARM code and data from mem.
261 If mem points into a relocatable block, that block must be locked before
262 calling PealLoad() and must remain locked until after PealUnload().
263 Note that PealLoad() may modify *mem. If mem points into a resource
264 or feature memory block, then mem must point to the beginning of
265 the block and the memory must be writable with DmWrite().
266 Returns NULL if the load fails for any reason.
267 Warning: if you do not call PealUnload() before your program exits,
268 your program may crash with a handle lock overflow error when run
271 PealModule *PealLoadFromResources(DmTypeID type, DmResID baseID)
272 Loads ARM code and data from resources of the given type, starting
273 with the given resource ID.
274 The resources should be numbered sequentially starting with baseID,
275 one for the ELF header and section list plus one for each ELF section.
276 This is the output format generated by `peal-postlink -s ...`.
277 The resources are loaded with DmGetResource(). Some of the
278 resources are kept open and locked until PealUnload() is called.
279 Others are released immediately.
280 The resources must be writable with DmWrite().
281 Returns NULL if the load fails for any reason.
282 Warning: if you do not call PealUnload() before your program exits,
283 your program may crash with a handle lock overflow error when run
286 void PealUnload(PealModule *m)
287 Unloads ARM code and data previously loaded by PealLoad().
288 The module must not be used after this call.
289 Warning: if you do not call PealUnload() before your program exits,
290 your program may crash with a handle lock overflow error when run
293 void *PealLookupSymbol(PealModule *m, char *query)
294 Returns the address of a named ARM function or variable in module m.
295 Returns NULL if the module contains no such function or variable.
296 A function can be called by passing this address to PealCall().
297 A variable can be read or written by dereferencing this address.
298 If the named function is a Thumb function, the returned address is
299 the function's address plus one. This address may be used as a
300 function pointer in interworking-enabled ARM code. However the
301 address may not be passed to PceNativeCall. Use PealCall instead.
303 uint32_t PealCall(PealModule *m, void *addr, void *arg)
304 Calls the function at addr in ARM module m, passing it the given arg.
305 Returns the value returned by that function.
306 The ARM function PealArmStub() is used to prepare ARM global state.
307 The called function should take zero or one arguments.
309 void PealCxxConstruct(PealModule *m)
310 Calls C++ constructors if they have not been called already.
311 By default, Peal calls C++ constructors (if any) during the
312 first PealCall(). You can force C++ constructors to run earlier
313 by calling PealCxxConstruct() directly.
314 Calling PealCxxConstruct() multiple times is harmless.
316 void PealCxxDestruct(PealModule *m)
317 Calls C++ destructors if they have not been called already.
318 By default, Peal calls C++ destructors (if any) during the
319 PealUnload(). You can force C++ destructors to run earlier
320 by calling PealCxxDestruct() directly.
321 Calling PealCxxDestruct() multiple times is harmless.
326 If you don't like Peal, there are several other tools to help provide
327 a more full-featured ARM environment on Palm OS:
329 ARM Relocatable ELF Loader by Hilary Cheng. GPL license.
330 http://hilary.e-fever.org/arm-elf/
332 elink by Brett Beebe. No license specified.
333 http://home.comcast.net/~beebeb/palmos/elink.zip
335 Roll your own, using Aaron Ardiri's instructions.
336 http://news.palmos.com/read/messages?id=143901#143901
337 http://news.palmos.com/read/messages?id=130117#130117
339 PNOLoader in Metrowerks CodeWarrior 9 for Palm OS.
340 http://www.metrowerks.com/
345 Peal was written by Greg Parker <gparker-peal@sealiesoftware.com>,
346 using ELF headers by David O'Brien and John Polstra.
350 Copyright (c) 2004-2005 Greg Parker. All rights reserved.
352 Redistribution and use in source and binary forms, with or without
353 modification, are permitted provided that the following conditions
355 1. Redistributions of source code must retain the above copyright
356 notice, this list of conditions and the following disclaimer.
357 2. Redistributions in binary form must reproduce the above copyright
358 notice, this list of conditions and the following disclaimer in the
359 documentation and/or other materials provided with the distribution.
361 THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR
362 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
363 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
364 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
365 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
366 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
367 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
368 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
369 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
370 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
374 Copyright (c) 2001 David E. O'Brien
375 Copyright (c) 1996-1998 John D. Polstra.
378 Redistribution and use in source and binary forms, with or without
379 modification, are permitted provided that the following conditions
381 1. Redistributions of source code must retain the above copyright
382 notice, this list of conditions and the following disclaimer.
383 2. Redistributions in binary form must reproduce the above copyright
384 notice, this list of conditions and the following disclaimer in the
385 documentation and/or other materials provided with the distribution.
387 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
388 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
389 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
390 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
391 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
392 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
393 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
394 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
395 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
396 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF