From: Srinath Parvathaneni <[email protected]>
Add support for the FEAT_S1POE POR_EL0 register on AArch64.
This patch adds POR_EL0 to the AArch64 register set and reads/writes it
using the NT_ARM_POE ptrace regset.
With this change, POR_EL0 is available through:
* info registers
* info registers por_el0
* p $por_el0
* p/x $por_el0
* set $por_el0 = <value>
Example:
(gdb) info register por_el0
por_el0 0x7 [ P15=--- P14=--- P13=--- P12=--- P11=--- P10=--- P9=--- P8=--- P7=--- P6=--- P5=--- P4=--- P3=--- P2=--- P1=--- P0=rwx ]
(gdb) set $por_el0=0xffffffff77777777
(gdb) info register por_el0
por_el0 0xffffffff77777777 [ P15=??? P14=??? P13=??? P12=??? P11=??? P10=??? P9=??? P8=??? P7=rwx P6=rwx P5=rwx P4=rwx P3=rwx P2=rwx P1=rwx P0=rwx ]
(gdb) p $por_el0
$1 = [ P15=??? P14=??? P13=??? P12=??? P11=??? P10=??? P9=??? P8=??? P7=rwx P6=rwx P5=rwx P4=rwx P3=rwx P2=rwx P1=rwx P0=rwx ]
(gdb) p/x $por_el0
$2 = 0xffffffff77777777
(gdb) set $por_el0=0x57
(gdb) info register por_el0
por_el0 0x57 [ P15=--- P14=--- P13=--- P12=--- P11=--- P10=--- P9=--- P8=--- P7=--- P6=--- P5=--- P4=--- P3=--- P2=--- P1=rw- P0=rwx ]
(gdb) set $por_el0=0xf7f7f7f7f7f7f7f7
(gdb) info register por_el0
por_el0 0xf7f7f7f7f7f7f7f7 [ P15=??? P14=rwx P13=??? P12=rwx P11=??? P10=rwx P9=??? P8=rwx P7=??? P6=rwx P5=??? P4=rwx P3=??? P2=rwx P1=??? P0=rwx ]
(gdb)
---
gdb/Makefile.in | 2 ++
gdb/aarch64-linux-nat.c | 64 +++++++++++++++++++++++++++++++++
gdb/aarch64-tdep.c | 23 ++++++++++++
gdb/aarch64-tdep.h | 10 ++++++
gdb/arch/aarch64-poe-linux.h | 29 +++++++++++++++
gdb/arch/aarch64.c | 4 +++
gdb/arch/aarch64.h | 8 ++++-
gdb/features/Makefile | 1 +
gdb/features/aarch64-poe.c | 68 ++++++++++++++++++++++++++++++++++++
gdb/features/aarch64-poe.xml | 47 +++++++++++++++++++++++++
gdb/nat/aarch64-poe-linux.h | 29 +++++++++++++++
11 files changed, 284 insertions(+), 1 deletion(-)
create mode 100644 gdb/arch/aarch64-poe-linux.h
create mode 100644 gdb/features/aarch64-poe.c
create mode 100644 gdb/features/aarch64-poe.xml
create mode 100644 gdb/nat/aarch64-poe-linux.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 57f384170ab..3dc9cd07dcb 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1292,6 +1292,7 @@ HFILES_NO_SRCDIR = \
arch/aarch32.h \
arch/aarch64-fpmr-linux.h \
arch/aarch64-gcs-linux.h \
+ arch/aarch64-poe-linux.h \
arch/aarch64.h \
arch/aarch64-insn.h \
arch/aarch64-mte.h \
@@ -1540,6 +1541,7 @@ HFILES_NO_SRCDIR = \
namespace.h \
nat/aarch64-fpmr-linux.h \
nat/aarch64-gcs-linux.h \
+ nat/aarch64-poe-linux.h \
nat/aarch64-hw-point.h \
nat/aarch64-linux.h \
nat/aarch64-linux-hw-point.h \
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 52ace4aab41..8e29c42908c 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -34,6 +34,7 @@
#include "arch/arm.h"
#include "nat/aarch64-fpmr-linux.h"
#include "nat/aarch64-gcs-linux.h"
+#include "nat/aarch64-poe-linux.h"
#include "nat/aarch64-linux.h"
#include "nat/aarch64-linux-hw-point.h"
#include "nat/aarch64-mte-linux-ptrace.h"
@@ -602,6 +603,54 @@ store_gcsregs_to_thread (regcache *regcache)
perror_with_name (_("Unable to store GCS registers"));
}
+/* Fill GDB's register array with the POE register value from the current
+ thread. */
+
+static void
+fetch_poeregs_from_thread (regcache *regcache)
+{
+ aarch64_gdbarch_tdep *tdep
+ = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
+
+ gdb_assert (tdep->has_poe ());
+
+ uint64_t user_poe;
+ iovec iovec;
+
+ iovec.iov_base = &user_poe;
+ iovec.iov_len = sizeof (user_poe);
+
+ int tid = get_ptrace_pid (regcache->ptid ());
+ if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_POE, &iovec) != 0)
+ perror_with_name (_("Unable to fetch POE register"));
+
+ regcache->raw_supply (tdep->poe_regnum, &user_poe);
+}
+
+/* Store the NT_ARM_POE register contents from GDB's REGCACHE to the
+ thread associated with REGCACHE. */
+
+static void
+store_poeregs_to_thread (struct regcache *regcache)
+{
+ aarch64_gdbarch_tdep *tdep
+ = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
+
+ gdb_assert (tdep->has_poe ());
+
+ int tid = regcache->ptid ().lwp ();
+
+ iovec iovec;
+ uint64_t user_poe;
+ iovec.iov_base = &user_poe;
+ iovec.iov_len = sizeof (user_poe);
+
+ regcache->raw_collect (tdep->poe_regnum, &user_poe);
+
+ if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_POE, &iovec) != 0)
+ perror_with_name (_("Unable to store POE register"));
+}
+
/* Fill GDB's REGCACHE with the FPMR register set content from the
thread associated with REGCACHE. */
@@ -683,6 +732,9 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
if (tdep->has_gcs_linux ())
fetch_gcsregs_from_thread (regcache);
+ if (tdep->has_poe ())
+ fetch_poeregs_from_thread (regcache);
+
if (tdep->has_fpmr ())
fetch_fpmr_from_thread (regcache);
}
@@ -722,6 +774,9 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
&& (regno == tdep->gcs_reg_base || regno == tdep->gcs_linux_reg_base
|| regno == tdep->gcs_linux_reg_base + 1))
fetch_gcsregs_from_thread (regcache);
+ /* POE register? */
+ else if (tdep->has_poe () && (regno == tdep->poe_regnum))
+ fetch_poeregs_from_thread (regcache);
/* FPMR? */
else if (tdep->has_fpmr () && (regno == tdep->fpmr_regnum))
fetch_fpmr_from_thread (regcache);
@@ -802,6 +857,9 @@ aarch64_store_registers (struct regcache *regcache, int regno)
if (tdep->has_fpmr ())
store_fpmr_to_thread (regcache);
+
+ if (tdep->has_poe ())
+ store_poeregs_to_thread (regcache);
}
/* General purpose register? */
else if (regno < AARCH64_V0_REGNUM)
@@ -836,6 +894,9 @@ aarch64_store_registers (struct regcache *regcache, int regno)
/* FPMR? */
else if (tdep->has_fpmr () && regno == tdep->fpmr_regnum)
store_fpmr_to_thread (regcache);
+ /* POE register? */
+ else if (tdep->has_poe () && regno == tdep->poe_regnum)
+ store_poeregs_to_thread (regcache);
/* PAuth registers are read-only. */
}
@@ -1024,6 +1085,9 @@ aarch64_linux_nat_target::read_description ()
/* Check for FPMR. */
features.fpmr = hwcap2 & HWCAP2_FPMR;
+ /* Check for POE support. */
+ features.poe = hwcap2 & HWCAP2_POE;
+
return aarch64_read_description (features);
}
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index a84da1fd59e..2e86d6e0452 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -164,6 +164,11 @@ static const char *const aarch64_gcs_register_names[] = {
"gcspr"
};
+static const char *const aarch64_poe_register_names[] = {
+ /* Permission Overlay Extension Register. */
+ "por_el0"
+};
+
static const char *const aarch64_gcs_linux_register_names[] = {
/* Field in struct user_gcs. */
"gcs_features_enabled",
@@ -4136,6 +4141,10 @@ aarch64_features_from_target_desc (const struct target_desc *tdesc)
features.fpmr = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpmr")
!= nullptr);
+ /* Check for POE feature. */
+ features.poe = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.poe")
+ != nullptr);
+
return features;
}
@@ -4556,6 +4565,19 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
fpmr_regnum, "fpmr");
}
+ int poe_regnum = -1;
+ const struct tdesc_feature *feature_poe
+ = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.poe");
+ if (feature_poe != nullptr)
+ {
+ poe_regnum = num_regs;
+ for (i = 0; i < ARRAY_SIZE (aarch64_poe_register_names); i++)
+ valid_p &= tdesc_numbered_register (feature_poe, tdesc_data.get (),
+ poe_regnum + i,
+ aarch64_poe_register_names[i]);
+ num_regs++;
+ }
+
int first_sme_regnum = -1;
int first_sme2_regnum = -1;
int first_sme_pseudo_regnum = -1;
@@ -4756,6 +4778,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->gcs_reg_base = first_gcs_regnum;
tdep->gcs_linux_reg_base = first_gcs_linux_regnum;
tdep->fpmr_regnum = fpmr_regnum;
+ tdep->poe_regnum = poe_regnum;
/* Set the SME register set details. The pseudo-registers will be adjusted
later. */
diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
index dff05a08f84..3c5d10beee5 100644
--- a/gdb/aarch64-tdep.h
+++ b/gdb/aarch64-tdep.h
@@ -208,6 +208,16 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base
return gcs_linux_reg_base != -1;
}
+ /* POE register. This is -1 if no POE feature is available. */
+ int poe_regnum = -1;
+
+ /* Returns true if the target supports the POE feature. */
+ bool
+ has_poe () const
+ {
+ return poe_regnum != -1;
+ }
+
/* First FPMR register. This is -1 if FPMR is not supported. */
int fpmr_regnum = -1;
diff --git a/gdb/arch/aarch64-poe-linux.h b/gdb/arch/aarch64-poe-linux.h
new file mode 100644
index 00000000000..8623fa43b54
--- /dev/null
+++ b/gdb/arch/aarch64-poe-linux.h
@@ -0,0 +1,29 @@
+/* Common Linux target-dependent definitions for AArch64 POE
+
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_ARCH_AARCH64_POE_LINUX_H
+#define GDB_ARCH_AARCH64_POE_LINUX_H
+
+/* Feature check for Permission Overlay Extension. */
+#define AARCH64_HWCAP2_POE (1ULL << 63)
+
+/* Data or instruction abort caused by Protection Key Violation. */
+#define AARCH64_SEGV_PKUERR 4
+
+#endif /* GDB_ARCH_AARCH64_POE_LINUX_H. */
diff --git a/gdb/arch/aarch64.c b/gdb/arch/aarch64.c
index 2401a325b7b..a567938d06d 100644
--- a/gdb/arch/aarch64.c
+++ b/gdb/arch/aarch64.c
@@ -28,6 +28,7 @@
#include "../features/aarch64-sme2.c"
#include "../features/aarch64-tls.c"
#include "../features/aarch64-gcs.c"
+#include "../features/aarch64-poe.c"
#include "../features/aarch64-gcs-linux.c"
/* See arch/aarch64.h. */
@@ -77,6 +78,9 @@ aarch64_create_target_description (const aarch64_features &features)
if (features.fpmr)
regnum = create_feature_aarch64_fpmr (tdesc.get (), regnum);
+ if (features.poe)
+ regnum = create_feature_aarch64_poe (tdesc.get (), regnum);
+
return tdesc;
}
diff --git a/gdb/arch/aarch64.h b/gdb/arch/aarch64.h
index cf7318cbe74..ba90d55c3bb 100644
--- a/gdb/arch/aarch64.h
+++ b/gdb/arch/aarch64.h
@@ -35,6 +35,8 @@ struct aarch64_features
bool pauth = false;
bool mte = false;
bool fpmr = false;
+ /* Whether the Permission Overlay Extension (FEAT_S1POE) is supported. */
+ bool poe = false;
/* A positive TLS value indicates the number of TLS registers available. */
uint8_t tls = 0;
@@ -70,7 +72,8 @@ inline bool operator==(const aarch64_features &lhs, const aarch64_features &rhs)
&& lhs.sme2 == rhs.sme2
&& lhs.gcs == rhs.gcs
&& lhs.gcs_linux == rhs.gcs_linux
- && lhs.fpmr == rhs.fpmr;
+ && lhs.fpmr == rhs.fpmr
+ && lhs.poe == rhs.poe;
}
namespace std
@@ -103,6 +106,9 @@ namespace std
/* FPMR feature. */
h = h << 1 | features.fpmr;
+
+ /* POE feature. */
+ h = h << 1 | features.poe;
return h;
}
};
diff --git a/gdb/features/Makefile b/gdb/features/Makefile
index 161a7453d66..cc77e5bb652 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -207,6 +207,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
aarch64-pauth.xml \
aarch64-mte.xml \
aarch64-gcs.xml \
+ aarch64-poe.xml \
aarch64-gcs-linux.xml \
arc/v1-core.xml \
arc/v1-aux.xml \
diff --git a/gdb/features/aarch64-poe.c b/gdb/features/aarch64-poe.c
new file mode 100644
index 00000000000..4bd795e9fe6
--- /dev/null
+++ b/gdb/features/aarch64-poe.c
@@ -0,0 +1,68 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: aarch64-poe.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_aarch64_poe (struct target_desc *result, long regnum)
+{
+ struct tdesc_feature *feature;
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.poe");
+ tdesc_type_with_fields *type_with_fields;
+ type_with_fields = tdesc_create_enum (feature, "por_el0_fmt", 4);
+ tdesc_add_enum_value (type_with_fields, 0, "---");
+ tdesc_add_enum_value (type_with_fields, 1, "r--");
+ tdesc_add_enum_value (type_with_fields, 2, "--x");
+ tdesc_add_enum_value (type_with_fields, 3, "r-x");
+ tdesc_add_enum_value (type_with_fields, 4, "-w-");
+ tdesc_add_enum_value (type_with_fields, 5, "rw-");
+ tdesc_add_enum_value (type_with_fields, 6, "-wx");
+ tdesc_add_enum_value (type_with_fields, 7, "rwx");
+ tdesc_add_enum_value (type_with_fields, 8, "???");
+ tdesc_add_enum_value (type_with_fields, 9, "???");
+ tdesc_add_enum_value (type_with_fields, 10, "???");
+ tdesc_add_enum_value (type_with_fields, 11, "???");
+ tdesc_add_enum_value (type_with_fields, 12, "???");
+ tdesc_add_enum_value (type_with_fields, 13, "???");
+ tdesc_add_enum_value (type_with_fields, 14, "???");
+ tdesc_add_enum_value (type_with_fields, 15, "???");
+
+ type_with_fields = tdesc_create_flags (feature, "por_el0_flags", 8);
+ tdesc_type *field_type;
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P15", 60, 63, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P14", 56, 59, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P13", 52, 55, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P12", 48, 51, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P11", 44, 47, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P10", 40, 43, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P9", 36, 39, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P8", 32, 35, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P7", 28, 31, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P6", 24, 27, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P5", 20, 23, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P4", 16, 19, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P3", 12, 15, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P2", 8, 11, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P1", 4, 7, field_type);
+ field_type = tdesc_named_type (feature, "por_el0_fmt");
+ tdesc_add_typed_bitfield (type_with_fields, "P0", 0, 3, field_type);
+
+ tdesc_create_reg (feature, "por_el0", regnum++, 1, "system", 64, "por_el0_flags");
+ return regnum;
+}
diff --git a/gdb/features/aarch64-poe.xml b/gdb/features/aarch64-poe.xml
new file mode 100644
index 00000000000..58fc4f80d5c
--- /dev/null
+++ b/gdb/features/aarch64-poe.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2026 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.aarch64.poe">
+ <enum id="por_el0_fmt" size="4">
+ <evalue name="---" value="0"/>
+ <evalue name="r--" value="1"/>
+ <evalue name="--x" value="2"/>
+ <evalue name="r-x" value="3"/>
+ <evalue name="-w-" value="4"/>
+ <evalue name="rw-" value="5"/>
+ <evalue name="-wx" value="6"/>
+ <evalue name="rwx" value="7"/>
+ <evalue name="???" value="8"/>
+ <evalue name="???" value="9"/>
+ <evalue name="???" value="10"/>
+ <evalue name="???" value="11"/>
+ <evalue name="???" value="12"/>
+ <evalue name="???" value="13"/>
+ <evalue name="???" value="14"/>
+ <evalue name="???" value="15"/>
+ </enum>
+ <flags id="por_el0_flags" size="8">
+ <field name="P15" start="60" end="63" type="por_el0_fmt"/>
+ <field name="P14" start="56" end="59" type="por_el0_fmt"/>
+ <field name="P13" start="52" end="55" type="por_el0_fmt"/>
+ <field name="P12" start="48" end="51" type="por_el0_fmt"/>
+ <field name="P11" start="44" end="47" type="por_el0_fmt"/>
+ <field name="P10" start="40" end="43" type="por_el0_fmt"/>
+ <field name="P9" start="36" end="39" type="por_el0_fmt"/>
+ <field name="P8" start="32" end="35" type="por_el0_fmt"/>
+ <field name="P7" start="28" end="31" type="por_el0_fmt"/>
+ <field name="P6" start="24" end="27" type="por_el0_fmt"/>
+ <field name="P5" start="20" end="23" type="por_el0_fmt"/>
+ <field name="P4" start="16" end="19" type="por_el0_fmt"/>
+ <field name="P3" start="12" end="15" type="por_el0_fmt"/>
+ <field name="P2" start="8" end="11" type="por_el0_fmt"/>
+ <field name="P1" start="4" end="7" type="por_el0_fmt"/>
+ <field name="P0" start="0" end="3" type="por_el0_fmt"/>
+ </flags>
+ <reg name="por_el0" bitsize="64" type="por_el0_flags" group="system"/>
+</feature>
diff --git a/gdb/nat/aarch64-poe-linux.h b/gdb/nat/aarch64-poe-linux.h
new file mode 100644
index 00000000000..f3d0256da3f
--- /dev/null
+++ b/gdb/nat/aarch64-poe-linux.h
@@ -0,0 +1,29 @@
+/* Common native Linux definitions for AArch64 Permission Overlay Extension.
+
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <asm/hwcap.h>
+#ifndef GDB_NAT_AARCH64_POE_LINUX_H
+#define GDB_NAT_AARCH64_POE_LINUX_H
+
+/* Feature check for Permission Overlay Extension. */
+#ifndef HWCAP2_POE
+#define HWCAP2_POE (1ULL << 63)
+#endif /* HWCAP2_POE. */
+
+#endif /* GDB_NAT_AARCH64_POE_LINUX_H. */
--
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.