Exemplo n.º 1
0
def _OutputOrderfile(offsets, offset_to_symbol_infos, symbol_to_section_map,
                     output_file):
    """Outputs the orderfile to output_file.

  Args:
    offsets: Iterable of offsets to match to section names
    offset_to_symbol_infos: {offset: [SymbolInfo]}
    symbol_to_section_map: {name: section}
    output_file: file-like object to write the results to
  """
    success = True
    unknown_symbol_warnings = cygprofile_utils.WarningCollector(300)
    symbol_not_found_warnings = cygprofile_utils.WarningCollector(300)
    output_sections = set()
    for offset in offsets:
        try:
            symbol_infos = _FindSymbolInfosAtOffset(offset_to_symbol_infos,
                                                    offset)
            for symbol_info in symbol_infos:
                if symbol_info.name in symbol_to_section_map:
                    section = symbol_to_section_map[symbol_info.name]
                    if not section in output_sections:
                        output_file.write(section + '\n')
                        output_sections.add(section)
                else:
                    unknown_symbol_warnings.Write(
                        'No known section for symbol ' + symbol_info.name)
        except SymbolNotFoundException:
            symbol_not_found_warnings.Write(
                'Did not find function in binary. offset: ' + hex(offset))
            success = False
    unknown_symbol_warnings.WriteEnd('no known section for symbol.')
    symbol_not_found_warnings.WriteEnd('symbol not found in the binary.')
    return success
Exemplo n.º 2
0
def CreateNameToSymbolInfo(symbol_infos):
  """Create a dict {name: symbol_info, ...}.

  Args:
    symbol_infos: iterable of SymbolInfo instances

  Returns:
    a dict {name: symbol_info, ...}
    If a symbol name corresponds to more than one symbol_info, the symbol_info
    with the lowest offset is chosen.
  """
  # TODO(lizeb,pasko): move the functionality in this method into
  # check_orderfile.
  symbol_infos_by_name = {}
  warnings = cygprofile_utils.WarningCollector(_MAX_WARNINGS_TO_PRINT)
  for infos in GroupSymbolInfosByName(symbol_infos).itervalues():
    first_symbol_info = min(infos, key=lambda x:x.offset)
    symbol_infos_by_name[first_symbol_info.name] = first_symbol_info
    if len(infos) > 1:
      warnings.Write('Symbol %s appears at %d offsets: %s' %
                     (first_symbol_info.name,
                      len(infos),
                      ','.join([hex(x.offset) for x in infos])))
  warnings.WriteEnd('symbols at multiple offsets.')
  return symbol_infos_by_name
Exemplo n.º 3
0
def _GetSymbolToSectionMapFromObjectFiles(obj_dir):
    """ Creates a mapping from symbol to linker section name by scanning all
      the object files.
  """
    object_files = _GetObjectFileNames(obj_dir)
    symbol_to_section_map = {}
    symbol_warnings = cygprofile_utils.WarningCollector(300)
    symbol_infos = _AllSymbolInfos(object_files)
    for symbol_info in symbol_infos:
        symbol = symbol_info.name
        if symbol.startswith('.LTHUNK'):
            continue
        section = symbol_info.section
        if ((symbol in symbol_to_section_map)
                and (symbol_to_section_map[symbol] != symbol_info.section)):
            symbol_warnings.Write('Symbol ' + symbol +
                                  ' in conflicting sections ' + section +
                                  ' and ' + symbol_to_section_map[symbol])
        elif not section.startswith('.text'):
            symbol_warnings.Write('Symbol ' + symbol +
                                  ' in incorrect section ' + section)
        else:
            symbol_to_section_map[symbol] = section
    symbol_warnings.WriteEnd('bad sections')
    return symbol_to_section_map
Exemplo n.º 4
0
    def GetOrderedSections(self, offsets):
        """Get ordered list of sections corresponding to offsets.

    Args:
      offsets ([int]) dump offsets, from same build as parameters to __init__.

    Returns:
      [str] ordered list of sections suitable for use as an orderfile, or
            None if failure.
    """
        symbol_to_sections = self._obj_processor.GetSymbolToSectionsMap()
        if not symbol_to_sections:
            logging.error('No symbol section names found')
            return None
        unknown_symbol_warnings = cygprofile_utils.WarningCollector(300)
        symbol_not_found_errors = cygprofile_utils.WarningCollector(
            300, level=logging.ERROR)
        seen_sections = set()
        ordered_sections = []
        success = True
        for offset in offsets:
            try:
                symbol_infos = self._SymbolsAtOffset(offset)
                for symbol_info in symbol_infos:
                    if symbol_info.name in symbol_to_sections:
                        sections = symbol_to_sections[symbol_info.name]
                        for section in sections:
                            if not section in seen_sections:
                                ordered_sections.append(section)
                                seen_sections.add(section)
                    else:
                        unknown_symbol_warnings.Write(
                            'No known section for symbol ' + symbol_info.name)
            except _SymbolNotFoundException:
                symbol_not_found_errors.Write(
                    'Did not find function in binary. offset: ' + hex(offset))
                success = False
        unknown_symbol_warnings.WriteEnd('no known section for symbol.')
        symbol_not_found_errors.WriteEnd('symbol not found in the binary.')
        if not success:
            return None
        return ordered_sections
Exemplo n.º 5
0
def GetSymbolToSectionsMapFromObjectFiles(obj_dir):
    """Scans object files to create a {symbol: linker section(s)} map.

  Args:
    obj_dir: The root of the output object file directory, which will be
             scanned for .o files to form the mapping.

  Returns:
    A map {symbol_name: [section_name1, section_name2...]}
  """
    object_files = GetObjectFileNames(obj_dir)
    symbol_to_sections_map = {}
    symbol_warnings = cygprofile_utils.WarningCollector(300)
    symbol_infos = _AllSymbolInfos(object_files)
    for symbol_info in symbol_infos:
        symbol = symbol_info.name
        if symbol.startswith('.LTHUNK'):
            continue
        section = symbol_info.section
        if ((symbol in symbol_to_sections_map) and
            (symbol_info.section not in symbol_to_sections_map[symbol])):
            symbol_to_sections_map[symbol].append(section)

            if not _SameCtorOrDtorNames(
                    symbol,
                    symbol_to_sections_map[symbol][0].lstrip('.text.')):
                symbol_warnings.Write(
                    'Symbol ' + symbol +
                    ' unexpectedly in more than one section: ' +
                    ', '.join(symbol_to_sections_map[symbol]))
        elif not section.startswith('.text.'):
            # Assembly functions have section ".text". These are all grouped together
            # near the end of the orderfile via an explicit ".text" entry.
            if section != '.text':
                symbol_warnings.Write('Symbol ' + symbol +
                                      ' in incorrect section ' + section)
        else:
            # In most cases we expect just one item in this list, and maybe 4 or so in
            # the worst case.
            symbol_to_sections_map[symbol] = [section]
    symbol_warnings.WriteEnd('bad sections')
    return symbol_to_sections_map
Exemplo n.º 6
0
    def GetSymbolToSectionsMap(self):
        """Scans object files to find symbol section names.

    Returns:
      {symbol: linker section(s)}
    """
        if self._symbol_to_sections_map is not None:
            return self._symbol_to_sections_map

        symbol_infos = self._GetAllSymbolInfos()
        self._symbol_to_sections_map = {}
        symbol_warnings = cygprofile_utils.WarningCollector(300)
        for symbol_info in symbol_infos:
            symbol = symbol_info.name
            if symbol.startswith('.LTHUNK'):
                continue
            section = symbol_info.section
            if ((symbol in self._symbol_to_sections_map)
                    and (symbol_info.section
                         not in self._symbol_to_sections_map[symbol])):
                self._symbol_to_sections_map[symbol].append(section)

                if not self._SameCtorOrDtorNames(
                        symbol, self._symbol_to_sections_map[symbol][0].lstrip(
                            '.text.')):
                    symbol_warnings.Write(
                        'Symbol ' + symbol +
                        ' unexpectedly in more than one section: ' +
                        ', '.join(self._symbol_to_sections_map[symbol]))
            elif not section.startswith('.text.'):
                # Assembly functions have section ".text". These are all grouped
                # together near the end of the orderfile via an explicit ".text" entry.
                if section != '.text':
                    symbol_warnings.Write('Symbol ' + symbol +
                                          ' in incorrect section ' + section)
            else:
                # In most cases we expect just one item in this list, and maybe 4 or so
                # in the worst case.
                self._symbol_to_sections_map[symbol] = [section]
        symbol_warnings.WriteEnd('bad sections')
        return self._symbol_to_sections_map