NetBSD version 5 requires PT_NOTE for PaX. Also adjust other *BSD and PT_NOTE.
[Tested OK on FreeBSD 8.1, NetBSD 5.1, OpenBSD 4.8. Cleanup needed.]
This commit is contained in:
+194
-93
@@ -181,10 +181,13 @@ void PackLinuxElf::pack3(OutputFile *fo, Filter &ft)
|
||||
fo->write(&zero, 3& (0u-len)); // ALIGN_UP 0 mod 4
|
||||
len += (3& (0u-len)); // 0 mod 4
|
||||
|
||||
unsigned const t = 4 ^ (4 & len) ^ ((!!xct_off)<<2); // 0 or 4
|
||||
unsigned const t = (4 & len) ^ ((!!xct_off)<<2); // 0 or 4
|
||||
fo->write(&zero, t);
|
||||
len += t;
|
||||
|
||||
set_te32(&disp, 2*sizeof(disp) + len - (sz_elf_hdrs + sizeof(p_info) + sizeof(l_info)));
|
||||
fo->write(&disp, sizeof(disp)); // .e_entry - &first_b_info
|
||||
len += sizeof(disp);
|
||||
set_te32(&disp, len); // distance back to beginning (detect dynamic reloc)
|
||||
fo->write(&disp, sizeof(disp));
|
||||
len += sizeof(disp);
|
||||
@@ -398,7 +401,7 @@ void PackLinuxElf::defineSymbols(Filter const *)
|
||||
}
|
||||
|
||||
PackLinuxElf32::PackLinuxElf32(InputFile *f)
|
||||
: super(f), phdri(NULL), pt_note(NULL), shdri(NULL),
|
||||
: super(f), phdri(NULL), note_body(NULL), shdri(NULL),
|
||||
page_mask(~0u<<lg2_page),
|
||||
dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
|
||||
shstrtab(NULL), n_elf_shnum(0),
|
||||
@@ -413,11 +416,12 @@ PackLinuxElf32::PackLinuxElf32(InputFile *f)
|
||||
|
||||
PackLinuxElf32::~PackLinuxElf32()
|
||||
{
|
||||
delete[] note_body;
|
||||
delete[] phdri; phdri = NULL;
|
||||
}
|
||||
|
||||
PackLinuxElf64::PackLinuxElf64(InputFile *f)
|
||||
: super(f), phdri(NULL), pt_note(NULL), shdri(NULL),
|
||||
: super(f), phdri(NULL), note_body(NULL), shdri(NULL),
|
||||
page_mask(~0ull<<lg2_page),
|
||||
dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
|
||||
shstrtab(NULL), n_elf_shnum(0),
|
||||
@@ -432,6 +436,7 @@ PackLinuxElf64::PackLinuxElf64(InputFile *f)
|
||||
|
||||
PackLinuxElf64::~PackLinuxElf64()
|
||||
{
|
||||
delete[] note_body;
|
||||
delete[] phdri; phdri = NULL;
|
||||
}
|
||||
|
||||
@@ -916,9 +921,15 @@ PackBSDElf32x86::buildLoader(const Filter *ft)
|
||||
tmp, sizeof(stub_i386_bsd_elf_fold), ft);
|
||||
}
|
||||
|
||||
static const
|
||||
#include "stub/i386-netbsd.elf-entry.h"
|
||||
|
||||
static const
|
||||
#include "stub/i386-netbsd.elf-fold.h"
|
||||
|
||||
#define WANT_NHDR_ENUM
|
||||
#include "p_elf_enum.h"
|
||||
|
||||
void
|
||||
PackNetBSDElf32x86::buildLoader(const Filter *ft)
|
||||
{
|
||||
@@ -938,8 +949,8 @@ PackNetBSDElf32x86::buildLoader(const Filter *ft)
|
||||
}
|
||||
}
|
||||
buildLinuxLoader(
|
||||
stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry),
|
||||
tmp, sizeof(stub_i386_netbsd_elf_fold), ft);
|
||||
stub_i386_netbsd_elf_entry, sizeof(stub_i386_netbsd_elf_entry),
|
||||
tmp, sizeof(stub_i386_netbsd_elf_fold), ft);
|
||||
}
|
||||
|
||||
static const
|
||||
@@ -1153,6 +1164,7 @@ bool PackLinuxElf32::canPack()
|
||||
unsigned osabi0 = u.buf[Elf32_Ehdr::EI_OSABI];
|
||||
// The first PT_LOAD32 must cover the beginning of the file (0==p_offset).
|
||||
Elf32_Phdr const *phdr = (Elf32_Phdr const *)(u.buf + e_phoff);
|
||||
note_size = 0;
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
if (j >= 14)
|
||||
return false;
|
||||
@@ -1166,17 +1178,30 @@ bool PackLinuxElf32::canPack()
|
||||
load_va = get_te32(&phdr->p_vaddr);
|
||||
exetype = 1;
|
||||
}
|
||||
if (phdr->PT_NOTE == p_type) {
|
||||
unsigned const x = get_te32(&phdr->p_memsz);
|
||||
if ( sizeof(elfout.notes) < x // beware overflow of note_size
|
||||
|| (sizeof(elfout.notes) < (note_size += x)) ) {
|
||||
throwCantPack("PT_NOTEs too big; try '--force-execve'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Elf32_Ehdr::ELFOSABI_NONE==osabi0 // Still seems to be generic.
|
||||
&& NULL!=osabi_note && phdr->PT_NOTE == p_type) {
|
||||
struct Elf32_Note note; memset(¬e, 0, sizeof(note));
|
||||
struct {
|
||||
struct Elf32_Nhdr nhdr;
|
||||
char name[8];
|
||||
unsigned body;
|
||||
} note;
|
||||
memset(¬e, 0, sizeof(note));
|
||||
fi->seek(p_offset, SEEK_SET);
|
||||
fi->readx(¬e, sizeof(note));
|
||||
fi->seek(0, SEEK_SET);
|
||||
if (4==get_te32(¬e.descsz)
|
||||
&& 1==get_te32(¬e.type)
|
||||
if (4==get_te32(¬e.nhdr.descsz)
|
||||
&& 1==get_te32(¬e.nhdr.type)
|
||||
// && 0==note.end
|
||||
&& (1+ strlen(osabi_note))==get_te32(¬e.namesz)
|
||||
&& 0==strcmp(osabi_note, (char const *)note.text)
|
||||
&& (1+ strlen(osabi_note))==get_te32(¬e.nhdr.namesz)
|
||||
&& 0==strcmp(osabi_note, (char const *)¬e.name[0])
|
||||
) {
|
||||
osabi0 = ei_osabi; // Specified by PT_NOTE.
|
||||
}
|
||||
@@ -1596,6 +1621,12 @@ PackLinuxElf32::generateElfHdr(
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
up4(unsigned x)
|
||||
{
|
||||
return ~3u & (3+ x);
|
||||
}
|
||||
|
||||
void
|
||||
PackNetBSDElf32x86::generateElfHdr(
|
||||
OutputFile *fo,
|
||||
@@ -1603,62 +1634,92 @@ PackNetBSDElf32x86::generateElfHdr(
|
||||
unsigned const brka
|
||||
)
|
||||
{
|
||||
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
||||
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
||||
h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
|
||||
assert(2==get_te16(&h3->ehdr.e_phnum));
|
||||
set_te16(&h3->ehdr.e_phnum, 3);
|
||||
super::generateElfHdr(fo, proto, brka);
|
||||
cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
|
||||
|
||||
assert(get_te32(&h3->ehdr.e_phoff) == sizeof(Elf32_Ehdr));
|
||||
h3->ehdr.e_shoff = 0;
|
||||
assert(get_te16(&h3->ehdr.e_ehsize) == sizeof(Elf32_Ehdr));
|
||||
assert(get_te16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr));
|
||||
set_te16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr));
|
||||
h3->ehdr.e_shnum = 0;
|
||||
h3->ehdr.e_shstrndx = 0;
|
||||
sz_elf_hdrs = sizeof(*h2) - sizeof(linfo);
|
||||
unsigned note_offset = sz_elf_hdrs;
|
||||
|
||||
sz_elf_hdrs = sizeof(*h3) - sizeof(linfo);
|
||||
unsigned const note_offset = sz_elf_hdrs;
|
||||
set_te32(&h3->phdr[0].p_filesz, sizeof(*h3)+sizeof(elfnote)); // + identsize;
|
||||
h3->phdr[0].p_memsz = h3->phdr[0].p_filesz;
|
||||
// Find the NetBSD PT_NOTE and the PaX PT_NOTE.
|
||||
Elf32_Nhdr const *np_NetBSD = 0; unsigned sz_NetBSD = 0;
|
||||
Elf32_Nhdr const *np_PaX = 0; unsigned sz_PaX = 0;
|
||||
unsigned char *cp = note_body;
|
||||
unsigned j;
|
||||
for (j=0; j < note_size; ) {
|
||||
Elf32_Nhdr const *const np = (Elf32_Nhdr const *)cp;
|
||||
int k = sizeof(*np) + up4(get_te32(&np->namesz))
|
||||
+ up4(get_te32(&np->descsz));
|
||||
|
||||
unsigned const brkb = brka | ((0==(~page_mask & brka)) ? 0x20 : 0);
|
||||
set_te32(&h3->phdr[1].p_type, PT_LOAD32); // be sure
|
||||
set_te32(&h3->phdr[1].p_offset, ~page_mask & brkb);
|
||||
set_te32(&h3->phdr[1].p_vaddr, brkb);
|
||||
set_te32(&h3->phdr[1].p_paddr, brkb);
|
||||
h3->phdr[1].p_filesz = 0;
|
||||
h3->phdr[1].p_memsz = 0;
|
||||
set_te32(&h3->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
|
||||
|
||||
set_te32(&h3->phdr[2].p_type, Elf32_Phdr::PT_NOTE);
|
||||
set_te32(&h3->phdr[2].p_offset, note_offset);
|
||||
set_te32(&h3->phdr[2].p_vaddr, note_offset);
|
||||
set_te32(&h3->phdr[2].p_paddr, note_offset);
|
||||
set_te32(&h3->phdr[2].p_filesz, sizeof(elfnote));
|
||||
set_te32(&h3->phdr[2].p_memsz, sizeof(elfnote));
|
||||
set_te32(&h3->phdr[2].p_flags, Elf32_Phdr::PF_R);
|
||||
set_te32(&h3->phdr[2].p_align, 4);
|
||||
|
||||
set_te32(&elfnote.namesz, 8);
|
||||
set_te32(&elfnote.descsz, 4);
|
||||
set_te32(&elfnote.type, 1);
|
||||
strcpy(elfnote.text, "NetBSD");
|
||||
if (pt_note) {
|
||||
struct Elf32_Note oldnote;
|
||||
fi->seek(get_te32(&pt_note->p_offset), SEEK_SET);
|
||||
fi->readx(&oldnote, sizeof(oldnote));
|
||||
elfnote.end = oldnote.end;
|
||||
if (NHDR_NETBSD_TAG == np->type && 7== np->namesz
|
||||
&& NETBSD_DESCSZ == np->descsz
|
||||
&& 0==strcmp(ELF_NOTE_NETBSD_NAME, (char const *)&np->body)) {
|
||||
np_NetBSD = np;
|
||||
sz_NetBSD = k;
|
||||
}
|
||||
if (NHDR_PAX_TAG == np->type && 4== np->namesz
|
||||
&& PAX_DESCSZ==np->descsz
|
||||
&& 0==strcmp(ELF_NOTE_PAX_NAME, (char const *)&np->body)) {
|
||||
np_PaX = np;
|
||||
sz_PaX = k;
|
||||
}
|
||||
cp += k;
|
||||
j += k;
|
||||
}
|
||||
else {
|
||||
elfnote.end = 0;
|
||||
|
||||
// Add PT_NOTE for the NetBSD note and PaX note, if any.
|
||||
note_offset += (np_NetBSD ? sizeof(Elf32_Phdr) : 0);
|
||||
note_offset += (np_PaX ? sizeof(Elf32_Phdr) : 0);
|
||||
Elf32_Phdr *phdr = &elfout.phdr[2];
|
||||
if (np_NetBSD) {
|
||||
set_te32(&phdr->p_type, Elf32_Phdr::PT_NOTE);
|
||||
set_te32(&phdr->p_offset, note_offset);
|
||||
set_te32(&phdr->p_vaddr, note_offset);
|
||||
set_te32(&phdr->p_paddr, note_offset);
|
||||
set_te32(&phdr->p_filesz, sz_NetBSD);
|
||||
set_te32(&phdr->p_memsz, sz_NetBSD);
|
||||
set_te32(&phdr->p_flags, Elf32_Phdr::PF_R);
|
||||
set_te32(&phdr->p_align, 4);
|
||||
|
||||
sz_elf_hdrs += sz_NetBSD + sizeof(*phdr);
|
||||
note_offset += sz_NetBSD;
|
||||
++phdr;
|
||||
}
|
||||
if (np_PaX) {
|
||||
set_te32(&phdr->p_type, Elf32_Phdr::PT_NOTE);
|
||||
set_te32(&phdr->p_offset, note_offset);
|
||||
set_te32(&phdr->p_vaddr, note_offset);
|
||||
set_te32(&phdr->p_paddr, note_offset);
|
||||
set_te32(&phdr->p_filesz, sz_PaX);
|
||||
set_te32(&phdr->p_memsz, sz_PaX);
|
||||
set_te32(&phdr->p_flags, Elf32_Phdr::PF_R);
|
||||
set_te32(&phdr->p_align, 4);
|
||||
|
||||
unsigned bits = get_te32(&np_PaX->body[4]);
|
||||
bits &= ~PAX_MPROTECT;
|
||||
bits |= PAX_NOMPROTECT;
|
||||
set_te32((unsigned *)&np_PaX->body[4], bits);
|
||||
|
||||
sz_elf_hdrs += sz_PaX + sizeof(*phdr);
|
||||
note_offset += sz_PaX;
|
||||
++phdr;
|
||||
}
|
||||
set_te32(&h2->phdr[0].p_filesz, note_offset);
|
||||
h2->phdr[0].p_memsz = h2->phdr[0].p_filesz;
|
||||
|
||||
if (ph.format==getFormat()) {
|
||||
memset(&h3->linfo, 0, sizeof(h3->linfo));
|
||||
fo->write(h3, sizeof(*h3) - sizeof(h3->linfo));
|
||||
fo->write(&elfnote, sizeof(elfnote));
|
||||
fo->write(&h3->linfo, sizeof(h3->linfo));
|
||||
set_te16(&h2->ehdr.e_phnum, !!sz_NetBSD + !!sz_PaX +
|
||||
get_te16(&h2->ehdr.e_phnum));
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(h2, sizeof(*h2) - sizeof(h2->linfo));
|
||||
|
||||
memcpy(&((char *)phdr)[0], np_NetBSD, sz_NetBSD);
|
||||
memcpy(&((char *)phdr)[sz_NetBSD], np_PaX, sz_PaX);
|
||||
|
||||
fo->write(&elfout.phdr[2],
|
||||
&((char *)phdr)[sz_PaX + sz_NetBSD] - (char *)&elfout.phdr[2]);
|
||||
|
||||
l_info foo; memset(&foo, 0, sizeof(foo));
|
||||
fo->rewrite(&foo, sizeof(foo));
|
||||
}
|
||||
else {
|
||||
assert(false); // unknown ph.format, PackLinuxElf32
|
||||
@@ -1686,19 +1747,14 @@ PackOpenBSDElf32x86::generateElfHdr(
|
||||
h3->ehdr.e_shnum = 0;
|
||||
h3->ehdr.e_shstrndx = 0;
|
||||
|
||||
sz_elf_hdrs = sizeof(*h3) - sizeof(linfo);
|
||||
unsigned const note_offset = sz_elf_hdrs;
|
||||
set_te32(&h3->phdr[0].p_filesz, sizeof(*h3)+sizeof(elfnote)); // + identsize;
|
||||
h3->phdr[0].p_memsz = h3->phdr[0].p_filesz;
|
||||
struct {
|
||||
Elf32_Nhdr nhdr;
|
||||
char name[8];
|
||||
unsigned body;
|
||||
} elfnote;
|
||||
|
||||
unsigned const brkb = brka | ((0==(~page_mask & brka)) ? 0x20 : 0);
|
||||
set_te32(&h3->phdr[1].p_type, PT_LOAD32); // be sure
|
||||
set_te32(&h3->phdr[1].p_offset, ~page_mask & brkb);
|
||||
set_te32(&h3->phdr[1].p_vaddr, brkb);
|
||||
set_te32(&h3->phdr[1].p_paddr, brkb);
|
||||
h3->phdr[1].p_filesz = 0;
|
||||
h3->phdr[1].p_memsz = 0;
|
||||
set_te32(&h3->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
|
||||
unsigned const note_offset = sizeof(*h3) - sizeof(linfo);
|
||||
sz_elf_hdrs = sizeof(elfnote) + note_offset;
|
||||
|
||||
set_te32(&h3->phdr[2].p_type, Elf32_Phdr::PT_NOTE);
|
||||
set_te32(&h3->phdr[2].p_offset, note_offset);
|
||||
@@ -1709,11 +1765,24 @@ PackOpenBSDElf32x86::generateElfHdr(
|
||||
set_te32(&h3->phdr[2].p_flags, Elf32_Phdr::PF_R);
|
||||
set_te32(&h3->phdr[2].p_align, 4);
|
||||
|
||||
set_te32(&elfnote.namesz, 8);
|
||||
set_te32(&elfnote.descsz, 4);
|
||||
set_te32(&elfnote.type, 1);
|
||||
strcpy(elfnote.text, "OpenBSD");
|
||||
elfnote.end = 0;
|
||||
// Q: Same as this->note_body[0 .. this->note_size-1] ?
|
||||
set_te32(&elfnote.nhdr.namesz, 8);
|
||||
set_te32(&elfnote.nhdr.descsz, OPENBSD_DESCSZ);
|
||||
set_te32(&elfnote.nhdr.type, NHDR_OPENBSD_TAG);
|
||||
memcpy(elfnote.name, "OpenBSD", sizeof(elfnote.name));
|
||||
elfnote.body = 0;
|
||||
|
||||
set_te32(&h3->phdr[0].p_filesz, sz_elf_hdrs);
|
||||
h3->phdr[0].p_memsz = h3->phdr[0].p_filesz;
|
||||
|
||||
unsigned const brkb = brka | ((0==(~page_mask & brka)) ? 0x20 : 0);
|
||||
set_te32(&h3->phdr[1].p_type, PT_LOAD32); // be sure
|
||||
set_te32(&h3->phdr[1].p_offset, ~page_mask & brkb);
|
||||
set_te32(&h3->phdr[1].p_vaddr, brkb);
|
||||
set_te32(&h3->phdr[1].p_paddr, brkb);
|
||||
h3->phdr[1].p_filesz = 0;
|
||||
h3->phdr[1].p_memsz = 0;
|
||||
set_te32(&h3->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
|
||||
|
||||
if (ph.format==getFormat()) {
|
||||
memset(&h3->linfo, 0, sizeof(h3->linfo));
|
||||
@@ -1790,12 +1859,28 @@ void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter & /*ft*/)
|
||||
fi->seek(e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, sz_phdrs);
|
||||
|
||||
// Remember all PT_NOTE, and find lg2_page from PT_LOAD.
|
||||
Elf32_Phdr const *phdr = phdri;
|
||||
note_size = 0;
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
if (!pt_note && phdr->PT_NOTE32 == get_te32(&phdr->p_type)) {
|
||||
pt_note = const_cast<Elf32_Phdr *>(phdr);
|
||||
if (phdr->PT_NOTE32 == get_te32(&phdr->p_type)) {
|
||||
note_size += ~3u & (3+ get_te32(&phdr->p_filesz));
|
||||
}
|
||||
if (phdr->PT_LOAD32 == get_te32(&phdr->p_type)) {
|
||||
}
|
||||
if (note_size) {
|
||||
note_body = new unsigned char[note_size];
|
||||
note_size = 0;
|
||||
}
|
||||
phdr = phdri;
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
unsigned const type = get_te32(&phdr->p_type);
|
||||
if (phdr->PT_NOTE32 == type) {
|
||||
unsigned const len = get_te32(&phdr->p_filesz);
|
||||
fi->seek(get_te32(&phdr->p_offset), SEEK_SET);
|
||||
fi->readx(¬e_body[note_size], len);
|
||||
note_size += ~3u & (3+ len);
|
||||
}
|
||||
if (phdr->PT_LOAD32 == type) {
|
||||
unsigned x = get_te32(&phdr->p_align) >> lg2_page;
|
||||
while (x>>=1) {
|
||||
++lg2_page;
|
||||
@@ -1899,11 +1984,26 @@ void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter & /*ft*/)
|
||||
fi->readx(phdri, sz_phdrs);
|
||||
|
||||
Elf64_Phdr const *phdr = phdri;
|
||||
note_size = 0;
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
if (!pt_note && phdr->PT_NOTE64 == get_te32(&phdr->p_type)) {
|
||||
pt_note = const_cast<Elf64_Phdr *>(phdr);
|
||||
if (phdr->PT_NOTE64 == get_te32(&phdr->p_type)) {
|
||||
note_size += ~3u & (3+ get_te64(&phdr->p_filesz));
|
||||
}
|
||||
if (phdr->PT_LOAD64 == get_te64(&phdr->p_type)) {
|
||||
}
|
||||
if (note_size) {
|
||||
note_body = new unsigned char[note_size];
|
||||
note_size = 0;
|
||||
}
|
||||
phdr = phdri;
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
unsigned const type = get_te32(&phdr->p_type);
|
||||
if (phdr->PT_NOTE64 == type) {
|
||||
unsigned const len = get_te64(&phdr->p_filesz);
|
||||
fi->seek(get_te64(&phdr->p_offset), SEEK_SET);
|
||||
fi->readx(¬e_body[note_size], len);
|
||||
note_size += ~3u & (3+ len);
|
||||
}
|
||||
if (phdr->PT_LOAD64 == type) {
|
||||
unsigned x = get_te64(&phdr->p_align) >> lg2_page;
|
||||
while (x>>=1) {
|
||||
++lg2_page;
|
||||
@@ -2420,18 +2520,19 @@ void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
|
||||
fo->rewrite(phdri, e_phnum * sizeof(*phdri));
|
||||
}
|
||||
else {
|
||||
if (Elf32_Phdr::PT_NOTE==get_te32(&elfout.phdr[2].p_type)) {
|
||||
unsigned const reloc = get_te32(&elfout.phdr[0].p_vaddr);
|
||||
set_te32( &elfout.phdr[2].p_vaddr,
|
||||
reloc + get_te32(&elfout.phdr[2].p_vaddr));
|
||||
set_te32( &elfout.phdr[2].p_paddr,
|
||||
reloc + get_te32(&elfout.phdr[2].p_paddr));
|
||||
fo->rewrite(&elfout, sz_elf_hdrs);
|
||||
fo->rewrite(&elfnote, sizeof(elfnote));
|
||||
}
|
||||
else {
|
||||
fo->rewrite(&elfout, sz_elf_hdrs);
|
||||
unsigned const reloc = get_te32(&elfout.phdr[0].p_vaddr);
|
||||
Elf32_Phdr *phdr = &elfout.phdr[2];
|
||||
unsigned const o_phnum = get_te16(&elfout.ehdr.e_phnum);
|
||||
for (unsigned j = 2; j < o_phnum; ++j, ++phdr) {
|
||||
if (Elf32_Phdr::PT_NOTE==get_te32(&phdr->p_type)) {
|
||||
set_te32( &phdr->p_vaddr,
|
||||
reloc + get_te32(&phdr->p_vaddr));
|
||||
set_te32( &phdr->p_paddr,
|
||||
reloc + get_te32(&phdr->p_paddr));
|
||||
}
|
||||
}
|
||||
fo->rewrite(&elfout, sizeof(Elf32_Phdr) * o_phnum + sizeof(Elf32_Ehdr));
|
||||
fo->seek(sz_elf_hdrs, SEEK_SET); // skip over PT_NOTE bodies, if any
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user