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 ( |
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 ( |
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 ( |
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 ( |
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 ( |
1956 | fprintf (fp, "ifstool - QNX in-kernel filesystem creation utility by Pierre-Marie Baty <pm@pmbaty.com>\n"); |
1951 | fprintf ( |
1957 | fprintf (fp, " version " VERSION_FMT_YYYYMMDD "\n", VERSION_ARG_YYYYMMDD); |
1952 | if (!want_help) |
1958 | if (!want_help) |
1953 | fprintf ( |
1959 | fprintf (fp, "error: missing parameters\n"); |
1954 | fprintf ( |
1960 | fprintf (fp, "usage:\n"); |
1955 | fprintf ( |
1961 | fprintf (fp, " ifstool [--bootfile <pathname>] [--startupfile <pathname>@<EP_from_imgbase>] [--kernelfile <pathname>@<fileoffs>] [-n[n]] <buildfile> <outfile>\n"); |
1956 | fprintf ( |
1962 | fprintf (fp, " ifstool --info [--everything] <ifs file>\n"); |
1957 | fprintf ( |
1963 | fprintf (fp, " ifstool --help\n"); |
1958 | fprintf ( |
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 ( |
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 ( |
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); |