Exemple #1
0
//--------------------------------------------------------------------------
//lint -e{1764} could be declared const ref
static int handle_symbol(
        reader_t &reader,
        int shndx,
        int _info,
        uint32 st_name,
        uval_t st_value,
        int namsec,
        symbol_visitor_t &sv)
{
  if ( shndx == SHN_UNDEF
    || shndx == SHN_LOPROC
    || shndx == SHN_HIPROC
    || shndx == SHN_ABS )
  {
    return 0;
  }

  int type = ELF_ST_TYPE(_info);
  if ( type != STT_OBJECT && type != STT_FUNC )
    return 0;

  if ( st_name == 0 )
    return 0;

  if ( imagebase != uval_t(-1) )
    st_value -= imagebase;

  qstring name;
  reader.sections.get_name(&name, namsec, st_name);
  return sv.visit_symbol(st_value, name.c_str());
}
//--------------------------------------------------------------------------
//parse a mach-o file image in memory and enumerate its segments and symbols
bool parse_macho(ea_t start, linput_t *li, symbol_visitor_t &sv, bool in_mem)
{
  macho_file_t mfile(li);

  if ( !mfile.parse_header()
    || !mfile.select_subfile(CPUTYPE) )
  {
    msg("Warning: bad file or could not find a member with matching cpu type\n");
    return false;
  }

  // load sections
  const secvec_t &sections   = mfile.get_sections();
  const segcmdvec_t &segcmds = mfile.get_segcmds();

  ea_t expected_base = BADADDR;
  for ( size_t i=0; i < segcmds.size(); i++ )
  {
    const segment_command_64 &sg = segcmds[i];
    if ( is_text_segment(sg) && expected_base == BADADDR )
    {
      expected_base = sg.vmaddr;
      break;
    }
  }

  if ( expected_base == BADADDR )
    return false;

  sval_t slide = start - expected_base;

  // msg("%a: expected base is %a; in_mem = %d\n", start, expected_base, in_mem);

  if ( (sv.velf & VISIT_SEGMENTS) != 0 )
  {
    for ( size_t i=0; i < segcmds.size(); i++ )
    {
      const segment_command_64 &sg = segcmds[i];
      if ( sg.nsects == 0 )
        sv.visit_segment(sg.vmaddr + slide, sg.vmsize, sg.segname);
    }
    for ( size_t i=0; i < sections.size(); i++ )
    {
      const section_64 &sect = sections[i];
      sv.visit_segment(sect.addr + slide, sect.size, sect.sectname);
    }
  }

  if ( (sv.velf & VISIT_SYMBOLS) != 0 )
  {
    nlistvec_t symbols;
    qstring strings;
    mfile.get_symbol_table_info(symbols, strings, in_mem);

    // msg("%a: loaded %ld symbols and %ld string bytes\n", start, symbols.size(), strings.size());

    for ( size_t i=0; i < symbols.size(); i++ )
    {
      const struct nlist_64 &nl = symbols[i];
      if ( nl.n_un.n_strx > strings.size() )
        continue;
      const char *name = &strings[nl.n_un.n_strx];

      ea_t ea;
      int type = nl.n_type & N_TYPE;
      switch ( type )
      {
        case N_UNDF:
        case N_PBUD:
        case N_ABS:
          break;
        case N_SECT:
        case N_INDR:
          ea = nl.n_value + slide;
          if ( name[0] != '\0' )
          {
            if ( (nl.n_type & (N_EXT|N_PEXT)) == N_EXT ) // exported
            {
              sv.visit_symbol(ea, name);
            }
            else if ( type == N_SECT && nl.n_sect != NO_SECT ) // private symbols
            {
              sv.visit_symbol(ea, name);
            }
          }
          break;
      }
    }
  }
  return true;
}