121 lines
5.1 KiB
C
121 lines
5.1 KiB
C
|
#ifndef DWARF_H
|
||
|
#define DWARF_H
|
||
|
|
||
|
class CommonInformationEntryList;
|
||
|
class IArchitecture;
|
||
|
|
||
|
class EncodedData : public std::vector<uint8_t>
|
||
|
{
|
||
|
public:
|
||
|
EncodedData(uint64_t address = 0, OperandSize pointer_size = osByte);
|
||
|
void ReadFromFile(IArchitecture &file, size_t size);
|
||
|
uint8_t ReadByte(size_t *pos) const;
|
||
|
uint16_t ReadWord(size_t *pos) const;
|
||
|
uint32_t ReadDWord(size_t *pos) const;
|
||
|
uint64_t ReadQWord(size_t *pos) const;
|
||
|
uint64_t ReadUleb128(size_t *pos) const;
|
||
|
int64_t ReadSleb128(size_t *pos) const;
|
||
|
std::string ReadString(size_t *pos) const;
|
||
|
uint32_t ReadUnsigned(size_t *pos) const;
|
||
|
uint64_t ReadEncoding(uint8_t encoding, size_t *pos) const;
|
||
|
void WriteString(const std::string &str);
|
||
|
void WriteUleb128(uint64_t value);
|
||
|
void WriteSleb128(int64_t value);
|
||
|
void WriteByte(uint8_t value);
|
||
|
void WriteWord(uint16_t value);
|
||
|
void WriteDWord(uint32_t value);
|
||
|
void WriteQWord(uint64_t value);
|
||
|
void WriteEncoding(uint8_t encoding, uint64_t value);
|
||
|
uint64_t address() const { return address_; }
|
||
|
OperandSize pointer_size() const { return pointer_size_; }
|
||
|
void Read(void *buf, size_t count, size_t *pos) const;
|
||
|
void Write(const void *buf, size_t count);
|
||
|
size_t encoding_size(uint8_t encoding) const;
|
||
|
private:
|
||
|
uint64_t address_;
|
||
|
OperandSize pointer_size_;
|
||
|
};
|
||
|
|
||
|
class CommonInformationEntry : public IObject
|
||
|
{
|
||
|
public:
|
||
|
explicit CommonInformationEntry(CommonInformationEntryList *owner, uint8_t version, const std::string &augmentation,
|
||
|
uint64_t code_alignment_factor, uint64_t data_alignment_factor, uint8_t return_adddress_register, uint8_t fde_encoding,
|
||
|
uint8_t lsda_encoding, uint8_t personality_encoding, uint64_t personality_routine, const std::vector<uint8_t> &initial_instructions);
|
||
|
explicit CommonInformationEntry(CommonInformationEntryList *owner, const CommonInformationEntry &src);
|
||
|
~CommonInformationEntry();
|
||
|
CommonInformationEntry *Clone(CommonInformationEntryList *owner) const;
|
||
|
uint8_t version() const { return version_; }
|
||
|
std::string augmentation() const { return augmentation_; }
|
||
|
uint64_t code_alignment_factor() const { return code_alignment_factor_; }
|
||
|
uint64_t data_alignment_factor() const { return data_alignment_factor_; }
|
||
|
uint8_t return_address_register() const { return return_address_register_; }
|
||
|
uint8_t fde_encoding() const { return fde_encoding_; }
|
||
|
uint8_t lsda_encoding() const { return lsda_encoding_; }
|
||
|
uint8_t personality_encoding() const { return personality_encoding_; }
|
||
|
uint64_t personality_routine() const { return personality_routine_; }
|
||
|
std::vector<uint8_t> initial_instructions() const { return initial_instructions_; }
|
||
|
void Rebase(uint64_t delta_base);
|
||
|
private:
|
||
|
CommonInformationEntryList *owner_;
|
||
|
uint8_t version_;
|
||
|
std::string augmentation_;
|
||
|
uint64_t code_alignment_factor_;
|
||
|
uint64_t data_alignment_factor_;
|
||
|
uint8_t return_address_register_;
|
||
|
uint8_t fde_encoding_;
|
||
|
uint8_t lsda_encoding_;
|
||
|
uint8_t personality_encoding_;
|
||
|
uint64_t personality_routine_;
|
||
|
std::vector<uint8_t> initial_instructions_;
|
||
|
};
|
||
|
|
||
|
class CommonInformationEntryList : public ObjectList<CommonInformationEntry>
|
||
|
{
|
||
|
public:
|
||
|
explicit CommonInformationEntryList();
|
||
|
explicit CommonInformationEntryList(const CommonInformationEntryList &src);
|
||
|
CommonInformationEntry *Add(uint8_t version, const std::string &augmentation, uint64_t code_alignment_factor,
|
||
|
uint64_t data_alignment_factor, uint8_t return_address_register, uint8_t fde_encoding,
|
||
|
uint8_t lsda_encoding, uint8_t personality_encoding, uint64_t personality_routine, const std::vector<uint8_t> &call_frame_instructions);
|
||
|
CommonInformationEntryList *Clone() const;
|
||
|
void Rebase(uint64_t delta_base);
|
||
|
private:
|
||
|
// no assignment op
|
||
|
CommonInformationEntryList &operator =(const CommonInformationEntryList &);
|
||
|
};
|
||
|
|
||
|
class DwarfParser
|
||
|
{
|
||
|
public:
|
||
|
static uint32_t CreateCompactEncoding(IArchitecture &file, const std::vector<uint8_t> &fde_instructions, CommonInformationEntry *cie_, uint64_t start);
|
||
|
private:
|
||
|
enum { kMaxRegisterNumber = 120 };
|
||
|
enum RegisterSavedWhere { kRegisterUnused, kRegisterInCFA, kRegisterOffsetFromCFA,
|
||
|
kRegisterInRegister, kRegisterAtExpression, kRegisterIsExpression } ;
|
||
|
struct RegisterLocation {
|
||
|
RegisterSavedWhere location;
|
||
|
int64_t value;
|
||
|
};
|
||
|
|
||
|
struct PrologInfo {
|
||
|
uint32_t cfaRegister;
|
||
|
int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
|
||
|
int64_t cfaExpression; // CFA = expression
|
||
|
uint32_t spExtraArgSize;
|
||
|
uint32_t codeOffsetAtStackDecrement;
|
||
|
uint8_t registerSavedTwiceInCIE;
|
||
|
bool registersInOtherRegisters;
|
||
|
bool registerSavedMoreThanOnce;
|
||
|
bool cfaOffsetWasNegative;
|
||
|
bool sameValueUsed;
|
||
|
RegisterLocation savedRegisters[kMaxRegisterNumber]; // from where to restore registers
|
||
|
};
|
||
|
static bool ParseInstructions(const std::vector<uint8_t> &instructions, CommonInformationEntry *cie_, PrologInfo &info);
|
||
|
static uint32_t CreateCompactEncodingForX32(IArchitecture &file, uint64_t start, PrologInfo &info);
|
||
|
static uint32_t CreateCompactEncodingForX64(IArchitecture &file, uint64_t start, PrologInfo &info);
|
||
|
static uint32_t GetRBPEncodedRegister(uint32_t reg, int32_t regOffsetFromBaseOffset, bool &failure);
|
||
|
static uint32_t GetEBPEncodedRegister(uint32_t reg, int32_t regOffsetFromBaseOffset, bool &failure);
|
||
|
};
|
||
|
|
||
|
#endif
|