1/*
2 * Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1.  Redistributions of source code must retain the above copyright
8 *     notice, this list of conditions and the following disclaimer.
9 * 2.  Redistributions in binary form must reproduce the above copyright
10 *     notice, this list of conditions and the following disclaimer in the
11 *     documentation and/or other materials provided with the distribution.
12 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
13 *     its contributors may be used to endorse or promote products derived
14 *     from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28/* bytesex.h */
29#ifndef _STUFF_BYTESEX_H_
30#define _STUFF_BYTESEX_H_
31
32#if defined(__MWERKS__) && !defined(__private_extern__)
33#define __private_extern__ __declspec(private_extern)
34#endif
35
36#include <mach-o/fat.h>
37#include <mach-o/loader.h>
38#include <mach/m68k/thread_status.h>
39#undef MACHINE_THREAD_STATE	/* need to undef these to avoid warnings */
40#undef MACHINE_THREAD_STATE_COUNT
41#undef THREAD_STATE_NONE
42#undef VALID_THREAD_STATE_FLAVOR
43#include <mach/ppc/thread_status.h>
44#undef MACHINE_THREAD_STATE	/* need to undef these to avoid warnings */
45#undef MACHINE_THREAD_STATE_COUNT
46#undef THREAD_STATE_NONE
47#undef VALID_THREAD_STATE_FLAVOR
48#include <mach/m88k/thread_status.h>
49#include <mach/i860/thread_status.h>
50#include <mach/i386/thread_status.h>
51#include <mach/hppa/thread_status.h>
52#include <mach/sparc/thread_status.h>
53#include <mach/arm/thread_status.h>
54#include <mach-o/nlist.h>
55#include <mach-o/reloc.h>
56#include <mach-o/ranlib.h>
57#include "stuff/bool.h"
58
59enum byte_sex {
60    UNKNOWN_BYTE_SEX,
61    BIG_ENDIAN_BYTE_SEX,
62    LITTLE_ENDIAN_BYTE_SEX
63};
64
65#define SWAP_SHORT(a) ( ((a & 0xff) << 8) | ((unsigned short)(a) >> 8) )
66
67#define SWAP_INT(a)  ( ((a) << 24) | \
68		      (((a) << 8) & 0x00ff0000) | \
69		      (((a) >> 8) & 0x0000ff00) | \
70	 ((unsigned int)(a) >> 24) )
71
72#ifndef __LP64__
73#define SWAP_LONG(a) ( ((a) << 24) | \
74		      (((a) << 8) & 0x00ff0000) | \
75		      (((a) >> 8) & 0x0000ff00) | \
76	((unsigned long)(a) >> 24) )
77#endif
78
79__private_extern__ long long SWAP_LONG_LONG(
80    long long ll);
81
82__private_extern__ float SWAP_FLOAT(
83    float f);
84
85__private_extern__ double SWAP_DOUBLE(
86    double d);
87
88__private_extern__ enum byte_sex get_host_byte_sex(
89    void);
90
91__private_extern__ void swap_fat_header(
92    struct fat_header *fat_header,
93    enum byte_sex target_byte_sex);
94
95__private_extern__ void swap_fat_arch(
96    struct fat_arch *fat_archs,
97    uint32_t nfat_arch,
98    enum byte_sex target_byte_sex);
99
100__private_extern__ void swap_mach_header(
101    struct mach_header *mh,
102    enum byte_sex target_byte_sex);
103
104__private_extern__ void swap_mach_header_64(
105    struct mach_header_64 *mh,
106    enum byte_sex target_byte_sex);
107
108__private_extern__ void swap_load_command(
109    struct load_command *lc,
110    enum byte_sex target_byte_sex);
111
112__private_extern__ void swap_segment_command(
113    struct segment_command *sg,
114    enum byte_sex target_byte_sex);
115
116__private_extern__ void swap_segment_command_64(
117    struct segment_command_64 *sg,
118    enum byte_sex target_byte_sex);
119
120__private_extern__ void swap_section(
121    struct section *s,
122    uint32_t nsects,
123    enum byte_sex target_byte_sex);
124
125__private_extern__ void swap_section_64(
126    struct section_64 *s,
127    uint32_t nsects,
128    enum byte_sex target_byte_sex);
129
130__private_extern__ void swap_symtab_command(
131    struct symtab_command *st,
132    enum byte_sex target_byte_sex);
133
134__private_extern__ void swap_dysymtab_command(
135    struct dysymtab_command *dyst,
136    enum byte_sex target_byte_sex);
137
138__private_extern__ void swap_symseg_command(
139    struct symseg_command *ss,
140    enum byte_sex target_byte_sex);
141
142__private_extern__ void swap_fvmlib_command(
143    struct fvmlib_command *fl,
144    enum byte_sex target_byte_sex);
145
146__private_extern__ void swap_dylib_command(
147    struct dylib_command *dl,
148    enum byte_sex target_byte_sex);
149
150__private_extern__ void swap_sub_framework_command(
151    struct sub_framework_command *sub,
152    enum byte_sex target_byte_sex);
153
154__private_extern__ void swap_sub_umbrella_command(
155    struct sub_umbrella_command *usub,
156    enum byte_sex target_byte_sex);
157
158__private_extern__ void swap_sub_library_command(
159    struct sub_library_command *lsub,
160    enum byte_sex target_byte_sex);
161
162__private_extern__ void swap_sub_client_command(
163    struct sub_client_command *csub,
164    enum byte_sex target_byte_sex);
165
166__private_extern__ void swap_prebound_dylib_command(
167    struct prebound_dylib_command *pbdylib,
168    enum byte_sex target_byte_sex);
169
170__private_extern__ void swap_dylinker_command(
171    struct dylinker_command *dyld,
172    enum byte_sex target_byte_sex);
173
174__private_extern__ void swap_fvmfile_command(
175    struct fvmfile_command *ff,
176    enum byte_sex target_byte_sex);
177
178__private_extern__ void swap_thread_command(
179    struct thread_command *ut,
180    enum byte_sex target_byte_sex);
181
182__private_extern__ void swap_m68k_thread_state_regs(
183    struct m68k_thread_state_regs *cpu,
184    enum byte_sex target_byte_sex);
185
186__private_extern__ void swap_m68k_thread_state_68882(
187    struct m68k_thread_state_68882 *fpu,
188    enum byte_sex target_byte_sex);
189
190__private_extern__ void swap_m68k_thread_state_user_reg(
191    struct m68k_thread_state_user_reg *user_reg,
192    enum byte_sex target_byte_sex);
193
194__private_extern__ void swap_ppc_thread_state_t(
195    ppc_thread_state_t *cpu,
196    enum byte_sex target_byte_sex);
197
198__private_extern__ void swap_ppc_thread_state64_t(
199    ppc_thread_state64_t *cpu,
200    enum byte_sex target_byte_sex);
201
202__private_extern__ void swap_ppc_float_state_t(
203    ppc_float_state_t *fpu,
204    enum byte_sex target_byte_sex);
205
206__private_extern__ void swap_ppc_exception_state_t(
207    ppc_exception_state_t *state,
208    enum byte_sex target_byte_sex);
209
210__private_extern__ void swap_m88k_thread_state_grf_t(
211    m88k_thread_state_grf_t *cpu,
212    enum byte_sex target_byte_sex);
213
214__private_extern__ void swap_m88k_thread_state_xrf_t(
215    m88k_thread_state_xrf_t *fpu,
216    enum byte_sex target_byte_sex);
217
218__private_extern__ void swap_m88k_thread_state_user_t(
219    m88k_thread_state_user_t *user,
220    enum byte_sex target_byte_sex);
221
222__private_extern__ void swap_m88110_thread_state_impl_t(
223    m88110_thread_state_impl_t *spu,
224    enum byte_sex target_byte_sex);
225
226__private_extern__ void swap_i860_thread_state_regs(
227    struct i860_thread_state_regs *cpu,
228    enum byte_sex target_byte_sex);
229
230__private_extern__ void swap_i386_thread_state(
231    i386_thread_state_t *cpu,
232    enum byte_sex target_byte_sex);
233
234/* current i386 thread states */
235#if i386_THREAD_STATE == 1
236__private_extern__ void swap_i386_float_state(
237    struct __darwin_i386_float_state *fpu,
238    enum byte_sex target_byte_sex);
239
240__private_extern__ void swap_i386_exception_state(
241    i386_exception_state_t *exc,
242    enum byte_sex target_byte_sex);
243#endif /* i386_THREAD_STATE == 1 */
244
245/* i386 thread states on older releases */
246#if i386_THREAD_STATE == -1
247__private_extern__ void swap_i386_thread_fpstate(
248    i386_thread_fpstate_t *fpu,
249    enum byte_sex target_byte_sex);
250
251__private_extern__ void swap_i386_thread_exceptstate(
252    i386_thread_exceptstate_t *exc,
253    enum byte_sex target_byte_sex);
254
255__private_extern__ void swap_i386_thread_cthreadstate(
256    i386_thread_cthreadstate_t *user,
257    enum byte_sex target_byte_sex);
258#endif /* i386_THREAD_STATE == -1 */
259
260#ifdef x86_THREAD_STATE64
261__private_extern__ void swap_x86_thread_state64(
262    x86_thread_state64_t *cpu,
263    enum byte_sex target_byte_sex);
264
265__private_extern__ void swap_x86_float_state64(
266    x86_float_state64_t *fpu,
267    enum byte_sex target_byte_sex);
268
269__private_extern__ void swap_x86_state_hdr(
270    struct x86_state_hdr *hdr,
271    enum byte_sex target_byte_sex);
272
273__private_extern__ void swap_x86_exception_state64(
274    x86_exception_state64_t *exc,
275    enum byte_sex target_byte_sex);
276
277__private_extern__ void swap_x86_debug_state32(
278    x86_debug_state32_t *debug,
279    enum byte_sex target_byte_sex);
280
281__private_extern__ void swap_x86_debug_state64(
282    x86_debug_state64_t *debug,
283    enum byte_sex target_byte_sex);
284#endif /* x86_THREAD_STATE64 */
285
286__private_extern__ void swap_hppa_integer_thread_state(
287    struct hp_pa_integer_thread_state *regs,
288    enum byte_sex target_byte_order);
289
290__private_extern__ void swap_hppa_frame_thread_state(
291  struct hp_pa_frame_thread_state *frame,
292  enum byte_sex target_byte_order);
293
294__private_extern__ void swap_hppa_fp_thread_state(
295  struct hp_pa_fp_thread_state *fp,
296  enum byte_sex target_byte_order);
297
298__private_extern__ void swap_sparc_thread_state_regs(
299  struct sparc_thread_state_regs *cpu,
300  enum byte_sex target_byte_order);
301
302__private_extern__ void swap_sparc_thread_state_fpu(
303  struct sparc_thread_state_fpu *fpu,
304  enum byte_sex target_byte_order);
305
306__private_extern__ void swap_arm_thread_state_t(
307    arm_thread_state_t *cpu,
308    enum byte_sex target_byte_sex);
309
310__private_extern__ void swap_ident_command(
311    struct ident_command *id_cmd,
312    enum byte_sex target_byte_sex);
313
314__private_extern__ void swap_routines_command(
315    struct routines_command *r_cmd,
316    enum byte_sex target_byte_sex);
317
318__private_extern__ void swap_routines_command_64(
319    struct routines_command_64 *r_cmd,
320    enum byte_sex target_byte_sex);
321
322__private_extern__ void swap_twolevel_hints_command(
323    struct twolevel_hints_command *hints_cmd,
324    enum byte_sex target_byte_sex);
325
326__private_extern__ void swap_prebind_cksum_command(
327    struct prebind_cksum_command *cksum_cmd,
328    enum byte_sex target_byte_sex);
329
330__private_extern__ void swap_uuid_command(
331    struct uuid_command *uuid_cmd,
332    enum byte_sex target_byte_sex);
333
334__private_extern__ void swap_linkedit_data_command(
335    struct linkedit_data_command *ld,
336    enum byte_sex target_byte_sex);
337
338__private_extern__ void swap_version_min_command(
339    struct version_min_command *ver_cmd,
340    enum byte_sex target_byte_sex);
341
342__private_extern__ void swap_rpath_command(
343    struct rpath_command *rpath_cmd,
344    enum byte_sex target_byte_sex);
345
346__private_extern__ void swap_encryption_command(
347    struct encryption_info_command *ec,
348    enum byte_sex target_byte_sex);
349
350__private_extern__ void swap_encryption_command_64(
351    struct encryption_info_command_64 *ec,
352    enum byte_sex target_byte_sex);
353
354__private_extern__ void swap_linker_option_command(
355    struct linker_option_command *lo,
356    enum byte_sex target_byte_sex);
357
358__private_extern__ void swap_dyld_info_command(
359    struct dyld_info_command *dc,
360    enum byte_sex target_byte_sex);
361
362__private_extern__ void swap_entry_point_command(
363    struct entry_point_command *ep,
364    enum byte_sex target_byte_sex);
365
366__private_extern__ void swap_source_version_command(
367    struct source_version_command *sv,
368    enum byte_sex target_byte_sex);
369
370__private_extern__ void swap_nlist(
371    struct nlist *symbols,
372    uint32_t nsymbols,
373    enum byte_sex target_byte_sex);
374
375__private_extern__ void swap_nlist_64(
376    struct nlist_64 *symbols,
377    uint32_t nsymbols,
378    enum byte_sex target_byte_sex);
379
380__private_extern__ void swap_ranlib(
381    struct ranlib *ranlibs,
382    uint32_t nranlibs,
383    enum byte_sex target_byte_sex);
384
385__private_extern__ void swap_relocation_info(
386    struct relocation_info *relocs,
387    uint32_t nrelocs,
388    enum byte_sex target_byte_sex);
389
390__private_extern__ void swap_indirect_symbols(
391    uint32_t *indirect_symbols,
392    uint32_t nindirect_symbols,
393    enum byte_sex target_byte_sex);
394
395__private_extern__ void swap_dylib_reference(
396    struct dylib_reference *refs,
397    uint32_t nrefs,
398    enum byte_sex target_byte_sex);
399
400__private_extern__ void swap_dylib_module(
401    struct dylib_module *mods,
402    uint32_t nmods,
403    enum byte_sex target_byte_sex);
404
405__private_extern__ void swap_dylib_module_64(
406    struct dylib_module_64 *mods,
407    uint32_t nmods,
408    enum byte_sex target_byte_sex);
409
410__private_extern__ void swap_dylib_table_of_contents(
411    struct dylib_table_of_contents *tocs,
412    uint32_t ntocs,
413    enum byte_sex target_byte_sex);
414
415__private_extern__ void swap_twolevel_hint(
416    struct twolevel_hint *hints,
417    uint32_t nhints,
418    enum byte_sex target_byte_sex);
419
420__private_extern__ void swap_data_in_code_entry(
421    struct data_in_code_entry *dices,
422    uint32_t ndices,
423    enum byte_sex target_byte_sex);
424
425/*
426 * swap_object_headers() swaps the object file headers from the host byte sex
427 * into the non-host byte sex.  It returns TRUE if it can and did swap the
428 * headers else returns FALSE and does not touch the headers and prints an error
429 * using the error() routine.
430 */
431__private_extern__ enum bool swap_object_headers(
432    void *mach_header, /* either a mach_header or a mach_header_64 */
433    struct load_command *load_commands);
434
435/*
436 * get_toc_byte_sex() guesses the byte sex of the table of contents of the
437 * library mapped in at the address, addr, of size, size based on the first
438 * object file's bytesex.  If it can't figure it out, because the library has
439 * no object file members or is malformed it will return UNKNOWN_BYTE_SEX.
440 */
441__private_extern__ enum byte_sex get_toc_byte_sex(
442    char *addr,
443    uint32_t size);
444
445#endif /* _STUFF_BYTESEX_H_ */
446