attempts at reading an elf file
This commit is contained in:
@@ -1,112 +1,218 @@
|
|||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
|
#include "logger/logger.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <libelf.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void *hi_elf_load_module(const char *filename) {
|
||||||
|
int fd = open(filename, O_RDONLY);
|
||||||
|
|
||||||
|
Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
|
||||||
|
|
||||||
|
Elf_Kind modkind = elf_kind(elf);
|
||||||
|
log_debug("kind: %u\n", modkind);
|
||||||
|
|
||||||
|
uptr modbase = elf_getbase(elf);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return (void*)modbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hi_elf_print_module_from_memory(void *address, size_t size) {
|
||||||
|
Elf *elf = elf_memory(address, size);
|
||||||
|
|
||||||
|
int err = elf_errno();
|
||||||
|
if (err) {
|
||||||
|
log_error("%s\n", elf_errmsg(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t phdrnum = 0;
|
||||||
|
err = elf_getphdrnum(elf, &phdrnum);
|
||||||
|
Elf64_Phdr *phdr = elf64_getphdr(elf);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < phdrnum; ++i) {
|
||||||
|
Elf64_Phdr *p = phdr + i;
|
||||||
|
log_debugv("segment type: %s\n", segment_type_to_str(p->p_type));
|
||||||
|
|
||||||
|
size_t segment_size = p->p_memsz;
|
||||||
|
void *segment_start = address + p->p_vaddr;
|
||||||
|
void *segment_end = address + p->p_vaddr + segment_size;
|
||||||
|
|
||||||
|
void *strtab = 0;
|
||||||
|
void *symtab = 0;
|
||||||
|
size_t strsz = 0;
|
||||||
|
size_t syment = 0;
|
||||||
|
void *rela = 0;
|
||||||
|
size_t relasz = 0;
|
||||||
|
size_t relaent = 0;
|
||||||
|
size_t relacount = 0;
|
||||||
|
void *pltgot = 0;
|
||||||
|
size_t pltrelsz = 0;
|
||||||
|
void *pltrel = 0;
|
||||||
|
|
||||||
|
if (p->p_type == PT_DYNAMIC) {
|
||||||
|
Elf64_Dyn *dyn = (Elf64_Dyn *)segment_start;
|
||||||
|
while ((void *)dyn < segment_end) {
|
||||||
|
log_debugv(" dyn type: %s\n", dyn_type_to_str(dyn->d_tag));
|
||||||
|
|
||||||
|
if (dyn->d_tag == DT_STRTAB) {
|
||||||
|
strtab = (void *)dyn->d_un.d_ptr;
|
||||||
|
} else if (dyn->d_tag == DT_SYMTAB) {
|
||||||
|
symtab = (void *)dyn->d_un.d_ptr;
|
||||||
|
} else if (dyn->d_tag == DT_STRSZ) {
|
||||||
|
strsz = dyn->d_un.d_val;
|
||||||
|
} else if (dyn->d_tag == DT_SYMENT) {
|
||||||
|
syment = dyn->d_un.d_val;
|
||||||
|
} else if (dyn->d_tag == DT_RELA) {
|
||||||
|
rela = (void *)dyn->d_un.d_ptr;
|
||||||
|
} else if (dyn->d_tag == DT_RELASZ) {
|
||||||
|
relasz = dyn->d_un.d_val;
|
||||||
|
} else if (dyn->d_tag == DT_RELAENT) {
|
||||||
|
relaent = dyn->d_un.d_val;
|
||||||
|
} else if (dyn->d_tag == DT_RELACOUNT) {
|
||||||
|
relacount = dyn->d_un.d_val;
|
||||||
|
} else if (dyn->d_tag == DT_PLTGOT) {
|
||||||
|
pltgot = (void *)dyn->d_un.d_ptr;
|
||||||
|
} else if (dyn->d_tag == DT_PLTRELSZ) {
|
||||||
|
pltrelsz = dyn->d_un.d_val;
|
||||||
|
} else if (dyn->d_tag == DT_PLTREL) {
|
||||||
|
pltrel = (void *)dyn->d_un.d_val;
|
||||||
|
}
|
||||||
|
++dyn;
|
||||||
|
}
|
||||||
|
log_debugv("\nstrtab: %p\n"
|
||||||
|
"symtab: %p\n"
|
||||||
|
"strsz: %zu\n"
|
||||||
|
"syment: %zu\n"
|
||||||
|
"rela: %p\n"
|
||||||
|
"relasz: %zu\n"
|
||||||
|
"relaent: %zu\n"
|
||||||
|
"relacount: %zu\n"
|
||||||
|
"pltgot: %p\n"
|
||||||
|
"pltrelsz: %zu\n"
|
||||||
|
"pltrel: %p\n",
|
||||||
|
strtab, symtab, strsz, syment, rela, relasz, relaent,
|
||||||
|
relacount, pltgot, pltrelsz, pltrel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TYPE_TO_STR(type) \
|
||||||
|
case (type): \
|
||||||
|
return #type
|
||||||
|
|
||||||
const char *dyn_type_to_str(unsigned type) {
|
const char *dyn_type_to_str(unsigned type) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DT_NULL: return "NULL";
|
TYPE_TO_STR(DT_NULL);
|
||||||
case DT_NEEDED: return "NEEDED";
|
TYPE_TO_STR(DT_NEEDED);
|
||||||
case DT_PLTRELSZ: return "PLTRELSZ";
|
TYPE_TO_STR(DT_PLTRELSZ);
|
||||||
case DT_PLTGOT: return "PLTGOT";
|
TYPE_TO_STR(DT_PLTGOT);
|
||||||
case DT_HASH: return "HASH";
|
TYPE_TO_STR(DT_HASH);
|
||||||
case DT_STRTAB: return "STRTAB";
|
TYPE_TO_STR(DT_STRTAB);
|
||||||
case DT_SYMTAB: return "SYMTAB";
|
TYPE_TO_STR(DT_SYMTAB);
|
||||||
case DT_RELA: return "RELA";
|
TYPE_TO_STR(DT_RELA);
|
||||||
case DT_RELASZ: return "RELASZ";
|
TYPE_TO_STR(DT_RELASZ);
|
||||||
case DT_RELAENT: return "RELAENT";
|
TYPE_TO_STR(DT_RELAENT);
|
||||||
case DT_STRSZ: return "STRSZ";
|
TYPE_TO_STR(DT_STRSZ);
|
||||||
case DT_SYMENT: return "SYMENT";
|
TYPE_TO_STR(DT_SYMENT);
|
||||||
case DT_INIT: return "INIT";
|
TYPE_TO_STR(DT_INIT);
|
||||||
case DT_FINI: return "FINI";
|
TYPE_TO_STR(DT_FINI);
|
||||||
case DT_SONAME: return "SONAME";
|
TYPE_TO_STR(DT_SONAME);
|
||||||
case DT_RPATH: return "RPATH";
|
TYPE_TO_STR(DT_RPATH);
|
||||||
case DT_SYMBOLIC: return "SYMBOLIC";
|
TYPE_TO_STR(DT_SYMBOLIC);
|
||||||
case DT_REL: return "REL";
|
TYPE_TO_STR(DT_REL);
|
||||||
case DT_RELSZ: return "RELSZ";
|
TYPE_TO_STR(DT_RELSZ);
|
||||||
case DT_RELENT: return "RELENT";
|
TYPE_TO_STR(DT_RELENT);
|
||||||
case DT_PLTREL: return "PLTREL";
|
TYPE_TO_STR(DT_PLTREL);
|
||||||
case DT_DEBUG: return "DEBUG";
|
TYPE_TO_STR(DT_DEBUG);
|
||||||
case DT_TEXTREL: return "TEXTREL";
|
TYPE_TO_STR(DT_TEXTREL);
|
||||||
case DT_JMPREL: return "JMPREL";
|
TYPE_TO_STR(DT_JMPREL);
|
||||||
case DT_BIND_NOW: return "BIND_NOW";
|
TYPE_TO_STR(DT_BIND_NOW);
|
||||||
case DT_INIT_ARRAY: return "INIT_ARRAY";
|
TYPE_TO_STR(DT_INIT_ARRAY);
|
||||||
case DT_FINI_ARRAY: return "FINI_ARRAY";
|
TYPE_TO_STR(DT_FINI_ARRAY);
|
||||||
case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
|
TYPE_TO_STR(DT_INIT_ARRAYSZ);
|
||||||
case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
|
TYPE_TO_STR(DT_FINI_ARRAYSZ);
|
||||||
case DT_RUNPATH: return "RUNPATH";
|
TYPE_TO_STR(DT_RUNPATH);
|
||||||
case DT_FLAGS: return "FLAGS";
|
TYPE_TO_STR(DT_FLAGS);
|
||||||
case DT_PREINIT_ARRAY: return "ENCODING/PREINIT_ARRAY";
|
TYPE_TO_STR(DT_PREINIT_ARRAY);
|
||||||
case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
|
TYPE_TO_STR(DT_PREINIT_ARRAYSZ);
|
||||||
case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
|
TYPE_TO_STR(DT_SYMTAB_SHNDX);
|
||||||
case DT_RELRSZ: return "RELRSZ";
|
TYPE_TO_STR(DT_RELRSZ);
|
||||||
case DT_RELR: return "RELR";
|
TYPE_TO_STR(DT_RELR);
|
||||||
case DT_RELRENT: return "RELRENT";
|
TYPE_TO_STR(DT_RELRENT);
|
||||||
case DT_NUM: return "NUM";
|
TYPE_TO_STR(DT_NUM);
|
||||||
case DT_LOOS: return "LOOS";
|
TYPE_TO_STR(DT_LOOS);
|
||||||
case DT_HIOS: return "HIOS";
|
TYPE_TO_STR(DT_HIOS);
|
||||||
case DT_LOPROC: return "LOPROC";
|
TYPE_TO_STR(DT_LOPROC);
|
||||||
case DT_HIPROC: return "HIPROC";
|
TYPE_TO_STR(DT_HIPROC);
|
||||||
case DT_PROCNUM: return "PROCNUM";
|
TYPE_TO_STR(DT_PROCNUM);
|
||||||
case DT_VALRNGLO: return "VALRNGLO";
|
TYPE_TO_STR(DT_VALRNGLO);
|
||||||
case DT_GNU_PRELINKED: return "GNU_PRELINKED";
|
TYPE_TO_STR(DT_GNU_PRELINKED);
|
||||||
case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
|
TYPE_TO_STR(DT_GNU_CONFLICTSZ);
|
||||||
case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
|
TYPE_TO_STR(DT_GNU_LIBLISTSZ);
|
||||||
case DT_CHECKSUM: return "CHECKSUM";
|
TYPE_TO_STR(DT_CHECKSUM);
|
||||||
case DT_PLTPADSZ: return "PLTPADSZ";
|
TYPE_TO_STR(DT_PLTPADSZ);
|
||||||
case DT_MOVEENT: return "MOVEENT";
|
TYPE_TO_STR(DT_MOVEENT);
|
||||||
case DT_MOVESZ: return "MOVESZ";
|
TYPE_TO_STR(DT_MOVESZ);
|
||||||
case DT_FEATURE_1: return "FEATURE_1";
|
TYPE_TO_STR(DT_FEATURE_1);
|
||||||
case DT_POSFLAG_1: return "POSFLAG_1";
|
TYPE_TO_STR(DT_POSFLAG_1);
|
||||||
case DT_SYMINSZ: return "SYMINSZ";
|
TYPE_TO_STR(DT_SYMINSZ);
|
||||||
case DT_SYMINENT: return "SYMINENT/VALRNGHI";
|
TYPE_TO_STR(DT_SYMINENT);
|
||||||
case DT_ADDRRNGLO: return "ADDRRNGLO";
|
TYPE_TO_STR(DT_ADDRRNGLO);
|
||||||
case DT_GNU_HASH: return "GNU_HASH";
|
TYPE_TO_STR(DT_GNU_HASH);
|
||||||
case DT_TLSDESC_PLT: return "TLSDESC_PLT";
|
TYPE_TO_STR(DT_TLSDESC_PLT);
|
||||||
case DT_TLSDESC_GOT: return "TLSDESC_GOT";
|
TYPE_TO_STR(DT_TLSDESC_GOT);
|
||||||
case DT_GNU_CONFLICT: return "GNU_CONFLICT";
|
TYPE_TO_STR(DT_GNU_CONFLICT);
|
||||||
case DT_GNU_LIBLIST: return "GNU_LIBLIST";
|
TYPE_TO_STR(DT_GNU_LIBLIST);
|
||||||
case DT_CONFIG: return "CONFIG";
|
TYPE_TO_STR(DT_CONFIG);
|
||||||
case DT_DEPAUDIT: return "DEPAUDIT";
|
TYPE_TO_STR(DT_DEPAUDIT);
|
||||||
case DT_AUDIT: return "AUDIT";
|
TYPE_TO_STR(DT_AUDIT);
|
||||||
case DT_PLTPAD: return "PLTPAD";
|
TYPE_TO_STR(DT_PLTPAD);
|
||||||
case DT_MOVETAB: return "MOVETAB";
|
TYPE_TO_STR(DT_MOVETAB);
|
||||||
case DT_SYMINFO: return "SYMINFO/ADDRRNGHI";
|
TYPE_TO_STR(DT_SYMINFO);
|
||||||
case DT_VERSYM: return "VERSYM";
|
TYPE_TO_STR(DT_VERSYM);
|
||||||
case DT_RELACOUNT: return "RELACOUNT";
|
TYPE_TO_STR(DT_RELACOUNT);
|
||||||
case DT_RELCOUNT: return "RELCOUNT";
|
TYPE_TO_STR(DT_RELCOUNT);
|
||||||
case DT_FLAGS_1: return "FLAGS_1";
|
TYPE_TO_STR(DT_FLAGS_1);
|
||||||
case DT_VERDEF: return "VERDEF";
|
TYPE_TO_STR(DT_VERDEF);
|
||||||
case DT_VERDEFNUM: return "VERDEFNUM";
|
TYPE_TO_STR(DT_VERDEFNUM);
|
||||||
case DT_VERNEED: return "VERNEED";
|
TYPE_TO_STR(DT_VERNEED);
|
||||||
case DT_VERNEEDNUM: return "VERNEEDNUM";
|
TYPE_TO_STR(DT_VERNEEDNUM);
|
||||||
default: return "UNKNOWN";
|
default: return "UNKNOWN";
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *segment_type_to_str(unsigned type) {
|
const char *segment_type_to_str(unsigned type) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PT_NULL: return "NULL";
|
TYPE_TO_STR(PT_NULL);
|
||||||
case PT_LOAD: return "LOAD";
|
TYPE_TO_STR(PT_LOAD);
|
||||||
case PT_DYNAMIC: return "DYNAMIC";
|
TYPE_TO_STR(PT_DYNAMIC);
|
||||||
case PT_INTERP: return "INTERP";
|
TYPE_TO_STR(PT_INTERP);
|
||||||
case PT_NOTE: return "NOTE";
|
TYPE_TO_STR(PT_NOTE);
|
||||||
case PT_SHLIB: return "SHLIB";
|
TYPE_TO_STR(PT_SHLIB);
|
||||||
case PT_PHDR: return "PHDR";
|
TYPE_TO_STR(PT_PHDR);
|
||||||
case PT_TLS: return "TLS";
|
TYPE_TO_STR(PT_TLS);
|
||||||
case PT_NUM: return "NUM";
|
TYPE_TO_STR(PT_NUM);
|
||||||
case PT_LOOS: return "LOOS";
|
TYPE_TO_STR(PT_LOOS);
|
||||||
case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
|
TYPE_TO_STR(PT_GNU_EH_FRAME);
|
||||||
case PT_GNU_STACK: return "GNU_STACK";
|
TYPE_TO_STR(PT_GNU_STACK);
|
||||||
case PT_GNU_RELRO: return "GNU_RELRO";
|
TYPE_TO_STR(PT_GNU_RELRO);
|
||||||
case PT_GNU_PROPERTY: return "GNU_PROPERTY";
|
TYPE_TO_STR(PT_GNU_PROPERTY);
|
||||||
case PT_LOSUNW: return "LOSUNW/SUNWBSS";
|
TYPE_TO_STR(PT_LOSUNW);
|
||||||
case PT_SUNWSTACK: return "SUNWSTACK";
|
TYPE_TO_STR(PT_SUNWSTACK);
|
||||||
case PT_HIOS: return "HIOS";
|
TYPE_TO_STR(PT_HIOS);
|
||||||
case PT_LOPROC: return "LOPROC";
|
TYPE_TO_STR(PT_LOPROC);
|
||||||
case PT_HIPROC: return "HIPROC";
|
TYPE_TO_STR(PT_HIPROC);
|
||||||
default: return "UNKNOWN";
|
default: return "UNKNOWN";
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef TYPE_TO_STR
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
#include <gelf.h>
|
#include <gelf.h>
|
||||||
|
|
||||||
|
void *hi_elf_load_module(const char* filename);
|
||||||
|
void hi_elf_print_module_from_memory(void *address, size_t size);
|
||||||
|
|
||||||
const char *dyn_type_to_str(unsigned type);
|
const char *dyn_type_to_str(unsigned type);
|
||||||
const char *segment_type_to_str(unsigned type);
|
const char *segment_type_to_str(unsigned type);
|
||||||
|
|
||||||
|
|||||||
@@ -5,95 +5,17 @@
|
|||||||
#include "moduler/elf.h"
|
#include "moduler/elf.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
HiloadResult moduler_reload(HiModuleData *module,
|
HiloadResult moduler_reload(HiModuleData *module,
|
||||||
const struct sc_array_memreg *const memregs) {
|
const struct sc_array_memreg *const memregs) {
|
||||||
|
|
||||||
const char *modname = module->name;
|
MemoryRegionSpan memspan = memory_get_module_span(memregs, module->name);
|
||||||
MemoryRegionSpan memspan = memory_get_module_span(memregs, modname);
|
log_debugv("Module: %s - [%p, %p]\n", module->name, memspan.region_start,
|
||||||
log_debugv("Module: %s - [%p, %p]\n", modname, memspan.region_start,
|
|
||||||
memspan.region_end);
|
memspan.region_end);
|
||||||
|
|
||||||
Elf *elf = elf_memory((void *)memspan.region_start,
|
void *address = hi_elf_load_module(module->name);
|
||||||
memspan.region_end - memspan.region_start);
|
log_debug("modaddress: %p\n", address);
|
||||||
int err = elf_errno();
|
|
||||||
if (err) {
|
|
||||||
log_error("%s\n", elf_errmsg(err));
|
|
||||||
return HILOAD_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void *new_handle = dlopen(module->name, RTLD_NOW); */
|
|
||||||
/* assert(new_handle != module->dlhandle); */
|
|
||||||
void *module_address = (void *)module->address;
|
|
||||||
|
|
||||||
size_t phdrnum = 0;
|
|
||||||
err = elf_getphdrnum(elf, &phdrnum);
|
|
||||||
Elf64_Phdr *phdr = elf64_getphdr(elf);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < phdrnum; ++i) {
|
|
||||||
Elf64_Phdr *p = phdr + i;
|
|
||||||
log_debugv("segment type: %s\n", segment_type_to_str(p->p_type));
|
|
||||||
|
|
||||||
size_t segment_size = p->p_memsz;
|
|
||||||
void *segment_start = module_address + p->p_vaddr;
|
|
||||||
void *segment_end = module_address + p->p_vaddr + segment_size;
|
|
||||||
|
|
||||||
void *strtab = 0;
|
|
||||||
void *symtab = 0;
|
|
||||||
size_t strsz = 0;
|
|
||||||
size_t syment = 0;
|
|
||||||
void *rela = 0;
|
|
||||||
size_t relasz = 0;
|
|
||||||
size_t relaent = 0;
|
|
||||||
size_t relacount = 0;
|
|
||||||
void *pltgot = 0;
|
|
||||||
size_t pltrelsz = 0;
|
|
||||||
void *pltrel = 0;
|
|
||||||
|
|
||||||
if (p->p_type == PT_DYNAMIC) {
|
|
||||||
Elf64_Dyn *dyn = (Elf64_Dyn *)segment_start;
|
|
||||||
while ((void *)dyn < segment_end) {
|
|
||||||
log_debugv(" dyn type: %s\n", dyn_type_to_str(dyn->d_tag));
|
|
||||||
|
|
||||||
if (dyn->d_tag == DT_STRTAB) {
|
|
||||||
strtab = (void *)dyn->d_un.d_ptr;
|
|
||||||
} else if (dyn->d_tag == DT_SYMTAB) {
|
|
||||||
symtab = (void *)dyn->d_un.d_ptr;
|
|
||||||
} else if (dyn->d_tag == DT_STRSZ) {
|
|
||||||
strsz = dyn->d_un.d_val;
|
|
||||||
} else if (dyn->d_tag == DT_SYMENT) {
|
|
||||||
syment = dyn->d_un.d_val;
|
|
||||||
} else if (dyn->d_tag == DT_RELA) {
|
|
||||||
rela = (void *)dyn->d_un.d_ptr;
|
|
||||||
} else if (dyn->d_tag == DT_RELASZ) {
|
|
||||||
relasz = dyn->d_un.d_val;
|
|
||||||
} else if (dyn->d_tag == DT_RELAENT) {
|
|
||||||
relaent = dyn->d_un.d_val;
|
|
||||||
} else if (dyn->d_tag == DT_RELACOUNT) {
|
|
||||||
relacount = dyn->d_un.d_val;
|
|
||||||
} else if (dyn->d_tag == DT_PLTGOT) {
|
|
||||||
pltgot = (void *)dyn->d_un.d_ptr;
|
|
||||||
} else if (dyn->d_tag == DT_PLTRELSZ) {
|
|
||||||
pltrelsz = dyn->d_un.d_val;
|
|
||||||
} else if (dyn->d_tag == DT_PLTREL) {
|
|
||||||
pltrel = (void *)dyn->d_un.d_val;
|
|
||||||
}
|
|
||||||
++dyn;
|
|
||||||
}
|
|
||||||
log_debugv("\nstrtab: %p\n"
|
|
||||||
"symtab: %p\n"
|
|
||||||
"strsz: %zu\n"
|
|
||||||
"syment: %zu\n"
|
|
||||||
"rela: %p\n"
|
|
||||||
"relasz: %zu\n"
|
|
||||||
"relaent: %zu\n"
|
|
||||||
"relacount: %zu\n"
|
|
||||||
"pltgot: %p\n"
|
|
||||||
"pltrelsz: %zu\n"
|
|
||||||
"pltrel: %p\n",
|
|
||||||
strtab, symtab, strsz, syment, rela, relasz, relaent,
|
|
||||||
relacount, pltgot, pltrelsz, pltrel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module->state = HI_MODULE_STATE_CLEAN;
|
module->state = HI_MODULE_STATE_CLEAN;
|
||||||
return HILOAD_OK;
|
return HILOAD_OK;
|
||||||
|
|||||||
@@ -17,15 +17,8 @@ int main(int argc, char *argv[]) {
|
|||||||
int modified = -1;
|
int modified = -1;
|
||||||
while (modified != 0) {
|
while (modified != 0) {
|
||||||
|
|
||||||
// printf("==========================\n");
|
|
||||||
// printf("main address: %p\n", main);
|
|
||||||
// printf("minimal_lib::getNewValue address: %p\n", minimal_lib::getNewValue);
|
|
||||||
// printf("minimal_lib::otherValue address: %p\n", &minimal_lib::otherValue);
|
|
||||||
// printf("==========================\n");
|
|
||||||
// printf("");
|
|
||||||
|
|
||||||
modified = minimal_lib::getNewValue(5);
|
modified = minimal_lib::getNewValue(5);
|
||||||
printf("getModified(5): %d\n", modified);
|
printf("getNewValue(5): %d\n", modified);
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
|
||||||
printf("otherValue: %d\n", minimal_lib::otherValue++);
|
printf("otherValue: %d\n", minimal_lib::otherValue++);
|
||||||
|
|||||||
Reference in New Issue
Block a user