if image length is a power of 2, use binary search */
| 95 | |
| 96 | /* if image length is a power of 2, use binary search */ |
| 97 | static long fmap_bsearch(const uint8_t *image, size_t len) |
| 98 | { |
| 99 | unsigned long offset; |
| 100 | int fmap_found = 0, stride; |
| 101 | |
| 102 | /* |
| 103 | * For efficient operation, we start with the largest stride possible |
| 104 | * and then decrease the stride on each iteration. Also, check for a |
| 105 | * remainder when modding the offset with the previous stride. This |
| 106 | * makes it so that each offset is only checked once. |
| 107 | */ |
| 108 | for (stride = len / 2; stride >= 16; stride /= 2) { |
| 109 | if (fmap_found) |
| 110 | break; |
| 111 | |
| 112 | for (offset = 0; |
| 113 | offset < len - strlen(FMAP_SIGNATURE); |
| 114 | offset += stride) { |
| 115 | if ((offset % (stride * 2) == 0) && (offset != 0)) |
| 116 | continue; |
| 117 | if (is_valid_fmap( |
| 118 | (const struct fmap *)&image[offset])) { |
| 119 | fmap_found = 1; |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | if (!fmap_found) |
| 126 | return -1; |
| 127 | |
| 128 | if (offset + fmap_size((const struct fmap *)&image[offset]) > len) |
| 129 | return -1; |
| 130 | |
| 131 | return offset; |
| 132 | } |
| 133 | |
| 134 | static int popcnt(unsigned int u) |
| 135 | { |
no test coverage detected