* Parse an exclusion. */
| 291 | * Parse an exclusion. |
| 292 | */ |
| 293 | static Exclude parseExcludeBound(Parser &parser, const char *str, |
| 294 | const ELF &elf) |
| 295 | { |
| 296 | Exclude bound = {INTPTR_MAX, INTPTR_MIN}; |
| 297 | int t = parser.getToken(); |
| 298 | bool neg = false; |
| 299 | switch (t) |
| 300 | { |
| 301 | case '-': |
| 302 | neg = true; |
| 303 | // Fallthrough: |
| 304 | case '+': |
| 305 | parser.expectToken(TOKEN_INTEGER); |
| 306 | // Fallthrough: |
| 307 | case TOKEN_INTEGER: |
| 308 | { |
| 309 | intptr_t b = (neg? -parser.i: parser.i); |
| 310 | bound = {b, b}; |
| 311 | break; |
| 312 | } |
| 313 | case '&': |
| 314 | t = parser.getToken(); |
| 315 | // Fallthrough: |
| 316 | default: |
| 317 | { |
| 318 | std::string name; |
| 319 | if (t == '.') |
| 320 | { |
| 321 | t = parser.getToken(); |
| 322 | name += '.'; |
| 323 | } |
| 324 | if (t != TOKEN_STRING && t != TOKEN_NAME) |
| 325 | parser.unexpectedToken(); |
| 326 | name += parser.s; |
| 327 | const Elf64_Shdr *shdr = getELFSection(&elf, name.c_str()); |
| 328 | if (shdr != nullptr) |
| 329 | { |
| 330 | bound = {elf.base + (intptr_t)shdr->sh_addr, |
| 331 | elf.base + (intptr_t)shdr->sh_addr + |
| 332 | (intptr_t)shdr->sh_size}; |
| 333 | break; |
| 334 | } |
| 335 | const Elf64_Sym *sym = getELFDynSym(&elf, name.c_str()); |
| 336 | if (sym == nullptr) |
| 337 | sym = getELFSym(&elf, name.c_str()); |
| 338 | if (sym != nullptr && sym->st_shndx != SHN_UNDEF) |
| 339 | { |
| 340 | bound = {elf.base + (intptr_t)sym->st_value, |
| 341 | elf.base + (intptr_t)sym->st_value}; |
| 342 | break; |
| 343 | } |
| 344 | |
| 345 | intptr_t val = getELFPLTEntry(&elf, name.c_str()); |
| 346 | if (val != INTPTR_MIN) |
| 347 | { |
| 348 | bound = {val, val}; |
| 349 | break; |
| 350 | } |
no test coverage detected