Home | History | Annotate | Download | only in squashfs-tools
      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 (at) 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