1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/pdb/pdb_stream_record.h"
16 :
17 : #include "base/strings/utf_string_conversions.h"
18 : #include "syzygy/pdb/pdb_util.h"
19 : #include "syzygy/pe/cvinfo_ext.h"
20 :
21 : namespace pdb {
22 :
23 E : NumericConstant::NumericConstant() : kind_(CONSTANT_UNINITIALIZED) {
24 E : }
25 :
26 E : bool ReadWideString(PdbStream* stream, base::string16* string_field) {
27 E : DCHECK(stream);
28 E : DCHECK(string_field);
29 :
30 E : std::string narrow_string;
31 E : if (!ReadString(stream, &narrow_string))
32 E : return false;
33 : return base::UTF8ToWide(narrow_string.c_str(), narrow_string.length(),
34 E : string_field);
35 E : }
36 :
37 E : bool ReadUnsignedNumeric(PdbStream* stream, uint64_t* data_field) {
38 E : DCHECK(stream);
39 E : DCHECK(data_field);
40 :
41 E : NumericConstant numeric;
42 E : if (!ReadNumericConstant(stream, &numeric))
43 E : return false;
44 :
45 E : if (numeric.kind() != NumericConstant::CONSTANT_UNSIGNED)
46 i : return false;
47 :
48 E : *data_field = numeric.unsigned_value();
49 E : return true;
50 E : }
51 :
52 E : bool ReadNumericConstant(PdbStream* stream, NumericConstant* constant) {
53 E : DCHECK(stream);
54 E : DCHECK(constant);
55 :
56 E : uint16_t value_type = 0;
57 E : if (!stream->Read(&value_type, 1))
58 E : return false;
59 :
60 : // If the value is small then it's simply this value.
61 E : if (value_type < Microsoft_Cci_Pdb::LF_NUMERIC) {
62 E : constant->kind_ = NumericConstant::CONSTANT_UNSIGNED;
63 E : constant->unsigned_value_ = value_type;
64 E : return true;
65 : }
66 :
67 : // Otherwise load the constant given its value type.
68 E : switch (value_type) {
69 : case Microsoft_Cci_Pdb::LF_CHAR: {
70 E : int8_t value = 0;
71 E : if (!stream->Read(&value, 1))
72 i : return false;
73 E : constant->kind_ = NumericConstant::CONSTANT_SIGNED;
74 E : constant->signed_value_ = value;
75 E : return true;
76 : }
77 : case Microsoft_Cci_Pdb::LF_USHORT: {
78 E : uint16_t value = 0;
79 E : if (!stream->Read(&value, 1))
80 i : return false;
81 E : constant->kind_ = NumericConstant::CONSTANT_UNSIGNED;
82 E : constant->unsigned_value_ = value;
83 E : return true;
84 : }
85 : case Microsoft_Cci_Pdb::LF_ULONG: {
86 E : uint32_t value = 0;
87 E : if (!stream->Read(&value, 1))
88 i : return false;
89 E : constant->kind_ = NumericConstant::CONSTANT_UNSIGNED;
90 E : constant->unsigned_value_ = value;
91 E : return true;
92 : }
93 : case Microsoft_Cci_Pdb::LF_UQUADWORD: {
94 E : uint64_t value = 0;
95 E : if (!stream->Read(&value, 1))
96 i : return false;
97 E : constant->kind_ = NumericConstant::CONSTANT_UNSIGNED;
98 E : constant->unsigned_value_ = value;
99 E : return true;
100 : }
101 : case Microsoft_Cci_Pdb::LF_SHORT: {
102 E : int16_t value = 0;
103 E : if (!stream->Read(&value, 1))
104 i : return false;
105 E : constant->kind_ = NumericConstant::CONSTANT_SIGNED;
106 E : constant->unsigned_value_ = value;
107 E : return true;
108 : }
109 : case Microsoft_Cci_Pdb::LF_LONG: {
110 E : int32_t value = 0;
111 E : if (!stream->Read(&value, 1))
112 i : return false;
113 E : constant->kind_ = NumericConstant::CONSTANT_SIGNED;
114 E : constant->unsigned_value_ = value;
115 E : return true;
116 : }
117 : case Microsoft_Cci_Pdb::LF_QUADWORD: {
118 E : int64_t value = 0;
119 E : if (!stream->Read(&value, 1))
120 i : return false;
121 E : constant->kind_ = NumericConstant::CONSTANT_SIGNED;
122 E : constant->unsigned_value_ = value;
123 E : return true;
124 : }
125 i : default: { return false; }
126 : }
127 E : }
128 :
129 : } // namespace pdb
|