void Archive::dump() const { printf("Archive data %p len %zu, firstRegularData %p\n", data.data(), data.size(), firstRegularData); printf("Symbol table %p, len %u\n", symbolTable.data, symbolTable.len); printf("string table %p, len %u\n", stringTable.data, stringTable.len); const uint8_t* buf = symbolTable.data; if (!buf) { for (auto c = child_begin(), e = child_end(); c != e; ++c) { printf("Child %p, len %u, name %s, size %u\n", c->data, c->len, c->getName().c_str(), c->getSize()); } return; } uint32_t symbolCount = read32be(buf); printf("Symbol count %u\n", symbolCount); buf += sizeof(uint32_t) + (symbolCount * sizeof(uint32_t)); uint32_t string_start_offset = buf - symbolTable.data; Symbol sym = {0, string_start_offset}; while (sym.symbolIndex != symbolCount) { printf("Symbol %u, offset %u\n", sym.symbolIndex, sym.stringIndex); // get the member uint32_t offset = read32be(symbolTable.data + sym.symbolIndex * 4); auto* loc = (const uint8_t*)&data[offset]; child_iterator it; it.child = Child(this, loc, &it.error); printf("Child %p, len %u\n", it.child.data, it.child.len); } }
static GElf_Addr get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data) { Elf_Scn *ppcgot_sec = NULL; GElf_Shdr ppcgot_shdr; if (ppcgot != 0 && !get_section_covering(lte, ppcgot, &ppcgot_sec, &ppcgot_shdr)) // xxx should be the log out fprintf(stderr, "DT_PPC_GOT=%#" PRIx64 ", but no such section found.\n", ppcgot); if (ppcgot_sec != NULL) { Elf_Data *data = loaddata(ppcgot_sec, &ppcgot_shdr); if (data == NULL || data->d_size < 8 ) debug(1, "Couldn't read GOT data."); else { // where PPCGOT begins in .got size_t offset = ppcgot - ppcgot_shdr.sh_addr; GElf_Addr glink_vma = read32be(data, offset + 4); if (glink_vma != 0) { debug(1, "PPC GOT glink_vma address: %#" PRIx64, glink_vma); return glink_vma; } } } if (plt_data != NULL) { GElf_Addr glink_vma = read32be(plt_data, 0); debug(1, ".plt glink_vma address: %#" PRIx64, glink_vma); return glink_vma; } return 0; }
inline int unpack_body(uint8_t* src, int src_len) { if (src_len < body_size()) { return -1; } id = read64be(src); src += 8; seq = read64be(src); src += 8; round = read64be(src); src += 8; next = read64be(src); src += 8; uint32_t next_content_size = read32be(src); src += 4; if (src_len < 8+8+8+8+4 + next_content_size) { return -2; } next_content = std::string((const char*)src, next_content_size); return 0; }
uint32_t read32(bool be,void *p) { return (be)?(read32be(p)):(read32le(p)); }
static void aoutmint_writeexec(struct GlobalVars *gv,FILE *f) /* creates an a.out-MiNT executable file */ { const int be = _BIG_ENDIAN_; uint8_t jmp_entry_code[] = { 0x20,0x3a,0x00,0x1a,0x4e,0xfb,0x08,0xfa }; struct LinkedSection *sections[3]; unsigned long secsizes[2]; struct mint_exec me; long tparel_offset,tparel_size; struct nlist32 *stksize; aout_initwrite(gv,sections); if (sections[0] == NULL) /* this requires a .text section! */ error(97,fff[gv->dest_format]->tname,TEXTNAME); memset(&me,0,sizeof(struct mint_exec)); /* init header with zero */ text_data_bss_gaps(sections); /* calculate gap size between sections */ secsizes[0] = sections[0]->size + sections[0]->gapsize; secsizes[1] = sections[1] ? sections[1]->filesize : 0; /* init TOS header */ write16be(me.tos.ph_branch,0x601a); write32be(me.tos.ph_tlen,secsizes[0]+TEXT_OFFSET); write32be(me.tos.ph_dlen,secsizes[1]); write32be(me.tos.ph_blen,(sections[2]?sections[2]->size:0) + (sections[1]?sections[1]->gapsize:0)); write32be(me.tos.ph_magic,0x4d694e54); /* "MiNT" */ write32be(me.tos.ph_flags,gv->tosflags); /* Atari memory flags */ write16be(me.tos.ph_abs,0); /* includes relocations */ aout_addsymlist(gv,sections,BIND_GLOBAL,0,be); aout_addsymlist(gv,sections,BIND_WEAK,0,be); aout_addsymlist(gv,sections,BIND_LOCAL,0,be); aout_debugsyms(gv,be); calc_relocs(gv,sections[0]); calc_relocs(gv,sections[1]); /* The Atari symbol table size is the sum of a.out symbols and strings, which is now known. */ write32be(me.tos.ph_slen,aoutsymlist.nextindex * sizeof(struct nlist32) + aoutstrlist.nextoffset); /* set jmp_entry to move.l a_entry(pc),d0 jmp (-6,pc,d0.l) */ memcpy(me.jmp_entry,jmp_entry_code,sizeof(jmp_entry_code)); /* init a.out NMAGIC header */ SETMIDMAG(&me.aout,NMAGIC,0,0); write32be(me.aout.a_text,sections[0]->size+sections[0]->gapsize); write32be(me.aout.a_data,sections[1]?sections[1]->filesize:0); write32be(me.aout.a_bss,(sections[2]?sections[2]->size:0) + (sections[1]?sections[1]->gapsize:0)); write32be(me.aout.a_syms,aoutsymlist.nextindex*sizeof(struct nlist32)); write32be(me.aout.a_entry,TEXT_OFFSET); /* save offset to __stksize when symbol is present */ if (stksize = find_aout_sym("__stksize")) { write32be(me.stkpos, read32be(&stksize->n_value)+sizeof(me)-TEXT_OFFSET); } /* write a.out-MiNT header (256 bytes) */ fwritex(f,&me,sizeof(me)); /* write sections */ fwritex(f,sections[0]->data,sections[0]->size); fwritegap(f,sections[0]->gapsize); if (sections[1]) fwritex(f,sections[1]->data,sections[1]->filesize); /* write a.out symbols */ aout_writesymbols(f); aout_writestrings(f,be); /* write TPA relocs */ tparel_offset = ftell(f); tos_writerelocs(gv,f,sections); tparel_size = ftell(f) - tparel_offset; /* we have to patch tparel_pos and tparel_size in the header, as we didn't know about the size of the TPA relocs table before */ fseek(f,offsetof(struct mint_exec,tparel_pos),SEEK_SET); fwrite32be(f,tparel_offset); fwrite32be(f,tparel_size); }