* Fix computation of the new start page.

This commit is contained in:
Eelco Dolstra
2005-10-03 18:25:15 +00:00
parent b60d8d3ef2
commit a36b2c6144

View File

@@ -260,26 +260,32 @@ static void rewriteSections()
assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */ assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */
off_t startOffset = shdrs[lastReplaced + 1].sh_offset; off_t startOffset = shdrs[lastReplaced + 1].sh_offset;
Elf32_Addr startAddr = shdrs[lastReplaced + 1].sh_addr; Elf32_Addr startAddr = shdrs[lastReplaced + 1].sh_addr;
string prevSection;
for (unsigned int i = 1; i <= lastReplaced; ++i) { for (unsigned int i = 1; i <= lastReplaced; ++i) {
Elf32_Shdr & shdr(shdrs[i]); Elf32_Shdr & shdr(shdrs[i]);
string sectionName = getSectionName(shdr); string sectionName = getSectionName(shdr);
fprintf(stderr, "looking at section `%s'\n", sectionName.c_str()); fprintf(stderr, "looking at section `%s'\n", sectionName.c_str());
if (replacedSections.find(sectionName) != replacedSections.end()) continue; if ((shdr.sh_type == SHT_PROGBITS && sectionName != ".interp") || prevSection == ".dynstr") {
//if (shdr.sh_type == SHT_PROGBITS && sectionName != ".interp") { //if (true) {
if (true) {
startOffset = shdr.sh_offset; startOffset = shdr.sh_offset;
startAddr = shdr.sh_addr; startAddr = shdr.sh_addr;
lastReplaced = i - 1; lastReplaced = i - 1;
break; break;
} else { } else {
if (replacedSections.find(sectionName) == replacedSections.end()) {
fprintf(stderr, "replacing section `%s' which is in the way\n", sectionName.c_str()); fprintf(stderr, "replacing section `%s' which is in the way\n", sectionName.c_str());
replaceSection(sectionName, shdr.sh_size); replaceSection(sectionName, shdr.sh_size);
} }
} }
prevSection = sectionName;
}
fprintf(stderr, "first reserved offset/addr is %d/0x%x\n", fprintf(stderr, "first reserved offset/addr is 0x%x/0x%x\n",
startOffset, startAddr); startOffset, startAddr);
Elf32_Addr startPage = startAddr / pageSize * pageSize;
assert(startAddr % pageSize == startOffset % pageSize);
Elf32_Addr firstPage = startAddr - startOffset;
fprintf(stderr, "first page is 0x%x\n", firstPage);
/* Right now we assume that the section headers are somewhere near /* Right now we assume that the section headers are somewhere near
the end, which appears to be the case most of the time. the end, which appears to be the case most of the time.
@@ -303,17 +309,18 @@ static void rewriteSections()
if (neededSpace > startOffset) { if (neededSpace > startOffset) {
/* We also need an additional program header, so adjust for that. */ /* We also need an additional program header, so adjust for that. */
if (neededSpace > startOffset) neededSpace += sizeof(Elf32_Phdr); neededSpace += sizeof(Elf32_Phdr);
fprintf(stderr, "needed space is %d\n", neededSpace); fprintf(stderr, "needed space is %d\n", neededSpace);
unsigned int neededPages = roundUp(neededSpace - startOffset, pageSize) / pageSize; unsigned int neededPages = roundUp(neededSpace - startOffset, pageSize) / pageSize;
fprintf(stderr, "needed pages is %d\n", neededPages); fprintf(stderr, "needed pages is %d\n", neededPages);
if (neededPages * pageSize > startPage) if (neededPages * pageSize > firstPage)
error("virtual address space underrun!"); error("virtual address space underrun!");
startPage -= neededPages * pageSize;
firstPage -= neededPages * pageSize;
startOffset += neededPages * pageSize; startOffset += neededPages * pageSize;
shiftFile(neededPages, startPage); shiftFile(neededPages, firstPage);
} }
@@ -335,7 +342,7 @@ static void rewriteSections()
/* Update the section header for this section. */ /* Update the section header for this section. */
Elf32_Shdr & shdr = findSection(sectionName); Elf32_Shdr & shdr = findSection(sectionName);
shdr.sh_offset = curOff; shdr.sh_offset = curOff;
shdr.sh_addr = startPage + curOff; shdr.sh_addr = firstPage + curOff;
shdr.sh_size = i->second.size(); shdr.sh_size = i->second.size();
shdr.sh_addralign = 4; shdr.sh_addralign = 4;
@@ -377,7 +384,7 @@ static void rewriteSections()
(According to the ELF spec, it must be the first entry.) */ (According to the ELF spec, it must be the first entry.) */
if (phdrs[0].p_type == PT_PHDR) { if (phdrs[0].p_type == PT_PHDR) {
phdrs[0].p_offset = hdr->e_phoff; phdrs[0].p_offset = hdr->e_phoff;
phdrs[0].p_vaddr = phdrs[0].p_paddr = startPage + hdr->e_phoff; phdrs[0].p_vaddr = phdrs[0].p_paddr = firstPage + hdr->e_phoff;
phdrs[0].p_filesz = phdrs[0].p_memsz = phdrs.size() * sizeof(Elf32_Phdr); phdrs[0].p_filesz = phdrs[0].p_memsz = phdrs.size() * sizeof(Elf32_Phdr);
} }
@@ -398,7 +405,7 @@ static void rewriteSections()
dyn->d_un.d_ptr = findSection(".dynstr").sh_addr; dyn->d_un.d_ptr = findSection(".dynstr").sh_addr;
else if (dyn->d_tag == DT_STRSZ) else if (dyn->d_tag == DT_STRSZ)
dyn->d_un.d_val = findSection(".dynstr").sh_size; dyn->d_un.d_val = findSection(".dynstr").sh_size;
#if 0 #if 1
else if (dyn->d_tag == DT_SYMTAB) else if (dyn->d_tag == DT_SYMTAB)
dyn->d_un.d_ptr = findSection(".dynsym").sh_addr; dyn->d_un.d_ptr = findSection(".dynsym").sh_addr;
else if (dyn->d_tag == DT_HASH) else if (dyn->d_tag == DT_HASH)