Subversion Repositories QNX 8.QNX8 IFS tool

Rev

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

Rev 11 Rev 12
Line 1... Line 1...
1
// ifstool.c -- portable reimplementation of QNX's mkifs by Pierre-Marie Baty <pm@pmbaty.com>
1
// ifstool.c -- portable reimplementation of QNX's mkifs by Pierre-Marie Baty <pm@pmbaty.com>
-
 
2
 
-
 
3
// TODO: preboot file stripping
-
 
4
// TODO: startup file stripping
-
 
5
// TODO: kernel file stripping
-
 
6
// TODO: boot script compiler
2
 
7
 
3
#include <stdint.h>
8
#include <stdint.h>
4
#include <stdbool.h>
9
#include <stdbool.h>
5
#include <stdlib.h>
10
#include <stdlib.h>
6
#include <stdarg.h>
11
#include <stdarg.h>
Line 1524... Line 1529...
1524
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1529
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1525
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1530
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1526
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1531
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1527
               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
1532
               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
1528
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1533
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1529
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
1534
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (which should be zero anyway)
1530
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1535
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1531
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1536
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1532
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1537
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1533
            }
1538
            }
1534
            if ((shdr = elf_get_section_header_by_name (elf, ".gnu_debuglink")) != NULL)
1539
            if ((shdr = elf_get_section_header_by_name (elf, ".gnu_debuglink")) != NULL)
Line 1552... Line 1557...
1552
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1557
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1553
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1558
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1554
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1559
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1555
               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
1560
               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
1556
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1561
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1557
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
1562
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (which should be zero anyway)
1558
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1563
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1559
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1564
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1560
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1565
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1561
            }
1566
            }
1562
            if ((shdr = elf_get_section_header_by_name (elf, "QNX_usage")) != NULL)
1567
            if ((shdr = elf_get_section_header_by_name (elf, "QNX_usage")) != NULL)
Line 1580... Line 1585...
1580
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1585
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1581
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1586
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1582
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1587
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1583
               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
1588
               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
1584
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1589
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1585
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
1590
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (which should be zero anyway)
1586
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1591
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1587
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1592
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1588
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1593
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1589
            }
1594
            }
1590
            if ((shdr = elf_get_section_header_by_name (elf, ".note.gnu.build-id")) != NULL)
1595
            if ((shdr = elf_get_section_header_by_name (elf, ".note.gnu.build-id")) != NULL)
Line 1608... Line 1613...
1608
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1613
               ELF_SET_NUMERIC (elf, new_shdr, type,         ELF_GET_NUMERIC (elf, shdr, type)); // duplicate section type
1609
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1614
               ELF_SET_NUMERIC (elf, new_shdr, flags,        ELF_GET_NUMERIC (elf, shdr, flags)); // duplicate section flags
1610
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1615
               ELF_SET_NUMERIC (elf, new_shdr, virtual_addr, ELF_GET_NUMERIC (elf, shdr, virtual_addr)); // duplicate section virtual address
1611
               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
1616
               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
1612
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1617
               ELF_SET_NUMERIC (elf, new_shdr, size,         ELF_GET_NUMERIC (elf, shdr, size)); // duplicate section size
1613
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (FIXME: may be wrong now!)
1618
               ELF_SET_NUMERIC (elf, new_shdr, linked_index, ELF_GET_NUMERIC (elf, shdr, linked_index)); // duplicate section linked index (which should be zero anyway)
1614
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1619
               ELF_SET_NUMERIC (elf, new_shdr, info,         ELF_GET_NUMERIC (elf, shdr, info)); // duplicate section info
1615
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1620
               ELF_SET_NUMERIC (elf, new_shdr, alignment,    ELF_GET_NUMERIC (elf, shdr, alignment)); // duplicate section alignment
1616
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1621
               ELF_SET_NUMERIC (elf, new_shdr, entry_size,   ELF_GET_NUMERIC (elf, shdr, entry_size)); // duplicate section entry size
1617
            }
1622
            }
1618
            reallocated_ptr = realloc (new_shtab.bytes, new_shtab.len + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
1623
            reallocated_ptr = realloc (new_shtab.bytes, new_shtab.len + ELF_STRUCT_SIZE (elf, shdr)); // grow our section headers table to have one entry more
Line 1945... Line 1950...
1945
   }
1950
   }
1946
 
1951
 
1947
   // do we not have enough information to run ?
1952
   // do we not have enough information to run ?
1948
   if (want_help || (buildfile_pathname == NULL) || (!want_info && (ifs_pathname == NULL)))
1953
   if (want_help || (buildfile_pathname == NULL) || (!want_info && (ifs_pathname == NULL)))
1949
   {
1954
   {
-
 
1955
      fp = (want_help ? stdout : stderr); // select the right output channel
1950
      fprintf ((want_help ? stdout : stderr), "ifstool - QNX in-kernel filesystem creation utility by Pierre-Marie Baty <pm@pmbaty.com>\n");
1956
      fprintf (fp, "ifstool - QNX in-kernel filesystem creation utility by Pierre-Marie Baty <pm@pmbaty.com>\n");
1951
      fprintf ((want_help ? stdout : stderr), "          version " VERSION_FMT_YYYYMMDD "\n", VERSION_ARG_YYYYMMDD);
1957
      fprintf (fp, "          version " VERSION_FMT_YYYYMMDD "\n", VERSION_ARG_YYYYMMDD);
1952
      if (!want_help)
1958
      if (!want_help)
1953
         fprintf (stderr, "error: missing parameters\n");
1959
         fprintf (fp, "error: missing parameters\n");
1954
      fprintf ((want_help ? stdout : stderr), "usage:\n");
1960
      fprintf (fp, "usage:\n");
1955
      fprintf ((want_help ? stdout : stderr), "    ifstool [--bootfile <pathname>] [--startupfile <pathname>@<EP_from_imgbase>] [--kernelfile <pathname>@<fileoffs>] [-n[n]] <buildfile> <outfile>\n");
1961
      fprintf (fp, "    ifstool [--bootfile <pathname>] [--startupfile <pathname>@<EP_from_imgbase>] [--kernelfile <pathname>@<fileoffs>] [-n[n]] <buildfile> <outfile>\n");
1956
      fprintf ((want_help ? stdout : stderr), "    ifstool --info [--everything] <ifs file>\n");
1962
      fprintf (fp, "    ifstool --info [--everything] <ifs file>\n");
1957
      fprintf ((want_help ? stdout : stderr), "    ifstool --help\n");
1963
      fprintf (fp, "    ifstool --help\n");
1958
      fprintf ((want_help ? stdout : stderr), "NOTE: the compilation feature requires predigested boot, startup and kernel files produced by mkifs.\n");
1964
      fprintf (fp, "NOTE: the compilation feature requires predigested boot, startup and kernel files produced by mkifs.\n");
1959
      exit (want_help ? 0 : 1);
1965
      exit (want_help ? 0 : 1);
1960
   }
1966
   }
1961
 
1967
 
1962
   // do we want info about a particular IFS ? if so, dump it
1968
   // do we want info about a particular IFS ? if so, dump it
1963
   if (want_info)
1969
   if (want_info)
Line 2052... Line 2058...
2052
            else if (strncmp (token, "perms=",   6) == 0) { REACH_TOKEN_VALUE (); entry_parms.perms   = (int) read_integer (value); }
2058
            else if (strncmp (token, "perms=",   6) == 0) { REACH_TOKEN_VALUE (); entry_parms.perms   = (int) read_integer (value); }
2053
            else if (strncmp (token, "type=",    5) == 0) { REACH_TOKEN_VALUE (); entry_parms.st_mode = (strcmp (value, "dir") == 0 ? S_IFDIR : (strcmp (value, "file") == 0 ? S_IFREG : (strcmp (value, "link") == 0 ? S_IFLNK : (strcmp (value, "fifo") == 0 ? S_IFIFO : (fprintf (stderr, "warning: invalid 'type' attribute in \"%s\" line %d: '%s', defaulting to 'file'\n", buildfile_pathname, lineno, value), S_IFREG))))); }
2059
            else if (strncmp (token, "type=",    5) == 0) { REACH_TOKEN_VALUE (); entry_parms.st_mode = (strcmp (value, "dir") == 0 ? S_IFDIR : (strcmp (value, "file") == 0 ? S_IFREG : (strcmp (value, "link") == 0 ? S_IFLNK : (strcmp (value, "fifo") == 0 ? S_IFIFO : (fprintf (stderr, "warning: invalid 'type' attribute in \"%s\" line %d: '%s', defaulting to 'file'\n", buildfile_pathname, lineno, value), S_IFREG))))); }
2054
            else if (strncmp (token, "prefix=",  7) == 0) { REACH_TOKEN_VALUE (); strcpy (entry_parms.prefix, (*value == '/' ? value + 1 : value)); } // skip possible leading slash in prefix
2060
            else if (strncmp (token, "prefix=",  7) == 0) { REACH_TOKEN_VALUE (); strcpy (entry_parms.prefix, (*value == '/' ? value + 1 : value)); } // skip possible leading slash in prefix
2055
            else if (strncmp (token, "image=",   6) == 0) { REACH_TOKEN_VALUE ();
2061
            else if (strncmp (token, "image=",   6) == 0) { REACH_TOKEN_VALUE ();
2056
               image_base = (uint32_t) read_integer (value); // read image base address
2062
               image_base = (uint32_t) read_integer (value); // read image base address
2057
               if ((sep = strchr (value, '-')) != NULL) image_end       = (uint32_t) read_integer (sep + 1); // if we have a dash, read optional image end (FIXME: check this value and produce an error in the relevant case. Not important.)
2063
               if ((sep = strchr (value, '-')) != NULL) image_end       = (uint32_t) read_integer (sep + 1); // if we have a dash, read optional image end (TODO: check this value and produce an error in the relevant case. Not important.)
2058
               if ((sep = strchr (value, ',')) != NULL) image_maxsize   = (uint32_t) read_integer (sep + 1); // if we have a comma, read optional image max size
2064
               if ((sep = strchr (value, ',')) != NULL) image_maxsize   = (uint32_t) read_integer (sep + 1); // if we have a comma, read optional image max size
2059
               if ((sep = strchr (value, '=')) != NULL) image_totalsize = (uint32_t) read_integer (sep + 1); // if we have an equal sign, read optional image padding size
2065
               if ((sep = strchr (value, '=')) != NULL) image_totalsize = (uint32_t) read_integer (sep + 1); // if we have an equal sign, read optional image padding size
2060
               if ((sep = strchr (value, '%')) != NULL) image_align     = (uint32_t) read_integer (sep + 1); // if we have a modulo sign, read optional image aligmnent
2066
               if ((sep = strchr (value, '%')) != NULL) image_align     = (uint32_t) read_integer (sep + 1); // if we have a modulo sign, read optional image aligmnent
2061
               fprintf (stderr, "info: image 0x%x-0x%x maxsize %d totalsize %d align %d\n", image_base, image_end, image_maxsize, image_totalsize, image_align);
2067
               fprintf (stderr, "info: image 0x%x-0x%x maxsize %d totalsize %d align %d\n", image_base, image_end, image_maxsize, image_totalsize, image_align);
2062
            }
2068
            }
Line 2071... Line 2077...
2071
                  *sep = 0;
2077
                  *sep = 0;
2072
                  strcpy (image_processor, value); // save processor
2078
                  strcpy (image_processor, value); // save processor
2073
                  update_MKIFS_PATH (image_processor);
2079
                  update_MKIFS_PATH (image_processor);
2074
                  value = sep + 1;
2080
                  value = sep + 1;
2075
               }
2081
               }
2076
               //sprintf (image_bootfile, "%s/%s/boot/sys/%s.boot", QNX_TARGET, image_processor, value); // save preboot file name (FIXME: we should search in MKIFS_PATH instead of this. Not important.)
2082
               //sprintf (image_bootfile, "%s/%s/boot/sys/%s.boot", QNX_TARGET, image_processor, value); // save preboot file name (TODO: we should search in MKIFS_PATH instead of this. Not important.)
2077
               //strcpy (image_bootfile, bootfile_pathname); // FIXME: HACK
2083
               //strcpy (image_bootfile, bootfile_pathname); // FIXME: HACK
2078
               if (stat (bootfile_pathname, &stat_buf) != 0)
2084
               if (stat (bootfile_pathname, &stat_buf) != 0)
2079
               {
2085
               {
2080
                  fprintf (stderr, "error: unable to stat the boot file \"%s\" specified in \"%s\" line %d: %s\n", bootfile_pathname, buildfile_pathname, lineno, strerror (errno));
2086
                  fprintf (stderr, "error: unable to stat the boot file \"%s\" specified in \"%s\" line %d: %s\n", bootfile_pathname, buildfile_pathname, lineno, strerror (errno));
2081
                  exit (1);
2087
                  exit (1);