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 
38 struct 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 
67 struct 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 
74 struct 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 
83 struct 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 
93 struct 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 
104 struct 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 
116 struct 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 
130 struct 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 
145 struct 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 
159 struct 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 
175 union 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 
186 struct 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 
194 struct squashfs_dir_header_3 {
195 	unsigned int		count:8;
196 	unsigned int		start_block;
197 	unsigned int		inode_number;
198 } __attribute__ ((packed));
199 
200 struct squashfs_fragment_entry_3 {
201 	long long		start_block;
202 	unsigned int		size;
203 	unsigned int		pending;
204 } __attribute__ ((packed));
205 
206 
207 typedef struct squashfs_super_block_3 squashfs_super_block_3;
208 typedef struct squashfs_dir_index_3 squashfs_dir_index_3;
209 typedef struct squashfs_base_inode_header_3 squashfs_base_inode_header_3;
210 typedef struct squashfs_ipc_inode_header_3 squashfs_ipc_inode_header_3;
211 typedef struct squashfs_dev_inode_header_3 squashfs_dev_inode_header_3;
212 typedef struct squashfs_symlink_inode_header_3 squashfs_symlink_inode_header_3;
213 typedef struct squashfs_reg_inode_header_3 squashfs_reg_inode_header_3;
214 typedef struct squashfs_lreg_inode_header_3 squashfs_lreg_inode_header_3;
215 typedef struct squashfs_dir_inode_header_3 squashfs_dir_inode_header_3;
216 typedef struct squashfs_ldir_inode_header_3 squashfs_ldir_inode_header_3;
217 typedef struct squashfs_dir_entry_3 squashfs_dir_entry_3;
218 typedef struct squashfs_dir_header_3 squashfs_dir_header_3;
219 typedef 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 
446 struct 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 
453 struct 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 
462 struct 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 
470 struct 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 
479 struct 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 
490 struct 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 
501 union 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 
510 typedef struct squashfs_dir_index_1 squashfs_dir_index_1;
511 typedef struct squashfs_base_inode_header_1 squashfs_base_inode_header_1;
512 typedef struct squashfs_ipc_inode_header_1 squashfs_ipc_inode_header_1;
513 typedef struct squashfs_dev_inode_header_1 squashfs_dev_inode_header_1;
514 typedef struct squashfs_symlink_inode_header_1 squashfs_symlink_inode_header_1;
515 typedef struct squashfs_reg_inode_header_1 squashfs_reg_inode_header_1;
516 typedef 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  */
574 struct 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 
581 struct 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 
588 struct 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 
595 struct 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 
603 struct 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 
612 struct 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 
625 struct 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 
636 struct 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 
649 union 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 
659 struct squashfs_dir_header_2 {
660 	unsigned int		count:8;
661 	unsigned int		start_block:24;
662 } __attribute__ ((packed));
663 
664 struct 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 
671 struct squashfs_fragment_entry_2 {
672 	unsigned int		start_block;
673 	unsigned int		size;
674 } __attribute__ ((packed));
675 
676 typedef struct squashfs_dir_index_2 squashfs_dir_index_2;
677 typedef struct squashfs_base_inode_header_2 squashfs_base_inode_header_2;
678 typedef struct squashfs_ipc_inode_header_2 squashfs_ipc_inode_header_2;
679 typedef struct squashfs_dev_inode_header_2 squashfs_dev_inode_header_2;
680 typedef struct squashfs_symlink_inode_header_2 squashfs_symlink_inode_header_2;
681 typedef struct squashfs_reg_inode_header_2 squashfs_reg_inode_header_2;
682 typedef struct squashfs_lreg_inode_header_2 squashfs_lreg_inode_header_2;
683 typedef struct squashfs_dir_inode_header_2 squashfs_dir_inode_header_2;
684 typedef struct squashfs_ldir_inode_header_2 squashfs_ldir_inode_header_2;
685 typedef struct squashfs_dir_entry_2 squashfs_dir_entry_2;
686 typedef struct squashfs_dir_header_2 squashfs_dir_header_2;
687 typedef 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