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