// -*- mode: c++ -*-

// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// The DwarfLineToModule class accepts line number information from a
// DWARF parser and adds it to a google_breakpad::Module. The Module
// can write that data out as a Breakpad symbol file.

#ifndef COMMON_LINUX_DWARF_LINE_TO_MODULE_H
#define COMMON_LINUX_DWARF_LINE_TO_MODULE_H

#include <string>

#include "common/module.h"
#include "common/dwarf/dwarf2reader.h"
#include "common/using_std_string.h"

namespace google_breakpad {

// A class for producing a vector of google_breakpad::Module::Line
// instances from parsed DWARF line number data.  
//
// An instance of this class can be provided as a handler to a
// dwarf2reader::LineInfo DWARF line number information parser. The
// handler accepts source location information from the parser and
// uses it to produce a vector of google_breakpad::Module::Line
// objects, referring to google_breakpad::Module::File objects added
// to a particular google_breakpad::Module.
//
// GNU toolchain omitted sections support:
// ======================================
//
// Given the right options, the GNU toolchain will omit unreferenced
// functions from the final executable. Unfortunately, when it does so, it
// does not remove the associated portions of the DWARF line number
// program; instead, it gives the DW_LNE_set_address instructions referring
// to the now-deleted code addresses of zero. Given this input, the DWARF
// line parser will call AddLine with a series of lines starting at address
// zero. For example, here is the output from 'readelf -wl' for a program
// with four functions, the first three of which have been omitted:
//
//   Line Number Statements:
//    Extended opcode 2: set Address to 0x0
//    Advance Line by 14 to 15
//    Copy
//    Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 16
//    Special opcode 119: advance Address by 8 to 0xb and Line by 2 to 18
//    Advance PC by 2 to 0xd
//    Extended opcode 1: End of Sequence
// 
//    Extended opcode 2: set Address to 0x0
//    Advance Line by 14 to 15
//    Copy
//    Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 16
//    Special opcode 119: advance Address by 8 to 0xb and Line by 2 to 18
//    Advance PC by 2 to 0xd
//    Extended opcode 1: End of Sequence
// 
//    Extended opcode 2: set Address to 0x0
//    Advance Line by 19 to 20
//    Copy
//    Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 21
//    Special opcode 76: advance Address by 5 to 0x8 and Line by 1 to 22
//    Advance PC by 2 to 0xa
//    Extended opcode 1: End of Sequence
// 
//    Extended opcode 2: set Address to 0x80483a4
//    Advance Line by 23 to 24
//    Copy
//    Special opcode 202: advance Address by 14 to 0x80483b2 and Line by 1 to 25
//    Special opcode 76: advance Address by 5 to 0x80483b7 and Line by 1 to 26
//    Advance PC by 6 to 0x80483bd
//    Extended opcode 1: End of Sequence
//
// Instead of collecting runs of lines describing code that is not there,
// we try to recognize and drop them. Since the linker doesn't explicitly
// distinguish references to dropped sections from genuine references to
// code at address zero, we must use a heuristic. We have chosen:
//
// - If a line starts at address zero, omit it. (On the platforms
//   breakpad targets, it is extremely unlikely that there will be code
//   at address zero.)
//
// - If a line starts immediately after an omitted line, omit it too.
class DwarfLineToModule: public dwarf2reader::LineInfoHandler {
 public:
  // As the DWARF line info parser passes us line records, add source
  // files to MODULE, and add all lines to the end of LINES. LINES
  // need not be empty. If the parser hands us a zero-length line, we
  // omit it. If the parser hands us a line that extends beyond the
  // end of the address space, we clip it. It's up to our client to
  // sort out which lines belong to which functions; we don't add them
  // to any particular function in MODULE ourselves.
  DwarfLineToModule(Module *module, const string& compilation_dir,
                    vector<Module::Line>* lines)
      : module_(module),
        compilation_dir_(compilation_dir),
        lines_(lines),
        highest_file_number_(-1),
        omitted_line_end_(0),
        warned_bad_file_number_(false),
        warned_bad_directory_number_(false) { }
  
  ~DwarfLineToModule() { }

  void DefineDir(const string& name, uint32_t dir_num);
  void DefineFile(const string& name, int32_t file_num,
                  uint32_t dir_num, uint64_t mod_time,
                  uint64_t length);
  void AddLine(uint64_t address, uint64_t length,
               uint32_t file_num, uint32_t line_num, uint32_t column_num);

 private:

  typedef std::map<uint32_t, string> DirectoryTable;
  typedef std::map<uint32_t, Module::File*> FileTable;

  // The module we're contributing debugging info to. Owned by our
  // client.
  Module *module_;

  // The compilation directory for the current compilation unit whose
  // lines are being accumulated.
  string compilation_dir_;

  // The vector of lines we're accumulating. Owned by our client.
  //
  // In a Module, as in a breakpad symbol file, lines belong to
  // specific functions, but DWARF simply assigns lines to addresses;
  // one must infer the line/function relationship using the
  // functions' beginning and ending addresses. So we can't add these
  // to the appropriate function from module_ until we've read the
  // function info as well. Instead, we accumulate lines here, and let
  // whoever constructed this sort it all out.
  vector<Module::Line>* lines_;

  // A table mapping directory numbers to paths.
  DirectoryTable directories_;

  // A table mapping file numbers to Module::File pointers.
  FileTable files_;

  // The highest file number we've seen so far, or -1 if we've seen
  // none.  Used for dynamically defined file numbers.
  int32_t highest_file_number_;
  
  // This is the ending address of the last line we omitted, or zero if we
  // didn't omit the previous line. It is zero before we have received any
  // AddLine calls.
  uint64_t omitted_line_end_;

  // True if we've warned about:
  bool warned_bad_file_number_; // bad file numbers
  bool warned_bad_directory_number_; // bad directory numbers
};

} // namespace google_breakpad

#endif // COMMON_LINUX_DWARF_LINE_TO_MODULE_H
