Subversion Repositories QNX 8.QNX8 IFS tool

Rev

Rev 9 | Rev 11 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9 Rev 10
Line 122... Line 122...
122
#define RECORD_SEP '\x1e' // ASCII record separator
122
#define RECORD_SEP '\x1e' // ASCII record separator
123
#define RECORD_SEP_STR "\x1e" // ASCII record separator (as string)
123
#define RECORD_SEP_STR "\x1e" // ASCII record separator (as string)
124
 
124
 
125
// macros for accessing ELF files
125
// macros for accessing ELF files
126
#define ELF_MAGIC_STR "\x7f" "ELF"
126
#define ELF_MAGIC_STR "\x7f" "ELF"
127
#define ELF_ENDIAN_LITTLE 1 // ELF file is little endian
127
#define ELF_ENDIAN_LITTLE 1 // 'endianness' member of an ELF header: ELF file is little endian
128
#define ELF_ENDIAN_BIG    2 // ELF file is big endian
128
#define ELF_ENDIAN_BIG    2 // 'endianness' member of an ELF header: ELF file is big endian
-
 
129
#define ELF_MACHINE_X86_64  0x3e // 'instruction_set' member of an ELF header, also used in the IFS startup header: ELF file is for x86_64 processors (62 decimal)
-
 
130
#define ELF_MACHINE_AARCH64 0xb7 // 'instruction_set' member of an ELF header, also used in the IFS startup header: ELF file is for ARM64 processors (183 decimal)
-
 
131
#define ELF_SECTIONTYPE_STRINGTABLE 3
129
#define ELF_DT_NULL    0 // marks end of dynamic section
132
#define ELF_DT_NULL    0 // marks end of dynamic section
130
#define ELF_DT_SONAME 14 // canonical name of shared object
133
#define ELF_DT_SONAME 14 // canonical name of shared object
131
#define ELF_STRUCT_MEMBER_NUMERIC(elfhdr,elfstruct,member) ((elfhdr)->u.elf.platform_size == 2 ? /* is it a 64-bit ELF file ? */ \
134
#define ELF_GET_NUMERIC(elfhdr,elfstruct,member) ((elfhdr)->u.elf.platform_size == 2 ? /* is it a 64-bit ELF file ? */ \
132
   ( \
135
   ( \
133
      (sizeof ((elfstruct)->u.elf64.member) == 1) || (((elfhdr)->u.elf.endianness == 1) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || (((elfhdr)->u.elf.endianness == 2) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) ? /* single-byte, or same endianness ? */ \
136
      (sizeof ((elfstruct)->u.elf64.member) == 1) || (((elfhdr)->u.elf.endianness == 1) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || (((elfhdr)->u.elf.endianness == 2) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) ? /* single-byte, or same endianness ? */ \
134
         (elfstruct)->u.elf64.member /* same endianness, or single byte required: don't swap */ \
137
         (elfstruct)->u.elf64.member /* same endianness, or single byte required: don't swap */ \
135
      : /* else */ \
138
      : /* else */ \
136
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? __builtin_bswap64 ((elfstruct)->u.elf64.member) : (sizeof ((elfstruct)->u.elf64.member) == 4 ? __builtin_bswap32 ((elfstruct)->u.elf64.member) : __builtin_bswap16 ((elfstruct)->u.elf64.member))) /* different endianness: swap */ \
139
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? __builtin_bswap64 ((elfstruct)->u.elf64.member) : (sizeof ((elfstruct)->u.elf64.member) == 4 ? __builtin_bswap32 ((elfstruct)->u.elf64.member) : __builtin_bswap16 ((elfstruct)->u.elf64.member))) /* different endianness: swap */ \
Line 141... Line 144...
141
         (elfstruct)->u.elf32.member /* same endianness, or single byte required: don't swap */ \
144
         (elfstruct)->u.elf32.member /* same endianness, or single byte required: don't swap */ \
142
      : /* else */ \
145
      : /* else */ \
143
         (sizeof ((elfstruct)->u.elf32.member) == 4 ? __builtin_bswap32 ((elfstruct)->u.elf32.member) : __builtin_bswap16 ((elfstruct)->u.elf32.member)) /* different endianness: swap */ \
146
         (sizeof ((elfstruct)->u.elf32.member) == 4 ? __builtin_bswap32 ((elfstruct)->u.elf32.member) : __builtin_bswap16 ((elfstruct)->u.elf32.member)) /* different endianness: swap */ \
144
   ) \
147
   ) \
145
) // this macro supports 32- and 64-bit ELF files in low and big endianness transparently
148
) // this macro supports 32- and 64-bit ELF files in low and big endianness transparently
-
 
149
#define ELF_SET_NUMERIC(elfhdr,elfstruct,member,data) ((elfhdr)->u.elf.platform_size == 2 ? /* is it a 64-bit ELF file ? */ \
-
 
150
   ((elfstruct)->u.elf64.member = ( \
-
 
151
      (sizeof ((elfstruct)->u.elf64.member) == 1) || (((elfhdr)->u.elf.endianness == 1) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || (((elfhdr)->u.elf.endianness == 2) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) ? /* single-byte, or same endianness ? */ \
-
 
152
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? (uint64_t) ((data)) : (sizeof ((elfstruct)->u.elf64.member) == 4 ? (uint32_t) ((data)) : (sizeof ((elfstruct)->u.elf64.member) == 2 ? (uint16_t) ((data)) : (uint8_t) ((data))))) /* same endianness, or single byte required: don't swap */ \
-
 
153
      : /* else */ \
-
 
154
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? __builtin_bswap64 ((data)) : (sizeof ((elfstruct)->u.elf64.member) == 4 ? __builtin_bswap32 ((data)) : __builtin_bswap16 ((data)))) /* different endianness: swap */ \
-
 
155
   )) \
-
 
156
   : /* else poke at 32-bit ELF */ \
-
 
157
   ((elfstruct)->u.elf32.member = ( \
-
 
158
      (sizeof ((elfstruct)->u.elf32.member) == 1) || (((elfhdr)->u.elf.endianness == 1) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || (((elfhdr)->u.elf.endianness == 2) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) ? /* single-byte, or same endianness ? */ \
-
 
159
         (sizeof ((elfstruct)->u.elf64.member) == 4 ? (uint32_t) ((data)) : (sizeof ((elfstruct)->u.elf64.member) == 2 ? (uint16_t) ((data)) : (uint8_t) ((data)))) /* same endianness, or single byte required: don't swap */ \
-
 
160
      : /* else */ \
-
 
161
         (sizeof ((elfstruct)->u.elf32.member) == 4 ? __builtin_bswap32 ((data)) : __builtin_bswap16 ((data))) /* different endianness: swap */ \
-
 
162
   )) \
-
 
163
) // this macro supports 32- and 64-bit ELF files in low and big endianness transparently
146
#define ELF_STRUCT_MEMBER_STRING(elfhdr,elfstruct,member) ((elfhdr)->u.elf.platform_size == 2 ? (elfstruct)->u.elf64.member : (elfstruct)->u.elf32.member) // this macro supports 32- and 64-bit ELF files transparently
164
#define ELF_GET_STRING(elfhdr,elfstruct,member) ((elfhdr)->u.elf.platform_size == 2 ? (elfstruct)->u.elf64.member : (elfstruct)->u.elf32.member) // this macro supports 32- and 64-bit ELF files transparently
-
 
165
#define ELF_SET_STRING(elfhdr,elfstruct,member,data,len) memcpy (((elfhdr)->u.elf.platform_size == 2 ? (elfstruct)->u.elf64.member : (elfstruct)->u.elf32.member), (data), (len)) // this macro supports 32- and 64-bit ELF files transparently
147
#define ELF_STRUCT_SIZE(elfhdr,elfstruct) ((elfhdr)->u.elf.platform_size == 2 ? sizeof ((elfstruct)->u.elf64) : sizeof ((elfstruct)->u.elf32)) // this macro supports 32- and 64-bit ELF files transparently
166
#define ELF_STRUCT_SIZE(elfhdr,elfstruct) ((elfhdr)->u.elf.platform_size == 2 ? sizeof ((elfstruct)->u.elf64) : sizeof ((elfstruct)->u.elf32)) // this macro supports 32- and 64-bit ELF files transparently
-
 
167
 
-
 
168
 
148
 
169
 
149
#define WILL_BE_FILLED_LATER 0xbaadf00d
170
#define WILL_BE_FILLED_LATER 0xbaadf00d
150
 
171
 
151
 
172
 
152
// bitmapped flags used in the flags1 member of the startup header
173
// bitmapped flags used in the flags1 member of the startup header
Line 157... Line 178...
157
//#define STARTUP_HDR_FLAGS1_COMPRESS_NONE  0x00
178
//#define STARTUP_HDR_FLAGS1_COMPRESS_NONE  0x00
158
//#define STARTUP_HDR_FLAGS1_COMPRESS_ZLIB  0x04
179
//#define STARTUP_HDR_FLAGS1_COMPRESS_ZLIB  0x04
159
//#define STARTUP_HDR_FLAGS1_COMPRESS_LZO   0x08
180
//#define STARTUP_HDR_FLAGS1_COMPRESS_LZO   0x08
160
//#define STARTUP_HDR_FLAGS1_COMPRESS_UCL   0x0c
181
//#define STARTUP_HDR_FLAGS1_COMPRESS_UCL   0x0c
161
#define STARTUP_HDR_FLAGS1_TRAILER_V2     (1 << 5) // if set, then a struct startup_trailer_v2 follows the startup. If the image is compressed, then the compressed imagefs is followed by a struct image_trailer_v2
182
#define STARTUP_HDR_FLAGS1_TRAILER_V2     (1 << 5) // if set, then a struct startup_trailer_v2 follows the startup. If the image is compressed, then the compressed imagefs is followed by a struct image_trailer_v2
162
 
-
 
163
 
-
 
164
#define STARTUP_HDR_MACHINE_X86_64  0x3e
-
 
165
#define STARTUP_HDR_MACHINE_AARCH64 0xb7
-
 
166
 
183
 
167
 
184
 
168
// bitmapped flags used in the flags member of the image header
185
// bitmapped flags used in the flags member of the image header
169
#define IMAGE_FLAGS_BIGENDIAN  (1 << 0) // header, trailer, dirents in big-endian format
186
#define IMAGE_FLAGS_BIGENDIAN  (1 << 0) // header, trailer, dirents in big-endian format
170
#define IMAGE_FLAGS_READONLY   (1 << 1) // do not try to write to image (rom/flash)
187
#define IMAGE_FLAGS_READONLY   (1 << 1) // do not try to write to image (rom/flash)
Line 423... Line 440...
423
{
440
{
424
   union __attribute__((packed))
441
   union __attribute__((packed))
425
   {
442
   {
426
      struct __attribute__((packed))
443
      struct __attribute__((packed))
427
      {
444
      {
428
         uint8_t magic[4];                     // offset 0: "\x07" + "ELF"
445
         uint8_t magic[4];                     // offset 0: "\x7f" + "ELF"
429
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
446
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
430
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
447
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
431
         uint8_t header_version;               // offset 6: typically 1
448
         uint8_t header_version;               // offset 6: typically 1
432
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
449
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
433
         uint8_t spare[8];                     // offset 8: zeroes
450
         uint8_t spare[8];                     // offset 8: zeroes
434
         uint16_t type;                        // offset 16: 1 = relocatable, 2 = executable, 3 = shared, 4 = core dump
451
         uint16_t type;                        // offset 16: 1 = relocatable, 2 = executable, 3 = shared, 4 = core dump
435
         uint16_t instruction_set;             // offset 18: 2 = Sparc, 3 = i386, 8 = MIPS, 20 = PowerPC, 40 = ARM, 42 = SuperH, 50 = IA-64, 62 = x86_64, 183 = AArch64, 243 = RISC-V
452
         uint16_t instruction_set;             // offset 18: 2 = Sparc, 3 = i386, 8 = MIPS, 20 = PowerPC, 40 = ARM, 42 = SuperH, 50 = IA-64, 62 = x86_64, 183 = AArch64, 243 = RISC-V
436
         uint32_t elf_version;                 // offset 20: typically 1
453
         uint32_t elf_version;                 // offset 20: typically 1
437
      } elf;
454
      } elf;
438
      struct __attribute__((packed))
455
      struct __attribute__((packed)) // size == 52
439
      {
456
      {
440
         uint8_t magic[4];                     // offset 0: "\x07" + "ELF"
457
         uint8_t magic[4];                     // offset 0: "\x7f" + "ELF"
441
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
458
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
442
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
459
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
443
         uint8_t header_version;               // offset 6: typically 1
460
         uint8_t header_version;               // offset 6: typically 1
444
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
461
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
445
         uint8_t spare[8];                     // offset 8: zeroes
462
         uint8_t spare[8];                     // offset 8: zeroes
Line 454... Line 471...
454
         uint16_t program_header_item_size;    // offset 42: size of an entry in the program header table
471
         uint16_t program_header_item_size;    // offset 42: size of an entry in the program header table
455
         uint16_t program_header_table_len;    // offset 44: number of entries in the program header table
472
         uint16_t program_header_table_len;    // offset 44: number of entries in the program header table
456
         uint16_t section_header_item_size;    // offset 46: size of an entry in the section header table
473
         uint16_t section_header_item_size;    // offset 46: size of an entry in the section header table
457
         uint16_t section_header_table_len;    // offset 48: number of entries in the section header table
474
         uint16_t section_header_table_len;    // offset 48: number of entries in the section header table
458
         uint16_t section_header_names_idx;    // offset 50: index of the entry in the section header table that contains the section names
475
         uint16_t section_header_names_idx;    // offset 50: index of the entry in the section header table that contains the section names
459
      } elf32;
476
      } elf32; // size == 52
460
      struct __attribute__((packed))
477
      struct __attribute__((packed)) // size == 64
461
      {
478
      {
462
         uint8_t magic[4];                     // offset 0: "\x07" + "ELF"
479
         uint8_t magic[4];                     // offset 0: "\x7f" + "ELF"
463
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
480
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
464
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
481
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
465
         uint8_t header_version;               // offset 6: typically 1
482
         uint8_t header_version;               // offset 6: typically 1
466
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
483
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
467
         uint8_t spare[8];                     // offset 8: zeroes
484
         uint8_t spare[8];                     // offset 8: zeroes
Line 476... Line 493...
476
         uint16_t program_header_item_size;    // offset 54: size of an entry in the program header table
493
         uint16_t program_header_item_size;    // offset 54: size of an entry in the program header table
477
         uint16_t program_header_table_len;    // offset 56: number of entries in the program header table
494
         uint16_t program_header_table_len;    // offset 56: number of entries in the program header table
478
         uint16_t section_header_item_size;    // offset 58: size of an entry in the section header table
495
         uint16_t section_header_item_size;    // offset 58: size of an entry in the section header table
479
         uint16_t section_header_table_len;    // offset 60: number of entries in the section header table
496
         uint16_t section_header_table_len;    // offset 60: number of entries in the section header table
480
         uint16_t section_header_names_idx;    // offset 62: index of the entry in the section header table that contains the section names
497
         uint16_t section_header_names_idx;    // offset 62: index of the entry in the section header table that contains the section names
481
      } elf64;
498
      } elf64; // size == 64
482
   } u;
499
   } u;
483
} elf_header_t;
500
} elf_header_t;
-
 
501
 
-
 
502
 
-
 
503
// Executable and Linkable Format program header structure type definition
-
 
504
typedef struct __attribute__((packed)) elf_program_header_s
-
 
505
{
-
 
506
   union __attribute__((packed))
-
 
507
   {
-
 
508
      struct __attribute__((packed))
-
 
509
      {
-
 
510
         uint32_t segment_type; // offset 0: type of segment (0: unused table entry, 1: loadable, 2: dynamic linking information, 3: interpreter information, 4: auxiliary information, 5: reserved, 6: this very segment, 7: TLS template)
-
 
511
      } elf;
-
 
512
      struct __attribute__((packed)) // size == 32
-
 
513
      {
-
 
514
         uint32_t segment_type;   // offset 0: type of segment (0: unused table entry, 1: loadable, 2: dynamic linking information, 3: interpreter information, 4: auxiliary information, 5: reserved, 6: this very segment, 7: TLS template)
-
 
515
         uint32_t file_offset;    // offset 4: file offset of this segment
-
 
516
         uint32_t virtual_addr;   // offset 8: virtual address where this segment should be mapped in memory
-
 
517
         uint32_t physical_addr;  // offset 12: on systems where this is relevant, PHYSICAL address where this segment should be mapped in memory
-
 
518
         uint32_t size_in_file;   // offset 16: size of this segment in the ELF file (may be zero)
-
 
519
         uint32_t size_in_memory; // offset 20: size of this segment in memory (may be zero)
-
 
520
         uint32_t segment_flags;  // offset 24: bitmap of segment flags (1: executable, 2: writable, 4: readable)
-
 
521
         uint32_t alignment;      // offset 28: memory alignment (0 or 1 mean non alignment, else must be a power of 2 where virtual_addr == file_offset % alignment)
-
 
522
      } elf32; // size == 32
-
 
523
      struct __attribute__((packed)) // size == 56
-
 
524
      {
-
 
525
         uint32_t segment_type;   // offset 0: type of segment (0: unused table entry, 1: loadable, 2: dynamic linking information, 3: interpreter information, 4: auxiliary information, 5: reserved, 6: this very segment, 7: TLS template)
-
 
526
         uint32_t segment_flags;  // offset 4: bitmap of segment flags (1: executable, 2: writable, 4: readable)
-
 
527
         uint64_t file_offset;    // offset 8: file offset of this segment
-
 
528
         uint64_t virtual_addr;   // offset 16: virtual address where this segment should be mapped in memory
-
 
529
         uint64_t physical_addr;  // offset 24: on systems where this is relevant, PHYSICAL address where this segment should be mapped in memory
-
 
530
         uint64_t size_in_file;   // offset 32: size of this segment in the ELF file (may be zero)
-
 
531
         uint64_t size_in_memory; // offset 40: size of this segment in memory (may be zero)
-
 
532
         uint64_t alignment;      // offset 48: memory alignment (0 or 1 mean non alignment, else must be a power of 2 where virtual_addr == file_offset % alignment)
-
 
533
      } elf64; // size == 56
-
 
534
   } u;
-
 
535
} elf_program_header_t;
484
 
536
 
485
 
537
 
486
// Executable and Linkable Format section header structure type definition
538
// Executable and Linkable Format section header structure type definition
487
typedef struct __attribute__((packed)) elf_section_header_s
539
typedef struct __attribute__((packed)) elf_section_header_s
488
{
540
{
489
   union __attribute__((packed))
541
   union __attribute__((packed))
490
   {
542
   {
491
      struct __attribute__((packed))
543
      struct __attribute__((packed)) // size == 40
492
      {
544
      {
493
         uint32_t name_offset;  // offset 0: offset in the string table of the name of this section
545
         uint32_t name_offset;  // offset 0: offset in the string table of the name of this section
494
         uint32_t type;         // offset 4:
546
         uint32_t type;         // offset 4:
495
         uint32_t flags;        // offset 8:
547
         uint32_t flags;        // offset 8:
496
         uint32_t virtual_addr; // offset 12: address in virtual memory where this section may be loaded
548
         uint32_t virtual_addr; // offset 12: address in virtual memory where this section may be loaded
Line 498... Line 550...
498
         uint32_t size;         // offset 20: size of this section
550
         uint32_t size;         // offset 20: size of this section
499
         uint32_t linked_index; // offset 24: optional section index of an associated section
551
         uint32_t linked_index; // offset 24: optional section index of an associated section
500
         uint32_t info;         // offset 28: optional extra information
552
         uint32_t info;         // offset 28: optional extra information
501
         uint32_t alignment;    // offset 32: required memory alignment (must be a power of 2)
553
         uint32_t alignment;    // offset 32: required memory alignment (must be a power of 2)
502
         uint32_t entry_size;   // offset 36: for table-like sections, size of an element in the table
554
         uint32_t entry_size;   // offset 36: for table-like sections, size of an element in the table
503
      } elf32;
555
      } elf32; // size == 40
504
      struct __attribute__((packed))
556
      struct __attribute__((packed)) // size == 64
505
      {
557
      {
506
         uint32_t name_offset;  // offset 0: offset in the string table of the name of this section
558
         uint32_t name_offset;  // offset 0: offset in the string table of the name of this section
507
         uint32_t type;         // offset 4:
559
         uint32_t type;         // offset 4:
508
         uint64_t flags;        // offset 8:
560
         uint64_t flags;        // offset 8:
509
         uint64_t virtual_addr; // offset 16: address in virtual memory where this section may be loaded
561
         uint64_t virtual_addr; // offset 16: address in virtual memory where this section may be loaded
Line 511... Line 563...
511
         uint64_t size;         // offset 32: size of this section
563
         uint64_t size;         // offset 32: size of this section
512
         uint32_t linked_index; // offset 40: optional section index of an associated section
564
         uint32_t linked_index; // offset 40: optional section index of an associated section
513
         uint32_t info;         // offset 44: optional extra information
565
         uint32_t info;         // offset 44: optional extra information
514
         uint64_t alignment;    // offset 48: required memory alignment (must be a power of 2)
566
         uint64_t alignment;    // offset 48: required memory alignment (must be a power of 2)
515
         uint64_t entry_size;   // offset 56: for table-like sections, size of an element in the table
567
         uint64_t entry_size;   // offset 56: for table-like sections, size of an element in the table
516
      } elf64;
568
      } elf64; // size == 64
517
   } u;
569
   } u;
518
} elf_section_header_t;
570
} elf_section_header_t;
519
 
571
 
520
 
572
 
521
// Executable and Linkable Format dynamic section entry structure type definition
573
// Executable and Linkable Format dynamic section entry structure type definition
522
typedef struct __attribute__((packed)) elf_dynamic_section_entry_s
574
typedef struct __attribute__((packed)) elf_dynamic_section_entry_s
523
{
575
{
524
   union __attribute__((packed))
576
   union __attribute__((packed))
525
   {
577
   {
526
      struct __attribute__((packet))
578
      struct __attribute__((packed)) // size == 8
527
      {
579
      {
528
         int32_t tag; // dynamic entry type (one of ELF_DT_xxx #defines)
580
         int32_t tag; // dynamic entry type (one of ELF_DT_xxx #defines)
529
         union
581
         union
530
         {
582
         {
531
            uint32_t as_integer; // value as integer
583
            uint32_t as_integer; // value as integer
532
            uint32_t as_pointer; // value as address
584
            uint32_t as_pointer; // value as address
533
         } value;
585
         } value;
534
      } elf32;
586
      } elf32; // size == 8
535
      struct __attribute__((packed))
587
      struct __attribute__((packed)) // size == 16
536
      {
588
      {
537
         int64_t tag; // dynamic entry type (one of ELF_DT_xxx #defines)
589
         int64_t tag; // dynamic entry type (one of ELF_DT_xxx #defines)
538
         union
590
         union
539
         {
591
         {
540
            uint64_t as_integer; // value as intege
592
            uint64_t as_integer; // value as intege
541
            uint64_t as_pointer; // value as address
593
            uint64_t as_pointer; // value as address
542
         } value;
594
         } value;
543
      } elf64;
595
      } elf64; // size == 16
544
   } u;
596
   } u;
545
} elf_dynamic_section_entry_t;
597
} elf_dynamic_section_entry_t;
546
 
598
 
547
 
599
 
548
#ifdef _MSC_VER
600
#ifdef _MSC_VER
Line 561... Line 613...
561
   uint32_t mtime_for_inline_files; // same as above but only for files that don't exist on the build host (i.e. files with an explicit content blob)
613
   uint32_t mtime_for_inline_files; // same as above but only for files that don't exist on the build host (i.e. files with an explicit content blob)
562
   char prefix[MAXPATHLEN]; // install path (e.g. "proc/boot")
614
   char prefix[MAXPATHLEN]; // install path (e.g. "proc/boot")
563
   bool should_follow_symlinks; // follow symlinks
615
   bool should_follow_symlinks; // follow symlinks
564
   bool should_autosymlink_dylib; // dynamic libraries should be written under their official SONAME and a named symlink be created pointing at them
616
   bool should_autosymlink_dylib; // dynamic libraries should be written under their official SONAME and a named symlink be created pointing at them
565
   bool is_compiled_bootscript; // entry has [+script] attribute
617
   bool is_compiled_bootscript; // entry has [+script] attribute
-
 
618
   int extra_ino_flags; // bitmap of extra inode flags (IFS_INO_xxx)
566
   char search[10 * MAXPATHLEN]; // binary search path (the default one will be constructed at startup)
619
   char search[10 * MAXPATHLEN]; // binary search path (the default one will be constructed at startup)
567
 
620
 
568
   uint8_t *data;
621
   uint8_t *data;
569
   size_t datalen;
622
   size_t datalen;
570
} parms_t;
623
} parms_t;
Line 604... Line 657...
604
static void hex_fprintf (FILE *fp, const uint8_t *data, size_t data_size, int howmany_columns, const char *fmt, ...); // hexdump-style formatted output to a file stream (which may be stdout/stderr)
657
static void hex_fprintf (FILE *fp, const uint8_t *data, size_t data_size, int howmany_columns, const char *fmt, ...); // hexdump-style formatted output to a file stream (which may be stdout/stderr)
605
static char *binary (const uint8_t x, char char_for_zero, char char_for_one); // returns the binary representation of byte 'x' as a string
658
static char *binary (const uint8_t x, char char_for_zero, char char_for_one); // returns the binary representation of byte 'x' as a string
606
static char *describe_uint8 (const uint8_t x, const char *bitwise_stringdescs[8]); // returns the ORed description of byte 'x' according to the description strings for each bit
659
static char *describe_uint8 (const uint8_t x, const char *bitwise_stringdescs[8]); // returns the ORed description of byte 'x' according to the description strings for each bit
607
static char *read_filecontents (const char *pathname, const char *search_path, uint8_t **databuf, size_t *datalen); // locates pathname among MKIFS_PATH, reads it, places its contents in a buffer (caller frees) and returns a pointer to the resolved pathname (static string)
660
static char *read_filecontents (const char *pathname, const char *search_path, uint8_t **databuf, size_t *datalen); // locates pathname among MKIFS_PATH, reads it, places its contents in a buffer (caller frees) and returns a pointer to the resolved pathname (static string)
608
static int fwrite_filecontents (const char *pathname, FILE *fp); // dumps the contents of pathname into fp
661
static int fwrite_filecontents (const char *pathname, FILE *fp); // dumps the contents of pathname into fp
-
 
662
static int relative_offset_of_in (const char *name, const char *string_table, const size_t table_len); // returns the relative offset of a particular string in a string table
-
 
663
static elf_section_header_t *elf_get_section_header_by_name (const elf_header_t *elf, const char *section_name); // get a pointer to a named section header in an ELF file
609
static size_t fwrite_fsentry (const fsentry_t *fsentry, FILE *fp); // writes the given filesystem entry into fp (without its contents)
664
static size_t fwrite_fsentry (const fsentry_t *fsentry, FILE *fp); // writes the given filesystem entry into fp (without its contents)
610
static size_t add_fsentry (fsentry_t **fsentries, size_t *fsentry_count, parms_t *entry_parms, const char *stored_pathname, const char *buildhost_pathname); // stack up a new filesystem entry
665
static size_t add_fsentry (fsentry_t **fsentries, size_t *fsentry_count, parms_t *entry_parms, const char *stored_pathname, const char *buildhost_pathname); // stack up a new filesystem entry
611
static int fsentry_compare_pathnames_cb (const void *a, const void *b); // qsort() comparison callback that sorts filesystem entries by pathnames
666
static int fsentry_compare_pathnames_cb (const void *a, const void *b); // qsort() comparison callback that sorts filesystem entries by pathnames
612
static void update_MKIFS_PATH (const char *processor);
667
static void update_MKIFS_PATH (const char *processor);
613
static int dump_ifs_info (const char *ifs_pathname); // dumps detailed info about a particular IFS file on the standard output, returns 0 on success and >0 on error
668
static int dump_ifs_info (const char *ifs_pathname, bool want_everything); // dumps detailed info about a particular IFS file on the standard output, returns 0 on success and >0 on error
614
 
669
 
615
 
670
 
616
static void sha512_private_transform (SHA512_CTX *context, const uint64_t *data)
671
static void sha512_private_transform (SHA512_CTX *context, const uint64_t *data)
617
{
672
{
618
   // logical functions used in SHA-384 and SHA-512
673
   // logical functions used in SHA-384 and SHA-512
Line 1057... Line 1112...
1057
 
1112
 
1058
   ret = (int) fwrite (blob_buffer, 1, blob_size, fp);
1113
   ret = (int) fwrite (blob_buffer, 1, blob_size, fp);
1059
   fflush (fp); // force flush to disk, because the C stream API is *buffered*
1114
   fflush (fp); // force flush to disk, because the C stream API is *buffered*
1060
   free (blob_buffer);
1115
   free (blob_buffer);
1061
   return (ret);
1116
   return (ret);
-
 
1117
}
-
 
1118
 
-
 
1119
 
-
 
1120
static int relative_offset_of_in (const char *name, const char *string_table, const size_t table_len)
-
 
1121
{
-
 
1122
   int name_len = (int) strlen (name) + 1;
-
 
1123
   WELLMANNERED_ASSERT (name_len < table_len, "bad call (name longer than string table)");
-
 
1124
   for (int idx = 0; idx <= table_len - name_len; idx++)
-
 
1125
      if (memcmp (&string_table[idx], name, name_len) == 0)
-
 
1126
         return (idx);
-
 
1127
   WELLMANNERED_ASSERT (false, "bad call (name '%s' not found in string table)", name);
-
 
1128
   return (0);
-
 
1129
}
-
 
1130
 
-
 
1131
 
-
 
1132
static elf_section_header_t *elf_get_section_header_by_name (const elf_header_t *elf, const char *section_name)
-
 
1133
{
-
 
1134
   elf_section_header_t *shdr_shstrtab; // section header of the section header strings table
-
 
1135
   elf_section_header_t *shdr;
-
 
1136
   size_t table_count;
-
 
1137
   size_t table_index;
-
 
1138
   char *shstrtab; // section header strings table
-
 
1139
   char *name;
-
 
1140
 
-
 
1141
   shdr_shstrtab = (elf_section_header_t *) ((uint8_t *) elf + ELF_GET_NUMERIC (elf, elf, section_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, section_header_item_size) * ELF_GET_NUMERIC (elf, elf, section_header_names_idx)); // quick access to section header for the section that contains the section names
-
 
1142
   shstrtab = ((uint8_t *) elf + ELF_GET_NUMERIC (elf, shdr_shstrtab, file_offset)); // locate the start of the strings table that contains the section names
-
 
1143
 
-
 
1144
   // cycle through the sections table
-
 
1145
   table_count = ELF_GET_NUMERIC (elf, elf, section_header_table_len);
-
 
1146
   for (table_index = 0; table_index < table_count; table_index++)
-
 
1147
   {
-
 
1148
      shdr = (elf_section_header_t *) ((uint8_t *) elf + ELF_GET_NUMERIC (elf, elf, section_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, section_header_item_size) * table_index); // quick access to section header
-
 
1149
      name = &shstrtab[ELF_GET_NUMERIC (elf, shdr, name_offset)]; // peek at its name
-
 
1150
      if (strcmp (name, section_name) == 0)
-
 
1151
         return (shdr); // if found, return a pointer to this section header
-
 
1152
   }
-
 
1153
 
-
 
1154
   return (NULL); // section not found
1062
}
1155
}
1063
 
1156
 
1064
 
1157
 
1065
static size_t fwrite_fsentry (const fsentry_t *fsentry, FILE *fp)
1158
static size_t fwrite_fsentry (const fsentry_t *fsentry, FILE *fp)
1066
{
1159
{
Line 1143... Line 1236...
1143
}
1236
}
1144
 
1237
 
1145
 
1238
 
1146
static size_t add_fsentry (fsentry_t **fsentries, size_t *fsentry_count, parms_t *entry_parms, const char *stored_pathname, const char *buildhost_pathname)
1239
static size_t add_fsentry (fsentry_t **fsentries, size_t *fsentry_count, parms_t *entry_parms, const char *stored_pathname, const char *buildhost_pathname)
1147
{
1240
{
-
 
1241
   #define ADD_NAME_TO_STRINGTABLE(name,pstrtab,pstrtablen) do { \
-
 
1242
      name_len = strlen ((name)) + 1; \
-
 
1243
      reallocated_ptr = realloc (*(pstrtab), *(pstrtablen) + name_len); \
-
 
1244
      WELLMANNERED_ASSERT (reallocated_ptr, "out of memory"); \
-
 
1245
      *(pstrtab) = reallocated_ptr; \
-
 
1246
      memcpy (&(*pstrtab)[*(pstrtablen)], (name), name_len); \
-
 
1247
      *(pstrtablen) += name_len; \
-
 
1248
   } while (0)
-
 
1249
 
1148
   static thread_local char candidate_pathname[1024];
1250
   static thread_local char candidate_pathname[1024];
1149
   static int inode_count = 0; // will be preincremented each time this function is called
1251
   static int inode_count = 0; // will be preincremented each time this function is called
1150
 
1252
 
1151
   const char *original_stored_pathname = NULL;
1253
   const char *original_stored_pathname = NULL;
1152
   const elf_dynamic_section_entry_t *dynamic_entry; // dynamic section entry
1254
   const elf_dynamic_section_entry_t *dynamic_entry; // dynamic section entry
1153
   const elf_section_header_t *shdr_shstr; // section headers strings (containing ELF sections names)
-
 
1154
   const elf_section_header_t *shdr_dynstr; // dynamic strings
1255
   const elf_section_header_t *shdr_dynstr; // dynamic strings
1155
   const elf_section_header_t *shdr_dynamic; // dynamic section
1256
   const elf_section_header_t *shdr_dynamic; // dynamic section
1156
   const elf_section_header_t *shdr;
1257
   const elf_section_header_t *shdr;
-
 
1258
   elf_section_header_t *new_shdr;
-
 
1259
   size_t new_qnxinfo_shdr_offset;
-
 
1260
   size_t new_debuglink_shdr_offset;
-
 
1261
   size_t new_qnxusage_shdr_offset;
-
 
1262
   size_t new_buildid_shdr_offset;
-
 
1263
   size_t new_shstrtab_shdr_offset;
-
 
1264
   elf_program_header_t *phdr;
1157
   const char *canonical_dylib_name;
1265
   const char *canonical_dylib_name;
1158
   const char *elf_section_name;
-
 
1159
   const char *dynamic_strings; // strings table of the ".dynamic" section
1266
   const char *dynamic_strings; // strings table of the ".dynamic" section
1160
   const char *shtable_strings; // strings table of the section headers table
-
 
1161
   const char *last_dirsep;
1267
   const char *last_dirsep;
1162
   const elf_header_t *elf;
1268
   elf_header_t *elf;
-
 
1269
   uint8_t *new_shdr_table = NULL; // mallocated
-
 
1270
   size_t new_shdr_tablesize = 0;
-
 
1271
   uint8_t *elfsection_qnxinfo_data = NULL; // mallocated
-
 
1272
   size_t elfsection_qnxinfo_size = 0;
-
 
1273
   uint8_t *elfsection_qnxusage_data = NULL; // mallocated
-
 
1274
   size_t elfsection_qnxusage_size = 0;
-
 
1275
   uint8_t *elfsection_debuglink_data = NULL; // mallocated
-
 
1276
   size_t elfsection_debuglink_size = 0;
-
 
1277
   uint8_t *elfsection_buildid_data = NULL; // mallocated
-
 
1278
   size_t elfsection_buildid_size = 0;
-
 
1279
   uint8_t *elfsection_shstrtab_data = NULL; // mallocated
-
 
1280
   size_t elfsection_shstrtab_size = 0;
1163
   char *resolved_pathname;
1281
   char *resolved_pathname;
1164
   void *reallocated_ptr;
1282
   void *reallocated_ptr;
1165
   void *old_data;
1283
   void *old_data;
1166
   struct stat stat_buf;
1284
   struct stat stat_buf;
-
 
1285
   size_t new_shdrtable_offset;
-
 
1286
   size_t end_padding_offset;
1167
   size_t table_index;
1287
   size_t table_index;
1168
   size_t table_count;
1288
   size_t table_count;
1169
   //uint32_t mtime = (entry_parms->m(uint32_t) time (NULL);
-
 
1170
   uint32_t extra_ino_flags = 0;
1289
   size_t name_len;
1171
   fsentry_t *fsentry;
1290
   fsentry_t *fsentry;
1172
 
1291
 
1173
   if (S_ISDIR (entry_parms->st_mode)) // are we storing a directory ?
1292
   if (S_ISDIR (entry_parms->st_mode)) // are we storing a directory ?
1174
   {
1293
   {
1175
      fprintf (stderr, "directory: ino 0x%x uid %d gid %d mode 0%o path \"%s\"\n", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname);
1294
      fprintf (stderr, "directory: ino 0x%x uid %d gid %d mode 0%o path \"%s\"\n", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname);
Line 1180... Line 1299...
1180
      {
1299
      {
1181
         // HACK: for now just consider the kernel as a binary blob
1300
         // HACK: for now just consider the kernel as a binary blob
1182
         // FIXME: reimplement properly
1301
         // FIXME: reimplement properly
1183
         sprintf (candidate_pathname, "%s/procnto-smp-instr", entry_parms->prefix); // fix the entry name
1302
         sprintf (candidate_pathname, "%s/procnto-smp-instr", entry_parms->prefix); // fix the entry name
1184
         stored_pathname = candidate_pathname;
1303
         stored_pathname = candidate_pathname;
1185
         extra_ino_flags = IFS_INO_PROCESSED_ELF | IFS_INO_BOOTSTRAP_EXE; // procnto needs to have these flags stamped on the inode
1304
         entry_parms->extra_ino_flags |= IFS_INO_PROCESSED_ELF | IFS_INO_BOOTSTRAP_EXE; // procnto needs to have these flags stamped on the inode
1186
         entry_parms->st_mode = S_IFREG | 0700; // procnto requires 0700 permissions
1305
         entry_parms->st_mode = S_IFREG | 0700; // procnto requires 0700 permissions
1187
         image_kernel_ino = extra_ino_flags | (inode_count + 1);
1306
         image_kernel_ino = entry_parms->extra_ino_flags | (inode_count + 1);
1188
      }
1307
      }
1189
      else if (entry_parms->is_compiled_bootscript) // else is it a startup script ?
1308
      else if (entry_parms->is_compiled_bootscript) // else is it a startup script ?
1190
         image_bootscript_ino = inode_count + 1; // save boot script inode number for image header
1309
         image_bootscript_ino = inode_count + 1; // save boot script inode number for image header
1191
 
1310
 
1192
      // do we already know the data for this data blob ?
1311
      // do we already know the data for this data blob ?
1193
      if (entry_parms->data != NULL)
1312
      if (entry_parms->data != NULL)
1194
      {
1313
      {
1195
         entry_parms->mtime = entry_parms->mtime_for_inline_files;
1314
         entry_parms->mtime = entry_parms->mtime_for_inline_files;
1196
         fprintf (stderr, "file: ino 0x%x uid %d gid %d mode 0%o path \"%s\" blob (len %zd)\n", extra_ino_flags | (inode_count + 1), entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, entry_parms->datalen);
1315
         fprintf (stderr, "file: ino 0x%x uid %d gid %d mode 0%o path \"%s\" blob (len %zd)\n", entry_parms->extra_ino_flags | (inode_count + 1), entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, entry_parms->datalen);
1197
      }
1316
      }
1198
      else if (buildhost_pathname != NULL) // else was a source file pathname supplied ?
1317
      else if (buildhost_pathname != NULL) // else was a source file pathname supplied ?
1199
      {
1318
      {
1200
         resolved_pathname = read_filecontents (buildhost_pathname, (entry_parms->search[0] != 0 ? entry_parms->search : MKIFS_PATH), &entry_parms->data, &entry_parms->datalen); // locate the file
1319
         resolved_pathname = read_filecontents (buildhost_pathname, (entry_parms->search[0] != 0 ? entry_parms->search : MKIFS_PATH), &entry_parms->data, &entry_parms->datalen); // locate the file
1201
         if (resolved_pathname == NULL)
1320
         if (resolved_pathname == NULL)
Line 1210... Line 1329...
1210
      }
1329
      }
1211
 
1330
 
1212
      // is the file we're storing an ELF file ?
1331
      // is the file we're storing an ELF file ?
1213
      if ((entry_parms->datalen > 52) // file is big enough to contain an ELF header
1332
      if ((entry_parms->datalen > 52) // file is big enough to contain an ELF header
1214
          && ((elf = (elf_header_t *) entry_parms->data) != NULL) // cast (necessary true)
1333
          && ((elf = (elf_header_t *) entry_parms->data) != NULL) // cast (necessary true)
1215
          && (memcmp (ELF_STRUCT_MEMBER_STRING (elf, elf, magic), ELF_MAGIC_STR, 4) == 0)) // file starts with the ELF magic
1334
          && (memcmp (ELF_GET_STRING (elf, elf, magic), ELF_MAGIC_STR, 4) == 0)) // file starts with the ELF magic
1216
      {
1335
      {
1217
         shdr_shstr = (elf_section_header_t *) &entry_parms->data[ELF_STRUCT_MEMBER_NUMERIC (elf, elf, section_header_table_offset) + (size_t) ELF_STRUCT_MEMBER_NUMERIC (elf, elf, section_header_item_size) * ELF_STRUCT_MEMBER_NUMERIC (elf, elf, section_header_names_idx)]; // quick access to section header for the section that contains the section names
-
 
1218
         shtable_strings = &entry_parms->data[ELF_STRUCT_MEMBER_NUMERIC (elf, shdr_shstr, file_offset)]; // locate the start of the strings table that contains the section names
-
 
1219
 
-
 
1220
         // strip this ELF file
-
 
1221
 
-
 
1222
         // is the file we're storing a relocatable executable (i.e. a dynamic library) and should we check for its canonical name ?
1336
         // is the file we're storing a relocatable executable (i.e. a dynamic library) and should we check for its canonical name ?
1223
         if ((ELF_STRUCT_MEMBER_NUMERIC (elf, elf, type) == 3) && entry_parms->should_autosymlink_dylib)
1337
         if ((ELF_GET_NUMERIC (elf, elf, type) == 3) && entry_parms->should_autosymlink_dylib)
1224
         {
1338
         {
1225
            // we need to find the SONAME of this library
1339
            // we need to find the SONAME of this library
1226
            canonical_dylib_name = NULL;
1340
            canonical_dylib_name = NULL;
1227
 
1341
 
1228
            // locate the sections we need (the dynamic section and its strings table)
1342
            // locate the sections we need (the dynamic section and its strings table)
1229
            table_count = ELF_STRUCT_MEMBER_NUMERIC (elf, elf, section_header_table_len);
-
 
1230
            shdr_dynamic = NULL;
-
 
1231
            shdr_dynstr = NULL;
-
 
1232
            for (table_index = 0; table_index < table_count; table_index++)
-
 
1233
            {
-
 
1234
               shdr = (elf_section_header_t *) &entry_parms->data[ELF_STRUCT_MEMBER_NUMERIC (elf, elf, section_header_table_offset) + (size_t) ELF_STRUCT_MEMBER_NUMERIC (elf, elf, section_header_item_size) * table_index]; // quick access to section header
1343
            shdr_dynamic = elf_get_section_header_by_name (elf, ".dynamic");
1235
               elf_section_name = &shtable_strings[ELF_STRUCT_MEMBER_NUMERIC (elf, shdr, name_offset)];
-
 
1236
               if (strcmp (elf_section_name, ".dynamic") == 0)
-
 
1237
                  shdr_dynamic = shdr;
-
 
1238
               else if (strcmp (elf_section_name, ".dynstr") == 0)
1344
            shdr_dynstr = elf_get_section_header_by_name (elf, ".dynstr");
1239
                  shdr_dynstr = shdr;
-
 
1240
            }
-
 
1241
 
1345
 
1242
            // make sure we have both the dynamic section header and its own strings table header
1346
            // make sure we have both the dynamic section header and its own strings table header
1243
            if ((shdr_dynamic != NULL) && (shdr_dynstr != NULL))
1347
            if ((shdr_dynamic != NULL) && (shdr_dynstr != NULL))
1244
            {
1348
            {
1245
               dynamic_strings = (char *) &entry_parms->data[ELF_STRUCT_MEMBER_NUMERIC (elf, shdr_dynstr, file_offset)]; // quick access to dynamic sections strings table
1349
               dynamic_strings = (char *) &entry_parms->data[ELF_GET_NUMERIC (elf, shdr_dynstr, file_offset)]; // quick access to dynamic sections strings table
1246
 
1350
 
1247
               // walk through the dynamic section, look for the DT_SONAME entry
1351
               // walk through the dynamic section, look for the DT_SONAME entry
1248
               for (dynamic_entry = (elf_dynamic_section_entry_t *) &entry_parms->data[ELF_STRUCT_MEMBER_NUMERIC (elf, shdr_dynamic, file_offset)];
1352
               for (dynamic_entry = (elf_dynamic_section_entry_t *) &entry_parms->data[ELF_GET_NUMERIC (elf, shdr_dynamic, file_offset)];
1249
                    (ELF_STRUCT_MEMBER_NUMERIC (elf, dynamic_entry, tag) != ELF_DT_NULL);
1353
                    (ELF_GET_NUMERIC (elf, dynamic_entry, tag) != ELF_DT_NULL);
1250
                    dynamic_entry = (elf_dynamic_section_entry_t *) ((uint8_t *) dynamic_entry + ELF_STRUCT_SIZE (elf, dynamic_entry)))
1354
                    dynamic_entry = (elf_dynamic_section_entry_t *) ((uint8_t *) dynamic_entry + ELF_STRUCT_SIZE (elf, dynamic_entry)))
1251
                  if (ELF_STRUCT_MEMBER_NUMERIC (elf, dynamic_entry, tag) == ELF_DT_SONAME)
1355
                  if (ELF_GET_NUMERIC (elf, dynamic_entry, tag) == ELF_DT_SONAME)
1252
                  {
1356
                  {
1253
                     canonical_dylib_name = dynamic_strings + ELF_STRUCT_MEMBER_NUMERIC (elf, dynamic_entry, value.as_integer);
1357
                     canonical_dylib_name = dynamic_strings + ELF_GET_NUMERIC (elf, dynamic_entry, value.as_integer);
1254
                     break;
1358
                     break;
1255
                  }
1359
                  }
1256
 
1360
 
1257
               // do we have it ?
1361
               // do we have it ?
1258
               if ((canonical_dylib_name != NULL) && (canonical_dylib_name[0] != 0))
1362
               if ((canonical_dylib_name != NULL) && (canonical_dylib_name[0] != 0))
Line 1264... Line 1368...
1264
                     stored_pathname = candidate_pathname;
1368
                     stored_pathname = candidate_pathname;
1265
                  }
1369
                  }
1266
               }
1370
               }
1267
            }
1371
            }
1268
         } // end if the file we're storing is a dylib
1372
         } // end if the file we're storing is a dylib
-
 
1373
 
-
 
1374
         // now strip this ELF file if necessary
-
 
1375
         if (!(entry_parms->extra_ino_flags & IFS_INO_PROCESSED_ELF))
-
 
1376
         {
-
 
1377
            // NOTE: for each ELF file, mkifs
-
 
1378
            // -> alters the program header table and offsets each p_addr (physical address) member by 0x1400000 plus the current file offset (this cannot be done right now, will need to be done once they are known)
-
 
1379
            // -> throws away and reconstructs the sections table by keeping only the sections that are in the program header, and writes the section table at the start of the first thrown-away section
-
 
1380
            // FIXME: what if a section thrown away is located between two program segments ? are they collapsed, moving everything one slot down ? this looks improbable...
-
 
1381
 
-
 
1382
            // reconstructed ELF:
-
 
1383
            // ==== START OF FILE ====
-
 
1384
            // ELF header
-
 
1385
            // program header table
-
 
1386
            //  (same sections, just p_addr offset down by first section's p_addr)
-
 
1387
            // section data 5 (named ".note.gnu.build-id")
-
 
1388
            //  "............GNU....ZY.....c.o..l"
-
 
1389
            // PROGRAM
-
 
1390
            // sections table
-
 
1391
            // + section 1: ALL ZEROES
-
 
1392
            // + section 2: fileoffs 0x21a8 size 0xfd --> "QNX_info" --> QNX binary description: "NAME=pci_debug2.so.3.0\nDESCRIPTION=PCI Server System Debug Module\nDATE=2023/11/19-10:01:13-EST\nSTATE=lookup\nHOST=docker-n1.bts.rim.net\nUSER=builder\nVERSION=QNXOS_main\nTAGID=QNXOS_800-135\nPACKAGE=com.qnx.qnx800.target.pci.debug/3.0.0.00135T202311191043L\n"
-
 
1393
            // + section 3: fileoffs 0x22a5 size 0x1c --> ".gnu_debuglink" --> indicates the debug file (and a possible checksum?): "pci_debug2.so.3.0.sym" "\0\0\0" "VX2p"
-
 
1394
            // + section 4: fileoffs 0x22c1 size 0x2ad --> "QNX_usage" --> HELP TEXT: "\n-------------------------------------------------------------------------------\n%C\n\nThis module implements debug logging for all PCI server modules. It is\nincluded by setting the environment variable PCI_DEBUG_MODULE and uses\nthe slogger2 APIs.\nNOTE:.On systems which support slogger2, you are encouraged to use this module.instead of pci_debug.so...Release History.---------------..3.0 - This module is functionally equivalent to the previous 2.x version.      however it is incompatible with all pre v3.x PCI components..2.1 - fixes a bug whereby if slogger2 is not running and the PCI_DEBUG_MODULE.      environment variable is set, the client will SIGSEGV..2.0 - initial release.."
-
 
1395
            // + section 5: fileoffs 0x190 size 0x32 --> ".note.gnu.build-id" --> GNU build ID
-
 
1396
            // + section 6: fileoffs 0x256e size 0x40 --> ".shstrtab" --> sections names strings table
-
 
1397
            // section data 2 (named "QNX_info")
-
 
1398
            //  (QNX binary description)
-
 
1399
            // section data 3 (named ".gnu_debuglink")
-
 
1400
            //  (debug file)
-
 
1401
            // section data 4 (named "QNX_usage")
-
 
1402
            //  (help text)
-
 
1403
            // section data 6 (named ".shstrtab")
-
 
1404
            //  "\0"
-
 
1405
            //  ".shstrtab\0"
-
 
1406
            //  "QNX_info\0"
-
 
1407
            //  ".gnu_debuglink\0"
-
 
1408
            //  "QNX_usage\0"
-
 
1409
            //  ".note.gnu.build-id\0"
-
 
1410
            // ==== END OF FILE ====
-
 
1411
 
-
 
1412
            // task 1: alter the program header table, and measure the farthest offset known by this table where we'll write the reconstructed section headers table
-
 
1413
 
-
 
1414
            //first_offset = SIZE_MAX;
-
 
1415
            new_shdrtable_offset = 0;
-
 
1416
            table_count = ELF_GET_NUMERIC (elf, elf, program_header_table_len);
-
 
1417
            for (table_index = 0; table_index < table_count; table_index++)
-
 
1418
            {
-
 
1419
               phdr = (elf_program_header_t *) &entry_parms->data[ELF_GET_NUMERIC (elf, elf, program_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, program_header_item_size) * table_index]; // quick access to program header
-
 
1420
               //if (first_offset == SIZE_MAX)
-
 
1421
               //   first_offset = ELF_GET_NUMERIC (elf, phdr, physical_addr);
-
 
1422
               if (ELF_GET_NUMERIC (elf, phdr, file_offset) + ELF_GET_NUMERIC (elf, phdr, size_in_file) > new_shdrtable_offset)
-
 
1423
                  new_shdrtable_offset = ELF_GET_NUMERIC (elf, phdr, file_offset) + ELF_GET_NUMERIC (elf, phdr, size_in_file);
-
 
1424
//               ELF_SET_NUMERIC (elf, phdr, physical_addr, ELF_GET_NUMERIC (elf, phdr, physical_addr) + (0x1400000 + ));
-
 
1425
            }
-
 
1426
 
-
 
1427
            // task 2: re-create the section header table
-
 
1428
 
-
 
1429
            elfsection_shstrtab_data = malloc (1); // initialize an empty section headers strings table
-
 
1430
            WELLMANNERED_ASSERT (elfsection_shstrtab_data, "out of memory");
-
 
1431
            elfsection_shstrtab_data[0] = 0;
-
 
1432
            elfsection_shstrtab_size = 1;
-
 
1433
            ADD_NAME_TO_STRINGTABLE (".shstrtab", &elfsection_shstrtab_data, &elfsection_shstrtab_size);
-
 
1434
 
-
 
1435
            reallocated_ptr = realloc (new_shdr_table, new_shdr_tablesize + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
-
 
1436
            WELLMANNERED_ASSERT (reallocated_ptr, "out of memory");
-
 
1437
            new_shdr_table = reallocated_ptr; // reallocation succeeded, save the new pointer
-
 
1438
            memset (&new_shdr_table[new_shdr_tablesize], 0, ELF_STRUCT_SIZE (elf, shdr)); // the first section header is always zerofilled
-
 
1439
            new_shdr_tablesize += ELF_STRUCT_SIZE (elf, shdr); // and remember how bigger the section headers table is now
-
 
1440
            if ((shdr = elf_get_section_header_by_name (elf, "QNX_info")) != NULL)
-
 
1441
            {
-
 
1442
               if (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset) // if this section needs to be moved around, have a copy of it
-
 
1443
               {
-
 
1444
                  elfsection_qnxinfo_size = ELF_GET_NUMERIC (elf, shdr, size);
-
 
1445
                  elfsection_qnxinfo_data = malloc (elfsection_qnxinfo_size);
-
 
1446
                  WELLMANNERED_ASSERT (elfsection_qnxinfo_data, "out of memory");
-
 
1447
                  memcpy (elfsection_qnxinfo_data, &entry_parms->data[ELF_GET_NUMERIC (elf, shdr, file_offset)], elfsection_qnxinfo_size);
-
 
1448
               }
-
 
1449
               reallocated_ptr = realloc (new_shdr_table, new_shdr_tablesize + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
-
 
1450
               WELLMANNERED_ASSERT (reallocated_ptr, "out of memory");
-
 
1451
               new_shdr_table = reallocated_ptr; // reallocation succeeded, save the new pointer
-
 
1452
               new_qnxinfo_shdr_offset = new_shdr_tablesize; // remember the new offset of this section header
-
 
1453
               new_shdr_tablesize += ELF_STRUCT_SIZE (elf, shdr); // and remember how bigger the section headers table is now
-
 
1454
 
-
 
1455
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_qnxinfo_shdr_offset]; // now populate this section header
-
 
1456
               ADD_NAME_TO_STRINGTABLE ("QNX_info", &elfsection_shstrtab_data, &elfsection_shstrtab_size);
-
 
1457
               ELF_SET_NUMERIC (elf, new_shdr, name_offset, relative_offset_of_in ("QNX_info", elfsection_shstrtab_data, elfsection_shstrtab_size)); // update the relative offset of the section name
-
 
1458
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
-
 
1459
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
-
 
1460
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
-
 
1461
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset ? WILL_BE_FILLED_LATER : ELF_GET_NUMERIC (elf, shdr, file_offset))); // duplicate section offset only if it doesn't move
-
 
1462
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
-
 
1463
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
-
 
1464
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
-
 
1465
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
-
 
1466
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
-
 
1467
            }
-
 
1468
            if ((shdr = elf_get_section_header_by_name (elf, ".gnu_debuglink")) != NULL)
-
 
1469
            {
-
 
1470
               if (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset) // if this section needs to be moved around, have a copy of it
-
 
1471
               {
-
 
1472
                  elfsection_debuglink_size = ELF_GET_NUMERIC (elf, shdr, size);
-
 
1473
                  elfsection_debuglink_data = malloc (elfsection_debuglink_size);
-
 
1474
                  WELLMANNERED_ASSERT (elfsection_debuglink_data, "out of memory");
-
 
1475
                  memcpy (elfsection_debuglink_data, &entry_parms->data[ELF_GET_NUMERIC (elf, shdr, file_offset)], elfsection_debuglink_size);
-
 
1476
               }
-
 
1477
               reallocated_ptr = realloc (new_shdr_table, new_shdr_tablesize + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
-
 
1478
               WELLMANNERED_ASSERT (reallocated_ptr, "out of memory");
-
 
1479
               new_shdr_table = reallocated_ptr; // reallocation succeeded, save the new pointer
-
 
1480
               new_debuglink_shdr_offset = new_shdr_tablesize; // remember the new offset of this section header
-
 
1481
               new_shdr_tablesize += ELF_STRUCT_SIZE (elf, shdr); // and remember how bigger the section headers table is now
-
 
1482
 
-
 
1483
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_debuglink_shdr_offset]; // now populate this section header
-
 
1484
               ADD_NAME_TO_STRINGTABLE (".gnu_debuglink", &elfsection_shstrtab_data, &elfsection_shstrtab_size);
-
 
1485
               ELF_SET_NUMERIC (elf, new_shdr, name_offset, relative_offset_of_in (".gnu_debuglink", elfsection_shstrtab_data, elfsection_shstrtab_size)); // update the relative offset of the section name
-
 
1486
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
-
 
1487
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
-
 
1488
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
-
 
1489
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset ? WILL_BE_FILLED_LATER : ELF_GET_NUMERIC (elf, shdr, file_offset))); // duplicate section offset only if it doesn't move
-
 
1490
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
-
 
1491
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
-
 
1492
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
-
 
1493
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
-
 
1494
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
-
 
1495
            }
-
 
1496
            if ((shdr = elf_get_section_header_by_name (elf, "QNX_usage")) != NULL)
-
 
1497
            {
-
 
1498
               if (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset) // if this section needs to be moved around, have a copy of it
-
 
1499
               {
-
 
1500
                  elfsection_qnxusage_size = ELF_GET_NUMERIC (elf, shdr, size);
-
 
1501
                  elfsection_qnxusage_data = malloc (elfsection_qnxusage_size);
-
 
1502
                  WELLMANNERED_ASSERT (elfsection_qnxusage_data, "out of memory");
-
 
1503
                  memcpy (elfsection_qnxusage_data, &entry_parms->data[ELF_GET_NUMERIC (elf, shdr, file_offset)], elfsection_qnxusage_size);
-
 
1504
               }
-
 
1505
               reallocated_ptr = realloc (new_shdr_table, new_shdr_tablesize + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
-
 
1506
               WELLMANNERED_ASSERT (reallocated_ptr, "out of memory");
-
 
1507
               new_shdr_table = reallocated_ptr; // reallocation succeeded, save the new pointer
-
 
1508
               new_qnxusage_shdr_offset = new_shdr_tablesize; // remember the new offset of this section header
-
 
1509
               new_shdr_tablesize += ELF_STRUCT_SIZE (elf, shdr); // and remember how bigger the section headers table is now
-
 
1510
 
-
 
1511
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_qnxusage_shdr_offset]; // now populate this section header
-
 
1512
               ADD_NAME_TO_STRINGTABLE ("QNX_usage", &elfsection_shstrtab_data, &elfsection_shstrtab_size);
-
 
1513
               ELF_SET_NUMERIC (elf, new_shdr, name_offset, relative_offset_of_in ("QNX_usage", elfsection_shstrtab_data, elfsection_shstrtab_size)); // update the relative offset of the section name
-
 
1514
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
-
 
1515
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
-
 
1516
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
-
 
1517
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset ? WILL_BE_FILLED_LATER : ELF_GET_NUMERIC (elf, shdr, file_offset))); // duplicate section offset only if it doesn't move
-
 
1518
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
-
 
1519
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
-
 
1520
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
-
 
1521
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
-
 
1522
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
-
 
1523
            }
-
 
1524
            if ((shdr = elf_get_section_header_by_name (elf, ".note.gnu.build-id")) != NULL)
-
 
1525
            {
-
 
1526
               if (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset) // if this section needs to be moved around, have a copy of it
-
 
1527
               {
-
 
1528
                  elfsection_buildid_size = ELF_GET_NUMERIC (elf, shdr, size);
-
 
1529
                  elfsection_buildid_data = malloc (elfsection_buildid_size);
-
 
1530
                  WELLMANNERED_ASSERT (elfsection_buildid_data, "out of memory");
-
 
1531
                  memcpy (elfsection_buildid_data, &entry_parms->data[ELF_GET_NUMERIC (elf, shdr, file_offset)], elfsection_buildid_size);
-
 
1532
               }
-
 
1533
               reallocated_ptr = realloc (new_shdr_table, new_shdr_tablesize + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
-
 
1534
               WELLMANNERED_ASSERT (reallocated_ptr, "out of memory");
-
 
1535
               new_shdr_table = reallocated_ptr; // reallocation succeeded, save the new pointer
-
 
1536
               new_buildid_shdr_offset = new_shdr_tablesize; // remember the new offset of this section header
-
 
1537
               new_shdr_tablesize += ELF_STRUCT_SIZE (elf, shdr); // and remember how bigger the section headers table is now
-
 
1538
 
-
 
1539
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_buildid_shdr_offset]; // now populate this section header
-
 
1540
               ADD_NAME_TO_STRINGTABLE (".note.gnu.build-id", &elfsection_shstrtab_data, &elfsection_shstrtab_size);
-
 
1541
               ELF_SET_NUMERIC (elf, new_shdr, name_offset, relative_offset_of_in (".note.gnu.build-id", elfsection_shstrtab_data, elfsection_shstrtab_size)); // update the relative offset of the section name
-
 
1542
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
-
 
1543
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
-
 
1544
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
-
 
1545
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, (ELF_GET_NUMERIC (elf, shdr, file_offset) > new_shdrtable_offset ? WILL_BE_FILLED_LATER : ELF_GET_NUMERIC (elf, shdr, file_offset))); // duplicate section offset only if it doesn't move
-
 
1546
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
-
 
1547
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
-
 
1548
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
-
 
1549
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
-
 
1550
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
-
 
1551
            }
-
 
1552
            reallocated_ptr = realloc (new_shdr_table, new_shdr_tablesize + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
-
 
1553
            WELLMANNERED_ASSERT (reallocated_ptr, "out of memory");
-
 
1554
            new_shdr_table = reallocated_ptr; // reallocation succeeded, save the new pointer
-
 
1555
            new_shstrtab_shdr_offset = new_shdr_tablesize; // remember the new offset of this section header
-
 
1556
            new_shdr_tablesize += ELF_STRUCT_SIZE (elf, shdr); // and remember how bigger the section headers table is now
-
 
1557
 
-
 
1558
            new_shdr = (elf_section_header_t *) &new_shdr_table[new_shstrtab_shdr_offset]; // now populate this section header
-
 
1559
            ELF_SET_NUMERIC (elf, new_shdr, name_offset, relative_offset_of_in (".shstrtab", elfsection_shstrtab_data, elfsection_shstrtab_size)); // update the relative offset of the section name
-
 
1560
            ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_SECTIONTYPE_STRINGTABLE); // section type (SHT_STRTAB)
-
 
1561
            ELF_SET_NUMERIC (elf, new_shdr, flags,        0); // section flags (we could set SHF_STRINGS i.e. 0x20 here, but mkifs does not, so mimic that)
-
 
1562
            ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, 0); // this section does not need to be mapped
-
 
1563
            ELF_SET_NUMERIC (elf, new_shdr, file_offset, WILL_BE_FILLED_LATER); // FIXME
-
 
1564
            ELF_SET_NUMERIC (elf, new_shdr, size,         elfsection_shstrtab_size); // section size
-
 
1565
            ELF_SET_NUMERIC (elf, new_shdr, linked_index, 0); // this section is not linked to any other
-
 
1566
            ELF_SET_NUMERIC (elf, new_shdr, info,         0); // this section has no additional info
-
 
1567
            ELF_SET_NUMERIC (elf, new_shdr, alignment,    1); // this section is byte-aligned
-
 
1568
            ELF_SET_NUMERIC (elf, new_shdr, entry_size,   0); // this section is not a table, so entry_size is zero
-
 
1569
 
-
 
1570
            // jump over the new section headers table and write the sections that need to be relocated after the section headers table
-
 
1571
            entry_parms->datalen = new_shdrtable_offset + new_shdr_tablesize; // assume there are no sections beyond the section headers table until known otherwise
-
 
1572
            if (elfsection_qnxinfo_data != NULL)
-
 
1573
            {
-
 
1574
               memcpy (&entry_parms->data[entry_parms->datalen], elfsection_qnxinfo_data, elfsection_qnxinfo_size); // write section in place
-
 
1575
               free (elfsection_qnxinfo_data); // free it
-
 
1576
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_qnxinfo_shdr_offset]; // now fix this section header
-
 
1577
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, entry_parms->datalen); // fix section offset in the new section headers table
-
 
1578
               entry_parms->datalen += elfsection_qnxinfo_size; // update new ELF file length
-
 
1579
            }
-
 
1580
            if (elfsection_debuglink_data != NULL)
-
 
1581
            {
-
 
1582
               memcpy (&entry_parms->data[entry_parms->datalen], elfsection_debuglink_data, elfsection_debuglink_size); // write section in place
-
 
1583
               free (elfsection_debuglink_data); // free it
-
 
1584
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_debuglink_shdr_offset]; // now fix this section header
-
 
1585
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, entry_parms->datalen); // fix section offset in the new section headers table
-
 
1586
               entry_parms->datalen += elfsection_debuglink_size; // update new ELF file length
-
 
1587
            }
-
 
1588
            if (elfsection_qnxusage_data != NULL)
-
 
1589
            {
-
 
1590
               memcpy (&entry_parms->data[entry_parms->datalen], elfsection_qnxusage_data, elfsection_qnxusage_size); // write section in place
-
 
1591
               free (elfsection_qnxusage_data); // free it
-
 
1592
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_qnxusage_shdr_offset]; // now fix this section header
-
 
1593
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, entry_parms->datalen); // fix section offset in the new section headers table
-
 
1594
               entry_parms->datalen += elfsection_qnxusage_size; // update new ELF file length
-
 
1595
            }
-
 
1596
            if (elfsection_buildid_data != NULL)
-
 
1597
            {
-
 
1598
               memcpy (&entry_parms->data[entry_parms->datalen], elfsection_buildid_data, elfsection_buildid_size); // write section in place
-
 
1599
               free (elfsection_buildid_data); // free it
-
 
1600
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_buildid_shdr_offset]; // now fix this section header
-
 
1601
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, entry_parms->datalen); // fix section offset in the new section headers table
-
 
1602
               entry_parms->datalen += elfsection_buildid_size; // update new ELF file length
-
 
1603
            }
-
 
1604
            if (elfsection_shstrtab_data != NULL)
-
 
1605
            {
-
 
1606
               memcpy (&entry_parms->data[entry_parms->datalen], elfsection_shstrtab_data, elfsection_shstrtab_size); // write section header strings table section in place
-
 
1607
               free (elfsection_shstrtab_data);
-
 
1608
               new_shdr = (elf_section_header_t *) &new_shdr_table[new_shstrtab_shdr_offset]; // now fix this section header
-
 
1609
               ELF_SET_NUMERIC (elf, new_shdr, file_offset, entry_parms->datalen); // fix section offset in the new section headers table
-
 
1610
               entry_parms->datalen += elfsection_shstrtab_size; // update new ELF file length
-
 
1611
            }
-
 
1612
 
-
 
1613
            // now write the section headers table
-
 
1614
            fprintf (stderr, "rewriting section headers table at offset 0x%zd\n", new_shdrtable_offset);
-
 
1615
            memcpy (&entry_parms->data[new_shdrtable_offset], new_shdr_table, new_shdr_tablesize);
-
 
1616
            free (new_shdr_table); // free it
-
 
1617
 
-
 
1618
            // and finally fix the ELF header
-
 
1619
            ELF_SET_NUMERIC (elf, elf, section_header_table_offset, new_shdrtable_offset);
-
 
1620
            ELF_SET_NUMERIC (elf, elf, section_header_table_len, new_shdr_tablesize / ELF_STRUCT_SIZE (elf, shdr));
-
 
1621
            ELF_SET_NUMERIC (elf, elf, section_header_names_idx, new_shdr_tablesize / ELF_STRUCT_SIZE (elf, shdr) - 1); // the section headers strings table is the last section
-
 
1622
 
-
 
1623
            // align size with page size (4096 on x86, 16k on ARM)
-
 
1624
            end_padding_offset = entry_parms->datalen;
-
 
1625
            if (ELF_GET_NUMERIC (elf, elf, instruction_set) == ELF_MACHINE_X86_64)
-
 
1626
               entry_parms->datalen = ROUND_TO_UPPER_MULTIPLE (end_padding_offset, 4 * 1024); // 4 kb pages on Intel processors
-
 
1627
            else if (ELF_GET_NUMERIC (elf, elf, instruction_set) == ELF_MACHINE_AARCH64)
-
 
1628
               entry_parms->datalen = ROUND_TO_UPPER_MULTIPLE (end_padding_offset, 16 * 1024); // 16 kb pages on ARM64
-
 
1629
            else
-
 
1630
            {
-
 
1631
               fprintf (stderr, "fatal error: this ELF file \"%s\" does not belong to an architecture supported by ifstool (neither x86_64, nor aarch64)\n", stored_pathname);
-
 
1632
               exit (1);
-
 
1633
            }
-
 
1634
            memset (&entry_parms->data[end_padding_offset], 0, entry_parms->datalen - end_padding_offset); // zerofill
-
 
1635
 
-
 
1636
            entry_parms->extra_ino_flags |= IFS_INO_PROCESSED_ELF; // mark this inode as a preprocessed ELF file
-
 
1637
         } // end if the file is not yet a processed ELF
1269
      } // end if the file we're storing is an ELF file
1638
      } // end if the file we're storing is an ELF file
1270
   }
1639
   }
1271
   else if (S_ISLNK (entry_parms->st_mode)) // else are we storing a symbolic link ?
1640
   else if (S_ISLNK (entry_parms->st_mode)) // else are we storing a symbolic link ?
1272
      fprintf (stderr, "symlink: ino 0x%x uid %d gid %d mode 0%o path \"%s\" -> \"%s\"\n", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, entry_parms->data);
1641
      fprintf (stderr, "symlink: ino 0x%x uid %d gid %d mode 0%o path \"%s\" -> \"%s\"\n", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, entry_parms->data);
1273
   else // we must be storing a FIFO
1642
   else // we must be storing a FIFO
Line 1289... Line 1658...
1289
   }
1658
   }
1290
   *fsentries = reallocated_ptr; // save reallocated pointer
1659
   *fsentries = reallocated_ptr; // save reallocated pointer
1291
   fsentry = &(*fsentries)[*fsentry_count]; // quick access to fs entry slot
1660
   fsentry = &(*fsentries)[*fsentry_count]; // quick access to fs entry slot
1292
   //fsentry->header.size = 0; // will be filled once we know it
1661
   //fsentry->header.size = 0; // will be filled once we know it
1293
   fsentry->header.extattr_offset = 0;
1662
   fsentry->header.extattr_offset = 0;
1294
   fsentry->header.ino = extra_ino_flags | (++inode_count);
1663
   fsentry->header.ino = entry_parms->extra_ino_flags | (++inode_count);
1295
   fsentry->header.mode = entry_parms->st_mode;
1664
   fsentry->header.mode = entry_parms->st_mode;
1296
   fsentry->header.gid = entry_parms->gid;
1665
   fsentry->header.gid = entry_parms->gid;
1297
   fsentry->header.uid = entry_parms->uid;
1666
   fsentry->header.uid = entry_parms->uid;
1298
   fsentry->header.mtime = (entry_parms->mtime == UINT32_MAX ? (uint32_t) time (NULL) : entry_parms->mtime);
1667
   fsentry->header.mtime = (entry_parms->mtime == UINT32_MAX ? (uint32_t) time (NULL) : entry_parms->mtime);
1299
   if (S_ISDIR (entry_parms->st_mode))
1668
   if (S_ISDIR (entry_parms->st_mode))
Line 1338... Line 1707...
1338
   {
1707
   {
1339
      entry_parms->is_compiled_bootscript = false;
1708
      entry_parms->is_compiled_bootscript = false;
1340
      entry_parms->should_autosymlink_dylib = false;
1709
      entry_parms->should_autosymlink_dylib = false;
1341
      entry_parms->should_follow_symlinks = false;
1710
      entry_parms->should_follow_symlinks = false;
1342
      entry_parms->st_mode = S_IFLNK | 0777; // NOTE: mkifs stores symlink permissions as rwxrwxrwx !
1711
      entry_parms->st_mode = S_IFLNK | 0777; // NOTE: mkifs stores symlink permissions as rwxrwxrwx !
-
 
1712
      entry_parms->extra_ino_flags = (fsentry->header.ino & (IFS_INO_PROCESSED_ELF | IFS_INO_RUNONCE_ELF | IFS_INO_BOOTSTRAP_EXE)); // preserve target's inode flags
1343
      last_dirsep = strrchr (stored_pathname, '/');
1713
      last_dirsep = strrchr (stored_pathname, '/');
1344
      old_data = entry_parms->data; // backup previous data pointer
1714
      old_data = entry_parms->data; // backup previous data pointer
1345
      entry_parms->data = (uint8_t *) (last_dirsep == NULL ? stored_pathname : last_dirsep + 1); // store symlink target in dirent data
1715
      entry_parms->data = (uint8_t *) (last_dirsep == NULL ? stored_pathname : last_dirsep + 1); // store symlink target in dirent data
1346
      entry_parms->datalen = strlen (entry_parms->data);
1716
      entry_parms->datalen = strlen (entry_parms->data);
1347
      add_fsentry (fsentries, fsentry_count, entry_parms, original_stored_pathname, NULL);
1717
      add_fsentry (fsentries, fsentry_count, entry_parms, original_stored_pathname, NULL);
Line 1429... Line 1799...
1429
      .mtime_for_inline_files = UINT32_MAX,
1799
      .mtime_for_inline_files = UINT32_MAX,
1430
      .prefix = "/proc/boot",
1800
      .prefix = "/proc/boot",
1431
      .should_follow_symlinks = true, // [+|-followlink]
1801
      .should_follow_symlinks = true, // [+|-followlink]
1432
      .should_autosymlink_dylib = true, // [+|-autolink]
1802
      .should_autosymlink_dylib = true, // [+|-autolink]
1433
      .is_compiled_bootscript = false, // [+|-script]
1803
      .is_compiled_bootscript = false, // [+|-script]
-
 
1804
      .extra_ino_flags = 0,
1434
      .search = "",
1805
      .search = "",
1435
      .data = NULL,
1806
      .data = NULL,
1436
      .datalen = 0
1807
      .datalen = 0
1437
   };
1808
   };
1438
   static parms_t entry_parms = { 0 }; // current parameters for a filesystem entry (will be initialized to default_parms each time a new entry is parsed in the build file)
1809
   static parms_t entry_parms = { 0 }; // current parameters for a filesystem entry (will be initialized to default_parms each time a new entry is parsed in the build file)
Line 1447... Line 1818...
1447
 
1818
 
1448
   char path_on_buildhost[MAXPATHLEN] = "";
1819
   char path_on_buildhost[MAXPATHLEN] = "";
1449
   char path_in_ifs[MAXPATHLEN] = "";
1820
   char path_in_ifs[MAXPATHLEN] = "";
1450
   char *ifs_pathname = NULL;
1821
   char *ifs_pathname = NULL;
1451
   void *reallocated_ptr;
1822
   void *reallocated_ptr;
-
 
1823
   const elf_header_t *elf;
-
 
1824
   elf_program_header_t *phdr;
1452
   struct tm utc_time;
1825
   struct tm utc_time;
1453
   struct stat stat_buf;
1826
   struct stat stat_buf;
1454
   size_t startuptrailer_offset;
1827
   size_t startuptrailer_offset;
1455
   size_t startupheader_offset;
1828
   size_t startupheader_offset;
1456
   size_t imagetrailer_offset;
1829
   size_t imagetrailer_offset;
Line 1463... Line 1836...
1463
   size_t allocated_size;
1836
   size_t allocated_size;
1464
   size_t fsentry_index;
1837
   size_t fsentry_index;
1465
   size_t largest_index;
1838
   size_t largest_index;
1466
   size_t largest_size;
1839
   size_t largest_size;
1467
   size_t curr_offset;
1840
   size_t curr_offset;
-
 
1841
   size_t table_index;
-
 
1842
   size_t table_count;
1468
   uint8_t *blob_data;
1843
   uint8_t *blob_data;
1469
   int32_t checksum;
1844
   int32_t checksum;
1470
   char *specifiedpathname_start;
1845
   char *specifiedpathname_start;
1471
   char *directiveblock_start;
1846
   char *directiveblock_start;
1472
   char *write_ptr;
1847
   char *write_ptr;
Line 1478... Line 1853...
1478
   int arg_index;
1853
   int arg_index;
1479
   bool is_quoted_context = false;
1854
   bool is_quoted_context = false;
1480
   bool is_escaped_char = false;
1855
   bool is_escaped_char = false;
1481
   bool has_data_already = false;
1856
   bool has_data_already = false;
1482
   bool want_info = false;
1857
   bool want_info = false;
-
 
1858
   bool want_everything = false;
1483
   bool want_help = false;
1859
   bool want_help = false;
1484
   bool is_foreign_endianness;
1860
   bool is_foreign_endianness;
1485
   int string_len;
1861
   int string_len;
1486
   int read_char;
1862
   int read_char;
1487
   FILE *buildfile_fp;
1863
   FILE *buildfile_fp;
Line 1523... Line 1899...
1523
         default_parms.mtime = 0; // all files should have a mtime set to zero
1899
         default_parms.mtime = 0; // all files should have a mtime set to zero
1524
         default_parms.mtime_for_inline_files = 0;
1900
         default_parms.mtime_for_inline_files = 0;
1525
      }
1901
      }
1526
      else if (strcmp (argv[arg_index], "--info") == 0)
1902
      else if (strcmp (argv[arg_index], "--info") == 0)
1527
         want_info = true;
1903
         want_info = true;
-
 
1904
      else if (strcmp (argv[arg_index], "--everything") == 0)
-
 
1905
         want_everything = true;
1528
      else if ((strcmp (argv[arg_index], "-?") == 0) || (strcmp (argv[arg_index], "--help") == 0))
1906
      else if ((strcmp (argv[arg_index], "-?") == 0) || (strcmp (argv[arg_index], "--help") == 0))
1529
         want_help = true;
1907
         want_help = true;
1530
      else if (buildfile_pathname == NULL)
1908
      else if (buildfile_pathname == NULL)
1531
         buildfile_pathname = argv[arg_index];
1909
         buildfile_pathname = argv[arg_index];
1532
      else if (ifs_pathname == NULL)
1910
      else if (ifs_pathname == NULL)
Line 1540... Line 1918...
1540
      fprintf ((want_help ? stdout : stderr), "          version " VERSION_FMT_YYYYMMDD "\n", VERSION_ARG_YYYYMMDD);
1918
      fprintf ((want_help ? stdout : stderr), "          version " VERSION_FMT_YYYYMMDD "\n", VERSION_ARG_YYYYMMDD);
1541
      if (!want_help)
1919
      if (!want_help)
1542
         fprintf (stderr, "error: missing parameters\n");
1920
         fprintf (stderr, "error: missing parameters\n");
1543
      fprintf ((want_help ? stdout : stderr), "usage:\n");
1921
      fprintf ((want_help ? stdout : stderr), "usage:\n");
1544
      fprintf ((want_help ? stdout : stderr), "    ifstool [--bootfile <pathname>] [--startupfile <pathname>@<EP_from_imgbase>] [--kernelfile <pathname>@<fileoffs>] [-n[n]] <buildfile> <outfile>\n");
1922
      fprintf ((want_help ? stdout : stderr), "    ifstool [--bootfile <pathname>] [--startupfile <pathname>@<EP_from_imgbase>] [--kernelfile <pathname>@<fileoffs>] [-n[n]] <buildfile> <outfile>\n");
1545
      fprintf ((want_help ? stdout : stderr), "    ifstool --info <ifs file>\n");
1923
      fprintf ((want_help ? stdout : stderr), "    ifstool --info [--everything] <ifs file>\n");
1546
      fprintf ((want_help ? stdout : stderr), "    ifstool --help\n");
1924
      fprintf ((want_help ? stdout : stderr), "    ifstool --help\n");
1547
      fprintf ((want_help ? stdout : stderr), "WARNING: the compilation feature is currently a work in progress (broken). Only the --info mode is usable at the moment.\n");
1925
      fprintf ((want_help ? stdout : stderr), "WARNING: the compilation feature is currently a work in progress (broken). Only the --info mode is usable at the moment.\n");
1548
      exit (want_help ? 0 : 1);
1926
      exit (want_help ? 0 : 1);
1549
   }
1927
   }
1550
 
1928
 
1551
   // do we want info about a particular IFS ? if so, dump it
1929
   // do we want info about a particular IFS ? if so, dump it
1552
   if (want_info)
1930
   if (want_info)
1553
      exit (dump_ifs_info (buildfile_pathname)); // NOTE: the first argument after --info is actually the IFS file, not a build file, but the arguments are collected in this order
1931
      exit (dump_ifs_info (buildfile_pathname, want_everything)); // NOTE: the first argument after --info is actually the IFS file, not a build file, but the arguments are collected in this order
1554
 
1932
 
1555
   // make sure we have ${QNX_TARGET} pointing somewhere
1933
   // make sure we have ${QNX_TARGET} pointing somewhere
1556
   QNX_TARGET = getenv ("QNX_TARGET");
1934
   QNX_TARGET = getenv ("QNX_TARGET");
1557
   if (QNX_TARGET == NULL)
1935
   if (QNX_TARGET == NULL)
1558
   {
1936
   {
Line 1911... Line 2289...
1911
      memcpy (startup_header.signature, "\xeb\x7e\xff\x00", 4); // startup header signature, i.e. 0xff7eeb
2289
      memcpy (startup_header.signature, "\xeb\x7e\xff\x00", 4); // startup header signature, i.e. 0xff7eeb
1912
      startup_header.version       = 1;
2290
      startup_header.version       = 1;
1913
      startup_header.flags1        = STARTUP_HDR_FLAGS1_VIRTUAL | STARTUP_HDR_FLAGS1_TRAILER_V2; // flags, 0x21 (STARTUP_HDR_FLAGS1_VIRTUAL | STARTUP_HDR_FLAGS1_TRAILER_V2)
2291
      startup_header.flags1        = STARTUP_HDR_FLAGS1_VIRTUAL | STARTUP_HDR_FLAGS1_TRAILER_V2; // flags, 0x21 (STARTUP_HDR_FLAGS1_VIRTUAL | STARTUP_HDR_FLAGS1_TRAILER_V2)
1914
      startup_header.header_size   = sizeof (startup_header); // 256
2292
      startup_header.header_size   = sizeof (startup_header); // 256
1915
      if (strcmp (image_processor, "x86_64") == 0)
2293
      if (strcmp (image_processor, "x86_64") == 0)
1916
         startup_header.machine = STARTUP_HDR_MACHINE_X86_64; // EM_X86_64
2294
         startup_header.machine = ELF_MACHINE_X86_64; // EM_X86_64
1917
      else if (strcmp (image_processor, "aarch64le") == 0)
2295
      else if (strcmp (image_processor, "aarch64le") == 0)
1918
         startup_header.machine = STARTUP_HDR_MACHINE_AARCH64; // EM_AARCH64
2296
         startup_header.machine = ELF_MACHINE_AARCH64; // EM_AARCH64
1919
      else
2297
      else
1920
      {
2298
      {
1921
         fprintf (stderr, "fatal error: unsupported processor type '%s' found in build file \"%s\"\n", image_processor, buildfile_pathname);
2299
         fprintf (stderr, "fatal error: unsupported processor type '%s' found in build file \"%s\"\n", image_processor, buildfile_pathname);
1922
         exit (1);
2300
         exit (1);
1923
      }
2301
      }
Line 2005... Line 2383...
2005
               largest_index = fsentry_index;
2383
               largest_index = fsentry_index;
2006
            }
2384
            }
2007
         }
2385
         }
2008
         if (largest_size == 0)
2386
         if (largest_size == 0)
2009
            break; // found none ? if so, stop searching
2387
            break; // found none ? if so, stop searching
-
 
2388
 
-
 
2389
         // is the file we're storing a preprocessed ELF file ?
-
 
2390
         if (fsentries[fsentry_index].header.ino & IFS_INO_PROCESSED_ELF)
-
 
2391
         {
-
 
2392
            elf = (elf_header_t *) fsentries[fsentry_index].u.file.UNSAVED_databuf; // quick access to ELF header
-
 
2393
            table_count = ELF_GET_NUMERIC (elf, elf, program_header_table_len); // get the number of program headers
-
 
2394
            for (table_index = 0; table_index < table_count; table_index++)
-
 
2395
            {
-
 
2396
               phdr = (elf_program_header_t *) &fsentries[fsentry_index].u.file.UNSAVED_databuf[ELF_GET_NUMERIC (elf, elf, program_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, program_header_item_size) * table_index]; // quick access to program header
-
 
2397
               ELF_SET_NUMERIC (elf, phdr, physical_addr, ELF_GET_NUMERIC (elf, phdr, physical_addr) + (0x1400000 + curr_offset)); // patch the physical address member of the program header table
-
 
2398
            }
-
 
2399
         }
2010
 
2400
 
2011
         fsentries[largest_index].u.file.offset = (uint32_t) (curr_offset - imageheader_offset); // save file data blob offset in file structure
2401
         fsentries[largest_index].u.file.offset = (uint32_t) (curr_offset - imageheader_offset); // save file data blob offset in file structure
2012
         fwrite_or_die (fsentries[largest_index].u.file.UNSAVED_databuf, 1, fsentries[largest_index].u.file.size, fp); // write file data blob
2402
         fwrite_or_die (fsentries[largest_index].u.file.UNSAVED_databuf, 1, fsentries[largest_index].u.file.size, fp); // write file data blob
2013
         fsentries[largest_index].UNSAVED_was_data_written = true; // and remember this file's data was written
2403
         fsentries[largest_index].UNSAVED_was_data_written = true; // and remember this file's data was written
2014
      }
2404
      }
-
 
2405
      fprintf (stderr, "Current offset: 0x%zx\n", curr_offset);
-
 
2406
      fprintf (stderr, "Kernel file offset: 0x%zx\n", kernelfile_offset);
2015
      PAD_OUTFILE_TO (kernelfile_offset); // reach the kernel offset
2407
      PAD_OUTFILE_TO (kernelfile_offset); // reach the kernel offset
2016
 
2408
 
2017
      // now write the QNX kernel
2409
      // now write the QNX kernel
2018
      for (fsentry_index = 1; fsentry_index < fsentry_count; fsentry_index++)
2410
      for (fsentry_index = 1; fsentry_index < fsentry_count; fsentry_index++)
2019
         if (fsentries[fsentry_index].header.ino == image_kernel_ino)
2411
         if (fsentries[fsentry_index].header.ino == image_kernel_ino)
Line 2035... Line 2427...
2035
      if (!S_ISREG (fsentries[fsentry_index].header.mode) || fsentries[fsentry_index].UNSAVED_was_data_written // filter out anything that's not a file, and anything that's been already written
2427
      if (!S_ISREG (fsentries[fsentry_index].header.mode) || fsentries[fsentry_index].UNSAVED_was_data_written // filter out anything that's not a file, and anything that's been already written
2036
          || (fsentries[fsentry_index].u.file.size < 4) || (memcmp (fsentries[fsentry_index].u.file.UNSAVED_databuf, ELF_MAGIC_STR, 4) != 0)) // filter out anything that's not an ELF file
2428
          || (fsentries[fsentry_index].u.file.size < 4) || (memcmp (fsentries[fsentry_index].u.file.UNSAVED_databuf, ELF_MAGIC_STR, 4) != 0)) // filter out anything that's not an ELF file
2037
         continue; // skip all entries that don't have a separate data block and those who were written already
2429
         continue; // skip all entries that don't have a separate data block and those who were written already
2038
      curr_offset = ftell (fp);
2430
      curr_offset = ftell (fp);
2039
      fsentries[fsentry_index].u.file.offset = (uint32_t) (curr_offset - imageheader_offset); // save file data blob offset in file structure
2431
      fsentries[fsentry_index].u.file.offset = (uint32_t) (curr_offset - imageheader_offset); // save file data blob offset in file structure
-
 
2432
 
-
 
2433
      // is the file we're storing a preprocessed ELF file ?
-
 
2434
      if (fsentries[fsentry_index].header.ino & IFS_INO_PROCESSED_ELF)
-
 
2435
      {
-
 
2436
         elf = (elf_header_t *) fsentries[fsentry_index].u.file.UNSAVED_databuf; // quick access to ELF header
-
 
2437
         table_count = ELF_GET_NUMERIC (elf, elf, program_header_table_len); // get the number of program headers
-
 
2438
         for (table_index = 0; table_index < table_count; table_index++)
-
 
2439
         {
-
 
2440
            phdr = (elf_program_header_t *) &fsentries[fsentry_index].u.file.UNSAVED_databuf[ELF_GET_NUMERIC (elf, elf, program_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, program_header_item_size) * table_index]; // quick access to program header
-
 
2441
            ELF_SET_NUMERIC (elf, phdr, physical_addr, ELF_GET_NUMERIC (elf, phdr, physical_addr) + (0x1400000 + curr_offset)); // patch the physical address member of the program header table
-
 
2442
         }
-
 
2443
      }
-
 
2444
 
2040
      fwrite_or_die (fsentries[fsentry_index].u.file.UNSAVED_databuf, 1, fsentries[fsentry_index].u.file.size, fp); // write file data blob
2445
      fwrite_or_die (fsentries[fsentry_index].u.file.UNSAVED_databuf, 1, fsentries[fsentry_index].u.file.size, fp); // write file data blob
2041
      fsentries[fsentry_index].UNSAVED_was_data_written = true; // and remember this file's data was written
2446
      fsentries[fsentry_index].UNSAVED_was_data_written = true; // and remember this file's data was written
2042
   }
2447
   }
2043
   for (fsentry_index = 1; fsentry_index < fsentry_count; fsentry_index++) // other files (non-ELF, e.g. scripts and data files) last
2448
   for (fsentry_index = 1; fsentry_index < fsentry_count; fsentry_index++) // other files (non-ELF, e.g. scripts and data files) last
2044
   {
2449
   {
Line 2137... Line 2542...
2137
   fprintf (stdout, "Success\n");
2542
   fprintf (stdout, "Success\n");
2138
   exit (0);
2543
   exit (0);
2139
}
2544
}
2140
 
2545
 
2141
 
2546
 
2142
static int dump_ifs_info (const char *ifs_pathname)
2547
static int dump_ifs_info (const char *ifs_pathname, bool want_everything)
2143
{
2548
{
2144
   #define hex_printf(buf,size,...) do { \
2549
   #define hex_printf(buf,size,...) do { \
2145
      if ((size) <= 16 * 1024) /* only print when it's not too big (up to 16 kb) */\
2550
      if (want_everything || ((size) <= 16 * 1024)) /* only print when it's not too big (up to 16 kb) */\
2146
         hex_fprintf (stdout, (buf), (size), 16, __VA_ARGS__); /* use 16 columns in hex output to stdout */ \
2551
         hex_fprintf (stdout, (buf), (size), 16, __VA_ARGS__); /* use 16 columns in hex output to stdout */ \
2147
      else { \
2552
      else { \
2148
         printf (__VA_ARGS__); \
2553
         printf (__VA_ARGS__); \
2149
         printf ("   size %zd > 16kb, not printed\n", (size_t) (size)); \
2554
         hex_fprintf (stdout, (buf), 1024, 16, "   first kilobyte:\n"); \
2150
      } \
2555
      } \
2151
   } while (0)
2556
   } while (0)
2152
   #define BINARY(x) binary ((x), '-', 'x')
2557
   #define BINARY(x) binary ((x), '-', 'x')
2153
 
2558
 
2154
   static const char *startupheader_flags1_strings[8] = {
2559
   static const char *startupheader_flags1_strings[8] = {
Line 2232... Line 2637...
2232
         printf ("   signature     = %02x %02x %02x %02x - good\n", startup_header->signature[0], startup_header->signature[1], startup_header->signature[2], startup_header->signature[3]);
2637
         printf ("   signature     = %02x %02x %02x %02x - good\n", startup_header->signature[0], startup_header->signature[1], startup_header->signature[2], startup_header->signature[3]);
2233
         printf ("   version       = 0x%04x (%d) - %s\n", startup_header->version, startup_header->version, (startup_header->version == 1 ? "looks good" : "???"));
2638
         printf ("   version       = 0x%04x (%d) - %s\n", startup_header->version, startup_header->version, (startup_header->version == 1 ? "looks good" : "???"));
2234
         printf ("   flags1        = 0x%02x (%s)\n", startup_header->flags1, describe_uint8 (startup_header->flags1, startupheader_flags1_strings));
2639
         printf ("   flags1        = 0x%02x (%s)\n", startup_header->flags1, describe_uint8 (startup_header->flags1, startupheader_flags1_strings));
2235
         printf ("   flags2        = 0x%02x (%s) - %s\n", startup_header->flags2, BINARY (startup_header->flags2), (startup_header->flags2 == 0 ? "looks good" : "???"));
2640
         printf ("   flags2        = 0x%02x (%s) - %s\n", startup_header->flags2, BINARY (startup_header->flags2), (startup_header->flags2 == 0 ? "looks good" : "???"));
2236
         printf ("   header_size   = 0x%04x (%d) - %s\n", startup_header->header_size, startup_header->header_size, (startup_header->header_size == sizeof (startup_header_t) ? "looks good" : "BAD"));
2641
         printf ("   header_size   = 0x%04x (%d) - %s\n", startup_header->header_size, startup_header->header_size, (startup_header->header_size == sizeof (startup_header_t) ? "looks good" : "BAD"));
2237
         printf ("   machine       = 0x%04x (%d) - %s\n", startup_header->machine, startup_header->machine, (startup_header->machine == STARTUP_HDR_MACHINE_X86_64 ? "x86_64" : (startup_header->machine == STARTUP_HDR_MACHINE_AARCH64 ? "aarch64" : "unknown")));
2642
         printf ("   machine       = 0x%04x (%d) - %s\n", startup_header->machine, startup_header->machine, (startup_header->machine == ELF_MACHINE_X86_64 ? "x86_64" : (startup_header->machine == ELF_MACHINE_AARCH64 ? "aarch64" : "unknown")));
2238
         printf ("   startup_vaddr = 0x%08x (%d) - virtual address to transfer to after IPL is done\n", startup_header->startup_vaddr, startup_header->startup_vaddr);
2643
         printf ("   startup_vaddr = 0x%08x (%d) - virtual address to transfer to after IPL is done\n", startup_header->startup_vaddr, startup_header->startup_vaddr);
2239
         printf ("   paddr_bias    = 0x%08x (%d) - value to add to physical addresses to get an indirectable pointer value\n", startup_header->paddr_bias, startup_header->paddr_bias);
2644
         printf ("   paddr_bias    = 0x%08x (%d) - value to add to physical addresses to get an indirectable pointer value\n", startup_header->paddr_bias, startup_header->paddr_bias);
2240
         printf ("   image_paddr   = 0x%08x (%d) - physical address of image\n", startup_header->image_paddr, startup_header->image_paddr);
2645
         printf ("   image_paddr   = 0x%08x (%d) - physical address of image\n", startup_header->image_paddr, startup_header->image_paddr);
2241
         printf ("   ram_paddr     = 0x%08x (%d) - physical address of RAM to copy image to (startup_size bytes copied)\n", startup_header->ram_paddr, startup_header->ram_paddr);
2646
         printf ("   ram_paddr     = 0x%08x (%d) - physical address of RAM to copy image to (startup_size bytes copied)\n", startup_header->ram_paddr, startup_header->ram_paddr);
2242
         printf ("   ram_size      = 0x%08x (%d) - amount of RAM used by the startup program and executables in the fs\n", startup_header->ram_size, startup_header->ram_size);
2647
         printf ("   ram_size      = 0x%08x (%d) - amount of RAM used by the startup program and executables in the fs\n", startup_header->ram_size, startup_header->ram_size);
Line 2467... Line 2872...
2467
               printf ("   corresponding dirent index: %zd/%zd\n", fsentry_index, fsentry_count);
2872
               printf ("   corresponding dirent index: %zd/%zd\n", fsentry_index, fsentry_count);
2468
               printf ("   corresponding inode 0x%08x (%d) -%s%s%s%s\n", current_fsentry->header.ino, current_fsentry->header.ino, (current_fsentry->header.ino & 0xE0000000 ? "" : " nothing special"), (current_fsentry->header.ino & IFS_INO_PROCESSED_ELF ? " PROCESSED_ELF" : ""), (current_fsentry->header.ino & IFS_INO_RUNONCE_ELF ? " RUNONCE_ELF" : ""), (current_fsentry->header.ino & IFS_INO_BOOTSTRAP_EXE ? " BOOTSTRAP_EXE" : ""));
2873
               printf ("   corresponding inode 0x%08x (%d) -%s%s%s%s\n", current_fsentry->header.ino, current_fsentry->header.ino, (current_fsentry->header.ino & 0xE0000000 ? "" : " nothing special"), (current_fsentry->header.ino & IFS_INO_PROCESSED_ELF ? " PROCESSED_ELF" : ""), (current_fsentry->header.ino & IFS_INO_RUNONCE_ELF ? " RUNONCE_ELF" : ""), (current_fsentry->header.ino & IFS_INO_BOOTSTRAP_EXE ? " BOOTSTRAP_EXE" : ""));
2469
               printf ("   corresponding path: \"%s\"\n", (char *) &current_fsentry->u.file.path); // convert from pointer to char array
2874
               printf ("   corresponding path: \"%s\"\n", (char *) &current_fsentry->u.file.path); // convert from pointer to char array
2470
               printf ("   size 0x%zx (%zd) bytes\n", (size_t) current_fsentry->u.file.size, (size_t) current_fsentry->u.file.size);
2875
               printf ("   size 0x%zx (%zd) bytes\n", (size_t) current_fsentry->u.file.size, (size_t) current_fsentry->u.file.size);
2471
               if (current_offset + 4 < filesize)
2876
               if (current_offset + 4 < filesize)
2472
               {
-
 
2473
                  if ((current_fsentry->u.file.size < 16 * 1024) && (current_offset + current_fsentry->u.file.size < filesize))
-
 
2474
                     hex_printf (&filedata[current_offset], current_fsentry->u.file.size, "   data:\n");
2877
                  hex_printf (&filedata[current_offset], current_fsentry->u.file.size, "   data:\n");
2475
                  else
-
 
2476
                     printf ("   first 4 bytes: %02x%02x%02x%02x \"%c%c%c%c\" (%s)\n", (uint8_t) filedata[current_offset + 0], (uint8_t) filedata[current_offset + 1], (uint8_t) filedata[current_offset + 2], (uint8_t) filedata[current_offset + 3], (isprint (filedata[current_offset + 0]) ? filedata[current_offset + 0] : '.'), (isprint (filedata[current_offset + 1]) ? filedata[current_offset + 1] : '.'), (isprint (filedata[current_offset + 2]) ? filedata[current_offset + 2] : '.'), (isprint (filedata[current_offset + 3]) ? filedata[current_offset + 3] : '.'), (memcmp (&filedata[current_offset], ELF_MAGIC_STR, 4) == 0 ? "ELF binary" : (memcmp (&filedata[current_offset], "#!", 2) == 0 ? "shell script" : "data file")));
-
 
2477
               }
-
 
2478
               if (current_offset + current_fsentry->u.file.size < filesize)
2878
               if (current_offset + current_fsentry->u.file.size < filesize)
2479
                  printf ("   checksum %d\n", update_checksum (&filedata[current_offset], current_fsentry->u.file.size, is_foreign_endianness));
2879
                  printf ("   checksum %d\n", update_checksum (&filedata[current_offset], current_fsentry->u.file.size, is_foreign_endianness));
2480
               else
2880
               else
2481
               {
2881
               {
2482
                  printf ("WARNING: this IFS file is corrupted (the size of this file data extends past the IFS size)\n");
2882
                  printf ("WARNING: this IFS file is corrupted (the size of this file data extends past the IFS size)\n");