// 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>

// module_unittest.cc: Unit tests for google_breakpad::Module.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <sstream>
#include <string>

#include "breakpad_googletest_includes.h"
#include "common/module.h"
#include "common/using_std_string.h"

using google_breakpad::Module;
using std::stringstream;
using std::vector;
using testing::ContainerEq;

static Module::Function* generate_duplicate_function(const string& name) {
  const Module::Address DUP_ADDRESS = 0xd35402aac7a7ad5cULL;
  const Module::Address DUP_SIZE = 0x200b26e605f99071ULL;
  const Module::Address DUP_PARAMETER_SIZE = 0xf14ac4fed48c4a99ULL;

  Module::Function* function = new Module::Function(name, DUP_ADDRESS);
  Module::Range range(DUP_ADDRESS, DUP_SIZE);
  function->ranges.push_back(range);
  function->parameter_size = DUP_PARAMETER_SIZE;
  return function;
}

#define MODULE_NAME "name with spaces"
#define MODULE_OS "os-name"
#define MODULE_ARCH "architecture"
#define MODULE_ID "id-string"
#define MODULE_CODE_ID "code-id-string"

TEST(Write, Header) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n",
               contents.c_str());
}

TEST(Write, HeaderCodeId) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID, MODULE_CODE_ID);
  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "INFO CODE_ID code-id-string\n",
               contents.c_str());
}

TEST(Write, OneLineFunc) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  Module::File* file = m.FindFile("file_name.cc");
  Module::Function* function = new Module::Function(
      "function_name", 0xe165bf8023b9d9abULL);
  Module::Range range(0xe165bf8023b9d9abULL, 0x1e4bb0eb1cbf5b09ULL);
  function->ranges.push_back(range);
  function->parameter_size = 0x772beee89114358aULL;
  Module::Line line = { 0xe165bf8023b9d9abULL, 0x1e4bb0eb1cbf5b09ULL,
                        file, 67519080 };
  function->lines.push_back(line);
  m.AddFunction(function);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FILE 0 file_name.cc\n"
               "FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a"
               " function_name\n"
               "e165bf8023b9d9ab 1e4bb0eb1cbf5b09 67519080 0\n",
               contents.c_str());
}

TEST(Write, RelativeLoadAddress) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Some source files.  We will expect to see them in lexicographic order.
  Module::File* file1 = m.FindFile("filename-b.cc");
  Module::File* file2 = m.FindFile("filename-a.cc");

  // A function.
  Module::Function* function = new Module::Function(
      "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)", 0xbec774ea5dd935f3ULL);
  Module::Range range(0xbec774ea5dd935f3ULL, 0x2922088f98d3f6fcULL);
  function->ranges.push_back(range);
  function->parameter_size = 0xe5e9aa008bd5f0d0ULL;

  // Some source lines.  The module should not sort these.
  Module::Line line1 = { 0xbec774ea5dd935f3ULL, 0x1c2be6d6c5af2611ULL,
                         file1, 41676901 };
  Module::Line line2 = { 0xdaf35bc123885c04ULL, 0xcf621b8d324d0ebULL,
                         file2, 67519080 };
  function->lines.push_back(line2);
  function->lines.push_back(line1);

  m.AddFunction(function);

  // Some stack information.
  Module::StackFrameEntry* entry = new Module::StackFrameEntry();
  entry->address = 0x30f9e5c83323973dULL;
  entry->size = 0x49fc9ca7c7c13dc2ULL;
  entry->initial_rules[".cfa"] = "he was a handsome man";
  entry->initial_rules["and"] = "what i want to know is";
  entry->rule_changes[0x30f9e5c83323973eULL]["how"] =
    "do you like your blueeyed boy";
  entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = "Death";
  m.AddStackFrameEntry(entry);

  // Set the load address.  Doing this after adding all the data to
  // the module must work fine.
  m.SetLoadAddress(0x2ab698b0b6407073ULL);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FILE 0 filename-a.cc\n"
               "FILE 1 filename-b.cc\n"
               "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0"
               " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n"
               "b03cc3106d47eb91 cf621b8d324d0eb 67519080 0\n"
               "9410dc39a798c580 1c2be6d6c5af2611 41676901 1\n"
               "STACK CFI INIT 6434d177ce326ca 49fc9ca7c7c13dc2"
               " .cfa: he was a handsome man"
               " and: what i want to know is\n"
               "STACK CFI 6434d177ce326cb"
               " Mister: Death"
               " how: do you like your blueeyed boy\n",
               contents.c_str());
}

TEST(Write, OmitUnusedFiles) {
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Create some source files.
  Module::File* file1 = m.FindFile("filename1");
  m.FindFile("filename2");  // not used by any line
  Module::File* file3 = m.FindFile("filename3");

  // Create a function.
  Module::Function* function = new Module::Function(
      "function_name", 0x9b926d464f0b9384ULL);
  Module::Range range(0x9b926d464f0b9384ULL, 0x4f524a4ba795e6a6ULL);
  function->ranges.push_back(range);
  function->parameter_size = 0xbbe8133a6641c9b7ULL;

  // Source files that refer to some files, but not others.
  Module::Line line1 = { 0xab415089485e1a20ULL, 0x126e3124979291f2ULL,
                         file1, 137850127 };
  Module::Line line2 = { 0xb2675b5c3c2ed33fULL, 0x1df77f5551dbd68cULL,
                         file3, 28113549 };
  function->lines.push_back(line1);
  function->lines.push_back(line2);
  m.AddFunction(function);

  m.AssignSourceIds();

  vector<Module::File*> vec;
  m.GetFiles(&vec);
  EXPECT_EQ((size_t) 3, vec.size());
  EXPECT_STREQ("filename1", vec[0]->name.c_str());
  EXPECT_NE(-1, vec[0]->source_id);
  // Expect filename2 not to be used.
  EXPECT_STREQ("filename2", vec[1]->name.c_str());
  EXPECT_EQ(-1, vec[1]->source_id);
  EXPECT_STREQ("filename3", vec[2]->name.c_str());
  EXPECT_NE(-1, vec[2]->source_id);

  stringstream s;
  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FILE 0 filename1\n"
               "FILE 1 filename3\n"
               "FUNC 9b926d464f0b9384 4f524a4ba795e6a6 bbe8133a6641c9b7"
               " function_name\n"
               "ab415089485e1a20 126e3124979291f2 137850127 0\n"
               "b2675b5c3c2ed33f 1df77f5551dbd68c 28113549 1\n",
               contents.c_str());
}

TEST(Write, NoCFI) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Some source files.  We will expect to see them in lexicographic order.
  Module::File* file1 = m.FindFile("filename.cc");

  // A function.
  Module::Function* function = new Module::Function(
      "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)", 0xbec774ea5dd935f3ULL);
  Module::Range range(0xbec774ea5dd935f3ULL, 0x2922088f98d3f6fcULL);
  function->ranges.push_back(range);
  function->parameter_size = 0xe5e9aa008bd5f0d0ULL;

  // Some source lines.  The module should not sort these.
  Module::Line line1 = { 0xbec774ea5dd935f3ULL, 0x1c2be6d6c5af2611ULL,
                         file1, 41676901 };
  function->lines.push_back(line1);

  m.AddFunction(function);

  // Some stack information.
  Module::StackFrameEntry* entry = new Module::StackFrameEntry();
  entry->address = 0x30f9e5c83323973dULL;
  entry->size = 0x49fc9ca7c7c13dc2ULL;
  entry->initial_rules[".cfa"] = "he was a handsome man";
  entry->initial_rules["and"] = "what i want to know is";
  entry->rule_changes[0x30f9e5c83323973eULL]["how"] =
    "do you like your blueeyed boy";
  entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = "Death";
  m.AddStackFrameEntry(entry);

  // Set the load address.  Doing this after adding all the data to
  // the module must work fine.
  m.SetLoadAddress(0x2ab698b0b6407073ULL);

  m.Write(s, NO_CFI);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FILE 0 filename.cc\n"
               "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0"
               " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n"
               "9410dc39a798c580 1c2be6d6c5af2611 41676901 0\n",
               contents.c_str());
}

TEST(Construct, AddFunctions) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Two functions.
  Module::Function* function1 = new Module::Function(
      "_without_form", 0xd35024aa7ca7da5cULL);
  Module::Range r1(0xd35024aa7ca7da5cULL, 0x200b26e605f99071ULL);
  function1->ranges.push_back(r1);
  function1->parameter_size = 0xf14ac4fed48c4a99ULL;

  Module::Function* function2 = new Module::Function(
      "_and_void", 0x2987743d0b35b13fULL);
  Module::Range r2(0x2987743d0b35b13fULL, 0xb369db048deb3010ULL);
  function2->ranges.push_back(r2);
  function2->parameter_size = 0x938e556cb5a79988ULL;

  // Put them in a vector.
  vector<Module::Function*> vec;
  vec.push_back(function1);
  vec.push_back(function2);

  m.AddFunctions(vec.begin(), vec.end());

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988"
               " _and_void\n"
               "FUNC d35024aa7ca7da5c 200b26e605f99071 f14ac4fed48c4a99"
               " _without_form\n",
               contents.c_str());

  // Check that m.GetFunctions returns the functions we expect.
  vec.clear();
  m.GetFunctions(&vec, vec.end());
  EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function1));
  EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function2));
  EXPECT_EQ((size_t) 2, vec.size());
}

TEST(Construct, AddFrames) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // First STACK CFI entry, with no initial rules or deltas.
  Module::StackFrameEntry* entry1 = new Module::StackFrameEntry();
  entry1->address = 0xddb5f41285aa7757ULL;
  entry1->size = 0x1486493370dc5073ULL;
  m.AddStackFrameEntry(entry1);

  // Second STACK CFI entry, with initial rules but no deltas.
  Module::StackFrameEntry* entry2 = new Module::StackFrameEntry();
  entry2->address = 0x8064f3af5e067e38ULL;
  entry2->size = 0x0de2a5ee55509407ULL;
  entry2->initial_rules[".cfa"] = "I think that I shall never see";
  entry2->initial_rules["stromboli"] = "a poem lovely as a tree";
  entry2->initial_rules["cannoli"] = "a tree whose hungry mouth is prest";
  m.AddStackFrameEntry(entry2);

  // Third STACK CFI entry, with initial rules and deltas.
  Module::StackFrameEntry* entry3 = new Module::StackFrameEntry();
  entry3->address = 0x5e8d0db0a7075c6cULL;
  entry3->size = 0x1c7edb12a7aea229ULL;
  entry3->initial_rules[".cfa"] = "Whose woods are these";
  entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] =
    "the village though";
  entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
    "he will not see me stopping here";
  entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] =
    "his house is in";
  entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] =
    "I think I know";
  m.AddStackFrameEntry(entry3);

  // Check that Write writes STACK CFI records properly.
  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n"
               "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
               " .cfa: I think that I shall never see"
               " cannoli: a tree whose hungry mouth is prest"
               " stromboli: a poem lovely as a tree\n"
               "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229"
               " .cfa: Whose woods are these\n"
               "STACK CFI 36682fad3763ffff"
               " .cfa: I think I know"
               " stromboli: his house is in\n"
               "STACK CFI 47ceb0f63c269d7f"
               " calzone: the village though"
               " cannoli: he will not see me stopping here\n",
               contents.c_str());

  // Check that GetStackFrameEntries works.
  vector<Module::StackFrameEntry*> entries;
  m.GetStackFrameEntries(&entries);
  ASSERT_EQ(3U, entries.size());
  // Check first entry.
  EXPECT_EQ(0xddb5f41285aa7757ULL, entries[0]->address);
  EXPECT_EQ(0x1486493370dc5073ULL, entries[0]->size);
  ASSERT_EQ(0U, entries[0]->initial_rules.size());
  ASSERT_EQ(0U, entries[0]->rule_changes.size());
  // Check second entry.
  EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address);
  EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size);
  ASSERT_EQ(3U, entries[1]->initial_rules.size());
  Module::RuleMap entry2_initial;
  entry2_initial[".cfa"] = "I think that I shall never see";
  entry2_initial["stromboli"] = "a poem lovely as a tree";
  entry2_initial["cannoli"] = "a tree whose hungry mouth is prest";
  EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial));
  ASSERT_EQ(0U, entries[1]->rule_changes.size());
  // Check third entry.
  EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[2]->address);
  EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[2]->size);
  Module::RuleMap entry3_initial;
  entry3_initial[".cfa"] = "Whose woods are these";
  EXPECT_THAT(entries[2]->initial_rules, ContainerEq(entry3_initial));
  Module::RuleChangeMap entry3_changes;
  entry3_changes[0x36682fad3763ffffULL][".cfa"] = "I think I know";
  entry3_changes[0x36682fad3763ffffULL]["stromboli"] = "his house is in";
  entry3_changes[0x47ceb0f63c269d7fULL]["calzone"] = "the village though";
  entry3_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
    "he will not see me stopping here";
  EXPECT_THAT(entries[2]->rule_changes, ContainerEq(entry3_changes));
}

TEST(Construct, UniqueFiles) {
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
  Module::File* file1 = m.FindFile("foo");
  Module::File* file2 = m.FindFile(string("bar"));
  Module::File* file3 = m.FindFile(string("foo"));
  Module::File* file4 = m.FindFile("bar");
  EXPECT_NE(file1, file2);
  EXPECT_EQ(file1, file3);
  EXPECT_EQ(file2, file4);
  EXPECT_EQ(file1, m.FindExistingFile("foo"));
  EXPECT_TRUE(m.FindExistingFile("baz") == NULL);
}

TEST(Construct, DuplicateFunctions) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Two functions.
  Module::Function* function1 = generate_duplicate_function("_without_form");
  Module::Function* function2 = generate_duplicate_function("_without_form");

  m.AddFunction(function1);
  m.AddFunction(function2);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
               " _without_form\n",
               contents.c_str());
}

TEST(Construct, FunctionsWithSameAddress) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Two functions.
  Module::Function* function1 = generate_duplicate_function("_without_form");
  Module::Function* function2 = generate_duplicate_function("_and_void");

  m.AddFunction(function1);
  m.AddFunction(function2);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();
  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
               " _and_void\n"
               "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
               " _without_form\n",
               contents.c_str());
}

// Externs should be written out as PUBLIC records, sorted by
// address.
TEST(Construct, Externs) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Two externs.
  Module::Extern* extern1 = new Module::Extern(0xffff);
  extern1->name = "_abc";
  Module::Extern* extern2 = new Module::Extern(0xaaaa);
  extern2->name = "_xyz";

  m.AddExtern(extern1);
  m.AddExtern(extern2);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();

  EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
               MODULE_ID " " MODULE_NAME "\n"
               "PUBLIC aaaa 0 _xyz\n"
               "PUBLIC ffff 0 _abc\n",
               contents.c_str());
}

// Externs with the same address should only keep the first entry
// added.
TEST(Construct, DuplicateExterns) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Two externs.
  Module::Extern* extern1 = new Module::Extern(0xffff);
  extern1->name = "_xyz";
  Module::Extern* extern2 = new Module::Extern(0xffff);
  extern2->name = "_abc";

  m.AddExtern(extern1);
  m.AddExtern(extern2);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();

  EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
               MODULE_ID " " MODULE_NAME "\n"
               "PUBLIC ffff 0 _xyz\n",
               contents.c_str());
}

// If there exists an extern and a function at the same address, only write
// out the FUNC entry.
TEST(Construct, FunctionsAndExternsWithSameAddress) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Two externs.
  Module::Extern* extern1 = new Module::Extern(0xabc0);
  extern1->name = "abc";
  Module::Extern* extern2 = new Module::Extern(0xfff0);
  extern2->name = "xyz";

  m.AddExtern(extern1);
  m.AddExtern(extern2);

  Module::Function* function = new Module::Function("_xyz", 0xfff0);
  Module::Range range(0xfff0, 0x10);
  function->ranges.push_back(range);
  function->parameter_size = 0;
  m.AddFunction(function);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();

  EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
               MODULE_ID " " MODULE_NAME "\n"
               "FUNC fff0 10 0 _xyz\n"
               "PUBLIC abc0 0 abc\n",
               contents.c_str());
}

// If there exists an extern and a function at the same address, only write
// out the FUNC entry. For ARM THUMB, the extern that comes from the ELF
// symbol section has bit 0 set.
TEST(Construct, FunctionsAndThumbExternsWithSameAddress) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, "arm", MODULE_ID);

  // Two THUMB externs.
  Module::Extern* thumb_extern1 = new Module::Extern(0xabc1);
  thumb_extern1->name = "thumb_abc";
  Module::Extern* thumb_extern2 = new Module::Extern(0xfff1);
  thumb_extern2->name = "thumb_xyz";

  Module::Extern* arm_extern1 = new Module::Extern(0xcc00);
  arm_extern1->name = "arm_func";

  m.AddExtern(thumb_extern1);
  m.AddExtern(thumb_extern2);
  m.AddExtern(arm_extern1);

  // The corresponding function from the DWARF debug data have the actual
  // address.
  Module::Function* function = new Module::Function("_thumb_xyz", 0xfff0);
  Module::Range range(0xfff0, 0x10);
  function->ranges.push_back(range);
  function->parameter_size = 0;
  m.AddFunction(function);

  m.Write(s, ALL_SYMBOL_DATA);
  string contents = s.str();

  EXPECT_STREQ("MODULE " MODULE_OS " arm "
               MODULE_ID " " MODULE_NAME "\n"
               "FUNC fff0 10 0 _thumb_xyz\n"
               "PUBLIC abc1 0 thumb_abc\n"
               "PUBLIC cc00 0 arm_func\n",
               contents.c_str());
}

TEST(Write, OutOfRangeAddresses) {
  stringstream s;
  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);

  // Specify an allowed address range, representing a PT_LOAD segment in a
  // module.
  vector<Module::Range> address_ranges = {
    Module::Range(0x2000ULL, 0x1000ULL),
  };
  m.SetAddressRanges(address_ranges);

  // Add three stack frames (one lower, one in, and one higher than the allowed
  // address range).  Only the middle frame should be captured.
  Module::StackFrameEntry* entry1 = new Module::StackFrameEntry();
  entry1->address = 0x1000ULL;
  entry1->size = 0x100ULL;
  m.AddStackFrameEntry(entry1);
  Module::StackFrameEntry* entry2 = new Module::StackFrameEntry();
  entry2->address = 0x2000ULL;
  entry2->size = 0x100ULL;
  m.AddStackFrameEntry(entry2);
  Module::StackFrameEntry* entry3 = new Module::StackFrameEntry();
  entry3->address = 0x3000ULL;
  entry3->size = 0x100ULL;
  m.AddStackFrameEntry(entry3);

  // Add a function outside the allowed range.
  Module::File* file = m.FindFile("file_name.cc");
  Module::Function* function = new Module::Function(
      "function_name", 0x4000ULL);
  Module::Range range(0x4000ULL, 0x1000ULL);
  function->ranges.push_back(range);
  function->parameter_size = 0x100ULL;
  Module::Line line = { 0x4000ULL, 0x100ULL, file, 67519080 };
  function->lines.push_back(line);
  m.AddFunction(function);

  // Add an extern outside the allowed range.
  Module::Extern* extern1 = new Module::Extern(0x5000ULL);
  extern1->name = "_xyz";
  m.AddExtern(extern1);

  m.Write(s, ALL_SYMBOL_DATA);

  EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
               "STACK CFI INIT 2000 100 \n",
               s.str().c_str());

}
