📄 image.cc
字号:
newSections.push_back(s); } mSections = newSections;}void Image::buildSymbolStringTable(void){ sectionNames = new StringTable(*this); mSections.push_back(sectionNames); for (unsigned int i = 0; i < mSymtab->size(); i++) { sectionNames->addString(mSymtab->get(i)->name()); }}void Image::buildSectionStringTable(void){ for (unsigned int i = 0; i < mSections.size(); i++) { if (!mSections[i]) continue; sectionNames->addString(mSections[i]->name()); }}void Image::buildStub(const char* section)
{
Section *libSection = NULL;
if (section)
{
vector<Section *> newSections;
for (unsigned int i = 0; i < mSections.size(); i++) {
Section *s = mSections[i];
if (!s) continue;
uint32_t type = s->type();
// elided: relocs, strtabs other than main strtab
if (!(type == SHT_NULL || type == SHT_SYMTAB))
continue;
newSections.push_back(s);
}
string name = string(".lib") + section;
libSection = new Section(*this, name, SHT_PROGBITS, 0, 0, NULL, 0);
mSymtab->addSymbol(libSection->baseSymbol());
newSections.push_back(libSection);
mSections = newSections;
}
mSymtab->sortSymbols();
if (libSection)
mSymtab->forceSection(libSection);
}
void Image::buildRelocations(void){ vector<Section *> newSections; if (mGOT) mGOT->buildRelocations(); for (unsigned int i = 0; i < mSections.size(); i++) { Section *s = mSections[i]; vector<Relocation>& rels = s->relocations(); if (rels.size() == 0) continue; Elf32_Rela *relBytes = new Elf32_Rela[rels.size()]; for (unsigned int r = 0; r < rels.size(); r++) { relBytes[r] = rels[r].asElf(*mSymtab); } string name = string(".rela") + s->name(); Section *relSection = new Section(*this, name, SHT_RELA, 0, 0, (uint8_t *)relBytes, rels.size() * sizeof(Elf32_Rela)); rels.erase(rels.begin(), rels.end()); relSection->setLink(find(mSections.begin(), mSections.end(), mSymtab) - mSections.begin()); relSection->setInfo(i); relSection->setEntrySize(sizeof(Elf32_Rela)); newSections.push_back(relSection); } mSections.insert(mSections.end(), newSections.begin(), newSections.end());}// if id == -1:// write 'name' file in .ro format with a resource for each section, starting with resource ID baseID// else// write 'name' file in .bin format, ignoring resType and baseIDvoid Image::write(const char *resType, int baseID, const char *name){ uint32_t bufLen = sizeof(Elf32_Ehdr) + mSections.size()*sizeof(Elf32_Shdr); uint8_t *buf = (uint8_t *)calloc(bufLen, 1); int lastID; // fill out section data and section headers bool toobig = false; for (unsigned int i = 0; i < mSections.size(); i++) { Elf32_Shdr *shdr = (Elf32_Shdr *)(buf + sizeof(Elf32_Ehdr)); Section *s = mSections[i]; uint32_t offset = bufLen; s->emit(shdr+i, buf, bufLen); if (s->type() == SHT_NOBITS) { // .bss et al take no space in resources - no size check inform("emitting section '%s' (type %d flags %d) at 0x%x (%d bytes)", s->name().c_str(), s->type(), s->flags(), offset, s->size()); } else { if (s->thunkSize()) { inform("emitting section '%s' (type %d flags %d) at 0x%x (%d bytes [%d for thunks])", s->name().c_str(), s->type(), s->flags(), offset, s->size(), s->thunkSize()); } else { inform("emitting section '%s' (type %d flags %d) at 0x%x (%d bytes)", s->name().c_str(), s->type(), s->flags(), offset, s->size()); } if (baseID != -1 && s->size() > RESOURCE_MAX) { toobig = true; } } if (s->isReadOnly() && s->alignment() > 4) { error("Read-only section '%s' is more than 4-byte aligned %d", s->name().c_str(), s->alignment()); } } if (toobig) { warning("Some sections are over %d bytes. " "Consider using ld's --split-by-file to reduce section size " "and save dynamic heap memory at runtime.", RESOURCE_MAX); } // fill out ELF header Elf32_Ehdr *ehdr = (Elf32_Ehdr *)buf; memcpy(ehdr, &mEhdr, sizeof(mEhdr)); ehdr->e_entry = 0; ehdr->e_phoff = 0; ehdr->e_shoff = sizeof(Elf32_Ehdr); ehdr->e_phentsize = 0; ehdr->e_phnum = 0; ehdr->e_shentsize = sizeof(Elf32_Shdr); ehdr->e_shnum = mSections.size(); ehdr->e_shstrndx = find(mSections.begin(), mSections.end(), sectionNames) - mSections.begin(); ehdr->e_type = ET_REL; int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); if (fd < 0) { perror(name); exit(1); } if (baseID == -1) { // write everything together swap_ehdr(ehdr); ::write(fd, buf, bufLen); swap_ehdr(ehdr); } else { // count non-empty resources // resource baseID+0 is ehdr+shdrs // additional sections are in consecutive resources // sections bigger than 64 KB are split into multiple resources // section 0 (SHT_NULL) is skipped int res_count = 0; res_count++; // ehdr+shdrs for (unsigned i = 1; i < ehdr->e_shnum; i++) { Elf32_Shdr *shdr = i+(Elf32_Shdr *)(ehdr+1); uint32_t type = swap32(shdr->sh_type); size_t size = swap32(shdr->sh_size); if (size == 0 || type == SHT_NULL || type == SHT_NOBITS) { continue; // no resource } res_count += (size + RESOURCE_MAX - 1) / RESOURCE_MAX; } // gather .prc header (68K-swapped!) // Most fields are blank because this is only enough of a .prc // to work with build-prc. prc_header prc; memset(&prc, 0, sizeof(prc)); strcpy(prc.name, "foo"); prc.attr = swap16_68K(1); // dmHdrAttrResDB prc.version = swap16_68K(1); strncpy(prc.type, "RESO", 4); strncpy(prc.creator, "pRES", 4); prc.count = swap16_68K(res_count); // gather resource headers // resource baseID+0 is ehdr+shdrs // additional sections are in consecutive resources // sections bigger than 64 KB are split into multiple resources // section 0 (SHT_NULL) is skipped int r; res_header res[res_count]; ptrdiff_t offset; r = 0; lastID = baseID; offset = sizeof(prc) + sizeof(res) + 2; strncpy(res[r].type, resType, 4); res[r].id = swap16_68K(lastID); res[r].offset = swap32_68K(offset); r++; lastID++; offset += sizeof(*ehdr) + ehdr->e_shnum*ehdr->e_shentsize; for (unsigned int i = 1; i < ehdr->e_shnum; i++) { Elf32_Shdr *shdr = i+(Elf32_Shdr *)(ehdr+1); uint32_t type = swap32(shdr->sh_type); size_t size = swap32(shdr->sh_size); if (size == 0 || type == SHT_NULL || type == SHT_NOBITS) { continue; // no resource } while (1) { strncpy(res[r].type, resType, 4); res[r].id = swap16_68K(lastID); res[r].offset = swap32_68K(offset); r++; lastID++; if (size > RESOURCE_MAX) { // section too big - do another resource offset += RESOURCE_MAX; size -= RESOURCE_MAX; } else { offset += size; break; } } } // write prc header and resource headers uint16_t gap = 0; ::write(fd, &prc, sizeof(prc)); ::write(fd, res, sizeof(res)); ::write(fd, &gap, 2); // write resource data swap_ehdr(ehdr); ::write(fd, buf, bufLen); swap_ehdr(ehdr); } close(fd); if (baseID == -1) { inform("wrote file %s", name); } else { inform("wrote file %s (resource type '%s', id %d..%d)", name, resType, baseID, lastID-1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -