(self, elffile: ELFFile, mem_start: int)
| 438 | raise QlErrorELFFormat('invalid module: symbol init_module not found') |
| 439 | |
| 440 | def lkm_dynlinker(self, elffile: ELFFile, mem_start: int) -> Mapping[str, int]: |
| 441 | def __get_symbol(name: str) -> Optional[Symbol]: |
| 442 | _symtab = elffile.get_section_by_name('.symtab') |
| 443 | _sym = _symtab.get_symbol_by_name(name) |
| 444 | |
| 445 | return _sym[0] if _sym else None |
| 446 | |
| 447 | ql = self.ql |
| 448 | |
| 449 | all_symbols = [] |
| 450 | self.ql.os.hook_addr = API_HOOK_MEM |
| 451 | # map address to symbol name |
| 452 | self.import_symbols = {} |
| 453 | # reverse dictionary to map symbol name -> address |
| 454 | rev_reloc_symbols = {} |
| 455 | |
| 456 | rh = RelocationHandler(elffile) |
| 457 | sections = [sec for sec in elffile.iter_sections() if sec['sh_flags'] & SH_FLAGS.SHF_ALLOC] |
| 458 | |
| 459 | for sec in sections: |
| 460 | reloc_sec = rh.find_relocations_for_section(sec) |
| 461 | |
| 462 | if reloc_sec and reloc_sec.name != '.rela.gnu.linkonce.this_module': |
| 463 | # get the symbol table section pointed in sh_link |
| 464 | symtab = elffile.get_section(reloc_sec['sh_link']) |
| 465 | assert isinstance(symtab, SymbolTableSection) |
| 466 | |
| 467 | for rel in reloc_sec.iter_relocations(): |
| 468 | # if reloc['r_info_sym'] == 0: |
| 469 | # continue |
| 470 | |
| 471 | symbol = symtab.get_symbol(rel['r_info_sym']) |
| 472 | assert symbol |
| 473 | |
| 474 | # Some symbols have zero 'st_name', so instead what's used is |
| 475 | # the name of the section they point at. |
| 476 | if symbol['st_name'] == 0: |
| 477 | symsec = elffile.get_section(symbol['st_shndx']) |
| 478 | symbol_name = symsec.name |
| 479 | sym_offset = symsec['sh_offset'] |
| 480 | |
| 481 | rev_reloc_symbols[symbol_name] = sym_offset + mem_start |
| 482 | else: |
| 483 | symbol_name = symbol.name |
| 484 | # get info about related section to be patched |
| 485 | info_section = elffile.get_section(reloc_sec['sh_info']) |
| 486 | sym_offset = info_section['sh_offset'] |
| 487 | |
| 488 | if symbol_name in all_symbols: |
| 489 | sym_offset = rev_reloc_symbols[symbol_name] - mem_start |
| 490 | else: |
| 491 | all_symbols.append(symbol_name) |
| 492 | _symbol = __get_symbol(symbol_name) |
| 493 | |
| 494 | if _symbol['st_shndx'] == 'SHN_UNDEF': |
| 495 | # external symbol |
| 496 | # only save symbols of APIs |
| 497 |
no test coverage detected