/// Print the bytes of a symbol at a specific index to the /// output stream /// @param out The output stream to print to /// @param index The index of symbol to print void print_symbol(std::ostream& out, uint32_t index) const { assert(index < SuperCoder::symbols()); print_symbol_info(out, index); uint32_t size = SuperCoder::symbol_size(); if(SuperCoder::is_symbol_available(index)) { const uint8_t* symbol = SuperCoder::symbol(index); auto storage = sak::storage(symbol, size); hexdump hex(storage); hex.set_max_size(32); out << hex; } }
/* * ======== process_image ======== */ static int process_image() { int i; struct Elf32_Ehdr *hdr; struct Elf32_Shdr *shdr, *s, *s1, *s2; struct Elf32_Shdr vers_shdr; struct Elf32_Phdr *phdr, *p; struct Elf32_Sym *sym, *sm; int co = 0; int scnt = 0; int len = 0; printf("\nStart combining images....\n\n"); /* copy the header */ if (core0_info.e_hdr->e_entry != core1_info.e_hdr->e_entry) { printf("entry points are different in both the images.\n"); return -1; } hdr = core0_info.e_hdr; memcpy(cores_info.e_hdr, core0_info.e_hdr, sizeof(struct Elf32_Ehdr)); cores_info.e_hdr->e_phnum = core0_info.e_hdr->e_phnum + core1_info.e_hdr->e_phnum; fwrite(cores_info.e_hdr, 1, sizeof(struct Elf32_Ehdr), cores_info.fp); co += sizeof(struct Elf32_Ehdr); /* process the program data of Core0 ELF file */ printf("Processing Core0 program data sections....\n"); p = core0_info.p_hdrs; phdr = cores_info.p_hdrs; for (i = 0; i < core0_info.e_hdr->e_phnum; i++, p++, phdr++) { DEBUG_PRINT("Program Section #%d\n", i); DEBUG_PRINT(" input "); print_proghdr_info(p); memcpy((void *)phdr, p, sizeof(struct Elf32_Phdr)); /* copy the program data only if file size is non-zero */ co += fill_zero(co, p->p_align); if (p->p_filesz) { if (core0_info.data + p->p_offset == core0_info.rsc_table) { fixup_rsc_table(core0_info.data + p->p_offset); } fwrite(core0_info.data + p->p_offset, 1, p->p_filesz, cores_info.fp); } phdr->p_offset = co; co += p->p_filesz; DEBUG_PRINT(" output"); print_proghdr_info(phdr); DEBUG_PRINT(" Phdr_offset = 0x%x co = 0x%x\n", phdr->p_offset, co); } printf("Core0 program data processed for %d sections.\n", i); /* process the program data of Core1 ELF file */ printf("\nProcessing Core1 program data sections....\n"); p = core1_info.p_hdrs; for (i = 0; i < core1_info.e_hdr->e_phnum; i++, p++, phdr++) { DEBUG_PRINT("Program Section #%d\n", i); DEBUG_PRINT(" input "); print_proghdr_info(p); memcpy((void *)phdr, p, sizeof(struct Elf32_Phdr)); /* copy the program data only if file size is non-zero */ co += fill_zero(co, p->p_align); if (p->p_filesz) { fwrite(core1_info.data + p->p_offset, 1, p->p_filesz, cores_info.fp); } phdr->p_offset = co; co += p->p_filesz; DEBUG_PRINT(" output"); print_proghdr_info(phdr); DEBUG_PRINT(" Phdr_offset = 0x%x co = 0x%x\n", phdr->p_offset, co); } cores_info.last_phoffset = co; printf("Core1 program data processed for %d sections.\n", i); printf("\nProcessing Core0 section data....\n"); /* process the section data of Core0 ELF file */ shdr = cores_info.s_hdrs; s = core0_info.s_hdrs; /* Skip the last 5 sections, these need to be combined */ /* * TODO: Add check to ensure if these sections are different between the * two images */ for (i = 0; i < core0_info.e_hdr->e_shnum - 5; i++, s++) { /* skip the ".version" section, will write at the end */ if (!strcmp(core0_info.shstrtab + s->sh_name, ELF_SHDR_VERSION)) { memcpy(&vers_shdr, s, sizeof(struct Elf32_Shdr)); len = strlen(core0_info.shstrtab + s->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", i, (char *)((u32)core0_info.shstrtab + s->sh_name), len); len = strlen(core0_info.version); memcpy(cores_info.version + cores_info.version_size, core0_info.version, len); cores_info.version_size += len; DEBUG_PRINT(" skip processing of this section, size = %d\n", s->sh_size); continue; } memcpy((void *)shdr, s, sizeof(struct Elf32_Shdr)); scnt++; /* copy the section name into the new section string table */ shdr->sh_name = cores_info.shstrtab_size; /* doesn't matter */ len = strlen(core0_info.shstrtab + s->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", i, (char *)((u32)core0_info.shstrtab + s->sh_name), len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + s->sh_name, len + 1); DEBUG_PRINT(" check copied name [%s] new offset = %d \n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); /* process the ".stack" section specially - no offset adjustment */ if (!strcmp(core0_info.shstrtab + s->sh_name, ELF_SHDR_STACK)) { DEBUG_PRINT(" input "); print_secthdr_info(s); DEBUG_PRINT(" output"); print_secthdr_info(shdr); shdr++; continue; } if (s->sh_offset >= core0_info.last_phoffset) { if ((s->sh_type == SHT_PROGBITS && s->sh_size) || (s->sh_type == SHT_ARMATTRIBUTES) || (s->sh_type == SHT_STRTAB)) { fwrite(core0_info.data + s->sh_offset, 1, s->sh_size, cores_info.fp); shdr->sh_offset = co; co += s->sh_size; } else if (s->sh_type == SHT_SYMTAB) { co += fill_zero(co, 4); fwrite(core0_info.data + s->sh_offset, 1, s->sh_size, cores_info.fp); shdr->sh_offset = co; co += s->sh_size; } else if (s->sh_type == SHT_NOBITS) { DEBUG_PRINT(" offsets = 0x%x 0x%x 0x%x\n", cores_info.last_phoffset, core0_info.last_phoffset, s->sh_offset); shdr->sh_offset = cores_info.last_phoffset - core0_info.last_phoffset + s->sh_offset; } DEBUG_PRINT(" sh_offset = 0x%x co = 0x%x\n", shdr->sh_offset, co); } DEBUG_PRINT(" input "); print_secthdr_info(s); DEBUG_PRINT(" output"); print_secthdr_info(shdr); shdr++; } s1 = s; printf("Core0 section data processed for %d sections.\n", scnt); printf("\nProcessing Core1 section data....\n"); /* process the section data of Core1 ELF file */ s = core1_info.s_hdrs; /* Skip the last 5 sections, these need to be combined */ /* * TODO: Add check to ensure if these sections are different between the * two images */ for (i = 0; i < core1_info.e_hdr->e_shnum - 5; i++, s++) { /* skip the first null section */ if (s->sh_type == SHT_NULL) { continue; } /* skip the ".version" section, will write at the end */ if (!strcmp(core1_info.shstrtab + s->sh_name, ELF_SHDR_VERSION)) { len = strlen(core1_info.shstrtab + s->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", i, (char *)((u32)core1_info.shstrtab + s->sh_name), len); len = strlen(core1_info.version); memcpy(cores_info.version + cores_info.version_size, core1_info.version, len); cores_info.version_size += len; DEBUG_PRINT(" skip processing of this section, size = %d\n", s->sh_size); continue; } memcpy((void *)shdr, s, sizeof(struct Elf32_Shdr)); scnt++; /* copy the section name into the new section string table */ shdr->sh_name = cores_info.shstrtab_size; len = strlen(core1_info.shstrtab + s->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", i, (char *)((u32)core1_info.shstrtab + s->sh_name), len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core1_info.shstrtab + s->sh_name, len + 1); DEBUG_PRINT(" check copied name [%s] new offset = %d\n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); /* process the ".stack" section specially - no offset adjustment */ if (!strcmp(core1_info.shstrtab + s->sh_name, ELF_SHDR_STACK)) { DEBUG_PRINT(" input "); print_secthdr_info(s); DEBUG_PRINT(" output"); print_secthdr_info(shdr); shdr++; continue; } if (s->sh_offset && s->sh_offset < core1_info.last_phoffset) { shdr->sh_offset = s->sh_offset - hdr->e_ehsize + core0_info.last_phoffset; } else if (s->sh_offset >= core1_info.last_phoffset) { if ((s->sh_type == SHT_PROGBITS && s->sh_size) || (s->sh_type == SHT_ARMATTRIBUTES) || (s->sh_type == SHT_STRTAB)) { fwrite(core1_info.data + s->sh_offset, 1, s->sh_size, cores_info.fp); shdr->sh_offset = co; co += s->sh_size; } else if (s->sh_type == SHT_SYMTAB) { co += fill_zero(co, 4); fwrite(core1_info.data + s->sh_offset, 1, s->sh_size, cores_info.fp); shdr->sh_offset = co; co += s->sh_size; } else if (s->sh_type == SHT_NOBITS) { DEBUG_PRINT(" offsets = 0x%x 0x%x 0x%x\n", cores_info.last_phoffset, core1_info.last_phoffset, s->sh_offset); shdr->sh_offset = cores_info.last_phoffset - core1_info.last_phoffset + s->sh_offset; } DEBUG_PRINT(" sh_offset = 0x%x co = 0x%x\n", shdr->sh_offset, co); } DEBUG_PRINT(" input "); print_secthdr_info(s); DEBUG_PRINT(" output"); print_secthdr_info(shdr); shdr++; } s2 = s; printf("Core1 section data processed for %d sections.\n", scnt); printf("\nWriting combined section data....\n"); /* write the version section */ if (cores_info.version_size) { DEBUG_PRINT("Process version section....\n"); memcpy((void *)shdr, &vers_shdr, sizeof(struct Elf32_Shdr)); scnt++; shdr->sh_name = cores_info.shstrtab_size; len = strlen(core0_info.shstrtab + vers_shdr.sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", scnt - 1, (char *)core0_info.shstrtab + vers_shdr.sh_name, len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + vers_shdr.sh_name, len + 1); DEBUG_PRINT(" check copied name [%s] new offset = %d\n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); *(char *)(cores_info.version + cores_info.version_size) = 0; cores_info.version_size++; fwrite(cores_info.version, 1, cores_info.version_size, cores_info.fp); shdr->sh_offset = co; shdr->sh_size = cores_info.version_size; co += cores_info.version_size; shdr++; DEBUG_PRINT(" co = 0x%x\n", co); } printf("Version section processed.\n"); /* write the ARM attributes section */ if ((s1->sh_type == SHT_ARMATTRIBUTES) && (s2->sh_type == SHT_ARMATTRIBUTES)/* && (s1->sh_size == s2->sh_size) && (!memcmp(core0_info.data + s1->sh_offset, core1_info.data + s2->sh_offset, s1->sh_size)) && (!strcmp(core0_info.shstrtab + s1->sh_name, core1_info.shstrtab + s2->sh_name))*/) { DEBUG_PRINT("\nProcess ARM attributes section....\n"); memcpy((void *)shdr, s1, sizeof(struct Elf32_Shdr)); scnt++; shdr->sh_name = cores_info.shstrtab_size; len = strlen(core0_info.shstrtab + s1->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", scnt - 1, (char *)core0_info.shstrtab + s1->sh_name, len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + s1->sh_name, len + 1); DEBUG_PRINT(" check copied name [%s] new offset = %d \n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); fwrite(core0_info.data + s1->sh_offset, 1, s1->sh_size, cores_info.fp); shdr->sh_offset = co; co += s1->sh_size; shdr++; DEBUG_PRINT(" co = 0x%x\n", co); } else { printf("ARM attributes section is mismatched between the two ELF" "images.\n"); return -1; } printf("ARM attributes section processed.\n"); /* write the symtab section */ DEBUG_PRINT("\nProcess Symbol Table section....\n"); s1++; s2++; if (s1->sh_type != SHT_SYMTAB && s2->sh_type != SHT_SYMTAB && (!strcmp(core0_info.shstrtab + s1->sh_name, core1_info.shstrtab + s2->sh_name))) { printf("Expected symbol table section not found in the two ELF " "images.\n"); return -1; } memcpy((void *)shdr, s1, sizeof(struct Elf32_Shdr)); scnt++; co += fill_zero(co, 4); shdr->sh_offset = co; shdr->sh_name = cores_info.shstrtab_size; shdr->sh_link = scnt + 1; len = strlen(core0_info.shstrtab + s1->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", scnt - 1, (char *)core0_info.shstrtab + s1->sh_name, len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + s1->sh_name, len + 1); DEBUG_PRINT(" check copied name [%s] new offset = %d\n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); /* combine the symtab section */ DEBUG_PRINT(" Processing Core0 symbols....\n"); sym = cores_info.symtab; sm = (struct Elf32_Sym *) (core0_info.data + s1->sh_offset); for (i = 0; i < s1->sh_size/s1->sh_entsize; i++, sm++) { memcpy(sym, sm, sizeof(struct Elf32_Sym)); /* copy the symbol name into the new string table */ sym->st_name = cores_info.strtab_size; len = strlen(core0_info.strtab + sm->st_name); DEBUG_PRINT(" [%d] symbol string length = %d new = %d\n", i, len, cores_info.strtab_size); memcpy(cores_info.strtab + cores_info.strtab_size, core0_info.strtab + sm->st_name, len + 1); cores_info.strtab_size += (len + 1); DEBUG_PRINT(" input "); print_symbol_info(sm); DEBUG_PRINT(" output"); print_symbol_info(sym); sym++; } DEBUG_PRINT(" Core0 symbols processed.\n"); DEBUG_PRINT(" Processing Core1 symbols\n"); sm = (struct Elf32_Sym *) (core1_info.data + s2->sh_offset); for (i = 0; i < s2->sh_size/s2->sh_entsize; i++, sm++) { if (sm->st_shndx == STN_UNDEF) { continue; } memcpy(sym, sm, sizeof(struct Elf32_Sym)); /* copy the symbol name into the new string table */ sym->st_name = cores_info.strtab_size; len = strlen(core1_info.strtab + sm->st_name); DEBUG_PRINT(" [%d] symbol string length = %d new = %d\n", i, len, cores_info.strtab_size); memcpy(cores_info.strtab + cores_info.strtab_size, core1_info.strtab + sm->st_name, len + 1); cores_info.strtab_size += (len + 1); /* adjust the symbol section */ if (sm->st_shndx < (core1_info.e_hdr->e_shnum - 5)) { sym->st_shndx += (core0_info.e_hdr->e_shnum - 5); } DEBUG_PRINT(" input "); print_symbol_info(sm); DEBUG_PRINT(" output"); print_symbol_info(sym); shdr->sh_size += s2->sh_entsize; sym++; } DEBUG_PRINT(" Core1 symbols processed.\n"); DEBUG_PRINT(" Writing symbols to file....\n"); DEBUG_PRINT(" output strtab size = 0x%x scnt = %d\n", cores_info.strtab_size, scnt); fwrite(cores_info.symtab, 1, shdr->sh_size, cores_info.fp); co += shdr->sh_size; shdr++; DEBUG_PRINT(" co = 0x%x\n", co); DEBUG_PRINT(" Symbols written.\n"); printf("Symbol Table section processed.\n"); /* write the TI section flags section */ DEBUG_PRINT("\nProcess TI section flags section....\n"); s1++; s2++; if ((s1->sh_type == SHT_PROGBITS) && (s2->sh_type == SHT_PROGBITS) && (s1->sh_size == s2->sh_size) && (!memcmp(core0_info.data + s1->sh_offset, core1_info.data + s2->sh_offset, s1->sh_size)) && (!strcmp(core0_info.shstrtab + s1->sh_name, core1_info.shstrtab + s2->sh_name))) { memcpy((void *)shdr, s1, sizeof(struct Elf32_Shdr)); scnt++; shdr->sh_name = cores_info.shstrtab_size; len = strlen(core0_info.shstrtab + s1->sh_name); DEBUG_PRINT("[%d: %s] section string length = %d\n", scnt - 1, (char *)core0_info.shstrtab + s1->sh_name, len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + s1->sh_name, len + 1); DEBUG_PRINT(" check copied name [%s] new offset = %d \n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); fwrite(core0_info.data + s1->sh_offset, 1, s1->sh_size, cores_info.fp); shdr->sh_offset = co; co += s1->sh_size; shdr++; DEBUG_PRINT(" co = 0x%x\n", co); } else { printf("TI Section Flags section is mismatched between the two ELF" "images.\n"); return -1; } printf("TI Section Flags section processed.\n"); /* write the strtab section */ DEBUG_PRINT("\nProcess String table section....\n"); s1++; s2++; if ((s1->sh_type == SHT_STRTAB) && (s2->sh_type == SHT_STRTAB) && (!strcmp(core0_info.shstrtab + s1->sh_name, core1_info.shstrtab + s2->sh_name))) { memcpy((void *)shdr, s1, sizeof(struct Elf32_Shdr)); scnt++; shdr->sh_name = cores_info.shstrtab_size; len = strlen(core0_info.shstrtab + s1->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", scnt - 1, (char *)core0_info.shstrtab + s1->sh_name, len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + s1->sh_name, len + 1); DEBUG_PRINT("check copied name [%s] new offset = %d\n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); fwrite(cores_info.strtab, 1, cores_info.strtab_size, cores_info.fp); shdr->sh_offset = co; shdr->sh_size = cores_info.strtab_size; co += cores_info.strtab_size; shdr++; DEBUG_PRINT(" co = 0x%x\n", co); } else { printf("String Table section is mismatched between the two ELF " "images.\n"); return -1; } printf("String Table section processed.\n"); /* write the shstrtab section */ DEBUG_PRINT("\nProcess Section header string table section....\n"); s1++; s2++; if ((s1->sh_type == SHT_STRTAB) && (s2->sh_type == SHT_STRTAB) && (!strcmp(core0_info.shstrtab + s1->sh_name, core1_info.shstrtab + s2->sh_name))) { memcpy((void *)shdr, s1, sizeof(struct Elf32_Shdr)); scnt++; shdr->sh_name = cores_info.shstrtab_size; len = strlen(core0_info.shstrtab + s1->sh_name); DEBUG_PRINT("[%d: %s] section strlen = %d\n", scnt - 1, (char *)core0_info.shstrtab + s1->sh_name, len); memcpy(cores_info.shstrtab + cores_info.shstrtab_size, core0_info.shstrtab + s1->sh_name, len + 1); DEBUG_PRINT("check copied name [%s] new offset = %d\n", (char *)((u32)cores_info.shstrtab + cores_info.shstrtab_size), cores_info.shstrtab_size); cores_info.shstrtab_size += (len + 1); fwrite(cores_info.shstrtab, 1, cores_info.shstrtab_size, cores_info.fp); shdr->sh_offset = co; shdr->sh_size = cores_info.shstrtab_size; co += cores_info.shstrtab_size; DEBUG_PRINT(" co = 0x%x\n", co); } else { printf("String Table section is mismatched between the two ELF " "images.\n"); return -1; } printf("Section Header string table processed.\n"); printf("Combined sections data processed.\n"); /* write the program headers */ printf("\nWriting new program headers...."); DEBUG_PRINT("\n prev phoffset = 0x%x co = 0x%x\n", cores_info.e_hdr->e_phoff, co); cores_info.e_hdr->e_phoff = co; cores_info.e_hdr->e_shnum = scnt; cores_info.e_hdr->e_shstrndx = scnt - 1; fwrite(cores_info.p_hdrs, 1, cores_info.e_hdr->e_phnum * cores_info.e_hdr->e_phentsize, cores_info.fp); co += cores_info.e_hdr->e_phnum * cores_info.e_hdr->e_phentsize; printf("done.\n"); /* write the section headers */ printf("Writing new section headers...."); DEBUG_PRINT("\n prev shoffset = 0x%x co = 0x%x\n", cores_info.e_hdr->e_shoff, co); cores_info.e_hdr->e_shoff = co; fwrite(cores_info.s_hdrs, 1, cores_info.e_hdr->e_shnum * cores_info.e_hdr->e_shentsize, cores_info.fp); co += cores_info.e_hdr->e_shnum * cores_info.e_hdr->e_shentsize; printf("done.\n"); /* rewrite the new ELF header */ printf("Writing new ELF header...."); fflush(cores_info.fp); rewind(cores_info.fp); fwrite(cores_info.e_hdr, 1, sizeof(struct Elf32_Ehdr), cores_info.fp); fflush(cores_info.fp); printf("done.\n"); printf("\nCombined Output image created!\n"); return 0; }
void print_hashtab (FILE *fp, HASHTAB *tab) { fprintf (fp, "Idx: Info (hex): Len: Name:\n"); FOR_EACH_OCCUPIED_BUCKET (tab, i) { print_symbol_info (fp, tab, i); } END_FOR_EACH_OCCUPIED_BUCKET;