// Returns the address of the program header table as it appears in the loaded // segments in memory. This is in contrast with 'phdr_table_' which // is temporary and will be released before the library is relocated. bool ElfLoader::FindPhdr(Error* error) { const ELF::Phdr* phdr_limit = phdr_table_ + phdr_num_; // If there is a PT_PHDR, use it directly. for (const ELF::Phdr* phdr = phdr_table_; phdr < phdr_limit; ++phdr) { if (phdr->p_type == PT_PHDR) { return CheckPhdr(load_bias_ + phdr->p_vaddr, error); } } // Otherwise, check the first loadable segment. If its file offset // is 0, it starts with the ELF header, and we can trivially find the // loaded program header from it. for (const ELF::Phdr* phdr = phdr_table_; phdr < phdr_limit; ++phdr) { if (phdr->p_type == PT_LOAD) { if (phdr->p_offset == 0) { ELF::Addr elf_addr = load_bias_ + phdr->p_vaddr; const ELF::Ehdr* ehdr = (const ELF::Ehdr*)(void*)elf_addr; ELF::Addr offset = ehdr->e_phoff; return CheckPhdr((ELF::Addr)ehdr + offset, error); } break; } } error->Set("Can't find loaded program header"); return false; }
// Returns the address of the program header table as it appears in the loaded // segments in memory. This is in contrast with 'phdr_table_' which // is temporary and will be released before the library is relocated. bool ElfReader::FindPhdr() { const Elf32_Phdr* phdr_limit = phdr_table_ + phdr_num_; // If there is a PT_PHDR, use it directly. for (const Elf32_Phdr* phdr = phdr_table_; phdr < phdr_limit; ++phdr) { if (phdr->p_type == PT_PHDR) { return CheckPhdr(load_bias_ + phdr->p_vaddr); } } // Otherwise, check the first loadable segment. If its file offset // is 0, it starts with the ELF header, and we can trivially find the // loaded program header from it. for (const Elf32_Phdr* phdr = phdr_table_; phdr < phdr_limit; ++phdr) { if (phdr->p_type == PT_LOAD) { if (phdr->p_offset == 0) { Elf32_Addr elf_addr = load_bias_ + phdr->p_vaddr; const Elf32_Ehdr* ehdr = (const Elf32_Ehdr*)(void*)elf_addr; Elf32_Addr offset = ehdr->e_phoff; return CheckPhdr((Elf32_Addr)ehdr + offset); } break; } } DL_ERR("can't find loaded phdr for \"%s\"", name_); return false; }