Coverage Report

Created: 2022-08-24 06:55

/src/solidity/libevmasm/LinkerObject.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
  This file is part of solidity.
3
4
  solidity is free software: you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation, either version 3 of the License, or
7
  (at your option) any later version.
8
9
  solidity is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
14
  You should have received a copy of the GNU General Public License
15
  along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
// SPDX-License-Identifier: GPL-3.0
18
/** @file LinkerObject.cpp
19
 * @author Christian R <c@ethdev.com>
20
 * @date 2015
21
 */
22
23
#include <libevmasm/LinkerObject.h>
24
#include <libsolutil/CommonData.h>
25
#include <libsolutil/Keccak256.h>
26
27
using namespace std;
28
using namespace solidity;
29
using namespace solidity::util;
30
using namespace solidity::evmasm;
31
32
void LinkerObject::append(LinkerObject const& _other)
33
26.4k
{
34
26.4k
  for (auto const& ref: _other.linkReferences)
35
190
    linkReferences[ref.first + bytecode.size()] = ref.second;
36
26.4k
  bytecode += _other.bytecode;
37
26.4k
}
38
39
void LinkerObject::link(map<string, h160> const& _libraryAddresses)
40
53.5k
{
41
53.5k
  std::map<size_t, std::string> remainingRefs;
42
53.5k
  for (auto const& linkRef: linkReferences)
43
382
    if (h160 const* address = matchLibrary(linkRef.second, _libraryAddresses))
44
0
      copy(address->data(), address->data() + 20, bytecode.begin() + vector<uint8_t>::difference_type(linkRef.first));
45
382
    else
46
382
      remainingRefs.insert(linkRef);
47
53.5k
  linkReferences.swap(remainingRefs);
48
53.5k
}
49
50
string LinkerObject::toHex() const
51
0
{
52
0
  string hex = solidity::util::toHex(bytecode);
53
0
  for (auto const& ref: linkReferences)
54
0
  {
55
0
    size_t pos = ref.first * 2;
56
0
    string hash = libraryPlaceholder(ref.second);
57
0
    hex[pos] = hex[pos + 1] = hex[pos + 38] = hex[pos + 39] = '_';
58
0
    for (size_t i = 0; i < 36; ++i)
59
0
      hex[pos + 2 + i] = hash.at(i);
60
0
  }
61
0
  return hex;
62
0
}
63
64
string LinkerObject::libraryPlaceholder(string const& _libraryName)
65
0
{
66
0
  return "$" + keccak256(_libraryName).hex().substr(0, 34) + "$";
67
0
}
68
69
h160 const*
70
LinkerObject::matchLibrary(
71
  string const& _linkRefName,
72
  map<string, h160> const& _libraryAddresses
73
)
74
382
{
75
382
  auto it = _libraryAddresses.find(_linkRefName);
76
382
  if (it != _libraryAddresses.end())
77
0
    return &it->second;
78
382
  return nullptr;
79
382
}