Пример #1
1
bool ElfFile::load_tables() {
  assert(m_file, "file not open");
  assert(!NullDecoder::is_error(m_status), "already in error");

  // read elf file header
  if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
    m_status = NullDecoder::file_invalid;
    return false;
  }

  if (!is_elf_file(m_elfHdr)) {
    m_status = NullDecoder::file_invalid;
    return false;
  }

  // walk elf file's section headers, and load string tables
  Elf_Shdr shdr;
  if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
    if (NullDecoder::is_error(m_status)) return false;

    for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
      if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
        m_status = NullDecoder::file_invalid;
        return false;
      }
      // string table
      if (shdr.sh_type == SHT_STRTAB) {
        ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
        if (table == NULL) {
          m_status = NullDecoder::out_of_memory;
          return false;
        }
        add_string_table(table);
      } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
        ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
        if (table == NULL) {
          m_status = NullDecoder::out_of_memory;
          return false;
        }
        add_symbol_table(table);
      }
    }
  }
  return true;
}
Пример #2
0
lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
   lib_info* newlib;
  print_debug("add_lib_info_fd %s\n", libname);

  if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
    print_debug("can't allocate memory for lib_info\n");
    return NULL;
  }

  strncpy(newlib->name, libname, sizeof(newlib->name));
  newlib->base = base;

  if (fd == -1) {
    if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
      print_debug("can't open shared object %s\n", newlib->name);
      free(newlib);
      return NULL;
    }
  } else {
    newlib->fd = fd;
  }

#ifdef __APPLE__
  // check whether we have got an Macho file.
  if (is_macho_file(newlib->fd) == false) {
    close(newlib->fd);
    free(newlib);
    print_debug("not a mach-o file\n");
    return NULL;
  }
#else
  // check whether we have got an ELF file. /proc/<pid>/map
  // gives out all file mappings and not just shared objects
  if (is_elf_file(newlib->fd) == false) {
    close(newlib->fd);
    free(newlib);
    return NULL;
  }
#endif // __APPLE__

  newlib->symtab = build_symtab(newlib->fd);
  if (newlib->symtab == NULL) {
    print_debug("symbol table build failed for %s\n", newlib->name);
  } else {
    print_debug("built symbol table for %s\n", newlib->name);
  }

  // even if symbol table building fails, we add the lib_info.
  // This is because we may need to read from the ELF file or MachO file for core file
  // address read functionality. lookup_symbol checks for NULL symtab.
  if (ph->libs) {
    ph->lib_tail->next = newlib;
    ph->lib_tail = newlib;
  }  else {
    ph->libs = ph->lib_tail = newlib;
  }
  ph->num_libs++;
  return newlib;
}
Пример #3
0
BOOL
ElfLoader::read_header()
{
	// read ELF header
	_file->read(&_eh, sizeof(Elf_Ehdr), 0);

	// check ELF Magic.
	if (!is_elf_file()) {
		DPRINTF((TEXT("not a ELF file.\n")));
		return FALSE;
	}

	// Windows CE is 32bit little-endian only.
	if (_eh.e_ident[EI_DATA] != ELFDATA2LSB ||
	    _eh.e_ident[EI_CLASS] != ELFCLASS32) {
		DPRINTF((TEXT("invalid class/data(%d/%d)\n"),
		    _eh.e_ident[EI_CLASS], _eh.e_ident[EI_DATA]));
		return FALSE;
	}

	// Is native architecture?
	switch(_eh.e_machine) {
		ELF32_MACHDEP_ID_CASES;
	default:
		DPRINTF((TEXT("not a native architecture. machine = %d\n"),
		    _eh.e_machine));
		return FALSE;
	}

	// Check object type
	if (_eh.e_type != ET_EXEC) {
		DPRINTF((TEXT("not a executable file. type = %d\n"),
		    _eh.e_type));
		return FALSE;
	}

	if (_eh.e_phoff == 0 || _eh.e_phnum == 0 || _eh.e_phnum > 16 ||
	    _eh.e_phentsize != sizeof(Elf_Phdr)) {
		DPRINTF((TEXT("invalid program header information.\n")));
		return FALSE;
	}

	return TRUE;
}
Пример #4
0
bool ElfFile::load_tables() {
  assert(m_file, "file not open");
  assert(!NullDecoder::is_error(m_status), "already in error");

  // read elf file header
  if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
    m_status = NullDecoder::file_invalid;
    return false;
  }

  if (!is_elf_file(m_elfHdr)) {
    m_status = NullDecoder::file_invalid;
    return false;
  }

  // walk elf file's section headers, and load string tables
  Elf_Shdr shdr;
  if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
    if (NullDecoder::is_error(m_status)) return false;

    for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
      if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
        m_status = NullDecoder::file_invalid;
        return false;
      }
      if (shdr.sh_type == SHT_STRTAB) {
        // string tables
        ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
        if (table == NULL) {
          m_status = NullDecoder::out_of_memory;
          return false;
        }
        add_string_table(table);
      } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
        // symbol tables
        ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
        if (table == NULL) {
          m_status = NullDecoder::out_of_memory;
          return false;
        }
        add_symbol_table(table);
      }
    }

#if defined(PPC64) && !defined(ABI_ELFv2)
    // Now read the .opd section wich contains the PPC64 function descriptor table.
    // The .opd section is only available on PPC64 (see for example:
    // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
    // so this code should do no harm on other platforms but because of performance reasons we only
    // execute it on PPC64 platforms.
    // Notice that we can only find the .opd section after we have successfully read in the string
    // tables in the previous loop, because we need to query the name of each section which is
    // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx).

    // Reset the file pointer
    if (fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
      m_status = NullDecoder::file_invalid;
      return false;
    }
    for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
      if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
        m_status = NullDecoder::file_invalid;
        return false;
      }
      if (m_elfHdr.e_shstrndx != SHN_UNDEF && shdr.sh_type == SHT_PROGBITS) {
        ElfStringTable* string_table = get_string_table(m_elfHdr.e_shstrndx);
        if (string_table == NULL) {
          m_status = NullDecoder::file_invalid;
          return false;
        }
        char buf[8]; // '8' is enough because we only want to read ".opd"
        if (string_table->string_at(shdr.sh_name, buf, sizeof(buf)) && !strncmp(".opd", buf, 4)) {
          m_funcDesc_table = new (std::nothrow) ElfFuncDescTable(m_file, shdr, index);
          if (m_funcDesc_table == NULL) {
            m_status = NullDecoder::out_of_memory;
            return false;
          }
          break;
        }
      }
    }
#endif

  }
  return true;
}