pick a plausible-looking section name derived from the blob bytes
| 32 | |
| 33 | // pick a plausible-looking section name derived from the blob bytes |
| 34 | std::string pick_section_name(Span<std::uint8_t> blob) { |
| 35 | static constexpr const char* kPrefixes[] = { |
| 36 | ".text", ".code", ".CODE", ".init", ".text0", |
| 37 | }; |
| 38 | constexpr std::size_t n_pre = sizeof(kPrefixes) / sizeof(kPrefixes[0]); |
| 39 | static constexpr char kSfxChars[] = "abcdefghijklmnopqrstuvwxyz0123456789"; |
| 40 | constexpr std::size_t n_sfx = sizeof(kSfxChars) - 1; |
| 41 | |
| 42 | // fnv-1a over the blob. |
| 43 | std::uint64_t h = 0xcbf29ce484222325ULL; |
| 44 | for (std::size_t i = 0; i < blob.size; ++i) { |
| 45 | h ^= static_cast<std::uint64_t>(blob[i]); |
| 46 | h *= 0x100000001b3ULL; |
| 47 | } |
| 48 | |
| 49 | std::string out(kPrefixes[splitmix64_step(h) % n_pre]); |
| 50 | |
| 51 | // ~25% get the msvc-linker '$' group marker shape. |
| 52 | if ((splitmix64_step(h) & 0x3) == 0 && out.size() + 2 <= 8) { |
| 53 | out += '$'; |
| 54 | } |
| 55 | |
| 56 | const std::size_t slots = 8 - out.size(); |
| 57 | if (slots == 0) return out; |
| 58 | const std::size_t want = 1 + (splitmix64_step(h) % std::min<std::size_t>(slots, 3)); |
| 59 | |
| 60 | for (std::size_t i = 0; i < want; ++i) { |
| 61 | out += kSfxChars[splitmix64_step(h) % n_sfx]; |
| 62 | } |
| 63 | |
| 64 | return out; |
| 65 | } |
| 66 | |
| 67 | std::vector<std::uint8_t> read_file_bytes(const std::string& path) { |
| 68 | std::ifstream in(path, std::ios::binary | std::ios::ate); |
no test coverage detected