Skip to content

Commit

Permalink
Added dynamic TargetDescription
Browse files Browse the repository at this point in the history
TargetDescription dynamically generates the "master" target description
contents (target.xml), so that we only have to manage the individual
concrete CPU features (like foo-sse.xml, for instance). TargetDescription
will generate the xml contents that includes the used features.

Removed combinatorial target.xml files

These are now handled by `TargetDescription` instead.

This unblocks the #3776 PR (AVX512 support) from getting pulled in,
though that PR will need to take this PR into account.
  • Loading branch information
theIDinside authored and rocallahan committed Nov 26, 2024
1 parent 3121089 commit f7f4c29
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 150 deletions.
7 changes: 1 addition & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ set(RR_SOURCES
src/SourcesCommand.cc
src/StdioMonitor.cc
src/SysCpuMonitor.cc
src/TargetDescription.cc
src/Task.cc
src/ThreadGroup.cc
src/TraceeAttentionSet.cc
Expand Down Expand Up @@ -797,12 +798,6 @@ set(RR_GDB_RESOURCES
64bit-seg.xml
64bit-sse.xml
64bit-pkeys.xml
amd64-pkeys-linux.xml
amd64-avx-linux.xml
amd64-linux.xml
i386-pkeys-linux.xml
i386-avx-linux.xml
i386-linux.xml
aarch64-core.xml
aarch64-fpu.xml
aarch64-pauth.xml
Expand Down
1 change: 1 addition & 0 deletions src/GdbServer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ void GdbServer::dispatch_regs_request(const Registers& regs,
return;
}
vector<GdbServerRegisterValue> rs;
rs.reserve(end);
for (GdbServerRegister r = GdbServerRegister(0); r <= end; r = GdbServerRegister(r + 1)) {
rs.push_back(get_reg(regs, extra_regs, r));
}
Expand Down
43 changes: 13 additions & 30 deletions src/GdbServerConnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "DebuggerExtensionCommandHandler.h"
#include "ReplaySession.h"
#include "ScopedFd.h"
#include "TargetDescription.h"
#include "core.h"
#include "log.h"

Expand Down Expand Up @@ -67,7 +68,8 @@ GdbServerConnection::GdbServerConnection(ThreadGroupUid tguid, const Features& f
multiprocess_supported_(false),
hwbreak_supported_(false),
swbreak_supported_(false),
list_threads_in_stop_reply_(false) {
list_threads_in_stop_reply_(false),
target_description(nullptr) {
#ifndef REVERSE_EXECUTION
features_.reverse_execution = false;
#endif
Expand Down Expand Up @@ -111,7 +113,7 @@ unique_ptr<GdbServerConnection> GdbServerConnection::await_connection(
Task* t, ScopedFd& listen_fd, const GdbServerConnection::Features& features) {
auto dbg = unique_ptr<GdbServerConnection>(
new GdbServerConnection(t->thread_group()->tguid(), features));
dbg->set_cpu_features(get_cpu_features(t->arch()));
dbg->set_cpu_features(t->arch());
dbg->await_debugger(listen_fd);
return dbg;
}
Expand Down Expand Up @@ -503,29 +505,6 @@ static string read_target_desc(const char* file_name) {
return ss.str();
}

static const char* target_description_name(uint32_t cpu_features) {
// This doesn't scale, but it's what gdb does...
switch (cpu_features) {
case 0:
return "i386-linux.xml";
case GdbServerConnection::CPU_X86_64:
return "amd64-linux.xml";
case GdbServerConnection::CPU_AVX:
return "i386-avx-linux.xml";
case GdbServerConnection::CPU_X86_64 | GdbServerConnection::CPU_AVX:
return "amd64-avx-linux.xml";
case GdbServerConnection::CPU_PKU | GdbServerConnection::CPU_AVX:
return "i386-pkeys-linux.xml";
case GdbServerConnection::CPU_X86_64 | GdbServerConnection::CPU_PKU | GdbServerConnection::CPU_AVX:
return "amd64-pkeys-linux.xml";
case GdbServerConnection::CPU_AARCH64:
return "aarch64-core.xml";
default:
FATAL() << "Unknown features";
return nullptr;
}
}

bool GdbServerConnection::xfer(const char* name, char* args) {
const char* mode = args;
args = strchr(args, ':');
Expand Down Expand Up @@ -609,11 +588,8 @@ bool GdbServerConnection::xfer(const char* name, char* args) {
return false;
}

string target_desc =
read_target_desc((strcmp(annex, "") && strcmp(annex, "target.xml"))
? annex
: target_description_name(cpu_features_));
write_xfer_response(target_desc.c_str(), target_desc.size(), offset, len);
const auto desc = strcmp(annex, "") && strcmp(annex, "target.xml") ? read_target_desc(annex) : target_description->to_xml();
write_xfer_response(desc.c_str(), desc.size(), offset, len);
return false;
}

Expand Down Expand Up @@ -2335,4 +2311,11 @@ bool GdbServerConnection::is_connection_alive() { return connection_alive_; }

bool GdbServerConnection::is_pass_signal(int sig) { return pass_signals.find(to_gdb_signum(sig)) != pass_signals.end(); }

void GdbServerConnection::set_cpu_features(SupportedArch arch) {
cpu_features_ = get_cpu_features(arch);
DEBUG_ASSERT(target_description == nullptr &&
"Target description already created");
target_description = std::make_unique<TargetDescription>(arch, cpu_features_);
}

} // namespace rr
5 changes: 4 additions & 1 deletion src/GdbServerConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "ReplaySession.h"
#include "ReplayTimeline.h"
#include "ScopedFd.h"
#include "TargetDescription.h"
#include "TaskishUid.h"
#include "core.h"

Expand Down Expand Up @@ -750,7 +751,8 @@ class GdbServerConnection {
CPU_AARCH64 = 0x4,
CPU_PKU = 0x8
};
void set_cpu_features(uint32_t features) { cpu_features_ = features; }

void set_cpu_features(SupportedArch arch);
uint32_t cpu_features() const { return cpu_features_; }

GdbServerConnection(ThreadGroupUid tguid, const Features& features);
Expand Down Expand Up @@ -877,6 +879,7 @@ class GdbServerConnection {
bool hwbreak_supported_; // client supports hwbreak extension
bool swbreak_supported_; // client supports swbreak extension
bool list_threads_in_stop_reply_; // client requested threads: and thread-pcs: in stop replies
std::unique_ptr<TargetDescription> target_description;
};

} // namespace rr
Expand Down
132 changes: 132 additions & 0 deletions src/TargetDescription.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */

#include "TargetDescription.h"

#include <sstream>

#include "GdbServerConnection.h"
#include "kernel_abi.h"

namespace rr {

class FeatureStream {
public:
string result() { return stream.str(); }

template <typename Any>
friend FeatureStream& operator<<(FeatureStream& stream, Any any);

private:
stringstream stream;
const char* arch_prefix;
};

template <typename Any>
FeatureStream& operator<<(FeatureStream& stream, Any any) {
stream.stream << any;
return stream;
}

template <>
FeatureStream& operator<<(FeatureStream& stream, rr::SupportedArch arch) {
stream << "<architecture>";
switch (arch) {
case rr::x86:
stream << "i386";
stream.arch_prefix = "32bit-";
break;
case rr::x86_64:
stream << "i386:x86-64";
stream.arch_prefix = "64bit-";
break;
case rr::aarch64:
stream << "aarch64";
stream.arch_prefix = "aarch64-";
break;
}
stream << "</architecture>\n";
return stream;
}

template <>
FeatureStream& operator<<(FeatureStream& stream, TargetFeature feature) {
DEBUG_ASSERT(stream.arch_prefix != nullptr &&
"No architecture has been provided to description");
stream << R"( <xi:include href=")" << stream.arch_prefix;
switch (feature) {
case TargetFeature::Core:
stream << "core.xml";
break;
case TargetFeature::Linux:
stream << "linux.xml";
break;
case TargetFeature::SSE:
stream << "sse.xml";
break;
case TargetFeature::AVX:
stream << "avx.xml";
break;
case TargetFeature::PKeys:
stream << "pkeys.xml";
break;
case TargetFeature::Segment:
stream << "seg.xml";
break;
case TargetFeature::FPU:
stream << "fpu.xml";
break;
}
stream << R"("/>)" << '\n';
return stream;
}

TargetDescription::TargetDescription(rr::SupportedArch arch,
uint32_t cpu_features)
: arch(arch), target_features() {

// default-assumed registers per arch
switch (arch) {
case rr::x86:
target_features.push_back(TargetFeature::Core);
target_features.push_back(TargetFeature::SSE);
target_features.push_back(TargetFeature::Linux);
break;
case rr::x86_64:
target_features.push_back(TargetFeature::Core);
target_features.push_back(TargetFeature::SSE);
target_features.push_back(TargetFeature::Linux);
target_features.push_back(TargetFeature::Segment);
break;
case rr::aarch64:
target_features.push_back(TargetFeature::Core);
target_features.push_back(TargetFeature::FPU);
break;
}

if (cpu_features & rr::GdbServerConnection::CPU_AVX) {
DEBUG_ASSERT((arch == rr::x86 || arch == rr::x86_64) && "unexpected arch");
target_features.push_back(TargetFeature::AVX);
}

if (cpu_features & rr::GdbServerConnection::CPU_PKU) {
DEBUG_ASSERT((arch == rr::x86 || arch == rr::x86_64) && "unexpected arch");
target_features.push_back(TargetFeature::PKeys);
}
}

static const char header[] = R"(<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target>
)";

string TargetDescription::to_xml() const {
FeatureStream fs;
fs << header << arch << "<osabi>GNU/Linux</osabi>\n";
for (const auto feature : target_features) {
fs << feature;
}
fs << "</target>";

return fs.result();
}
} // namespace rr
35 changes: 35 additions & 0 deletions src/TargetDescription.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */

#ifndef RR_TARGET_DESCRIPTION_H_
#define RR_TARGET_DESCRIPTION_H_

#include <cstdint>

#include "kernel_abi.h"

using namespace std;

namespace rr {

enum class TargetFeature : uint32_t {
Core = 0,
SSE,
Linux,
Segment,
AVX,
PKeys,
FPU,
};

class TargetDescription {
public:
explicit TargetDescription(rr::SupportedArch arch, uint32_t cpu_features);
string to_xml() const;

private:
SupportedArch arch;
vector<TargetFeature> target_features;
};
} // namespace rr

#endif /* RR_TARGET_DESCRIPTION_H_ */
19 changes: 0 additions & 19 deletions third-party/gdb/amd64-avx-linux.xml

This file was deleted.

19 changes: 0 additions & 19 deletions third-party/gdb/amd64-linux.xml

This file was deleted.

20 changes: 0 additions & 20 deletions third-party/gdb/amd64-pkeys-linux.xml

This file was deleted.

18 changes: 0 additions & 18 deletions third-party/gdb/i386-avx-linux.xml

This file was deleted.

Loading

0 comments on commit f7f4c29

Please sign in to comment.