185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Copyright 2013 Google Inc. All rights reserved.
285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//
385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Redistribution and use in source and binary forms, with or without
485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// modification, are permitted provided that the following conditions are
585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// met:
685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//
785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//     * Redistributions of source code must retain the above copyright
885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// notice, this list of conditions and the following disclaimer.
985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//     * Redistributions in binary form must reproduce the above
1085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// copyright notice, this list of conditions and the following disclaimer
1185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// in the documentation and/or other materials provided with the
1285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// distribution.
1385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//     * Neither the name of Google Inc. nor the names of its
1485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// contributors may be used to endorse or promote products derived from
1585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// this software without specific prior written permission.
1685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//
1785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
2985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Unittests for OMAP related functions.
3085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
3185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org#include "common/windows/omap.h"
3285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
3385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org#include "gmock/gmock.h"
3485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org#include "gtest/gtest.h"
3585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
3685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgnamespace google_breakpad {
3785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
3885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Equality operators for ContainerEq. These must be outside of the anonymous
3985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// namespace in order for them to be found.
4085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgbool operator==(const MappedRange& mr1, const MappedRange& mr2) {
4185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return mr1.rva_original == mr2.rva_original &&
4285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org      mr1.rva_transformed == mr2.rva_transformed &&
4385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org      mr1.length == mr2.length &&
4485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org      mr1.injected == mr2.injected &&
4585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org      mr1.removed == mr2.removed;
4685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
4785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgbool operator==(const EndpointIndex& ei1, const EndpointIndex& ei2) {
4885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return ei1.endpoint == ei2.endpoint && ei1.index == ei2.index;
4985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
5085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
5185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Pretty printers for more meaningful error messages. Also need to be outside
5285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// the anonymous namespace.
5385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgstd::ostream& operator<<(std::ostream& os, const MappedRange& mr) {
5485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  os << "MappedRange(rva_original=" << mr.rva_original
5585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org     << ", rva_transformed=" << mr.rva_transformed
5685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org     << ", length=" << mr.length
5785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org     << ", injected=" << mr.injected
5885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org     << ", removed=" << mr.removed << ")";
5985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return os;
6085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
6185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgstd::ostream& operator<<(std::ostream& os, const EndpointIndex& ei) {
6285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  os << "EndpointIndex(endpoint=" << ei.endpoint
6385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org     << ", index=" << ei.index << ")";
6485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return os;
6585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
6685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgstd::ostream& operator<<(std::ostream& os, const AddressRange& ar) {
6785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  os << "AddressRange(rva=" << ar.rva << ", length=" << ar.length << ")";
6885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return os;
6985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
7085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
7185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgnamespace {
7285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
7385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgOMAP CreateOmap(DWORD rva, DWORD rvaTo) {
7485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  OMAP o = { rva, rvaTo };
7585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return o;
7685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
7785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
7885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgMappedRange CreateMappedRange(DWORD rva_original,
7985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                              DWORD rva_transformed,
8085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                              DWORD length,
8185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                              DWORD injected,
8285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                              DWORD removed) {
8385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MappedRange mr = { rva_original, rva_transformed, length, injected, removed };
8485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return mr;
8585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
8685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
8785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgEndpointIndex CreateEndpointIndex(DWORD endpoint, size_t index) {
8885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EndpointIndex ei = { endpoint, index };
8985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  return ei;
9085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
9185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
9285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//              (C is removed)
9385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Original   :  A B C D E F G H
9485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Transformed:  A B D F E * H1 G1 G2 H2
9585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org//              (* is injected, G is copied, H is split)
9685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// A is implied.
9785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
9885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Layout of the original image.
9985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange B(100, 15);
10085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange C(B.end(), 10);
10185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange D(C.end(), 25);
10285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange E(D.end(), 10);
10385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange F(E.end(), 40);
10485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange G(F.end(), 3);
10585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange H(G.end(), 7);
10685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
10785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org// Layout of the transformed image.
10885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange Bt(100, 15);
10985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange Dt(Bt.end(), 20);  // D is shortened.
11085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange Ft(Dt.end(), F.length);
11185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange Et(Ft.end(), E.length);
11285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange injected(Et.end(), 5);
11385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange H1t(injected.end(), 4);  // H is split.
11485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange G1t(H1t.end(), G.length);  // G is copied.
11585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange G2t(G1t.end(), G.length);  // G is copied.
11685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgconst AddressRange H2t(G2t.end(), 3);  // H is split.
11785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
11885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgclass BuildImageMapTest : public testing::Test {
11985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org public:
12085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  static const DWORD kInvalidAddress = 0xFFFFFFFF;
12185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
12285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  void InitOmapData() {
12385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.length_original = H.end();
12485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
12585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    // Build the OMAPTO vector (from transformed to original).
12685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(Bt.rva, B.rva));
12785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(Dt.rva, D.rva));
12885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(Ft.rva, F.rva));
12985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(Et.rva, E.rva));
13085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(injected.rva, kInvalidAddress));
13185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(H1t.rva, H.rva));
13285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(G1t.rva, G.rva));
13385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(G2t.rva, G.rva));
13485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(H2t.rva, H.rva + H1t.length));
13585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_to.push_back(CreateOmap(H2t.end(), kInvalidAddress));
13685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
13785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    // Build the OMAPFROM vector (from original to transformed).
13885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(B.rva, Bt.rva));
13985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(C.rva, kInvalidAddress));
14085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(D.rva, Dt.rva));
14185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(E.rva, Et.rva));
14285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(F.rva, Ft.rva));
14385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(G.rva, G1t.rva));
14485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(H.rva, H1t.rva));
14585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(H.rva + H1t.length, H2t.rva));
14685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    omap_data.omap_from.push_back(CreateOmap(H.end(), kInvalidAddress));
14785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  }
14885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
14985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  OmapData omap_data;
15085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org};
15185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
15285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}  // namespace
15385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
15485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(BuildImageMapTest, EmptyImageMapOnEmptyOmapData) {
15585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ASSERT_EQ(0u, omap_data.omap_from.size());
15685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ASSERT_EQ(0u, omap_data.omap_to.size());
15785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ASSERT_EQ(0u, omap_data.length_original);
15885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
15985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ImageMap image_map;
16085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  BuildImageMap(omap_data, &image_map);
16185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(0u, image_map.mapping.size());
16285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(0u, image_map.endpoint_index_map.size());
16385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
16485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
16585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(BuildImageMapTest, ImageMapIsCorrect) {
16685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  InitOmapData();
16785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ASSERT_LE(0u, omap_data.omap_from.size());
16885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ASSERT_LE(0u, omap_data.omap_to.size());
16985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ASSERT_LE(0u, omap_data.length_original);
17085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
17185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ImageMap image_map;
17285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  BuildImageMap(omap_data, &image_map);
17385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_LE(9u, image_map.mapping.size());
17485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_LE(9u, image_map.endpoint_index_map.size());
17585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
17685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  Mapping mapping;
17785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(0, 0, B.rva, 0, 0));
17885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // C is removed, and it originally comes immediately after B.
17985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(B.rva, Bt.rva, B.length, 0, C.length));
18085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // D is shortened by a length of 5.
18185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(D.rva, Dt.rva, Dt.length, 0, 5));
18285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // The injected content comes immediately after E in the transformed image.
18385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(E.rva, Et.rva, E.length, injected.length,
18485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                                      0));
18585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(F.rva, Ft.rva, F.length, 0, 0));
18685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // G is copied so creates two entries.
18785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(G.rva, G1t.rva, G.length, 0, 0));
18885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(G.rva, G2t.rva, G.length, 0, 0));
18985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // H is split, so create two entries.
19085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(H.rva, H1t.rva, H1t.length, 0, 0));
19185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  mapping.push_back(CreateMappedRange(H.rva + H1t.length, H2t.rva, H2t.length,
19285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                                      0, 0));
19385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapping,
19485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org              testing::ContainerEq(image_map.mapping));
19585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
19685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EndpointIndexMap endpoint_index_map;
19785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(0, 0));
19885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(B.rva, 1));
19985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(D.rva, 2));
20085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(E.rva, 3));
20185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(F.rva, 4));
20285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // G is duplicated so 2 ranges map back to it, hence the skip from 5 to 7.
20385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(G.rva, 5));
20485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  // H is split so we expect 2 endpoints to show up attributed to it.
20585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(H.rva, 7));
20685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(H.rva + H1t.length, 8));
20785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  endpoint_index_map.push_back(CreateEndpointIndex(H.end(), 9));
20885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(endpoint_index_map,
20985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org              testing::ContainerEq(image_map.endpoint_index_map));
21085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
21185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
21285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgnamespace {
21385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
21485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgclass MapAddressRangeTest : public BuildImageMapTest {
21585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org public:
21685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  typedef BuildImageMapTest Super;
21785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  virtual void SetUp() {
21885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    Super::SetUp();
21985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    InitOmapData();
22085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org    BuildImageMap(omap_data, &image_map);
22185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  }
22285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
22385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ImageMap image_map;
22485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
22585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org private:
22685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  using BuildImageMapTest::InitOmapData;
22785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  using BuildImageMapTest::omap_data;
22885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org};
22985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
23085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}  // namespace
23185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
23285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, EmptyImageMapReturnsIdentity) {
23385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  ImageMap im;
23485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
23585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange ar(0, 1024);
23685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(im, ar, &mapped_ranges);
23785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
23885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(ar, mapped_ranges[0]);
23985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
24085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
24185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapOutOfImage) {
24285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
24385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, AddressRange(H.end() + 10, 10), &mapped_ranges);
24485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(0u, mapped_ranges.size());
24585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
24685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
24785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapIdentity) {
24885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
24985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, B, &mapped_ranges);
25085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
25185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(B));
25285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
25385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
25485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapReorderedContiguous) {
25585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
25685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
25785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange DEF(D.rva, F.end() - D.rva);
25885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, DEF, &mapped_ranges);
25985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
26085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
26185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange DFEt(Dt.rva, Et.end() - Dt.rva);
26285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(DFEt));
26385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
26485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
26585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapEmptySingle) {
26685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
26785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, AddressRange(D.rva, 0), &mapped_ranges);
26885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
26985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(AddressRange(Dt.rva, 0)));
27085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
27185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
27285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapEmptyCopied) {
27385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
27485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, AddressRange(G.rva, 0), &mapped_ranges);
27585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(2u, mapped_ranges.size());
27685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(AddressRange(G1t.rva, 0),
27785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org                                                  AddressRange(G2t.rva, 0)));
27885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
27985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
28085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapCopiedContiguous) {
28185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
28285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, G, &mapped_ranges);
28385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
28485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(
28585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org      AddressRange(G1t.rva, G2t.end() - G1t.rva)));
28685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
28785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
28885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapSplitDiscontiguous) {
28985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
29085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, H, &mapped_ranges);
29185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(2u, mapped_ranges.size());
29285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(H1t, H2t));
29385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
29485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
29585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapInjected) {
29685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
29785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
29885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange EFGH(E.rva, H.end() - E.rva);
29985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, EFGH, &mapped_ranges);
30085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
30185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
30285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange FEHGGHt(Ft.rva, H2t.end() - Ft.rva);
30385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(FEHGGHt));
30485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
30585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
30685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapRemovedEntirely) {
30785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
30885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, C, &mapped_ranges);
30985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(0u, mapped_ranges.size());
31085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
31185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
31285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapRemovedPartly) {
31385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
31485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, D, &mapped_ranges);
31585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
31685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(Dt));
31785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
31885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
31985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.orgTEST_F(MapAddressRangeTest, MapFull) {
32085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRangeVector mapped_ranges;
32185be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
32285be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange AH(0, H.end());
32385be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  MapAddressRange(image_map, AH, &mapped_ranges);
32485be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_EQ(1u, mapped_ranges.size());
32585be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
32685be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  AddressRange AHt(0, H2t.end());
32785be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org  EXPECT_THAT(mapped_ranges, testing::ElementsAre(AHt));
32885be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}
32985be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org
33085be25b17ef145142197007edb785f236f5844d9chrisha@chromium.org}  // namespace google_breakpad
331