* Parse a binary message. */
| 129 | * Parse a binary message. |
| 130 | */ |
| 131 | static Binary *parseBinary(const Message &msg) |
| 132 | { |
| 133 | const char *filename = nullptr, *version = nullptr; |
| 134 | Mode mode = MODE_ELF_EXE; |
| 135 | bool have_mode = false, dup = false; |
| 136 | for (unsigned i = 0; i < msg.num_params; i++) |
| 137 | { |
| 138 | switch (msg.params[i].name) |
| 139 | { |
| 140 | case PARAM_FILENAME: |
| 141 | dup = dup || (filename != nullptr); |
| 142 | filename = msg.params[i].value.string; |
| 143 | break; |
| 144 | case PARAM_MODE: |
| 145 | dup = dup || have_mode; |
| 146 | mode = (Mode)msg.params[i].value.integer; |
| 147 | have_mode = true; |
| 148 | break; |
| 149 | case PARAM_VERSION: |
| 150 | dup = dup || (version != nullptr); |
| 151 | version = msg.params[i].value.string; |
| 152 | break; |
| 153 | default: |
| 154 | break; |
| 155 | } |
| 156 | } |
| 157 | if (filename == nullptr) |
| 158 | error("failed to parse \"binary\" message (id=%u); missing " |
| 159 | "\"filename\" parameter", msg.id); |
| 160 | if (version == nullptr) |
| 161 | error("failed to parse \"binary\" message (id=%u); missing " |
| 162 | "\"version\" parameter", msg.id); |
| 163 | if (strcmp(version, STRING(VERSION)) != 0) |
| 164 | error("failed to parse \"binary\" message (id=%u); invalid " |
| 165 | "version \"%s\"; expected \"%s\"", msg.id, version, |
| 166 | STRING(VERSION)); |
| 167 | if (dup) |
| 168 | error("failed to parse \"binary\" message (id=%u); duplicate " |
| 169 | "parameters detected", msg.id); |
| 170 | |
| 171 | Binary *B = new Binary; |
| 172 | B->filename = filename; |
| 173 | B->output = nullptr; |
| 174 | B->mode = mode; |
| 175 | B->cursor = INTPTR_MAX; |
| 176 | |
| 177 | // Open the binary: |
| 178 | int fd = open(filename, O_RDONLY); |
| 179 | if (fd < 0) |
| 180 | error("failed to open file \"%s\" for reading: %s", filename, |
| 181 | strerror(errno)); |
| 182 | |
| 183 | // Determine the binary size: |
| 184 | struct stat buf; |
| 185 | if (fstat(fd, &buf) < 0) |
| 186 | error("failed to get length of file \"%s\": %s", filename, |
| 187 | strerror(errno)); |
| 188 | size_t size = (size_t)buf.st_size; |