| 146 | } |
| 147 | |
| 148 | LongObject::LongObject( |
| 149 | const std::shared_ptr<const AbstractProcessManager>& manager, |
| 150 | remote_addr_t addr, |
| 151 | bool is_bool) |
| 152 | : d_is_bool(is_bool) |
| 153 | { |
| 154 | #ifdef ENVIRONMENT64 |
| 155 | constexpr unsigned int shift = 30; |
| 156 | #else |
| 157 | constexpr unsigned int shift = 15; |
| 158 | #endif |
| 159 | |
| 160 | Structure<py_long_v> longobj(manager, addr); |
| 161 | ssize_t size; |
| 162 | bool negative; |
| 163 | |
| 164 | Py_ssize_t ob_size = longobj.getField(&py_long_v::o_ob_size); |
| 165 | if (manager->versionIsAtLeast(3, 12)) { |
| 166 | auto lv_tag = *reinterpret_cast<uintptr_t*>(&ob_size); |
| 167 | negative = (lv_tag & 3) == 2; |
| 168 | size = lv_tag >> 3; |
| 169 | } else { |
| 170 | negative = ob_size < 0; |
| 171 | size = std::abs(ob_size); |
| 172 | } |
| 173 | |
| 174 | if (size == 0) { |
| 175 | d_value = 0; |
| 176 | return; |
| 177 | } |
| 178 | |
| 179 | /* Python's Include/longobjrep.h has this declaration: |
| 180 | * struct _longobject { |
| 181 | * PyObject_VAR_HEAD |
| 182 | * digit ob_digit[1]; |
| 183 | * }; |
| 184 | * |
| 185 | * with this description: |
| 186 | * The absolute value of a number is equal to |
| 187 | * SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) |
| 188 | * Negative numbers are represented with ob_size < 0; |
| 189 | * zero is represented by ob_size == 0. |
| 190 | * |
| 191 | * where SHIFT can be either: |
| 192 | * #define PyLong_SHIFT 30 |
| 193 | * #define PyLong_SHIFT 15 |
| 194 | */ |
| 195 | |
| 196 | std::vector<digit> digits; |
| 197 | digits.resize(size); |
| 198 | manager->copyMemoryFromProcess( |
| 199 | longobj.getFieldRemoteAddress(&py_long_v::o_ob_digit), |
| 200 | sizeof(digit) * size, |
| 201 | digits.data()); |
| 202 | for (ssize_t i = 0; i < size; ++i) { |
| 203 | long long factor; |
| 204 | if (__builtin_mul_overflow(digits[i], (1Lu << (ssize_t)(shift * i)), &factor)) { |
| 205 | d_overflowed = true; |
nothing calls this directly
no test coverage detected