Add C++ code to make use of .pc_list
This commit is contained in:
parent
83b304db95
commit
26d7b2afd5
8 changed files with 119 additions and 5 deletions
|
@ -2,6 +2,8 @@
|
||||||
#include "gen_context_struct.hpp"
|
#include "gen_context_struct.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static const char* PRELUDE =
|
static const char* PRELUDE =
|
||||||
|
@ -13,8 +15,12 @@ CodeGenerator::CodeGenerator(
|
||||||
const SimpleDwarf& dwarf,
|
const SimpleDwarf& dwarf,
|
||||||
std::ostream& os,
|
std::ostream& os,
|
||||||
NamingScheme naming_scheme):
|
NamingScheme naming_scheme):
|
||||||
dwarf(dwarf), os(os), naming_scheme(naming_scheme)
|
dwarf(dwarf), os(os), pc_list(nullptr), naming_scheme(naming_scheme)
|
||||||
{}
|
{
|
||||||
|
if(!settings::pc_list.empty()) {
|
||||||
|
pc_list = make_unique<PcListReader>(settings::pc_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CodeGenerator::generate() {
|
void CodeGenerator::generate() {
|
||||||
gen_of_dwarf();
|
gen_of_dwarf();
|
||||||
|
@ -95,8 +101,7 @@ void CodeGenerator::gen_of_row(
|
||||||
const SimpleDwarf::DwRow& row,
|
const SimpleDwarf::DwRow& row,
|
||||||
uintptr_t row_end)
|
uintptr_t row_end)
|
||||||
{
|
{
|
||||||
os << "\t\tcase " << std::hex << "0x" << row.ip
|
gen_case(row.ip, row_end);
|
||||||
<< " ... 0x" << row_end << ":" << std::dec << endl;
|
|
||||||
|
|
||||||
os << "\t\t\t" << "out_ctx.rsp = ";
|
os << "\t\t\t" << "out_ctx.rsp = ";
|
||||||
gen_of_reg(row.cfa);
|
gen_of_reg(row.cfa);
|
||||||
|
@ -113,6 +118,28 @@ void CodeGenerator::gen_of_row(
|
||||||
os << "\t\t\treturn " << "out_ctx" << ";" << endl;
|
os << "\t\t\treturn " << "out_ctx" << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::gen_case(uintptr_t low_bound, uintptr_t high_bound) {
|
||||||
|
if(pc_list == nullptr) {
|
||||||
|
os << "\t\tcase " << std::hex << "0x" << low_bound
|
||||||
|
<< " ... 0x" << high_bound << ":" << std::dec << endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const auto& first_it = lower_bound(
|
||||||
|
pc_list->get_list().begin(),
|
||||||
|
pc_list->get_list().end(),
|
||||||
|
low_bound);
|
||||||
|
const auto& last_it = upper_bound(
|
||||||
|
pc_list->get_list().begin(),
|
||||||
|
pc_list->get_list().end(),
|
||||||
|
high_bound);
|
||||||
|
|
||||||
|
os << std::hex;
|
||||||
|
for(auto it = first_it; it != last_it; ++it)
|
||||||
|
os << "\t\tcase 0x" << *it << ":\n";
|
||||||
|
os << std::dec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char* ctx_of_dw_name(SimpleDwarf::MachineRegister reg) {
|
static const char* ctx_of_dw_name(SimpleDwarf::MachineRegister reg) {
|
||||||
switch(reg) {
|
switch(reg) {
|
||||||
case SimpleDwarf::REG_RIP:
|
case SimpleDwarf::REG_RIP:
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "SimpleDwarf.hpp"
|
#include "SimpleDwarf.hpp"
|
||||||
|
#include "PcListReader.hpp"
|
||||||
|
|
||||||
class CodeGenerator {
|
class CodeGenerator {
|
||||||
public:
|
public:
|
||||||
|
@ -38,6 +40,7 @@ class CodeGenerator {
|
||||||
void gen_of_row(
|
void gen_of_row(
|
||||||
const SimpleDwarf::DwRow& row,
|
const SimpleDwarf::DwRow& row,
|
||||||
uintptr_t row_end);
|
uintptr_t row_end);
|
||||||
|
void gen_case(uintptr_t low_bound, uintptr_t high_bound);
|
||||||
void gen_of_reg(
|
void gen_of_reg(
|
||||||
const SimpleDwarf::DwRegister& reg);
|
const SimpleDwarf::DwRegister& reg);
|
||||||
|
|
||||||
|
@ -46,6 +49,7 @@ class CodeGenerator {
|
||||||
private:
|
private:
|
||||||
SimpleDwarf dwarf;
|
SimpleDwarf dwarf;
|
||||||
std::ostream& os;
|
std::ostream& os;
|
||||||
|
std::unique_ptr<PcListReader> pc_list;
|
||||||
|
|
||||||
NamingScheme naming_scheme;
|
NamingScheme naming_scheme;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,13 @@ CXXFLAGS=$(CXXLOCS) -Wall -Wextra -std=c++14 -O2 -g
|
||||||
CXXLIBS=-lelf -ldwarf -ldwarfpp -lsrk31c++ -lc++fileno
|
CXXLIBS=-lelf -ldwarf -ldwarfpp -lsrk31c++ -lc++fileno
|
||||||
|
|
||||||
TARGET=dwarf-assembly
|
TARGET=dwarf-assembly
|
||||||
OBJS=DwarfReader.o SimpleDwarf.o CodeGenerator.o settings.o main.o
|
OBJS=\
|
||||||
|
DwarfReader.o \
|
||||||
|
SimpleDwarf.o \
|
||||||
|
CodeGenerator.o \
|
||||||
|
PcListReader.o \
|
||||||
|
settings.o \
|
||||||
|
main.o
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
32
src/PcListReader.cpp
Normal file
32
src/PcListReader.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "PcListReader.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
PcListReader::PcListReader(const std::string& path): path(path)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void PcListReader::read() {
|
||||||
|
ifstream handle(path, ifstream::in | ifstream::binary);
|
||||||
|
if(!handle.good()) {
|
||||||
|
throw PcListReader::CannotReadFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t last_pc;
|
||||||
|
unsigned char buffer[8];
|
||||||
|
|
||||||
|
while(!handle.eof()) {
|
||||||
|
handle.read((char*)buffer, 8);
|
||||||
|
if(handle.gcount() != 8)
|
||||||
|
throw PcListReader::BadFormat();
|
||||||
|
|
||||||
|
last_pc = 0;
|
||||||
|
for(int shift = 0; shift < 8; ++shift) {
|
||||||
|
uintptr_t c_byte = buffer[shift];
|
||||||
|
c_byte <<= 8*shift;
|
||||||
|
last_pc |= c_byte;
|
||||||
|
}
|
||||||
|
pc_list.push_back(last_pc);
|
||||||
|
}
|
||||||
|
}
|
30
src/PcListReader.hpp
Normal file
30
src/PcListReader.hpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/** Reads .pc_list files, containing a list of valid program counters for some
|
||||||
|
* elf file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class PcListReader {
|
||||||
|
public:
|
||||||
|
/// Thrown when the file is somehow not readable
|
||||||
|
class CannotReadFile: std::exception {};
|
||||||
|
|
||||||
|
/// Thrown when the file contains bad content (probably not aligned 8B)
|
||||||
|
class BadFormat: std::exception {};
|
||||||
|
|
||||||
|
PcListReader(const std::string& path);
|
||||||
|
|
||||||
|
/// Actually read and process the file
|
||||||
|
void read();
|
||||||
|
|
||||||
|
/// Access the PC list (filled iff `read` was called before)
|
||||||
|
std::vector<uintptr_t>& get_list() { return pc_list; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string path;
|
||||||
|
std::vector<uintptr_t> pc_list;
|
||||||
|
};
|
11
src/main.cpp
11
src/main.cpp
|
@ -45,6 +45,17 @@ MainOptions options_parse(int argc, char** argv) {
|
||||||
settings::switch_generation_policy =
|
settings::switch_generation_policy =
|
||||||
settings::SGP_GlobalSwitch;
|
settings::SGP_GlobalSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(option == "--pc-list") {
|
||||||
|
if(option_pos + 1 == argc) { // missing parameter
|
||||||
|
exit_status = 1;
|
||||||
|
print_helptext = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++option_pos;
|
||||||
|
settings::pc_list = argv[option_pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!seen_switch_gen_policy) {
|
if(!seen_switch_gen_policy) {
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
namespace settings {
|
namespace settings {
|
||||||
SwitchGenerationPolicy switch_generation_policy = SGP_SwitchPerFunc;
|
SwitchGenerationPolicy switch_generation_policy = SGP_SwitchPerFunc;
|
||||||
|
std::string pc_list = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace settings {
|
namespace settings {
|
||||||
/// Controls how the eh_elf switches are generated
|
/// Controls how the eh_elf switches are generated
|
||||||
enum SwitchGenerationPolicy {
|
enum SwitchGenerationPolicy {
|
||||||
|
@ -12,4 +14,5 @@ namespace settings {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SwitchGenerationPolicy switch_generation_policy;
|
extern SwitchGenerationPolicy switch_generation_policy;
|
||||||
|
extern std::string pc_list;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue