+ if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident))
+ || le32(ehdr.e_version) != 1)
+ {
+ fprintf(stderr, "Not an ELF file or wrong ELF type\n");
+ goto fail;
+ }
+ if (le16(ehdr.e_type) != ET_EXEC) {
+ fprintf(stderr, "ELF is not executable\n");
+ goto fail;
+ }
+ if (le16(ehdr.e_machine) != EM_ARM) {
+ fprintf(stderr, "Wrong ELF architecture\n");
+ goto fail;
+ }
+ if (!ehdr.e_phnum || !ehdr.e_phoff) {
+ fprintf(stderr, "ELF has no PHDRs\n");
+ goto fail;
+ }
+ if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
+ // could be a structure padding issue...
+ fprintf(stderr, "Either the ELF file or this code is made of fail\n");
+ goto fail;
+ }
+ num_phdrs = le16(ehdr.e_phnum);
+
+ phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr));
+ if (!phdrs) {
+ fprintf(stderr, "Out of memory\n");
+ goto fail;
+ }
+ if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) {
+ fprintf(stderr, "Error while reading ELF PHDRs\n");
+ goto fail;
+ }
+ if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
+ fprintf(stderr, "Error while reading ELF PHDRs\n");
+ goto fail;
+ }
+
+ res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs);
+ if (res < 0)
+ goto fail;
+ res = check_segs(ctx, can_write_bl);
+ if (res < 0)
+ goto fail;
+
+ free(phdrs);
+ fclose(fd);
+ ctx->filename = name;
+ return 0;
+
+fail:
+ if (phdrs)
+ free(phdrs);
+ if (fd)
+ fclose(fd);
+ flash_free(ctx);
+ return -1;