]> asedeno.scripts.mit.edu Git - peal.git/blob - README.txt
Greg Parker's Palm Elf Arm Loader (PEAL)
[peal.git] / README.txt
1 Peal: Palm ELF ARM Loader
2 version 2005-4-14
3
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.
6
7 http://www.sealiesoftware.com/peal/
8
9
10 FEATURES
11
12 Features supported by Peal and Peal-loaded ARM code:
13
14 * Global variables
15
16 * Function pointers
17
18 * Automatic handling of code segments larger than 64 KB
19
20 * Multiple entry point functions
21
22 * Access to global variables from m68k code
23
24 * Minimum memory usage - code and read-only data are not copied to 
25   feature memory or the heap
26
27 * Thumb and ARM/Thumb interworking
28
29
30 LIMITATIONS
31
32 * Peal is substantially UNTESTED. It may crash, generate incorrect 
33   ARM global data, or modify random memory locations at runtime.
34
35 * Peal has some support for C++ code, but it is even less tested.
36
37 * Peal does not provide support for arbitrary ARM-ELF code. Only 
38   code built with Peal's postlinker can be loaded by Peal.
39
40 * Peal does not provide support for ELF shared libraries.
41
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.
45
46
47 USAGE
48
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.
51
52 0. Build the peal-postlink program in the postlink/ directory:
53       `cd postlink; make`
54
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) { ... }
60
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);
66       PealUnload(m);
67
68 3. Compile m68k/peal.c along with other m68k code.
69
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. 
73
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 ...`
77
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`
80
81 7. Add the resources generated by peal-postlink to your Palm program as usual.
82
83
84 LARGE CODE
85
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. 
88
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(). 
93
94       `arm-palmos-ld --split-by-file=64000 ...`
95    or `arm-palmos-gcc -Wl,--split-by-file=64000`
96
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.
101
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.
106
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. 
115
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(). 
120
121    This method consumes twice as much memory, and Peal provides no 
122    special support for this reassembly. 
123
124
125 C++ COMPATIBILITY
126
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().
132
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 
136 multiple times.
137
138 Support for other C++ code has received little testing. 
139 It may or may not work correctly.
140
141
142 THUMB COMPATIBILITY
143
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.
147
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.
153
154 PealArmStub() in pealstub.c may be compiled in ARM mode or in Thumb mode: 
155
156 If your code is ARM-only:
157    Compile pealstub.c in ARM mode as usual.
158
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.
163
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).
167
168
169 COMPATIBLITY WITH OTHER COMPILER OPTIONS
170
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.
174
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 
178 you choose.
179
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.
185
186
187 POSTLINKER
188
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. 
192
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`.
198
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 ...`). 
202
203 -s <resID>
204    Generates a PRC-format resource file, with each ELF section in its 
205       own resource. 
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.
211
212 (without -s)
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.
219
220 Other options:
221
222 -K <filename>
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.
232
233 -o <filename>
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.
238
239 -t <resType>
240    With -s, sets the resource type for generated resources.
241    This option is silently ignored when not using -s.
242
243 -v
244    Verbose output. Lists the sections and resources written.
245
246 -V
247    Prints peal-postlink version, copyright, and lack of warranty. 
248
249 peal-postlink silently removes any sections named ".disposn", ".comment", 
250 ".got.plt", ".debug*", and ".debu.*". Other sections are copied to the 
251 output file.
252
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. 
255
256
257 API
258
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 
269       more than 16 times.
270
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 
284       more than 16 times.
285
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 
291       more than 16 times.
292
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.
302
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.
308
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.
315
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.
322
323
324 ALTERNATIVES
325
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:
328
329    ARM Relocatable ELF Loader by Hilary Cheng. GPL license.
330    http://hilary.e-fever.org/arm-elf/
331
332    elink by Brett Beebe. No license specified.
333    http://home.comcast.net/~beebeb/palmos/elink.zip
334
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
338
339    PNOLoader in Metrowerks CodeWarrior 9 for Palm OS.
340    http://www.metrowerks.com/
341    
342
343 LICENSE
344
345 Peal was written by Greg Parker <gparker-peal@sealiesoftware.com>, 
346 using ELF headers by David O'Brien and John Polstra.
347
348 ***
349
350 Copyright (c) 2004-2005 Greg Parker.  All rights reserved.
351
352 Redistribution and use in source and binary forms, with or without
353 modification, are permitted provided that the following conditions
354 are met:
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.
360
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.
371
372 ***
373
374 Copyright (c) 2001 David E. O'Brien
375 Copyright (c) 1996-1998 John D. Polstra.
376 All rights reserved.
377
378 Redistribution and use in source and binary forms, with or without
379 modification, are permitted provided that the following conditions
380 are met:
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.
386
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
397 SUCH DAMAGE.
398
399 ***