1#ifndef SQUASHFS_COMPAT
2#define SQUASHFS_COMPAT
3/*
4 * Squashfs
5 *
6 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014
7 * Phillip Lougher <phillip@squashfs.org.uk>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2,
12 * or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 * squashfs_compat.h
24 */
25
26/*
27 * definitions for structures on disk - layout 3.x
28 */
29
30#define SQUASHFS_CHECK			2
31#define SQUASHFS_CHECK_DATA(flags)		SQUASHFS_BIT(flags, \
32						SQUASHFS_CHECK)
33
34/* Max number of uids and gids */
35#define SQUASHFS_UIDS			256
36#define SQUASHFS_GUIDS			255
37
38struct squashfs_super_block_3 {
39	unsigned int		s_magic;
40	unsigned int		inodes;
41	unsigned int		bytes_used_2;
42	unsigned int		uid_start_2;
43	unsigned int		guid_start_2;
44	unsigned int		inode_table_start_2;
45	unsigned int		directory_table_start_2;
46	unsigned int		s_major:16;
47	unsigned int		s_minor:16;
48	unsigned int		block_size_1:16;
49	unsigned int		block_log:16;
50	unsigned int		flags:8;
51	unsigned int		no_uids:8;
52	unsigned int		no_guids:8;
53	int			mkfs_time /* time of filesystem creation */;
54	squashfs_inode		root_inode;
55	unsigned int		block_size;
56	unsigned int		fragments;
57	unsigned int		fragment_table_start_2;
58	long long		bytes_used;
59	long long		uid_start;
60	long long		guid_start;
61	long long		inode_table_start;
62	long long		directory_table_start;
63	long long		fragment_table_start;
64	long long		lookup_table_start;
65} __attribute__ ((packed));
66
67struct squashfs_dir_index_3 {
68	unsigned int		index;
69	unsigned int		start_block;
70	unsigned char		size;
71	unsigned char		name[0];
72} __attribute__ ((packed));
73
74struct squashfs_base_inode_header_3 {
75	unsigned int		inode_type:4;
76	unsigned int		mode:12;
77	unsigned int		uid:8;
78	unsigned int		guid:8;
79	int			mtime;
80	unsigned int 		inode_number;
81} __attribute__ ((packed));
82
83struct squashfs_ipc_inode_header_3 {
84	unsigned int		inode_type:4;
85	unsigned int		mode:12;
86	unsigned int		uid:8;
87	unsigned int		guid:8;
88	int			mtime;
89	unsigned int 		inode_number;
90	unsigned int		nlink;
91} __attribute__ ((packed));
92
93struct squashfs_dev_inode_header_3 {
94	unsigned int		inode_type:4;
95	unsigned int		mode:12;
96	unsigned int		uid:8;
97	unsigned int		guid:8;
98	int			mtime;
99	unsigned int 		inode_number;
100	unsigned int		nlink;
101	unsigned short		rdev;
102} __attribute__ ((packed));
103
104struct squashfs_symlink_inode_header_3 {
105	unsigned int		inode_type:4;
106	unsigned int		mode:12;
107	unsigned int		uid:8;
108	unsigned int		guid:8;
109	int			mtime;
110	unsigned int 		inode_number;
111	unsigned int		nlink;
112	unsigned short		symlink_size;
113	char			symlink[0];
114} __attribute__ ((packed));
115
116struct squashfs_reg_inode_header_3 {
117	unsigned int		inode_type:4;
118	unsigned int		mode:12;
119	unsigned int		uid:8;
120	unsigned int		guid:8;
121	int			mtime;
122	unsigned int 		inode_number;
123	squashfs_block		start_block;
124	unsigned int		fragment;
125	unsigned int		offset;
126	unsigned int		file_size;
127	unsigned short		block_list[0];
128} __attribute__ ((packed));
129
130struct squashfs_lreg_inode_header_3 {
131	unsigned int		inode_type:4;
132	unsigned int		mode:12;
133	unsigned int		uid:8;
134	unsigned int		guid:8;
135	int			mtime;
136	unsigned int 		inode_number;
137	unsigned int		nlink;
138	squashfs_block		start_block;
139	unsigned int		fragment;
140	unsigned int		offset;
141	long long		file_size;
142	unsigned short		block_list[0];
143} __attribute__ ((packed));
144
145struct squashfs_dir_inode_header_3 {
146	unsigned int		inode_type:4;
147	unsigned int		mode:12;
148	unsigned int		uid:8;
149	unsigned int		guid:8;
150	int			mtime;
151	unsigned int 		inode_number;
152	unsigned int		nlink;
153	unsigned int		file_size:19;
154	unsigned int		offset:13;
155	unsigned int		start_block;
156	unsigned int		parent_inode;
157} __attribute__  ((packed));
158
159struct squashfs_ldir_inode_header_3 {
160	unsigned int		inode_type:4;
161	unsigned int		mode:12;
162	unsigned int		uid:8;
163	unsigned int		guid:8;
164	int			mtime;
165	unsigned int 		inode_number;
166	unsigned int		nlink;
167	unsigned int		file_size:27;
168	unsigned int		offset:13;
169	unsigned int		start_block;
170	unsigned int		i_count:16;
171	unsigned int		parent_inode;
172	struct squashfs_dir_index_3	index[0];
173} __attribute__  ((packed));
174
175union squashfs_inode_header_3 {
176	struct squashfs_base_inode_header_3	base;
177	struct squashfs_dev_inode_header_3	dev;
178	struct squashfs_symlink_inode_header_3	symlink;
179	struct squashfs_reg_inode_header_3	reg;
180	struct squashfs_lreg_inode_header_3	lreg;
181	struct squashfs_dir_inode_header_3	dir;
182	struct squashfs_ldir_inode_header_3	ldir;
183	struct squashfs_ipc_inode_header_3	ipc;
184};
185
186struct squashfs_dir_entry_3 {
187	unsigned int		offset:13;
188	unsigned int		type:3;
189	unsigned int		size:8;
190	int			inode_number:16;
191	char			name[0];
192} __attribute__ ((packed));
193
194struct squashfs_dir_header_3 {
195	unsigned int		count:8;
196	unsigned int		start_block;
197	unsigned int		inode_number;
198} __attribute__ ((packed));
199
200struct squashfs_fragment_entry_3 {
201	long long		start_block;
202	unsigned int		size;
203	unsigned int		pending;
204} __attribute__ ((packed));
205
206
207typedef struct squashfs_super_block_3 squashfs_super_block_3;
208typedef struct squashfs_dir_index_3 squashfs_dir_index_3;
209typedef struct squashfs_base_inode_header_3 squashfs_base_inode_header_3;
210typedef struct squashfs_ipc_inode_header_3 squashfs_ipc_inode_header_3;
211typedef struct squashfs_dev_inode_header_3 squashfs_dev_inode_header_3;
212typedef struct squashfs_symlink_inode_header_3 squashfs_symlink_inode_header_3;
213typedef struct squashfs_reg_inode_header_3 squashfs_reg_inode_header_3;
214typedef struct squashfs_lreg_inode_header_3 squashfs_lreg_inode_header_3;
215typedef struct squashfs_dir_inode_header_3 squashfs_dir_inode_header_3;
216typedef struct squashfs_ldir_inode_header_3 squashfs_ldir_inode_header_3;
217typedef struct squashfs_dir_entry_3 squashfs_dir_entry_3;
218typedef struct squashfs_dir_header_3 squashfs_dir_header_3;
219typedef struct squashfs_fragment_entry_3 squashfs_fragment_entry_3;
220
221/*
222 * macros to convert each packed bitfield structure from little endian to big
223 * endian and vice versa.  These are needed when creating or using a filesystem
224 * on a machine with different byte ordering to the target architecture.
225 *
226 */
227
228#define SQUASHFS_SWAP_START \
229	int bits;\
230	int b_pos;\
231	unsigned long long val;\
232	unsigned char *s;\
233	unsigned char *d;
234
235#define SQUASHFS_SWAP_SUPER_BLOCK_3(s, d) {\
236	SQUASHFS_SWAP_START\
237	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block_3));\
238	SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
239	SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
240	SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
241	SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
242	SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
243	SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
244	SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
245	SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
246	SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
247	SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
248	SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
249	SQUASHFS_SWAP((s)->flags, d, 288, 8);\
250	SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
251	SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
252	SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
253	SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
254	SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
255	SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
256	SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
257	SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
258	SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
259	SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
260	SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
261	SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
262	SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
263	SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\
264}
265
266#define SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, n)\
267	SQUASHFS_MEMSET(s, d, n);\
268	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
269	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
270	SQUASHFS_SWAP((s)->uid, d, 16, 8);\
271	SQUASHFS_SWAP((s)->guid, d, 24, 8);\
272	SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
273	SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
274
275#define SQUASHFS_SWAP_BASE_INODE_HEADER_3(s, d, n) {\
276	SQUASHFS_SWAP_START\
277	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, n)\
278}
279
280#define SQUASHFS_SWAP_IPC_INODE_HEADER_3(s, d) {\
281	SQUASHFS_SWAP_START\
282	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
283			sizeof(struct squashfs_ipc_inode_header_3))\
284	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
285}
286
287#define SQUASHFS_SWAP_DEV_INODE_HEADER_3(s, d) {\
288	SQUASHFS_SWAP_START\
289	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
290			sizeof(struct squashfs_dev_inode_header_3)); \
291	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
292	SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
293}
294
295#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_3(s, d) {\
296	SQUASHFS_SWAP_START\
297	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
298			sizeof(struct squashfs_symlink_inode_header_3));\
299	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
300	SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
301}
302
303#define SQUASHFS_SWAP_REG_INODE_HEADER_3(s, d) {\
304	SQUASHFS_SWAP_START\
305	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
306			sizeof(struct squashfs_reg_inode_header_3));\
307	SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
308	SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
309	SQUASHFS_SWAP((s)->offset, d, 192, 32);\
310	SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
311}
312
313#define SQUASHFS_SWAP_LREG_INODE_HEADER_3(s, d) {\
314	SQUASHFS_SWAP_START\
315	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
316			sizeof(struct squashfs_lreg_inode_header_3));\
317	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
318	SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
319	SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
320	SQUASHFS_SWAP((s)->offset, d, 224, 32);\
321	SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
322}
323
324#define SQUASHFS_SWAP_DIR_INODE_HEADER_3(s, d) {\
325	SQUASHFS_SWAP_START\
326	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
327			sizeof(struct squashfs_dir_inode_header_3));\
328	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
329	SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
330	SQUASHFS_SWAP((s)->offset, d, 147, 13);\
331	SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
332	SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
333}
334
335#define SQUASHFS_SWAP_LDIR_INODE_HEADER_3(s, d) {\
336	SQUASHFS_SWAP_START\
337	SQUASHFS_SWAP_BASE_INODE_CORE_3(s, d, \
338			sizeof(struct squashfs_ldir_inode_header_3));\
339	SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
340	SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
341	SQUASHFS_SWAP((s)->offset, d, 155, 13);\
342	SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
343	SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
344	SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
345}
346
347#define SQUASHFS_SWAP_DIR_INDEX_3(s, d) {\
348	SQUASHFS_SWAP_START\
349	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_3));\
350	SQUASHFS_SWAP((s)->index, d, 0, 32);\
351	SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
352	SQUASHFS_SWAP((s)->size, d, 64, 8);\
353}
354
355#define SQUASHFS_SWAP_DIR_HEADER_3(s, d) {\
356	SQUASHFS_SWAP_START\
357	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_3));\
358	SQUASHFS_SWAP((s)->count, d, 0, 8);\
359	SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
360	SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
361}
362
363#define SQUASHFS_SWAP_DIR_ENTRY_3(s, d) {\
364	SQUASHFS_SWAP_START\
365	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_3));\
366	SQUASHFS_SWAP((s)->offset, d, 0, 13);\
367	SQUASHFS_SWAP((s)->type, d, 13, 3);\
368	SQUASHFS_SWAP((s)->size, d, 16, 8);\
369	SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
370}
371
372#define SQUASHFS_SWAP_INODE_T_3(s, d) SQUASHFS_SWAP_LONG_LONGS_3(s, d, 1)
373
374#define SQUASHFS_SWAP_SHORTS_3(s, d, n) {\
375	int entry;\
376	int bit_position;\
377	SQUASHFS_SWAP_START\
378	SQUASHFS_MEMSET(s, d, n * 2);\
379	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
380			16)\
381		SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
382}
383
384#define SQUASHFS_SWAP_INTS_3(s, d, n) {\
385	int entry;\
386	int bit_position;\
387	SQUASHFS_SWAP_START\
388	SQUASHFS_MEMSET(s, d, n * 4);\
389	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
390			32)\
391		SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
392}
393
394#define SQUASHFS_SWAP_LONG_LONGS_3(s, d, n) {\
395	int entry;\
396	int bit_position;\
397	SQUASHFS_SWAP_START\
398	SQUASHFS_MEMSET(s, d, n * 8);\
399	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
400			64)\
401		SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
402}
403
404#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
405	int entry;\
406	int bit_position;\
407	SQUASHFS_SWAP_START\
408	SQUASHFS_MEMSET(s, d, n * bits / 8);\
409	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
410			bits)\
411		SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
412}
413
414#define SQUASHFS_SWAP_FRAGMENT_INDEXES_3(s, d, n) SQUASHFS_SWAP_LONG_LONGS_3(s, d, n)
415#define SQUASHFS_SWAP_LOOKUP_BLOCKS_3(s, d, n) SQUASHFS_SWAP_LONG_LONGS_3(s, d, n)
416
417#define SQUASHFS_SWAP_FRAGMENT_ENTRY_3(s, d) {\
418	SQUASHFS_SWAP_START\
419	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_3));\
420	SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
421	SQUASHFS_SWAP((s)->size, d, 64, 32);\
422}
423
424/* fragment and fragment table defines */
425#define SQUASHFS_FRAGMENT_BYTES_3(A)	((A) * sizeof(struct squashfs_fragment_entry_3))
426
427#define SQUASHFS_FRAGMENT_INDEX_3(A)	(SQUASHFS_FRAGMENT_BYTES_3(A) / \
428					SQUASHFS_METADATA_SIZE)
429
430#define SQUASHFS_FRAGMENT_INDEX_OFFSET_3(A)	(SQUASHFS_FRAGMENT_BYTES_3(A) % \
431						SQUASHFS_METADATA_SIZE)
432
433#define SQUASHFS_FRAGMENT_INDEXES_3(A)	((SQUASHFS_FRAGMENT_BYTES_3(A) + \
434					SQUASHFS_METADATA_SIZE - 1) / \
435					SQUASHFS_METADATA_SIZE)
436
437#define SQUASHFS_FRAGMENT_INDEX_BYTES_3(A)	(SQUASHFS_FRAGMENT_INDEXES_3(A) *\
438						sizeof(long long))
439
440/*
441 * definitions for structures on disk - layout 1.x
442 */
443#define SQUASHFS_TYPES			5
444#define SQUASHFS_IPC_TYPE		0
445
446struct squashfs_base_inode_header_1 {
447	unsigned int		inode_type:4;
448	unsigned int		mode:12; /* protection */
449	unsigned int		uid:4; /* index into uid table */
450	unsigned int		guid:4; /* index into guid table */
451} __attribute__ ((packed));
452
453struct squashfs_ipc_inode_header_1 {
454	unsigned int		inode_type:4;
455	unsigned int		mode:12; /* protection */
456	unsigned int		uid:4; /* index into uid table */
457	unsigned int		guid:4; /* index into guid table */
458	unsigned int		type:4;
459	unsigned int		offset:4;
460} __attribute__ ((packed));
461
462struct squashfs_dev_inode_header_1 {
463	unsigned int		inode_type:4;
464	unsigned int		mode:12; /* protection */
465	unsigned int		uid:4; /* index into uid table */
466	unsigned int		guid:4; /* index into guid table */
467	unsigned short		rdev;
468} __attribute__ ((packed));
469
470struct squashfs_symlink_inode_header_1 {
471	unsigned int		inode_type:4;
472	unsigned int		mode:12; /* protection */
473	unsigned int		uid:4; /* index into uid table */
474	unsigned int		guid:4; /* index into guid table */
475	unsigned short		symlink_size;
476	char			symlink[0];
477} __attribute__ ((packed));
478
479struct squashfs_reg_inode_header_1 {
480	unsigned int		inode_type:4;
481	unsigned int		mode:12; /* protection */
482	unsigned int		uid:4; /* index into uid table */
483	unsigned int		guid:4; /* index into guid table */
484	int			mtime;
485	unsigned int		start_block;
486	unsigned int		file_size:32;
487	unsigned short		block_list[0];
488} __attribute__ ((packed));
489
490struct squashfs_dir_inode_header_1 {
491	unsigned int		inode_type:4;
492	unsigned int		mode:12; /* protection */
493	unsigned int		uid:4; /* index into uid table */
494	unsigned int		guid:4; /* index into guid table */
495	unsigned int		file_size:19;
496	unsigned int		offset:13;
497	int			mtime;
498	unsigned int		start_block:24;
499} __attribute__  ((packed));
500
501union squashfs_inode_header_1 {
502	struct squashfs_base_inode_header_1	base;
503	struct squashfs_dev_inode_header_1	dev;
504	struct squashfs_symlink_inode_header_1	symlink;
505	struct squashfs_reg_inode_header_1	reg;
506	struct squashfs_dir_inode_header_1	dir;
507	struct squashfs_ipc_inode_header_1	ipc;
508};
509
510typedef struct squashfs_dir_index_1 squashfs_dir_index_1;
511typedef struct squashfs_base_inode_header_1 squashfs_base_inode_header_1;
512typedef struct squashfs_ipc_inode_header_1 squashfs_ipc_inode_header_1;
513typedef struct squashfs_dev_inode_header_1 squashfs_dev_inode_header_1;
514typedef struct squashfs_symlink_inode_header_1 squashfs_symlink_inode_header_1;
515typedef struct squashfs_reg_inode_header_1 squashfs_reg_inode_header_1;
516typedef struct squashfs_dir_inode_header_1 squashfs_dir_inode_header_1;
517
518#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
519	SQUASHFS_MEMSET(s, d, n);\
520	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
521	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
522	SQUASHFS_SWAP((s)->uid, d, 16, 4);\
523	SQUASHFS_SWAP((s)->guid, d, 20, 4);
524
525#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
526	SQUASHFS_SWAP_START\
527	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
528}
529
530#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
531	SQUASHFS_SWAP_START\
532	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
533			sizeof(struct squashfs_ipc_inode_header_1));\
534	SQUASHFS_SWAP((s)->type, d, 24, 4);\
535	SQUASHFS_SWAP((s)->offset, d, 28, 4);\
536}
537
538#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
539	SQUASHFS_SWAP_START\
540	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
541			sizeof(struct squashfs_dev_inode_header_1));\
542	SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
543}
544
545#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
546	SQUASHFS_SWAP_START\
547	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
548			sizeof(struct squashfs_symlink_inode_header_1));\
549	SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
550}
551
552#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
553	SQUASHFS_SWAP_START\
554	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
555			sizeof(struct squashfs_reg_inode_header_1));\
556	SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
557	SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
558	SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
559}
560
561#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
562	SQUASHFS_SWAP_START\
563	SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
564			sizeof(struct squashfs_dir_inode_header_1));\
565	SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
566	SQUASHFS_SWAP((s)->offset, d, 43, 13);\
567	SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
568	SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
569}
570
571/*
572 * definitions for structures on disk - layout 2.x
573 */
574struct squashfs_dir_index_2 {
575	unsigned int		index:27;
576	unsigned int		start_block:29;
577	unsigned char		size;
578	unsigned char		name[0];
579} __attribute__ ((packed));
580
581struct squashfs_base_inode_header_2 {
582	unsigned int		inode_type:4;
583	unsigned int		mode:12; /* protection */
584	unsigned int		uid:8; /* index into uid table */
585	unsigned int		guid:8; /* index into guid table */
586} __attribute__ ((packed));
587
588struct squashfs_ipc_inode_header_2 {
589	unsigned int		inode_type:4;
590	unsigned int		mode:12; /* protection */
591	unsigned int		uid:8; /* index into uid table */
592	unsigned int		guid:8; /* index into guid table */
593} __attribute__ ((packed));
594
595struct squashfs_dev_inode_header_2 {
596	unsigned int		inode_type:4;
597	unsigned int		mode:12; /* protection */
598	unsigned int		uid:8; /* index into uid table */
599	unsigned int		guid:8; /* index into guid table */
600	unsigned short		rdev;
601} __attribute__ ((packed));
602
603struct squashfs_symlink_inode_header_2 {
604	unsigned int		inode_type:4;
605	unsigned int		mode:12; /* protection */
606	unsigned int		uid:8; /* index into uid table */
607	unsigned int		guid:8; /* index into guid table */
608	unsigned short		symlink_size;
609	char			symlink[0];
610} __attribute__ ((packed));
611
612struct squashfs_reg_inode_header_2 {
613	unsigned int		inode_type:4;
614	unsigned int		mode:12; /* protection */
615	unsigned int		uid:8; /* index into uid table */
616	unsigned int		guid:8; /* index into guid table */
617	int			mtime;
618	unsigned int		start_block;
619	unsigned int		fragment;
620	unsigned int		offset;
621	unsigned int		file_size:32;
622	unsigned short		block_list[0];
623} __attribute__ ((packed));
624
625struct squashfs_dir_inode_header_2 {
626	unsigned int		inode_type:4;
627	unsigned int		mode:12; /* protection */
628	unsigned int		uid:8; /* index into uid table */
629	unsigned int		guid:8; /* index into guid table */
630	unsigned int		file_size:19;
631	unsigned int		offset:13;
632	int			mtime;
633	unsigned int		start_block:24;
634} __attribute__  ((packed));
635
636struct squashfs_ldir_inode_header_2 {
637	unsigned int		inode_type:4;
638	unsigned int		mode:12; /* protection */
639	unsigned int		uid:8; /* index into uid table */
640	unsigned int		guid:8; /* index into guid table */
641	unsigned int		file_size:27;
642	unsigned int		offset:13;
643	int			mtime;
644	unsigned int		start_block:24;
645	unsigned int		i_count:16;
646	struct squashfs_dir_index_2	index[0];
647} __attribute__  ((packed));
648
649union squashfs_inode_header_2 {
650	struct squashfs_base_inode_header_2	base;
651	struct squashfs_dev_inode_header_2	dev;
652	struct squashfs_symlink_inode_header_2	symlink;
653	struct squashfs_reg_inode_header_2	reg;
654	struct squashfs_dir_inode_header_2	dir;
655	struct squashfs_ldir_inode_header_2	ldir;
656	struct squashfs_ipc_inode_header_2	ipc;
657};
658
659struct squashfs_dir_header_2 {
660	unsigned int		count:8;
661	unsigned int		start_block:24;
662} __attribute__ ((packed));
663
664struct squashfs_dir_entry_2 {
665	unsigned int		offset:13;
666	unsigned int		type:3;
667	unsigned int		size:8;
668	char			name[0];
669} __attribute__ ((packed));
670
671struct squashfs_fragment_entry_2 {
672	unsigned int		start_block;
673	unsigned int		size;
674} __attribute__ ((packed));
675
676typedef struct squashfs_dir_index_2 squashfs_dir_index_2;
677typedef struct squashfs_base_inode_header_2 squashfs_base_inode_header_2;
678typedef struct squashfs_ipc_inode_header_2 squashfs_ipc_inode_header_2;
679typedef struct squashfs_dev_inode_header_2 squashfs_dev_inode_header_2;
680typedef struct squashfs_symlink_inode_header_2 squashfs_symlink_inode_header_2;
681typedef struct squashfs_reg_inode_header_2 squashfs_reg_inode_header_2;
682typedef struct squashfs_lreg_inode_header_2 squashfs_lreg_inode_header_2;
683typedef struct squashfs_dir_inode_header_2 squashfs_dir_inode_header_2;
684typedef struct squashfs_ldir_inode_header_2 squashfs_ldir_inode_header_2;
685typedef struct squashfs_dir_entry_2 squashfs_dir_entry_2;
686typedef struct squashfs_dir_header_2 squashfs_dir_header_2;
687typedef struct squashfs_fragment_entry_2 squashfs_fragment_entry_2;
688
689#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
690	SQUASHFS_MEMSET(s, d, n);\
691	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
692	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
693	SQUASHFS_SWAP((s)->uid, d, 16, 8);\
694	SQUASHFS_SWAP((s)->guid, d, 24, 8);\
695
696#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
697	SQUASHFS_SWAP_START\
698	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
699}
700
701#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
702	SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
703
704#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
705	SQUASHFS_SWAP_START\
706	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
707			sizeof(struct squashfs_dev_inode_header_2)); \
708	SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
709}
710
711#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
712	SQUASHFS_SWAP_START\
713	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
714			sizeof(struct squashfs_symlink_inode_header_2));\
715	SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
716}
717
718#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
719	SQUASHFS_SWAP_START\
720	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
721			sizeof(struct squashfs_reg_inode_header_2));\
722	SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
723	SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
724	SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
725	SQUASHFS_SWAP((s)->offset, d, 128, 32);\
726	SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
727}
728
729#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
730	SQUASHFS_SWAP_START\
731	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
732			sizeof(struct squashfs_dir_inode_header_2));\
733	SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
734	SQUASHFS_SWAP((s)->offset, d, 51, 13);\
735	SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
736	SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
737}
738
739#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
740	SQUASHFS_SWAP_START\
741	SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
742			sizeof(struct squashfs_ldir_inode_header_2));\
743	SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
744	SQUASHFS_SWAP((s)->offset, d, 59, 13);\
745	SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
746	SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
747	SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
748}
749
750#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
751	SQUASHFS_SWAP_START\
752	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
753	SQUASHFS_SWAP((s)->index, d, 0, 27);\
754	SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
755	SQUASHFS_SWAP((s)->size, d, 56, 8);\
756}
757#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
758	SQUASHFS_SWAP_START\
759	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
760	SQUASHFS_SWAP((s)->count, d, 0, 8);\
761	SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
762}
763
764#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
765	SQUASHFS_SWAP_START\
766	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
767	SQUASHFS_SWAP((s)->offset, d, 0, 13);\
768	SQUASHFS_SWAP((s)->type, d, 13, 3);\
769	SQUASHFS_SWAP((s)->size, d, 16, 8);\
770}
771
772#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
773	SQUASHFS_SWAP_START\
774	SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
775	SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
776	SQUASHFS_SWAP((s)->size, d, 32, 32);\
777}
778
779#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS_3(s, d, n)
780
781/* fragment and fragment table defines */
782#define SQUASHFS_FRAGMENT_BYTES_2(A)	((A) * sizeof(struct squashfs_fragment_entry_2))
783
784#define SQUASHFS_FRAGMENT_INDEX_2(A)	(SQUASHFS_FRAGMENT_BYTES_2(A) / \
785					SQUASHFS_METADATA_SIZE)
786
787#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A)	(SQUASHFS_FRAGMENT_BYTES_2(A) % \
788						SQUASHFS_METADATA_SIZE)
789
790#define SQUASHFS_FRAGMENT_INDEXES_2(A)	((SQUASHFS_FRAGMENT_BYTES_2(A) + \
791					SQUASHFS_METADATA_SIZE - 1) / \
792					SQUASHFS_METADATA_SIZE)
793
794#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A)	(SQUASHFS_FRAGMENT_INDEXES_2(A) *\
795						sizeof(int))
796/*
797 * macros used to swap each structure entry, taking into account
798 * bitfields and different bitfield placing conventions on differing architectures
799 */
800#if __BYTE_ORDER == __BIG_ENDIAN
801	/* convert from big endian to little endian */
802#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, b_pos)
803#else
804	/* convert from little endian to big endian */
805#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, 64 - tbits - b_pos)
806#endif
807
808#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
809	b_pos = pos % 8;\
810	val = 0;\
811	s = (unsigned char *)p + (pos / 8);\
812	d = ((unsigned char *) &val) + 7;\
813	for(bits = 0; bits < (tbits + b_pos); bits += 8) \
814		*d-- = *s++;\
815	value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
816}
817#define SQUASHFS_MEMSET(s, d, n)	memset(s, 0, n);
818#endif
819