p_lx_elf.h: turn file_image into a MemBuffer.

This commit is contained in:
Markus F.X.J. Oberhumer
2016-09-21 22:22:41 +02:00
parent 60a1214d7e
commit 242f606a29
5 changed files with 32 additions and 29 deletions
+2 -5
View File
@@ -242,6 +242,7 @@ void MemBuffer::alloc(unsigned size)
assert(b == NULL); assert(b == NULL);
assert(b_size == 0); assert(b_size == 0);
// //
assert(size > 0);
size_t bytes = mem_size(1, size, use_mcheck ? 32 : 0); size_t bytes = mem_size(1, size, use_mcheck ? 32 : 0);
unsigned char *p = (unsigned char *) malloc(bytes); unsigned char *p = (unsigned char *) malloc(bytes);
if (!p) if (!p)
@@ -262,8 +263,4 @@ void MemBuffer::alloc(unsigned size)
//fill(0, b_size, (rand() & 0xff) | 1); // debug //fill(0, b_size, (rand() & 0xff) | 1); // debug
} }
/* vim:set ts=4 sw=4 et: */
/*
vi:ts=4:et
*/
+3 -6
View File
@@ -55,7 +55,8 @@ public:
unsigned getSize() const { return b_size; } unsigned getSize() const { return b_size; }
operator unsigned char * () { return b; } operator unsigned char * () { return b; }
//operator const unsigned char * () const { return b; } operator const unsigned char * () const { return b; }
void *getVoidPtr() { return (void *) b; } void *getVoidPtr() { return (void *) b; }
const void *getVoidPtr() const { return (const void *) b; } const void *getVoidPtr() const { return (const void *) b; }
@@ -79,8 +80,4 @@ private:
#endif /* already included */ #endif /* already included */
/* vim:set ts=4 sw=4 et: */
/*
vi:ts=4:et
*/
+18 -12
View File
@@ -94,6 +94,16 @@ funpad4(InputFile *fi)
return d; return d;
} }
static void alloc_file_image(MemBuffer &mb, off_t size)
{
assert(mem_size_valid_bytes(size));
if (mb.getVoidPtr() == NULL) {
mb.alloc(size);
} else {
assert(size <= (off_t) mb.getSize());
}
}
int int
PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const
{ {
@@ -192,7 +202,7 @@ PackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const
} }
PackLinuxElf::PackLinuxElf(InputFile *f) PackLinuxElf::PackLinuxElf(InputFile *f)
: super(f), e_phnum(0), file_image(NULL), dynstr(NULL), : super(f), e_phnum(0), dynstr(NULL),
sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0), sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0),
lg2_page(12), page_size(1u<<lg2_page), xct_off(0), xct_va(0), lg2_page(12), page_size(1u<<lg2_page), xct_off(0), xct_va(0),
jni_onload_va(0), jni_onload_va(0),
@@ -203,7 +213,6 @@ PackLinuxElf::PackLinuxElf(InputFile *f)
PackLinuxElf::~PackLinuxElf() PackLinuxElf::~PackLinuxElf()
{ {
delete[] file_image; file_image = NULL;
} }
void void
@@ -230,14 +239,14 @@ PackLinuxElf32::PackLinuxElf32help1(InputFile *f)
if (f && Elf32_Ehdr::ET_DYN!=e_type) { if (f && Elf32_Ehdr::ET_DYN!=e_type) {
unsigned const len = sz_phdrs + e_phoff; unsigned const len = sz_phdrs + e_phoff;
assert(file_image != NULL); // set by PackLinuxElf64help1 alloc_file_image(file_image, len);
f->seek(0, SEEK_SET); f->seek(0, SEEK_SET);
f->readx(file_image, len); f->readx(file_image, len);
phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !! phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !!
} }
if (f && Elf32_Ehdr::ET_DYN==e_type) { if (f && Elf32_Ehdr::ET_DYN==e_type) {
// The DT_STRTAB has no designated length. Read the whole file. // The DT_STRTAB has no designated length. Read the whole file.
assert(file_image != NULL); // set by PackLinuxElf64help1 alloc_file_image(file_image, file_size);
f->seek(0, SEEK_SET); f->seek(0, SEEK_SET);
f->readx(file_image, file_size); f->readx(file_image, file_size);
phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !! phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !!
@@ -600,7 +609,7 @@ PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
if (f && Elf64_Ehdr::ET_DYN!=e_type) { if (f && Elf64_Ehdr::ET_DYN!=e_type) {
unsigned const len = sz_phdrs + e_phoff; unsigned const len = sz_phdrs + e_phoff;
assert(file_image != NULL); // set by PackLinuxElf64help1 alloc_file_image(file_image, len);
f->seek(0, SEEK_SET); f->seek(0, SEEK_SET);
f->readx(file_image, len); f->readx(file_image, len);
phdri= (Elf64_Phdr *)(e_phoff + file_image); // do not free() !! phdri= (Elf64_Phdr *)(e_phoff + file_image); // do not free() !!
@@ -1662,7 +1671,7 @@ PackLinuxElf64ppcle::canPack()
if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) { if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
// The DT_STRTAB has no designated length. Read the whole file. // The DT_STRTAB has no designated length. Read the whole file.
assert(file_image != NULL); // set by PackLinuxElf64help1 alloc_file_image(file_image, file_size);
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(file_image, file_size); fi->readx(file_image, file_size);
memcpy(&ehdri, ehdr, sizeof(Elf64_Ehdr)); memcpy(&ehdri, ehdr, sizeof(Elf64_Ehdr));
@@ -1837,7 +1846,7 @@ PackLinuxElf64amd::canPack()
if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) { if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
// The DT_STRTAB has no designated length. Read the whole file. // The DT_STRTAB has no designated length. Read the whole file.
assert(file_image != NULL); // set by PackLinuxElf64help1 alloc_file_image(file_image, file_size);
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(file_image, file_size); fi->readx(file_image, file_size);
memcpy(&ehdri, ehdr, sizeof(Elf64_Ehdr)); memcpy(&ehdri, ehdr, sizeof(Elf64_Ehdr));
@@ -3135,7 +3144,7 @@ void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
unsigned tmp = sz_pack2 + get_te32(&elfout.phdr[0].p_vaddr); unsigned tmp = sz_pack2 + get_te32(&elfout.phdr[0].p_vaddr);
tmp |= (Elf32_Ehdr::EM_ARM==e_machine); // THUMB mode tmp |= (Elf32_Ehdr::EM_ARM==e_machine); // THUMB mode
set_te32(&tmp, tmp); set_te32(&tmp, tmp);
fo->seek((char const *)&jni_onload_sym->st_value - file_image, SEEK_SET); fo->seek(ptr_udiff(&jni_onload_sym->st_value, file_image), SEEK_SET);
fo->rewrite(&tmp, sizeof(tmp)); fo->rewrite(&tmp, sizeof(tmp));
fo->seek(0, SEEK_SET); fo->seek(0, SEEK_SET);
} }
@@ -3978,7 +3987,4 @@ void PackLinuxElf::unpack(OutputFile * /*fo*/)
throwCantUnpack("internal error"); throwCantUnpack("internal error");
} }
/* /* vim:set ts=4 sw=4 et: */
vi:ts=4:et
*/
+2 -6
View File
@@ -72,7 +72,7 @@ protected:
unsigned e_type; unsigned e_type;
unsigned e_phnum; /* Program header table entry count */ unsigned e_phnum; /* Program header table entry count */
unsigned e_shnum; unsigned e_shnum;
char *file_image; // if ET_DYN investigation MemBuffer file_image; // if ET_DYN investigation
char const *dynstr; // from DT_STRTAB char const *dynstr; // from DT_STRTAB
unsigned sz_phdrs; // sizeof Phdr[] unsigned sz_phdrs; // sizeof Phdr[]
@@ -600,8 +600,4 @@ protected:
#endif /*} already included */ #endif /*} already included */
/* vim:set ts=4 sw=4 et: */
/*
vi:ts=4:et
*/
+7
View File
@@ -78,6 +78,13 @@ inline int ptr_diff(const void *p1, const void *p2) {
return ptr_diff((const char *) p1, (const char *) p2); return ptr_diff((const char *) p1, (const char *) p2);
} }
template <class T1, class T2>
inline int ptr_udiff(const T1 &p1, const T2 &p2) {
int d = ptr_diff(p1, p2);
assert(d >= 0);
return d;
}
/************************************************************************* /*************************************************************************
// some unsigned char string support functions // some unsigned char string support functions
**************************************************************************/ **************************************************************************/