aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2021-09-17 15:54:31 +0000
committerAndrew Turner <andrew@FreeBSD.org>2021-10-11 09:39:49 +0000
commitaacbf3fb8482226fcdf6a19af1011f9d65c20f2a (patch)
treec08dc5f6f100eaec00d00c1d4d54783bb62eb514
parenta90ebeb5feea63c9d8377cbc74e0442156a0ed15 (diff)
downloadsrc-aacbf3fb8482226fcdf6a19af1011f9d65c20f2a.tar.gz
src-aacbf3fb8482226fcdf6a19af1011f9d65c20f2a.zip
Teach the readelf about arm64 gnu properties
On arm64 binaries can be tagged as using BTI or PAC. Add support to decode these to the elftoolchain readelf. To simplify the code use a table based method to find the flag description table. Reviewed by: emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32315
-rw-r--r--contrib/elftoolchain/readelf/readelf.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index d5f9205e354d..f33519112eb4 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -229,6 +229,12 @@ struct flag_desc {
const char *desc;
};
+struct flag_desc_list {
+ uint32_t type;
+ const char *desc_str;
+ struct flag_desc *desc;
+};
+
struct mips_option {
uint64_t flag;
const char *desc;
@@ -3539,15 +3545,50 @@ dump_gnu_hash(struct readelf *re, struct section *s)
free(bl);
}
+static struct flag_desc gnu_property_aarch64_feature_1_and_bits[] = {
+ { GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI" },
+ { GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC" },
+ { 0, NULL }
+};
+
+static struct flag_desc_list gnu_property_aarch64[] = {
+ {
+ GNU_PROPERTY_AARCH64_FEATURE_1_AND,
+ "AArch64 features",
+ gnu_property_aarch64_feature_1_and_bits
+ },
+ { 0, NULL, NULL }
+};
+
static struct flag_desc gnu_property_x86_feature_1_and_bits[] = {
{ GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT" },
{ GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK" },
{ 0, NULL }
};
+static struct flag_desc_list gnu_property_x86[] = {
+ {
+ GNU_PROPERTY_X86_FEATURE_1_AND,
+ "x64 features",
+ gnu_property_x86_feature_1_and_bits
+ },
+ { 0, NULL, NULL }
+};
+
+static struct {
+ unsigned int emachine;
+ struct flag_desc_list *flag_list;
+} gnu_property_archs[] = {
+ { EM_AARCH64, gnu_property_aarch64 },
+ { EM_X86_64, gnu_property_x86 },
+ { 0, NULL }
+};
+
static void
dump_gnu_property_type_0(struct readelf *re, const char *buf, size_t sz)
{
+ struct flag_desc_list *desc_list;
+ struct flag_desc *desc;
size_t i;
uint32_t type, prop_sz;
@@ -3566,19 +3607,35 @@ dump_gnu_property_type_0(struct readelf *re, const char *buf, size_t sz)
if (type >= GNU_PROPERTY_LOPROC &&
type <= GNU_PROPERTY_HIPROC) {
- if (re->ehdr.e_machine != EM_X86_64) {
+ desc_list = NULL;
+ for (i = 0; gnu_property_archs[i].flag_list != NULL;
+ i++) {
+ if (gnu_property_archs[i].emachine ==
+ re->ehdr.e_machine) {
+ desc_list =
+ gnu_property_archs[i].flag_list;
+ break;
+ }
+ }
+ if (desc_list == NULL) {
printf("machine type %x unknown\n",
re->ehdr.e_machine);
goto unknown;
}
- switch (type) {
- case GNU_PROPERTY_X86_FEATURE_1_AND:
- printf("x86 features:");
+
+ desc = NULL;
+ for (i = 0; desc_list[i].desc != NULL; i++) {
+ if (desc_list[i].type == type) {
+ desc = desc_list[i].desc;
+ break;
+ }
+ }
+ if (desc != NULL) {
+ printf("%s:", desc_list[i].desc_str);
if (prop_sz != 4)
goto bad;
- dump_flags(gnu_property_x86_feature_1_and_bits,
+ dump_flags(desc,
*(const uint32_t *)(const void *)buf);
- break;
}
}