Page MenuHomeFreeBSD

D14267.id39046.diff
No OneTemporary

D14267.id39046.diff

Index: stand/common/load_elf.c
===================================================================
--- stand/common/load_elf.c
+++ stand/common/load_elf.c
@@ -87,6 +87,112 @@
u_int64_t __elfN(relocation_offset) = 0;
+extern void elf_wrong_field_size(void);
+#define CONVERT_FIELD(b, f, e) \
+ switch (sizeof((b)->f)) { \
+ case 2: \
+ (b)->f = e ## 16toh((b)->f); \
+ break; \
+ case 4: \
+ (b)->f = e ## 32toh((b)->f); \
+ break; \
+ case 8: \
+ (b)->f = e ## 64toh((b)->f); \
+ break; \
+ default: \
+ /* Force a link time error. */ \
+ elf_wrong_field_size(); \
+ break; \
+ }
+
+#define CONVERT_SWITCH(h, d, f) \
+ switch ((h)->e_ident[EI_DATA]) { \
+ case ELFDATA2MSB: \
+ f(d, be); \
+ break; \
+ case ELFDATA2LSB: \
+ f(d, le); \
+ break; \
+ default: \
+ return (EINVAL); \
+ }
+
+
+static int elf_header_convert(Elf_Ehdr *ehdr)
+{
+ /*
+ * Fixup ELF header endianness.
+ *
+ * The Xhdr structure was loaded using block read call to optimize file
+ * accesses. It might happen, that the endianness of the system memory
+ * is different that endianness of the ELF header. Swap fields here to
+ * guarantee that Xhdr always contain valid data regardless of
+ * architecture.
+ */
+#define HEADER_FIELDS(b, e) \
+ CONVERT_FIELD(b, e_type, e); \
+ CONVERT_FIELD(b, e_machine, e); \
+ CONVERT_FIELD(b, e_version, e); \
+ CONVERT_FIELD(b, e_entry, e); \
+ CONVERT_FIELD(b, e_phoff, e); \
+ CONVERT_FIELD(b, e_shoff, e); \
+ CONVERT_FIELD(b, e_flags, e); \
+ CONVERT_FIELD(b, e_ehsize, e); \
+ CONVERT_FIELD(b, e_phentsize, e); \
+ CONVERT_FIELD(b, e_phnum, e); \
+ CONVERT_FIELD(b, e_shentsize, e); \
+ CONVERT_FIELD(b, e_shnum, e); \
+ CONVERT_FIELD(b, e_shstrndx, e)
+
+ CONVERT_SWITCH(ehdr, ehdr, HEADER_FIELDS);
+
+#undef HEADER_FIELDS
+
+ return (0);
+}
+
+static int elf_program_header_convert(Elf_Ehdr *ehdr, Elf_Phdr *phdr)
+{
+#define PROGRAM_HEADER_FIELDS(b, e) \
+ CONVERT_FIELD(b, p_type, e); \
+ CONVERT_FIELD(b, p_flags, e); \
+ CONVERT_FIELD(b, p_offset, e); \
+ CONVERT_FIELD(b, p_vaddr, e); \
+ CONVERT_FIELD(b, p_paddr, e); \
+ CONVERT_FIELD(b, p_filesz, e); \
+ CONVERT_FIELD(b, p_memsz, e); \
+ CONVERT_FIELD(b, p_align, e)
+
+ CONVERT_SWITCH(ehdr, phdr, PROGRAM_HEADER_FIELDS);
+
+#undef PROGRAM_HEADER_FIELDS
+
+ return (0);
+}
+
+static int elf_section_header_convert(Elf_Ehdr *ehdr, Elf_Shdr *shdr)
+{
+#define SECTION_HEADER_FIELDS(b, e) \
+ CONVERT_FIELD(b, sh_name, e); \
+ CONVERT_FIELD(b, sh_type, e); \
+ CONVERT_FIELD(b, sh_link, e); \
+ CONVERT_FIELD(b, sh_info, e); \
+ CONVERT_FIELD(b, sh_flags, e); \
+ CONVERT_FIELD(b, sh_addr, e); \
+ CONVERT_FIELD(b, sh_offset, e); \
+ CONVERT_FIELD(b, sh_size, e); \
+ CONVERT_FIELD(b, sh_addralign, e); \
+ CONVERT_FIELD(b, sh_entsize, e)
+
+ CONVERT_SWITCH(ehdr, shdr, SECTION_HEADER_FIELDS);
+
+#undef SECTION_HEADER_FIELDS
+
+ return (0);
+}
+#undef CONVERT_SWITCH
+#undef CONVERT_FIELD
+
static int
__elfN(load_elf_header)(char *filename, elf_file_t ef)
{
@@ -127,62 +233,9 @@
goto error;
}
-#ifdef __powerpc__
- /*
- * XXX: should be in a separate helper.
- *
- * Fixup ELF endianness.
- *
- * The Xhdr structure was loaded using block read call to
- * optimize file accesses. It might happen, that the endianness
- * of the system memory is different that endianness of
- * the ELF header.
- * Swap fields here to guarantee that Xhdr always contain
- * valid data regardless of architecture.
- */
- if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
- ehdr->e_type = be16toh(ehdr->e_type);
- ehdr->e_machine = be16toh(ehdr->e_machine);
- ehdr->e_version = be32toh(ehdr->e_version);
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) {
- ehdr->e_entry = be64toh(ehdr->e_entry);
- ehdr->e_phoff = be64toh(ehdr->e_phoff);
- ehdr->e_shoff = be64toh(ehdr->e_shoff);
- } else {
- ehdr->e_entry = be32toh(ehdr->e_entry);
- ehdr->e_phoff = be32toh(ehdr->e_phoff);
- ehdr->e_shoff = be32toh(ehdr->e_shoff);
- }
- ehdr->e_flags = be32toh(ehdr->e_flags);
- ehdr->e_ehsize = be16toh(ehdr->e_ehsize);
- ehdr->e_phentsize = be16toh(ehdr->e_phentsize);
- ehdr->e_phnum = be16toh(ehdr->e_phnum);
- ehdr->e_shentsize = be16toh(ehdr->e_shentsize);
- ehdr->e_shnum = be16toh(ehdr->e_shnum);
- ehdr->e_shstrndx = be16toh(ehdr->e_shstrndx);
-
- } else {
- ehdr->e_type = le16toh(ehdr->e_type);
- ehdr->e_machine = le16toh(ehdr->e_machine);
- ehdr->e_version = le32toh(ehdr->e_version);
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) {
- ehdr->e_entry = le64toh(ehdr->e_entry);
- ehdr->e_phoff = le64toh(ehdr->e_phoff);
- ehdr->e_shoff = le64toh(ehdr->e_shoff);
- } else {
- ehdr->e_entry = le32toh(ehdr->e_entry);
- ehdr->e_phoff = le32toh(ehdr->e_phoff);
- ehdr->e_shoff = le32toh(ehdr->e_shoff);
- }
- ehdr->e_flags = le32toh(ehdr->e_flags);
- ehdr->e_ehsize = le16toh(ehdr->e_ehsize);
- ehdr->e_phentsize = le16toh(ehdr->e_phentsize);
- ehdr->e_phnum = le16toh(ehdr->e_phnum);
- ehdr->e_shentsize = le16toh(ehdr->e_shentsize);
- ehdr->e_shnum = le16toh(ehdr->e_shnum);
- ehdr->e_shstrndx = le16toh(ehdr->e_shstrndx);
- }
-#endif
+ err = elf_header_convert(ehdr);
+ if (err)
+ goto error;
if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */
err = EFTYPE;
@@ -453,57 +506,8 @@
phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
-#ifdef __powerpc__
- /*
- * XXX: should be in a seprate helper.
- *
- * Fixup ELF endianness.
- *
- * The Xhdr structure was loaded using block read call to
- * optimize file accesses. It might happen, that the endianness
- * of the system memory is different that endianness of
- * the ELF header.
- * Swap fields here to guarantee that Xhdr always contain
- * valid data regardless of architecture.
- */
- if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
- phdr[i].p_type = be32toh(phdr[i].p_type);
- phdr[i].p_flags = be32toh(phdr[i].p_flags);
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) {
- phdr[i].p_offset = be64toh(phdr[i].p_offset);
- phdr[i].p_vaddr = be64toh(phdr[i].p_vaddr);
- phdr[i].p_paddr = be64toh(phdr[i].p_paddr);
- phdr[i].p_filesz = be64toh(phdr[i].p_filesz);
- phdr[i].p_memsz = be64toh(phdr[i].p_memsz);
- phdr[i].p_align = be64toh(phdr[i].p_align);
- } else {
- phdr[i].p_offset = be32toh(phdr[i].p_offset);
- phdr[i].p_vaddr = be32toh(phdr[i].p_vaddr);
- phdr[i].p_paddr = be32toh(phdr[i].p_paddr);
- phdr[i].p_filesz = be32toh(phdr[i].p_filesz);
- phdr[i].p_memsz = be32toh(phdr[i].p_memsz);
- phdr[i].p_align = be32toh(phdr[i].p_align);
- }
- } else {
- phdr[i].p_type = le32toh(phdr[i].p_type);
- phdr[i].p_flags = le32toh(phdr[i].p_flags);
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) {
- phdr[i].p_offset = le64toh(phdr[i].p_offset);
- phdr[i].p_vaddr = le64toh(phdr[i].p_vaddr);
- phdr[i].p_paddr = le64toh(phdr[i].p_paddr);
- phdr[i].p_filesz = le64toh(phdr[i].p_filesz);
- phdr[i].p_memsz = le64toh(phdr[i].p_memsz);
- phdr[i].p_align = le64toh(phdr[i].p_align);
- } else {
- phdr[i].p_offset = le32toh(phdr[i].p_offset);
- phdr[i].p_vaddr = le32toh(phdr[i].p_vaddr);
- phdr[i].p_paddr = le32toh(phdr[i].p_paddr);
- phdr[i].p_filesz = le32toh(phdr[i].p_filesz);
- phdr[i].p_memsz = le32toh(phdr[i].p_memsz);
- phdr[i].p_align = le32toh(phdr[i].p_align);
- }
- }
-#endif
+ if (elf_program_header_convert(ehdr, phdr))
+ continue;
/* We want to load PT_LOAD segments only.. */
if (phdr[i].p_type != PT_LOAD)
@@ -580,63 +584,8 @@
goto nosyms;
}
-#ifdef __powerpc__
- /*
- * XXX: should be in a seprate helper.
- *
- * Fixup ELF endianness.
- *
- * The Xhdr structure was loaded using block read call to
- * optimize file accesses. It might happen, that the endianness
- * of the system memory is different that endianness of
- * the ELF header.
- * Swap fields here to guarantee that Xhdr always contain
- * valid data regardless of architecture.
- */
- for (i = 0; i < ehdr->e_shnum; i++) {
- if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
- shdr[i].sh_name = be32toh(shdr[i].sh_name);
- shdr[i].sh_type = be32toh(shdr[i].sh_type);
- shdr[i].sh_link = be32toh(shdr[i].sh_link);
- shdr[i].sh_info = be32toh(shdr[i].sh_info);
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) {
- shdr[i].sh_flags = be64toh(shdr[i].sh_flags);
- shdr[i].sh_addr = be64toh(shdr[i].sh_addr);
- shdr[i].sh_offset = be64toh(shdr[i].sh_offset);
- shdr[i].sh_size = be64toh(shdr[i].sh_size);
- shdr[i].sh_addralign = be64toh(shdr[i].sh_addralign);
- shdr[i].sh_entsize = be64toh(shdr[i].sh_entsize);
- } else {
- shdr[i].sh_flags = be32toh(shdr[i].sh_flags);
- shdr[i].sh_addr = be32toh(shdr[i].sh_addr);
- shdr[i].sh_offset = be32toh(shdr[i].sh_offset);
- shdr[i].sh_size = be32toh(shdr[i].sh_size);
- shdr[i].sh_addralign = be32toh(shdr[i].sh_addralign);
- shdr[i].sh_entsize = be32toh(shdr[i].sh_entsize);
- }
- } else {
- shdr[i].sh_name = le32toh(shdr[i].sh_name);
- shdr[i].sh_type = le32toh(shdr[i].sh_type);
- shdr[i].sh_link = le32toh(shdr[i].sh_link);
- shdr[i].sh_info = le32toh(shdr[i].sh_info);
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) {
- shdr[i].sh_flags = le64toh(shdr[i].sh_flags);
- shdr[i].sh_addr = le64toh(shdr[i].sh_addr);
- shdr[i].sh_offset = le64toh(shdr[i].sh_offset);
- shdr[i].sh_size = le64toh(shdr[i].sh_size);
- shdr[i].sh_addralign = le64toh(shdr[i].sh_addralign);
- shdr[i].sh_entsize = le64toh(shdr[i].sh_entsize);
- } else {
- shdr[i].sh_flags = le32toh(shdr[i].sh_flags);
- shdr[i].sh_addr = le32toh(shdr[i].sh_addr);
- shdr[i].sh_offset = le32toh(shdr[i].sh_offset);
- shdr[i].sh_size = le32toh(shdr[i].sh_size);
- shdr[i].sh_addralign = le32toh(shdr[i].sh_addralign);
- shdr[i].sh_entsize = le32toh(shdr[i].sh_entsize);
- }
- }
- }
-#endif
+ for (i = 0; i < ehdr->e_shnum; i++)
+ elf_section_header_convert(ehdr, &shdr[i]);
file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr);

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 31, 9:06 AM (14 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30581762
Default Alt Text
D14267.id39046.diff (9 KB)

Event Timeline