+Huh? You just checked it against a constant so you know exactly what it
+/*
+ * Parse a single elf attribute.
+ */
+static int rv_parse_elf_attr_safe(unsigned char **dpp, unsigned char *p_end)
+{
+ unsigned char *p = *dpp;
+ unsigned char *str;
+ u64 tag, val;
+ u32 s_len;
+
+ if (decode_uleb128_safe(&p, &tag, p_end))
+ goto bad_attr;
+
+ switch (tag) {
+ case RV_ATTR_TAG_stack_align:
+ if (decode_uleb128_safe(&p, &val, p_end))
+ goto bad_attr;
+ if (!ELF_ATTR_TAG_EVEN(tag))
+ goto bad_attr;
is. This is just Static_assert(RV_ATTR_TAG_stack_align % 2 == 0) but at
run time. And you know that’s going to be the case, because the spec is
self-consistent by design (wouldn’t be a worthwhile spec otherwise).
+ rv_elf_attr_int(tag, val);The whole point of the even/odd split is so that when you *don’t* know
+ break;
+
+ case RV_ATTR_TAG_unaligned_access:
+ if (decode_uleb128_safe(&p, &val, p_end))
+ goto bad_attr;
+ if (!ELF_ATTR_TAG_EVEN(tag))
+ goto bad_attr;
+ rv_elf_attr_int(tag, val);
+ break;
+
+ case RV_ATTR_TAG_arch:
+ if (ELF_ATTR_TAG_EVEN(tag))
+ goto bad_attr;
+ str = p;
+ s_len = strnlen(p, p_end - p) + 1;
+ if ((p + s_len) > p_end)
+ goto bad_attr;
+ p += s_len;
+ rv_elf_attr_str(tag, str);
+ break;
+
+ default:
what the tag means you can still decode its value and thus know how to
skip past it. That is, *here* is where you need to be checking
even/odd, and deciding whether to treat it as a string or a ULEB128,
which is why I annotated *here* not one of the other case labels before.
+ memset(buf, 0, RV_ATTR_SEC_SZ);0 should be ENOEXEC not EIO? And surely in the < 0 case you want to be
+ pos = phdr->p_offset;
+ n = kernel_read(f, &buf, phdr->p_filesz, &pos);
+
+ if (n <= 0)
+ return -EIO;
forwarding on the exact error from kernel_read, not squashing it into
EIO?
+/*Both the executable and its interpreter matter.
+ * Hook invoked by generic elf loader to parse riscv specific elf segments.
+ */
+int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
+ bool is_interp, struct arch_elf_state *state)
+{
+ struct elf_phdr *phdr = _phdr;
+ int ret = 0;
+
+ if (phdr->p_type == PT_RISCV_ATTRIBUTES && !is_interp)