2020-09-13 21:32:55 -04:00
|
|
|
#pragma once
|
|
|
|
|
2020-08-22 23:30:17 -04:00
|
|
|
/*!
|
|
|
|
* @file LinkedWord.h
|
|
|
|
* A word (4 bytes), possibly with some linking info.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <string>
|
2021-12-04 12:33:18 -05:00
|
|
|
#include <cstring>
|
2021-02-25 09:51:28 -05:00
|
|
|
#include "common/common_types.h"
|
2022-02-08 19:02:47 -05:00
|
|
|
#include "common/util/Assert.h"
|
2020-08-22 23:30:17 -04:00
|
|
|
|
2021-01-06 20:04:15 -05:00
|
|
|
namespace decompiler {
|
2020-08-22 23:30:17 -04:00
|
|
|
class LinkedWord {
|
|
|
|
public:
|
2021-12-04 12:33:18 -05:00
|
|
|
enum Kind : u8 {
|
2020-08-22 23:30:17 -04:00
|
|
|
PLAIN_DATA, // just plain data
|
|
|
|
PTR, // pointer to a location
|
|
|
|
HI_PTR, // lower 16-bits of this data are the upper 16 bits of a pointer
|
|
|
|
LO_PTR, // lower 16-bits of this data are the lower 16 bits of a pointer
|
|
|
|
SYM_PTR, // this is a pointer to a symbol
|
|
|
|
EMPTY_PTR, // this is a pointer to the empty list
|
|
|
|
SYM_OFFSET, // this is an offset of a symbol in the symbol table
|
|
|
|
TYPE_PTR // this is a pointer to a type
|
2021-12-04 12:33:18 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
uintptr_t m_data_ptr = 0; // 8 bytes
|
|
|
|
public:
|
|
|
|
u32 data;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Kind m_kind = PLAIN_DATA;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit LinkedWord(uint32_t _data) : data(_data) {}
|
|
|
|
|
|
|
|
bool holds_string() const {
|
|
|
|
return m_kind == SYM_PTR || m_kind == SYM_OFFSET || m_kind == TYPE_PTR;
|
|
|
|
}
|
|
|
|
|
|
|
|
LinkedWord(const LinkedWord& other) {
|
|
|
|
if (&other != this) {
|
|
|
|
data = other.data;
|
|
|
|
m_kind = other.m_kind;
|
|
|
|
if (holds_string()) {
|
|
|
|
const char* other_str = (const char*)(other.m_data_ptr);
|
|
|
|
char* str = new char[strlen(other_str) + 1];
|
|
|
|
strcpy(str, other_str);
|
|
|
|
m_data_ptr = (uintptr_t)str;
|
|
|
|
} else {
|
|
|
|
m_data_ptr = other.m_data_ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LinkedWord& operator=(const LinkedWord& other) {
|
|
|
|
if (&other != this) {
|
|
|
|
data = other.data;
|
|
|
|
if (holds_string()) {
|
|
|
|
delete[]((char*)m_data_ptr);
|
|
|
|
}
|
|
|
|
m_kind = other.m_kind;
|
|
|
|
|
|
|
|
if (holds_string()) {
|
|
|
|
const char* other_str = (const char*)(other.m_data_ptr);
|
|
|
|
char* str = new char[strlen(other_str) + 1];
|
|
|
|
strcpy(str, other_str);
|
|
|
|
m_data_ptr = (uintptr_t)str;
|
|
|
|
} else {
|
|
|
|
m_data_ptr = other.m_data_ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
~LinkedWord() {
|
|
|
|
if (holds_string()) {
|
|
|
|
delete[]((char*)m_data_ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_to_empty_ptr() {
|
|
|
|
if (holds_string()) {
|
|
|
|
delete[]((char*)m_data_ptr);
|
|
|
|
}
|
|
|
|
m_kind = EMPTY_PTR;
|
|
|
|
}
|
2020-08-22 23:30:17 -04:00
|
|
|
|
2021-12-04 12:33:18 -05:00
|
|
|
void set_to_symbol(Kind kind, const std::string& name) {
|
|
|
|
if (holds_string()) {
|
|
|
|
delete[]((char*)m_data_ptr);
|
|
|
|
}
|
|
|
|
m_kind = kind;
|
|
|
|
char* str = new char[name.size() + 1];
|
|
|
|
strcpy(str, name.c_str());
|
|
|
|
m_data_ptr = (uintptr_t)str;
|
|
|
|
}
|
2020-08-22 23:30:17 -04:00
|
|
|
|
2021-12-04 12:33:18 -05:00
|
|
|
void set_to_pointer(Kind kind, u32 label_id) {
|
|
|
|
if (holds_string()) {
|
|
|
|
delete[]((char*)m_data_ptr);
|
|
|
|
}
|
|
|
|
m_data_ptr = label_id;
|
|
|
|
m_kind = kind;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_to_plain_data() {
|
|
|
|
if (holds_string()) {
|
|
|
|
delete[]((char*)m_data_ptr);
|
|
|
|
}
|
|
|
|
m_kind = PLAIN_DATA;
|
|
|
|
}
|
2021-02-25 09:51:28 -05:00
|
|
|
|
|
|
|
u8 get_byte(int idx) const {
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT(kind() == PLAIN_DATA);
|
2021-02-25 09:51:28 -05:00
|
|
|
switch (idx) {
|
|
|
|
case 0:
|
|
|
|
return data & 0xff;
|
|
|
|
case 1:
|
|
|
|
return (data >> 8) & 0xff;
|
|
|
|
case 2:
|
|
|
|
return (data >> 16) & 0xff;
|
|
|
|
case 3:
|
|
|
|
return (data >> 24) & 0xff;
|
|
|
|
default:
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT(false);
|
2021-03-07 12:01:59 -05:00
|
|
|
return 0;
|
2021-02-25 09:51:28 -05:00
|
|
|
}
|
|
|
|
}
|
2021-12-04 12:33:18 -05:00
|
|
|
|
|
|
|
// kind, label_id, symbol_name
|
|
|
|
Kind kind() const { return m_kind; }
|
|
|
|
|
|
|
|
u32 label_id() const {
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT(m_kind == PTR || m_kind == LO_PTR || m_kind == HI_PTR);
|
2021-12-04 12:33:18 -05:00
|
|
|
return m_data_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string symbol_name() const {
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT(holds_string());
|
2021-12-04 12:33:18 -05:00
|
|
|
return (const char*)(m_data_ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// if plain data, this is empty.
|
|
|
|
// otherwise:
|
|
|
|
// u8 (kind)
|
|
|
|
// u32 label id | actual string.
|
2020-08-22 23:30:17 -04:00
|
|
|
};
|
2021-12-04 12:33:18 -05:00
|
|
|
|
2021-01-06 20:04:15 -05:00
|
|
|
} // namespace decompiler
|