|
@@ -208,41 +208,22 @@ rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * rproc_elf_find_rsc_table() - find the resource table
|
|
|
- * @rproc: the rproc handle
|
|
|
- * @fw: the ELF firmware image
|
|
|
- * @tablesz: place holder for providing back the table size
|
|
|
- *
|
|
|
- * This function finds the resource table inside the remote processor's
|
|
|
- * firmware. It is used both upon the registration of @rproc (in order
|
|
|
- * to look for and register the supported virito devices), and when the
|
|
|
- * @rproc is booted.
|
|
|
- *
|
|
|
- * Returns the pointer to the resource table if it is found, and write its
|
|
|
- * size into @tablesz. If a valid table isn't found, NULL is returned
|
|
|
- * (and @tablesz isn't set).
|
|
|
- */
|
|
|
-static struct resource_table *
|
|
|
-rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
|
|
|
- int *tablesz)
|
|
|
+static struct elf32_shdr *
|
|
|
+find_table(struct device *dev, struct elf32_hdr *ehdr, size_t fw_size)
|
|
|
{
|
|
|
- struct elf32_hdr *ehdr;
|
|
|
struct elf32_shdr *shdr;
|
|
|
+ int i;
|
|
|
const char *name_table;
|
|
|
- struct device *dev = &rproc->dev;
|
|
|
struct resource_table *table = NULL;
|
|
|
- int i;
|
|
|
- const u8 *elf_data = fw->data;
|
|
|
+ const u8 *elf_data = (void *)ehdr;
|
|
|
|
|
|
- ehdr = (struct elf32_hdr *)elf_data;
|
|
|
+ /* look for the resource table and handle it */
|
|
|
shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
|
|
|
name_table = elf_data + shdr[ehdr->e_shstrndx].sh_offset;
|
|
|
|
|
|
- /* look for the resource table and handle it */
|
|
|
for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
|
|
|
- int size = shdr->sh_size;
|
|
|
- int offset = shdr->sh_offset;
|
|
|
+ u32 size = shdr->sh_size;
|
|
|
+ u32 offset = shdr->sh_offset;
|
|
|
|
|
|
if (strcmp(name_table + shdr->sh_name, ".resource_table"))
|
|
|
continue;
|
|
@@ -250,7 +231,7 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
|
|
|
table = (struct resource_table *)(elf_data + offset);
|
|
|
|
|
|
/* make sure we have the entire table */
|
|
|
- if (offset + size > fw->size) {
|
|
|
+ if (offset + size > fw_size || offset + size < size) {
|
|
|
dev_err(dev, "resource table truncated\n");
|
|
|
return NULL;
|
|
|
}
|
|
@@ -280,10 +261,46 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- *tablesz = shdr->sh_size;
|
|
|
- break;
|
|
|
+ return shdr;
|
|
|
}
|
|
|
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * rproc_elf_find_rsc_table() - find the resource table
|
|
|
+ * @rproc: the rproc handle
|
|
|
+ * @fw: the ELF firmware image
|
|
|
+ * @tablesz: place holder for providing back the table size
|
|
|
+ *
|
|
|
+ * This function finds the resource table inside the remote processor's
|
|
|
+ * firmware. It is used both upon the registration of @rproc (in order
|
|
|
+ * to look for and register the supported virito devices), and when the
|
|
|
+ * @rproc is booted.
|
|
|
+ *
|
|
|
+ * Returns the pointer to the resource table if it is found, and write its
|
|
|
+ * size into @tablesz. If a valid table isn't found, NULL is returned
|
|
|
+ * (and @tablesz isn't set).
|
|
|
+ */
|
|
|
+static struct resource_table *
|
|
|
+rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
|
|
|
+ int *tablesz)
|
|
|
+{
|
|
|
+ struct elf32_hdr *ehdr;
|
|
|
+ struct elf32_shdr *shdr;
|
|
|
+ struct device *dev = &rproc->dev;
|
|
|
+ struct resource_table *table = NULL;
|
|
|
+ const u8 *elf_data = fw->data;
|
|
|
+
|
|
|
+ ehdr = (struct elf32_hdr *)elf_data;
|
|
|
+
|
|
|
+ shdr = find_table(dev, ehdr, fw->size);
|
|
|
+ if (!shdr)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ table = (struct resource_table *)(elf_data + shdr->sh_offset);
|
|
|
+ *tablesz = shdr->sh_size;
|
|
|
+
|
|
|
return table;
|
|
|
}
|
|
|
|