|
@@ -29,6 +29,10 @@
|
|
|
#include <mach-o/getsect.h>
|
|
|
#include <sys/mman.h>
|
|
|
#include <sys/stat.h>
|
|
|
+#elif !defined(_WIN32)
|
|
|
+#include <sys/mman.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <elf.h>
|
|
|
#endif
|
|
|
|
|
|
#include "thorplugin.hpp"
|
|
@@ -201,7 +205,7 @@ bool HelperDll::getResource(size32_t & len, const void * & data, const char * ty
|
|
|
if (!data)
|
|
|
{
|
|
|
if (trace)
|
|
|
- printf("Failed to locate symbol %s", symName.str());
|
|
|
+ printf("Failed to locate symbol %s\n", symName.str());
|
|
|
return false;
|
|
|
}
|
|
|
byte bom;
|
|
@@ -245,6 +249,67 @@ static void secscan (bfd *file, sec_ptr sec, void *userParam)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+static bool getResourceFromMappedFile(const char * filename, const byte * start_addr, MemoryBuffer &data, const char * type, unsigned id)
|
|
|
+{
|
|
|
+#if defined(_WIN32) || defined (_USE_BINUTILS)
|
|
|
+ throwUnexpected();
|
|
|
+#elif defined(__APPLE__)
|
|
|
+ VStringBuffer sectname("%s_%u", type, id);
|
|
|
+ // The first bytes are the Mach-O header
|
|
|
+ const struct mach_header_64 *mh = (const struct mach_header_64 *) start_addr;
|
|
|
+ if (mh->magic != MH_MAGIC_64)
|
|
|
+ {
|
|
|
+ DBGLOG("Failed to extract resource %s: Does not appear to be a Mach-O 64-bit binary", filename);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ unsigned long len = 0;
|
|
|
+ unsigned char *data2 = getsectiondata(mh, "__TEXT", sectname.str(), &len);
|
|
|
+ data.append(len, data2);
|
|
|
+ return true;
|
|
|
+#else
|
|
|
+ // The first bytes are the ELF header
|
|
|
+ const Elf64_Ehdr * hdr = (const Elf64_Ehdr *) start_addr;
|
|
|
+ if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
|
|
|
+ {
|
|
|
+ DBGLOG("Failed to extract resource %s: Does not appear to be a ELF binary", filename);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (hdr->e_ident[EI_CLASS] != ELFCLASS64)
|
|
|
+ {
|
|
|
+ DBGLOG("Failed to extract resource %s: Does not appear to be a ELF 64-bit binary", filename);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check that there is a symbol table for the sections.
|
|
|
+ if (hdr->e_shstrndx == SHN_UNDEF)
|
|
|
+ {
|
|
|
+ DBGLOG("Failed to extract resource %s: Does include a section symbol table", filename);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Now walk the sections comparing the section names
|
|
|
+ Elf64_Half numSections = hdr->e_shnum;
|
|
|
+ const Elf64_Shdr * sectionHeaders = reinterpret_cast<const Elf64_Shdr *>(start_addr + hdr->e_shoff);
|
|
|
+ const Elf64_Shdr & symbolTableSection = sectionHeaders[hdr->e_shstrndx];
|
|
|
+ const char * symbolTable = (const char *)start_addr + symbolTableSection.sh_offset;
|
|
|
+ VStringBuffer sectname("%s_%u", type, id);
|
|
|
+ for (unsigned iSect= 0; iSect < numSections; iSect++)
|
|
|
+ {
|
|
|
+ const Elf64_Shdr & section = sectionHeaders[iSect];
|
|
|
+ const char * sectionName = symbolTable + section.sh_name;
|
|
|
+ if (streq(sectionName, sectname))
|
|
|
+ {
|
|
|
+ data.append(section.sh_size, start_addr + section.sh_offset);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DBGLOG("Failed to extract resource %s: Does include a matching entry", filename);
|
|
|
+ return false;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
extern bool getResourceFromFile(const char *filename, MemoryBuffer &data, const char * type, unsigned id)
|
|
|
{
|
|
|
#ifdef _WIN32
|
|
@@ -277,8 +342,7 @@ extern bool getResourceFromFile(const char *filename, MemoryBuffer &data, const
|
|
|
bfd_close (file);
|
|
|
}
|
|
|
return data.length() != 0;
|
|
|
-#elif defined(__APPLE__)
|
|
|
- unsigned long len = 0;
|
|
|
+#else
|
|
|
struct stat stat_buf;
|
|
|
VStringBuffer sectname("%s_%u", type, id);
|
|
|
int fd = open(filename, O_RDONLY);
|
|
@@ -287,31 +351,21 @@ extern bool getResourceFromFile(const char *filename, MemoryBuffer &data, const
|
|
|
DBGLOG("Failed to load library %s: %d", filename, errno);
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ bool ok = false;
|
|
|
__uint64 size = stat_buf.st_size;
|
|
|
- byte *start_addr = (byte *) mmap(0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
|
|
|
+ const byte *start_addr = (const byte *) mmap(0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
|
|
|
if (start_addr == MAP_FAILED)
|
|
|
{
|
|
|
DBGLOG("Failed to load library %s: %d", filename, errno);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // The first bytes are the Mach-O header
|
|
|
- struct mach_header_64 *mh = (struct mach_header_64 *) start_addr;
|
|
|
- if (mh->magic != MH_MAGIC_64)
|
|
|
- {
|
|
|
- DBGLOG("Failed to load library %s: Does not appear to be a Mach-O 64-bit binary", filename);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- unsigned char *data2 = getsectiondata(mh, "__TEXT", sectname.str(), &len);
|
|
|
- data.append(len, data2);
|
|
|
- }
|
|
|
- munmap(start_addr, size);
|
|
|
+ ok = getResourceFromMappedFile(filename, start_addr, data, type, id);
|
|
|
+ munmap((void *)start_addr, size);
|
|
|
}
|
|
|
close(fd);
|
|
|
- return len != 0;
|
|
|
-#else
|
|
|
- UNIMPLEMENTED;
|
|
|
+ return ok;
|
|
|
#endif
|
|
|
}
|
|
|
|