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); |