Compare commits

..

9 Commits

Author SHA1 Message Date
5594a4a4a9 The build is successful, testing is required 2025-08-23 12:12:22 +08:00
9ae3a3f374 todo: modpost undefined errors 2025-08-23 11:02:25 +08:00
64dbb93260 Still need to port some kernel modules 2025-08-23 00:35:29 +08:00
015a64039d Try to port mckernel to rhel9 2025-08-22 22:02:50 +08:00
7afd1c87f6 Update IHK submodule commit
Change-Id: I503233b393e5bfec003d407512d1028de3a60946
2022-05-31 13:39:07 +09:00
27b3f59031 Update IHK submodule
Change-Id: I01bb44d3cf40e431090785ea261926e89d835e66
2021-06-14 06:05:58 -04:00
a1b9721772 RHEL8.4: make mcinspect and eclair fPIE for RPM, clear build_ldflags in mckernel.spec
Change-Id: I06f09628629c2afb0d36ad6ab2e2ed2cc716a980
2021-06-14 06:04:30 -04:00
69187ea0fd Update IHK submodule commit
Change-Id: Ic952ff15e2269452ce0693a2a96653659431372b
2021-06-13 22:43:32 -04:00
0353fc1a0a RHEL8.4: support VDSO changes for aarch64 (by Fujitsu)
Change-Id: I1148d2e56eab52ee0264995dd32b9fd2f0d661f0
2021-06-13 22:33:29 -04:00
19 changed files with 494 additions and 218 deletions

View File

@ -84,7 +84,8 @@ if(ENABLE_FUGAKU_HACKS)
endif()
# Fujitsu MPI tries to xpmem-attach segment with size of range size + 1?
set(FJMPI_VERSION_COMMAND "a=\$(which mpifcc); b=\${a%/*/*}; c=\${b##*/}; d=\${c#*-}; echo \$d")
#set(FJMPI_VERSION_COMMAND "a=\$(which mpifcc); b=\${a%/*/*}; c=\${b##*/}; d=\${c#*-}; echo \$d")
set(FJMPI_VERSION_COMMAND "a=\$(which mpifort); b=\${a%/*/*}; c=\${b##*/}; d=\${c#*-}; echo \$d")
execute_process(COMMAND bash -c "${FJMPI_VERSION_COMMAND}"
OUTPUT_VARIABLE FJMPI_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
message("FJMPI_VERSION: ${FJMPI_VERSION}")
@ -191,6 +192,7 @@ file(REMOVE_RECURSE ${tmpdir})
file(MAKE_DIRECTORY ${tmpdir})
file(WRITE ${tmpdir}/driver.c "#include <linux/module.h>\n")
file(APPEND ${tmpdir}/driver.c "unsigned long MAP_KERNEL_START = MODULES_END - (1UL << 23);\n")
file(APPEND ${tmpdir}/driver.c "MODULE_LICENSE(\"GPL\");\n")
file(WRITE ${tmpdir}/Makefile "obj-m := driver.o\n")
file(APPEND ${tmpdir}/Makefile "all:\n")
file(APPEND ${tmpdir}/Makefile "\tmake ${KBUILD_MAKE_FLAGS_STR} -C ${KERNEL_DIR} M=${tmpdir} modules\n")
@ -276,11 +278,11 @@ set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR})
# ihk: ultimately should support extrnal build, but add as subproject for now
if (EXISTS ${PROJECT_SOURCE_DIR}/ihk/CMakeLists.txt)
set(IHK_SOURCE_DIR "ihk" CACHE STRINGS "path to ihk source directory from mckernel sources")
set(IHK_SOURCE_DIR "ihk" CACHE STRING "path to ihk source directory from mckernel sources")
elseif (EXISTS ${PROJECT_SOURCE_DIR}/../ihk/CMakeLists.txt)
set(IHK_SOURCE_DIR "../ihk" CACHE STRINGS "path to ihk source directory from mckernel sources")
set(IHK_SOURCE_DIR "../ihk" CACHE STRING "path to ihk source directory from mckernel sources")
else()
set(IHK_SOURCE_DIR "ihk" CACHE STRINGS "path to ihk source directory from mckernel sources")
set(IHK_SOURCE_DIR "ihk" CACHE STRING "path to ihk source directory from mckernel sources")
endif()
if (EXISTS ${PROJECT_SOURCE_DIR}/${IHK_SOURCE_DIR}/CMakeLists.txt)
set(IHK_FULL_SOURCE_DIR ${PROJECT_SOURCE_DIR}/${IHK_SOURCE_DIR})

View File

@ -33,7 +33,6 @@ struct vdso {
long offset_sigtramp;
};
extern char vdso_start, vdso_end;
static struct vdso vdso;
struct tod_data_s tod_data

View File

@ -183,7 +183,7 @@ enum ihk_mc_pt_attribute {
PTATTR_WRITE_COMBINED = 0x40000,
};
enum ihk_mc_pt_attribute attr_mask;
extern enum ihk_mc_pt_attribute attr_mask;
static inline int pfn_is_write_combined(uintptr_t pfn)
{

View File

@ -27,9 +27,12 @@
#define D(fmt, ...) printk("%s(%d) " fmt, __func__, __LINE__, ##__VA_ARGS__)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
void *vdso_start;
void *vdso_end;
static struct vm_special_mapping (*vdso_spec)[2];
void *mcctrl_vdso_start;
void *mcctrl_vdso_end;
static struct vm_special_mapping *mcctrl_vdso_spec;
#if defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 4)
static struct vdso_data **mcctrl_vdso_data;
#endif
#endif
#ifdef ENABLE_TOFU
@ -68,17 +71,36 @@ void __mcctrl_tof_utofu_mn_invalidate_range_end(
int arch_symbols_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
vdso_start = (void *) kallsyms_lookup_name("vdso_start");
if (WARN_ON(!vdso_start))
mcctrl_vdso_start = (void *) kallsyms_lookup_name("vdso_start");
if (WARN_ON(!mcctrl_vdso_start))
return -EFAULT;
vdso_end = (void *) kallsyms_lookup_name("vdso_end");
if (WARN_ON(!vdso_end))
mcctrl_vdso_end = (void *) kallsyms_lookup_name("vdso_end");
if (WARN_ON(!mcctrl_vdso_end))
return -EFAULT;
vdso_spec = (void *) kallsyms_lookup_name("vdso_spec");
if (WARN_ON(!vdso_spec))
#if defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 4)
mcctrl_vdso_spec = (void *) kallsyms_lookup_name("aarch64_vdso_maps");
#else
mcctrl_vdso_spec = (void *) kallsyms_lookup_name("vdso_spec");
#endif
if (WARN_ON(!mcctrl_vdso_spec))
return -EFAULT;
if (WARN_ON(!mcctrl_vdso_spec[0].name ||
strcmp(mcctrl_vdso_spec[0].name, "[vvar]")))
return -EFAULT;
if (WARN_ON(!mcctrl_vdso_spec[1].name ||
strcmp(mcctrl_vdso_spec[1].name, "[vdso]")))
return -EFAULT;
#if defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 4)
mcctrl_vdso_data = (struct vdso_data **) kallsyms_lookup_name("vdso_data");
if (WARN_ON(!mcctrl_vdso_data || !*mcctrl_vdso_data))
return -EFAULT;
#endif
#endif
#ifdef ENABLE_TOFU
@ -212,7 +234,7 @@ static long elf_search_vdso_sigtramp(void)
Elf64_Sym *sym = NULL;
/* ELF header */
eh = (Elf64_Ehdr *)vdso_start;
eh = (Elf64_Ehdr *)mcctrl_vdso_start;
if (eh == NULL) {
D("vdso_start is NULL.\n");
goto out;
@ -233,8 +255,8 @@ static long elf_search_vdso_sigtramp(void)
/* Search dynsym-table and dynstr-table offset
* from section header table
*/
tmp_sh = (Elf64_Shdr *)(vdso_start + eh->e_shoff);
shstr = vdso_start + (tmp_sh + eh->e_shstrndx)->sh_offset;
tmp_sh = (Elf64_Shdr *)(mcctrl_vdso_start + eh->e_shoff);
shstr = mcctrl_vdso_start + (tmp_sh + eh->e_shstrndx)->sh_offset;
for (i = 0; i < eh->e_shnum; i++, tmp_sh++) {
if (tmp_sh->sh_type == SHT_DYNSYM) {
sym_sh = tmp_sh;
@ -242,7 +264,7 @@ static long elf_search_vdso_sigtramp(void)
if (tmp_sh->sh_type == SHT_STRTAB &&
!strcmp(&shstr[tmp_sh->sh_name], ".dynstr")) {
dynstr = vdso_start + tmp_sh->sh_offset;
dynstr = mcctrl_vdso_start + tmp_sh->sh_offset;
}
}
@ -257,7 +279,7 @@ static long elf_search_vdso_sigtramp(void)
}
/* Search __kernel_rt_sigreturn offset from dynsym-table */
sym = (Elf64_Sym *)(vdso_start + sym_sh->sh_offset);
sym = (Elf64_Sym *)(mcctrl_vdso_start + sym_sh->sh_offset);
for (i = 0; (i * sym_sh->sh_entsize) < sym_sh->sh_size; i++, sym++) {
if (!strcmp(dynstr + sym->st_name, "__kernel_rt_sigreturn")) {
ans = sym->st_value;
@ -282,9 +304,9 @@ void get_vdso_info(ihk_os_t os, long vdso_rpa)
vdso = ihk_device_map_virtual(dev, vdso_pa, sizeof(*vdso), NULL, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
vvar_map = &(*vdso_spec)[0];
vdso_map = &(*vdso_spec)[1];
nr_vdso_page = ((vdso_end - vdso_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
vvar_map = &mcctrl_vdso_spec[0];
vdso_map = &mcctrl_vdso_spec[1];
nr_vdso_page = ((mcctrl_vdso_end - mcctrl_vdso_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
/* VDSO pages */
//D("nr_vdso_page:%d\n", nr_vdso_page);
@ -298,7 +320,11 @@ void get_vdso_info(ihk_os_t os, long vdso_rpa)
/* VVAR page */
//D("vdso->vvar_phys:0x#lx\n", vdso->vvar_phys);
#if defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 4)
vdso->vvar_phys = __pfn_to_phys(sym_to_pfn(*mcctrl_vdso_data));
#else
vdso->vvar_phys = page_to_phys(*vvar_map->pages);
#endif
/* offsets */
vdso->lbase = VDSO_LBASE;

View File

@ -6,8 +6,13 @@
#include <asm/vgtod.h>
#include "config.h"
#include "../../mcctrl.h"
#include "../../kallsyms_compat.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) && defined(CONFIG_X86_VSYSCALL_EMULATION)
#define gtod (&VVAR(vsyscall_gtod_data))
#else
#define gtod NULL
#endif
//#define SC_DEBUG
@ -24,36 +29,36 @@ static void *vdso_start;
static void *vdso_end;
static struct page **vdso_pages;
#endif
static void *__vvar_page;
static void *__vvar_page_ptr;
static long *hpet_address;
static void **hv_clock;
int arch_symbols_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
_vdso_image_64 = (void *) kallsyms_lookup_name("vdso_image_64");
_vdso_image_64 = (void *) mcctrl_lookup_name("vdso_image_64");
if (WARN_ON(!_vdso_image_64))
return -EFAULT;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
vdso_start = (void *) kallsyms_lookup_name("vdso_start");
vdso_start = (void *) mcctrl_lookup_name("vdso_start");
if (WARN_ON(!vdso_start))
return -EFAULT;
vdso_end = (void *) kallsyms_lookup_name("vdso_end");
vdso_end = (void *) mcctrl_lookup_name("vdso_end");
if (WARN_ON(!vdso_end))
return -EFAULT;
vdso_pages = (void *) kallsyms_lookup_name("vdso_pages");
vdso_pages = (void *) mcctrl_lookup_name("vdso_pages");
if (WARN_ON(!vdso_pages))
return -EFAULT;
#endif
__vvar_page = (void *) kallsyms_lookup_name("__vvar_page");
if (WARN_ON(!__vvar_page))
__vvar_page_ptr = (void *) &__vvar_page;
if (WARN_ON(!__vvar_page_ptr))
return -EFAULT;
hpet_address = (void *) kallsyms_lookup_name("hpet_address");
hv_clock = (void *) kallsyms_lookup_name("hv_clock");
hpet_address = (void *) mcctrl_lookup_name("hpet_address");
hv_clock = (void *) mcctrl_lookup_name("hv_clock");
return 0;
}
@ -93,18 +98,18 @@ reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsign
#define DESIRED_USER_END 0x800000000000
#define GAP_FOR_MCEXEC 0x008000000000UL
end = DESIRED_USER_END;
down_write(&current->mm->mmap_sem);
mmap_write_lock(current->mm);
vma = find_vma(current->mm, 0);
if (vma) {
end = (vma->vm_start - GAP_FOR_MCEXEC) & ~(GAP_FOR_MCEXEC - 1);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
up_write(&current->mm->mmap_sem);
mmap_write_unlock(current->mm);
#endif
start = reserve_user_space_common(usrdata, start, end);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
up_write(&current->mm->mmap_sem);
mmap_write_unlock(current->mm);
#endif
mutex_unlock(&usrdata->reserve_lock);
@ -161,19 +166,19 @@ void get_vdso_info(ihk_os_t os, long vdso_rpa)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)
vdso->vvar_is_global = 0;
vdso->vvar_virt = (void *)(-3 * PAGE_SIZE);
vdso->vvar_phys = virt_to_phys(__vvar_page);
vdso->vvar_phys = virt_to_phys(__vvar_page_ptr);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
vdso->vvar_is_global = 0;
vdso->vvar_virt = (void *)(-2 * PAGE_SIZE);
vdso->vvar_phys = virt_to_phys(__vvar_page);
vdso->vvar_phys = virt_to_phys(__vvar_page_ptr);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)
vdso->vvar_is_global = 0;
vdso->vvar_virt = (void *)(vdso->vdso_npages * PAGE_SIZE);
vdso->vvar_phys = virt_to_phys(__vvar_page);
vdso->vvar_phys = virt_to_phys(__vvar_page_ptr);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
vdso->vvar_is_global = 1;
vdso->vvar_virt = (void *)fix_to_virt(VVAR_PAGE);
vdso->vvar_phys = virt_to_phys(__vvar_page);
vdso->vvar_phys = virt_to_phys(__vvar_page_ptr);
#endif
/* HPET page */

View File

@ -126,8 +126,8 @@ static int load_elf(struct linux_binprm *bprm
if(st == 0){
off = p & ~PAGE_MASK;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
rc = get_user_pages_remote(current, bprm->mm,
bprm->p, 1, FOLL_FORCE, &page, NULL, NULL);
rc = get_user_pages_remote(bprm->mm,
bprm->p, 1, FOLL_FORCE, &page, NULL);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)
rc = get_user_pages_remote(current, bprm->mm,
bprm->p, 1, FOLL_FORCE, &page, NULL);
@ -234,7 +234,7 @@ static int load_elf(struct linux_binprm *bprm
kfree(pbuf);
return rc;
}
rc = copy_strings_kernel(1, &bprm->interp, bprm);
rc = copy_string_kernel(bprm->interp, bprm);
if (rc < 0){
fput(file);
kfree(pbuf);
@ -242,7 +242,7 @@ static int load_elf(struct linux_binprm *bprm
}
bprm->argc++;
wp = MCEXEC_PATH;
rc = copy_strings_kernel(1, &wp, bprm);
rc = copy_string_kernel(wp, bprm);
if (rc){
fput(file);
kfree(pbuf);
@ -260,19 +260,25 @@ static int load_elf(struct linux_binprm *bprm
fput(bprm->file);
bprm->file = file;
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)
rc = prepare_binprm(bprm);
if (rc < 0){
kfree(pbuf);
return rc;
}
#endif
kfree(pbuf);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)
return search_binary_handler(bprm
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
, regs
#endif
);
#else
return -ENOEXEC;
#endif
}
static struct linux_binfmt mcexec_format = {

View File

@ -978,7 +978,9 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
node = linux_numa_2_mckernel_numa(udp,
cpu_to_node(mckernel_cpu_2_linux_cpu(udp, cpu_prev)));
for_each_cpu_not(cpu, cpus_used) {
for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
if (cpumask_test_cpu(cpu, cpus_used))
continue;
/* Invalid CPU? */
if (cpu >= udp->cpu_info->n_cpus)
break;
@ -1797,7 +1799,7 @@ out:
}
LIST_HEAD(mckernel_exec_files);
DEFINE_SEMAPHORE(mckernel_exec_file_lock);
DEFINE_SEMAPHORE(mckernel_exec_file_lock, 1);
struct mckernel_exec_file {
@ -3262,8 +3264,9 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *_desc)
&lcache_topo->shared_cpu_map);
}
else {
cpumask_complement(wkmask,
&lcache_topo->shared_cpu_map);
bitmap_complement(cpumask_bits(wkmask),
cpumask_bits(&lcache_topo->shared_cpu_map),
nr_cpumask_bits);
cpumask_and(cpuset, cpuset, wkmask);
}
}
@ -3276,8 +3279,9 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *_desc)
&lcache_topo->shared_cpu_map);
}
else {
cpumask_complement(wkmask,
&lcache_topo->shared_cpu_map);
bitmap_complement(cpumask_bits(wkmask),
cpumask_bits(&lcache_topo->shared_cpu_map),
nr_cpumask_bits);
cpumask_and(cpuset, cpuset, wkmask);
}
}
@ -3290,8 +3294,9 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *_desc)
&lcache_topo->shared_cpu_map);
}
else {
cpumask_complement(wkmask,
&lcache_topo->shared_cpu_map);
bitmap_complement(cpumask_bits(wkmask),
cpumask_bits(&lcache_topo->shared_cpu_map),
nr_cpumask_bits);
cpumask_and(cpuset, cpuset, wkmask);
}
}

View File

@ -34,6 +34,7 @@
#include <linux/version.h>
#include "mcctrl.h"
#include <ihk/ihk_host_user.h>
#include "kallsyms_compat.h"
#define OS_MAX_MINOR 64
@ -237,75 +238,84 @@ struct inode_operations *mcctrl_hugetlbfs_inode_operations;
static int symbols_init(void)
{
int ret;
/* Initialize kallsyms compatibility layer */
ret = init_kallsyms_lookup();
if (ret) {
pr_err("Failed to initialize kallsyms compatibility layer: %d\n", ret);
return ret;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
mcctrl_sys_mount = (void *) kallsyms_lookup_name("ksys_mount");
mcctrl_sys_mount = (void *) mcctrl_lookup_name("ksys_mount");
#else
mcctrl_sys_mount = (void *) kallsyms_lookup_name("sys_mount");
mcctrl_sys_mount = (void *) mcctrl_lookup_name("sys_mount");
#if defined(CONFIG_X86_64_SMP)
if (!mcctrl_sys_mount)
mcctrl_sys_mount =
(void *) kallsyms_lookup_name("__x64_sys_mount");
(void *) mcctrl_lookup_name("__x64_sys_mount");
#endif
#endif
if (WARN_ON(!mcctrl_sys_mount))
return -EFAULT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
mcctrl_sys_umount = (void *) kallsyms_lookup_name("ksys_umount");
mcctrl_sys_umount = (void *) mcctrl_lookup_name("ksys_umount");
#else
mcctrl_sys_umount = (void *) kallsyms_lookup_name("sys_umount");
mcctrl_sys_umount = (void *) mcctrl_lookup_name("sys_umount");
#if defined(CONFIG_X86_64_SMP)
if (!mcctrl_sys_umount)
mcctrl_sys_umount =
(void *) kallsyms_lookup_name("__x64_sys_umount");
(void *) mcctrl_lookup_name("__x64_sys_umount");
#endif
#endif
if (WARN_ON(!mcctrl_sys_umount))
return -EFAULT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
mcctrl_sys_unshare = (void *) kallsyms_lookup_name("ksys_unshare");
mcctrl_sys_unshare = (void *) mcctrl_lookup_name("ksys_unshare");
#else
mcctrl_sys_unshare = (void *) kallsyms_lookup_name("sys_unshare");
mcctrl_sys_unshare = (void *) mcctrl_lookup_name("sys_unshare");
#if defined(CONFIG_X86_64_SMP)
if (!mcctrl_sys_unshare)
mcctrl_sys_unshare =
(void *) kallsyms_lookup_name("__x64_sys_unshare");
(void *) mcctrl_lookup_name("__x64_sys_unshare");
#endif
#endif
if (WARN_ON(!mcctrl_sys_unshare))
return -EFAULT;
mcctrl_sched_setaffinity =
(void *) kallsyms_lookup_name("sched_setaffinity");
(void *) mcctrl_lookup_name("sched_setaffinity");
if (WARN_ON(!mcctrl_sched_setaffinity))
return -EFAULT;
mcctrl_sched_setscheduler_nocheck =
(void *) kallsyms_lookup_name("sched_setscheduler_nocheck");
(void *) mcctrl_lookup_name("sched_setscheduler_nocheck");
if (WARN_ON(!mcctrl_sched_setscheduler_nocheck))
return -EFAULT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
mcctrl_sys_readlinkat = (void *)kallsyms_lookup_name("do_readlinkat");
mcctrl_sys_readlinkat = (void *)mcctrl_lookup_name("do_readlinkat");
#else
mcctrl_sys_readlinkat = (void *)kallsyms_lookup_name("sys_readlinkat");
mcctrl_sys_readlinkat = (void *)mcctrl_lookup_name("sys_readlinkat");
#if defined(CONFIG_X86_64_SMP)
if (!mcctrl_sys_readlinkat)
mcctrl_sys_readlinkat =
(void *) kallsyms_lookup_name("__x64_sys_readlinkat");
(void *) mcctrl_lookup_name("__x64_sys_readlinkat");
#endif
#endif
if (WARN_ON(!mcctrl_sys_readlinkat))
return -EFAULT;
mcctrl_zap_page_range =
(void *) kallsyms_lookup_name("zap_page_range");
(void *) mcctrl_lookup_name("zap_page_range");
if (WARN_ON(!mcctrl_zap_page_range))
return -EFAULT;
mcctrl_hugetlbfs_inode_operations =
(void *) kallsyms_lookup_name("hugetlbfs_inode_operations");
(void *) mcctrl_lookup_name("hugetlbfs_inode_operations");
if (WARN_ON(!mcctrl_hugetlbfs_inode_operations))
return -EFAULT;
@ -359,6 +369,7 @@ static void __exit mcctrl_exit(void)
binfmt_mcexec_exit();
uti_attr_finalize();
cleanup_kallsyms_lookup();
#ifdef ENABLE_TOFU
mcctrl_tofu_restore_release_handlers();
#endif

View File

@ -51,7 +51,7 @@ static long uti_wait_event(void *_resp, unsigned long nsec_timeout)
}
}
static int uti_clock_gettime(clockid_t clk_id, struct timespec *tp)
static int uti_clock_gettime(clockid_t clk_id, struct timespec64 *tp)
{
int ret = 0;
struct timespec64 ts64;
@ -60,7 +60,7 @@ static int uti_clock_gettime(clockid_t clk_id, struct timespec *tp)
clk_id, CLOCK_REALTIME, CLOCK_MONOTONIC);
switch (clk_id) {
case CLOCK_REALTIME:
getnstimeofday64(&ts64);
ktime_get_real_ts64(&ts64);
tp->tv_sec = ts64.tv_sec;
tp->tv_nsec = ts64.tv_nsec;
dprintk("%s: CLOCK_REALTIME,%ld.%09ld\n", __func__,
@ -1061,12 +1061,14 @@ static int futex(uint32_t *uaddr, int op, uint32_t val, uint64_t timeout,
switch (cmd) {
case FUTEX_WAIT:
val3 = FUTEX_BITSET_MATCH_ANY;
/* fallthrough */
case FUTEX_WAIT_BITSET:
ret = futex_wait(uaddr, fshared, val, timeout,
val3, clockrt, uti_info);
break;
case FUTEX_WAKE:
val3 = FUTEX_BITSET_MATCH_ANY;
/* fallthrough */
case FUTEX_WAKE_BITSET:
ret = futex_wake(uaddr, fshared, val, val3, uti_info);
break;
@ -1127,7 +1129,7 @@ long do_futex(int n, unsigned long arg0, unsigned long arg1,
int op = (int)arg1;
uint32_t val = (uint32_t)arg2;
struct timespec *utime = (struct timespec *)arg3;
struct timespec ts;
struct timespec64 ts;
uint32_t *uaddr2 = (uint32_t *)arg4;
uint32_t val3 = (uint32_t)arg5;
int flags = op;
@ -1158,12 +1160,12 @@ long do_futex(int n, unsigned long arg0, unsigned long arg1,
}
dprintk("%s: utime=%ld.%09ld\n", __func__, ts.tv_sec, ts.tv_nsec);
if (!timespec_valid(&ts)) {
if (!timespec64_valid(&ts)) {
return -EINVAL;
}
if (op == FUTEX_WAIT_BITSET) { /* User passed absolute time */
struct timespec ats;
struct timespec64 ats;
ret = uti_clock_gettime((flags & FUTEX_CLOCK_REALTIME) ?
CLOCK_REALTIME : CLOCK_MONOTONIC, &ats);

View File

@ -0,0 +1,72 @@
/* kallsyms_compat.h - Compatibility layer for kallsyms_lookup_name */
#ifndef KALLSYMS_COMPAT_H
#define KALLSYMS_COMPAT_H
#include <linux/version.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
/* kallsyms_lookup_name is no longer exported since kernel 5.7 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
/* Function pointer for kallsyms_lookup_name */
static unsigned long (*mcctrl_kallsyms_lookup_name)(const char *name);
/* Kprobe-based approach to get kallsyms_lookup_name function pointer */
static struct kprobe kp_kallsyms = {
.symbol_name = "kallsyms_lookup_name"
};
static int init_kallsyms_lookup(void)
{
int ret;
ret = register_kprobe(&kp_kallsyms);
if (ret < 0) {
pr_err("register_kprobe failed, returned %d\n", ret);
return ret;
}
mcctrl_kallsyms_lookup_name = (unsigned long (*)(const char *))kp_kallsyms.addr;
unregister_kprobe(&kp_kallsyms);
if (!mcctrl_kallsyms_lookup_name) {
pr_err("Failed to get kallsyms_lookup_name address\n");
return -EINVAL;
}
return 0;
}
static void cleanup_kallsyms_lookup(void)
{
mcctrl_kallsyms_lookup_name = NULL;
}
static inline unsigned long mcctrl_lookup_name(const char *name)
{
if (mcctrl_kallsyms_lookup_name)
return mcctrl_kallsyms_lookup_name(name);
return 0;
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 7, 0) */
static inline int init_kallsyms_lookup(void)
{
return 0;
}
static inline void cleanup_kallsyms_lookup(void)
{
}
static inline unsigned long mcctrl_lookup_name(const char *name)
{
return kallsyms_lookup_name(name);
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */
#endif /* KALLSYMS_COMPAT_H */

View File

@ -40,7 +40,7 @@ typedef gid_t kgid_t;
struct procfs_entry {
char *name;
mode_t mode;
const struct file_operations *fops;
const struct proc_ops *fops;
};
#define NOD(NAME, MODE, FOP) { \
@ -58,8 +58,8 @@ struct procfs_entry {
static const struct procfs_entry tid_entry_stuff[];
static const struct procfs_entry pid_entry_stuff[];
static const struct procfs_entry base_entry_stuff[];
static const struct file_operations mckernel_forward_ro;
static const struct file_operations mckernel_forward;
static const struct proc_ops mckernel_forward_ro;
static const struct proc_ops mckernel_forward;
static ssize_t mckernel_procfs_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos);
@ -84,7 +84,7 @@ struct procfs_list_entry {
* file.
*/
LIST_HEAD(procfs_file_list);
DEFINE_SEMAPHORE(procfs_file_list_lock);
DEFINE_SEMAPHORE(procfs_file_list_lock, 1);
static char *
getpath(struct procfs_list_entry *e, char *buf, int bufsize)
@ -183,10 +183,10 @@ add_procfs_entry(struct procfs_list_entry *parent, const char *name, int mode,
pde = proc_symlink(name, parent_pde, (char *)opaque);
}
else {
const struct file_operations *fop;
const struct proc_ops *fop;
if(opaque)
fop = (const struct file_operations *)opaque;
fop = (const struct proc_ops *)opaque;
else if(mode & S_IWUSR)
fop = &mckernel_forward;
else
@ -509,7 +509,7 @@ static ssize_t __mckernel_procfs_read_write(
struct proc_dir_entry *dp = PDE(inode);
struct procfs_list_entry *e = dp->data;
#else
struct procfs_list_entry *e = PDE_DATA(inode);
struct procfs_list_entry *e = pde_data(inode);
#endif
loff_t offset = *ppos;
char pathbuf[PROCFS_NAME_MAX];
@ -770,16 +770,16 @@ int procfsm_packet_handler(void *os, int msg, int pid, unsigned long arg,
return 0;
}
static const struct file_operations mckernel_forward_ro = {
.llseek = mckernel_procfs_lseek,
.read = mckernel_procfs_read,
.write = NULL,
static const struct proc_ops mckernel_forward_ro = {
.proc_lseek = mckernel_procfs_lseek,
.proc_read = mckernel_procfs_read,
.proc_write = NULL,
};
static const struct file_operations mckernel_forward = {
.llseek = mckernel_procfs_lseek,
.read = mckernel_procfs_read,
.write = mckernel_procfs_write,
static const struct proc_ops mckernel_forward = {
.proc_lseek = mckernel_procfs_lseek,
.proc_read = mckernel_procfs_read,
.proc_write = mckernel_procfs_write,
};
#define PA_NULL (-1L)
@ -812,7 +812,7 @@ static int mckernel_procfs_buff_open(struct inode *inode, struct file *file)
struct proc_dir_entry *dp = PDE(inode);
struct procfs_list_entry *e = dp->data;
#else
struct procfs_list_entry *e = PDE_DATA(inode);
struct procfs_list_entry *e = pde_data(inode);
#endif
os = osnum_to_os(e->osnum);
@ -1071,12 +1071,12 @@ rep:
return l;
}
static const struct file_operations mckernel_buff_io = {
.llseek = mckernel_procfs_lseek,
.read = mckernel_procfs_buff_read,
.write = NULL,
.open = mckernel_procfs_buff_open,
.release = mckernel_procfs_buff_release,
static const struct proc_ops mckernel_buff_io = {
.proc_lseek = mckernel_procfs_lseek,
.proc_read = mckernel_procfs_buff_read,
.proc_write = NULL,
.proc_open = mckernel_procfs_buff_open,
.proc_release = mckernel_procfs_buff_release,
};
static const struct procfs_entry tid_entry_stuff[] = {

View File

@ -57,6 +57,21 @@
#include <archdeps.h>
#include <asm/pgtable.h>
/* Compatibility function for vfs_fstat which is not exported in newer kernels */
static inline int mcctrl_vfs_fstat(int fd, struct kstat *stat)
{
struct file *file;
int error;
file = fget(fd);
if (!file)
return -EBADF;
error = vfs_getattr(&file->f_path, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
fput(file);
return error;
}
#define ALIGN_WAIT_BUF(z) (((z + 63) >> 6) << 6)
//#define SC_DEBUG
@ -733,7 +748,7 @@ static struct vm_operations_struct rus_vmops = {
static int rus_mmap(struct file *file, struct vm_area_struct *vma)
{
vma->vm_flags |= arch_rus_vm_flags;
vm_flags_set(vma, arch_rus_vm_flags);
vma->vm_ops = &rus_vmops;
return 0;
}
@ -776,10 +791,10 @@ reserve_user_space_common(struct mcctrl_usrdata *usrdata, unsigned long start, u
#if 0
{ /* debug */
struct vm_area_struct *vma;
down_write(&current->mm->mmap_sem);
mmap_write_lock(current->mm);
vma = find_vma(current->mm, start);
vma->vm_flags |= VM_DONTCOPY;
up_write(&current->mm->mmap_sem);
vm_flags_set(vma, VM_DONTCOPY);
mmap_write_unlock(current->mm);
}
#endif
revert_creds(original);
@ -950,7 +965,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
dprintk("pager_req_create(%d,%lx)\n", fd, (long)result_pa);
error = vfs_fstat(fd, &st);
error = mcctrl_vfs_fstat(fd, &st);
if (error) {
printk("pager_req_create(%d,%lx):vfs_stat failed. %d\n", fd, (long)result_pa, error);
goto out;
@ -1463,12 +1478,12 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
down_write(&current->mm->mmap_sem);
mmap_write_lock(current->mm);
va = do_mmap_pgoff(file, ANY_WHERE, len, maxprot,
prot_and_flags, pgoff);
up_write(&current->mm->mmap_sem);
mmap_write_unlock(current->mm);
#else
va = vm_mmap(file, ANY_WHERE, len, maxprot,
prot_and_flags, pgoff << PAGE_SHIFT);
@ -1571,7 +1586,7 @@ static int pager_req_pfn(ihk_os_t os, uintptr_t handle, off_t off, uintptr_t ppf
#define PFN_VALID ((uintptr_t)1 << 63)
pfn = PFN_VALID; /* Use "not present" as the default setting */
down_read(&current->mm->mmap_sem);
mmap_read_lock(current->mm);
retry:
pgd = pgd_offset(current->mm, va);
if (!pgd_none(*pgd) && !pgd_bad(*pgd) && pgd_present(*pgd)) {
@ -1587,7 +1602,7 @@ retry:
pmd = pmd_offset(pud, va);
if (!pmd_none(*pmd) && !pmd_bad(*pmd) &&
pmd_present(*pmd)) {
pte = pte_offset_map(pmd, va);
pte = pte_offset_kernel(pmd, va);
if (!pte_none(*pte) && pte_present(*pte)) {
pfn = (uintptr_t)pte_pfn(*pte) << PAGE_SHIFT;
#define PFN_PRESENT ((uintptr_t)1 << 0)
@ -1623,7 +1638,9 @@ retry:
goto out_release;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) || \
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
fault = handle_mm_fault(vma, va, flags, NULL);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 5))
fault = handle_mm_fault(vma, va, flags);
#else
@ -1656,7 +1673,7 @@ retry:
}
out_release:
up_read(&current->mm->mmap_sem);
mmap_read_unlock(current->mm);
phys = ihk_device_map_memory(dev, ppfn_rpa, sizeof(*ppfn));
ppfn = ihk_device_map_virtual(dev, phys, sizeof(*ppfn), NULL, 0);
@ -1682,9 +1699,9 @@ static int __pager_unmap(struct pager *pager)
int error;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
down_write(&current->mm->mmap_sem);
mmap_write_lock(current->mm);
error = do_munmap(current->mm, pager->map_uaddr, pager->map_len);
up_write(&current->mm->mmap_sem);
mmap_write_unlock(current->mm);
#else
error = vm_munmap(pager->map_uaddr, pager->map_len);
#endif
@ -1749,9 +1766,11 @@ static long pager_req_mlock_list(ihk_os_t os, unsigned long start,
struct vm_area_struct *vma;
kprintf("pager_req_mlock_list: addr(%p)\n", addr);
vma = find_vma(current->mm, 0x7010a0);
for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
if (vma->vm_start < start || vma->vm_start > end) continue;
/* Use find_vma to iterate through VMAs */
vma = find_vma(mm, start);
while (vma != NULL) {
if (vma->vm_start > end) break;
kprintf("\t%p: %p -- %p\t%lx\n", vma,
(void*)vma->vm_start, (void*)vma->vm_end,
vma->vm_flags & VM_LOCKED);
@ -1766,6 +1785,8 @@ static long pager_req_mlock_list(ihk_os_t os, unsigned long start,
addrpair->flag = vma->vm_flags;
addrpair++;
}
/* Use find_vma to get next VMA */
vma = find_vma(mm, vma->vm_end);
}
full:
return cnt;
@ -2129,14 +2150,14 @@ static int remap_user_space(uintptr_t rva, size_t len, int prot)
uintptr_t map;
dprintk("remap_user_space(%lx,%lx,%x)\n", rva, len, prot);
down_write(&mm->mmap_sem);
mmap_write_lock(mm);
vma = find_vma(mm, rva);
if (!vma || (rva < vma->vm_start)) {
printk("remap_user_space(%lx,%lx,%x):find_vma failed. %p %lx %lx\n",
rva, len, prot, vma,
(vma)? vma->vm_start: -1,
(vma)? vma->vm_end: 0);
up_write(&mm->mmap_sem);
mmap_write_unlock(mm);
map = -ENOMEM;
goto out;
}
@ -2150,7 +2171,7 @@ static int remap_user_space(uintptr_t rva, size_t len, int prot)
prot, MAP_FIXED|MAP_SHARED, pgoff);
#endif
up_write(&mm->mmap_sem);
mmap_write_unlock(mm);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
map = vm_mmap(file, start, len,
@ -2175,7 +2196,7 @@ int mcctrl_clear_pte_range(uintptr_t start, uintptr_t len)
int ret;
ret = 0;
down_read(&mm->mmap_sem);
mmap_read_lock(mm);
addr = start;
while (addr < (start + len)) {
vma = find_vma(mm, addr);
@ -2193,7 +2214,7 @@ int mcctrl_clear_pte_range(uintptr_t start, uintptr_t len)
if (addr < end) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
/* Revert permission */
vma->vm_flags |= VM_READ | VM_WRITE | VM_EXEC;
vm_flags_set(vma, VM_READ | VM_WRITE | VM_EXEC);
error = zap_vma_ptes(vma, addr, end-addr);
if (error) {
mcctrl_zap_page_range(vma, addr, end-addr,
@ -2212,14 +2233,14 @@ int mcctrl_clear_pte_range(uintptr_t start, uintptr_t len)
}
else {
/* Revert permission */
vma->vm_flags |= VM_READ | VM_WRITE | VM_EXEC;
vm_flags_set(vma, VM_READ | VM_WRITE | VM_EXEC);
zap_vma_ptes(vma, addr, end-addr);
}
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0) */
}
addr = end;
}
up_read(&mm->mmap_sem);
mmap_read_unlock(mm);
return ret;
}

View File

@ -20,20 +20,26 @@ target_include_directories(mcexec PUBLIC "${KERNEL_DIR}")
set_property(TARGET mcexec PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET mcexec PROPERTY LINK_FLAGS "-fPIE -pie")
#unset(LIBDWARF CACHE)
add_executable(mcinspect mcinspect.c)
if (NOT LIBDWARF)
target_include_directories(mcinspect PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/lib/")
target_include_directories(mcinspect PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/lib/libdwarf/libdwarf/libdwarf/")
target_link_libraries(mcinspect dwarf z elf)
else()
target_include_directories(mcinspect PRIVATE ${DWARF_H})
target_link_libraries(mcinspect ${LIBDWARF})
endif()
target_link_libraries(mcinspect ${LIBBFD})
target_link_libraries(mcinspect PRIVATE bfd dwarf z elf)
#if (NOT LIBDWARF)
# target_include_directories(mcinspect PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/lib/")
# target_include_directories(mcinspect PRIVATE
# "${CMAKE_CURRENT_SOURCE_DIR}/lib/libdwarf/libdwarf/libdwarf/")
# target_link_libraries(mcinspect dwarf z elf)
#else()
# target_include_directories(mcinspect PRIVATE ${DWARF_H})
# target_link_libraries(mcinspect ${LIBDWARF})
#endif()
#target_link_libraries(mcinspect ${LIBBFD})
set_property(TARGET mcinspect PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET mcinspect PROPERTY LINK_FLAGS "-fPIE -pie")
add_executable(eclair eclair.c arch/${ARCH}/arch-eclair.c)
target_link_libraries(eclair ${LIBBFD})
set_property(TARGET eclair PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET eclair PROPERTY LINK_FLAGS "-fPIE -pie")
add_library(sched_yield SHARED libsched_yield.c)
target_link_libraries(sched_yield dl)

View File

@ -279,13 +279,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, cpsize);
ok = bfd_set_section_size(scn, cpsize);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -300,13 +300,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, cpsize);
ok = bfd_set_section_size(scn, cpsize);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -321,13 +321,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, cpsize);
ok = bfd_set_section_size(scn, cpsize);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -341,13 +341,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, mem_size);
ok = bfd_set_section_size(scn, mem_size);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_ALLOC|SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_ALLOC|SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -366,14 +366,14 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, mem_chunks->chunks[i].size);
ok = bfd_set_section_size(scn, mem_chunks->chunks[i].size);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_ALLOC|SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_ALLOC|SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;

View File

@ -4,9 +4,9 @@ endif()
if (ENABLE_UTI)
if (${ARCH} STREQUAL "arm64")
set(SYSCALL_INTERCEPT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/syscall_intercept/arch/aarch64" CACHE STRINGS "relative path to syscalL_intercept source directory")
set(SYSCALL_INTERCEPT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/syscall_intercept/arch/aarch64" CACHE STRING "relative path to syscalL_intercept source directory")
elseif (${ARCH} STREQUAL "x86_64")
set(SYSCALL_INTERCEPT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/syscall_intercept" CACHE STRINGS "relative path to syscalL_intercept source directory")
set(SYSCALL_INTERCEPT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/syscall_intercept" CACHE STRING "relative path to syscalL_intercept source directory")
endif()

View File

@ -19,7 +19,7 @@
#include <string.h>
#include <errno.h>
#include <dwarf.h>
#include <libdwarf/libdwarf.h>
#include <libdwarf-0/libdwarf.h>
#include <getopt.h>
#include <libgen.h>
#include <bfd.h>
@ -130,14 +130,15 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
Dwarf_Error err;
Dwarf_Die unit;
Dwarf_Die die;
Dwarf_Half header_cu_type;
int rc;
/* Iterate compile and type units */
for (is_info = 0; is_info < 2; ++is_info) {
rc = dwarf_next_cu_header_c(dbg, is_info, &cu_length,
rc = dwarf_next_cu_header_d(dbg, is_info, &cu_length,
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
&cu_offset_size, &cu_extension_size, &type_signature,
&type_offset, &cu_next_offset, &err);
&type_offset, &cu_next_offset, &header_cu_type, &err);
while (rc != DW_DLV_NO_ENTRY) {
char *name = NULL;
@ -151,9 +152,9 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
return -1;
}
rc = dwarf_siblingof(dbg, NULL, &unit, &err);
rc = dwarf_siblingof_b(dbg, NULL, is_info, &unit, &err);
if (rc != DW_DLV_OK) {
fprintf(stderr, "error: dwarf_siblingof failed: %d %s\n",
fprintf(stderr, "error: dwarf_siblingof_b failed: %d %s\n",
rc, dwarf_errmsg(err));
return -1;
}
@ -237,7 +238,7 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
}
}
rc = dwarf_siblingof(dbg, die, &next, &err);
rc = dwarf_siblingof_b(dbg, die, is_info, &next, &err);
dwarf_dealloc(dbg, die, DW_DLA_DIE);
if (name)
dwarf_dealloc(dbg, name, DW_DLA_STRING);
@ -248,10 +249,10 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
die = next;
}
rc = dwarf_next_cu_header_c(dbg, is_info, &cu_length,
rc = dwarf_next_cu_header_d(dbg, is_info, &cu_length,
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
&cu_offset_size, &cu_extension_size, &type_signature,
&type_offset, &cu_next_offset, &err);
&type_offset, &cu_next_offset, &header_cu_type, &err);
}
}
@ -294,34 +295,64 @@ int dwarf_get_size(Dwarf_Debug dbg,
if (ssize < 0) {
fprintf(stderr, "%s: unsupported negative size\n",
__func__);
__func__);
return DW_DLV_ERROR;
}
size = (Dwarf_Unsigned) ssize;
}
else {
Dwarf_Locdesc **locdescs;
Dwarf_Signed len;
Dwarf_Loc_Head_c loclist_head = 0;
Dwarf_Unsigned lcount = 0;
Dwarf_Locdesc_c locdesc_entry = 0;
Dwarf_Small op;
Dwarf_Unsigned opd1, opd2, opd3;
Dwarf_Unsigned offsetforbranch;
int lres;
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
== DW_DLV_ERROR) {
lres = dwarf_get_loclist_c(attr, &loclist_head, &lcount, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr, "%s: unsupported member size\n",
__func__);
return DW_DLV_ERROR;
}
if (len != 1 ||
locdescs[0]->ld_cents != 1 ||
(locdescs[0]->ld_s[0]).lr_atom
!= DW_OP_plus_uconst) {
if (lcount != 1) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
size = (locdescs[0]->ld_s[0]).lr_number;
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
if (op != DW_OP_plus_uconst) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
size = opd1;
dwarf_loc_head_c_dealloc(loclist_head);
}
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
@ -455,27 +486,57 @@ int dwarf_get_offset(Dwarf_Debug dbg,
offset = (Dwarf_Unsigned) soffset;
}
else {
Dwarf_Locdesc **locdescs;
Dwarf_Signed len;
Dwarf_Loc_Head_c loclist_head = 0;
Dwarf_Unsigned lcount = 0;
Dwarf_Locdesc_c locdesc_entry = 0;
Dwarf_Small op;
Dwarf_Unsigned opd1, opd2, opd3;
Dwarf_Unsigned offsetforbranch;
int lres;
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
== DW_DLV_ERROR) {
lres = dwarf_get_loclist_c(attr, &loclist_head, &lcount, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr, "%s: unsupported member offset\n",
__func__);
return DW_DLV_ERROR;
}
if (len != 1 ||
locdescs[0]->ld_cents != 1 ||
(locdescs[0]->ld_s[0]).lr_atom
!= DW_OP_plus_uconst) {
if (lcount != 1) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
offset = (locdescs[0]->ld_s[0]).lr_number;
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
if (op != DW_OP_plus_uconst) {
fprintf(stderr,
"%s: unsupported location expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
return DW_DLV_ERROR;
}
offset = opd1;
dwarf_loc_head_c_dealloc(loclist_head);
}
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
@ -579,10 +640,10 @@ int dwarf_struct_field_offset(Dwarf_Debug dbg, Dwarf_Die die, void *arg)
break;
next_child:
rc = dwarf_siblingof(dbg, child, &next, &err);
rc = dwarf_siblingof_b(dbg, child, 1, &next, &err);
dwarf_dealloc(dbg, child, DW_DLA_DIE);
if (rc != DW_DLV_OK) {
fprintf(stderr, "%s: error: dwarf_siblingof: %d %s\n",
fprintf(stderr, "%s: error: dwarf_siblingof_b: %d %s\n",
__func__, rc, dwarf_errmsg(err));
rc = DW_DLV_NO_ENTRY;
goto out;
@ -617,7 +678,7 @@ out:
rc = dwarf_walk_tree(dbg, dwarf_struct_field_offset, &dsfo); \
if (rc != DW_DLV_OK) { \
fprintf(stderr, "%s: error: finding %s in struct %s\n", \
__func__, dsfo.field_name, dsfo.struct_name); \
__func__, dsfo.field_name, dsfo.struct_name); \
exit(1); \
} \
offset; \
@ -681,7 +742,7 @@ int dwarf_get_address(Dwarf_Debug dbg,
printf("%s: DW_AT_location\n", __func__);
rc = dwarf_whatform(attr, &form, perr);
if (rc != DW_DLV_OK) {
if (rc != DW_DLV_OK) {
fprintf(stderr, "%s: error: getting whatform: %s\n",
__func__, dwarf_errmsg(*perr));
goto dealloc_out;
@ -696,90 +757,148 @@ int dwarf_get_address(Dwarf_Debug dbg,
form == DW_FORM_data8 ||
form == DW_FORM_sec_offset) {
Dwarf_Locdesc **locdescs;
Dwarf_Signed len;
Dwarf_Loc_Head_c loclist_head = 0;
Dwarf_Unsigned lcount = 0;
Dwarf_Locdesc_c locdesc_entry = 0;
Dwarf_Small op;
Dwarf_Unsigned opd1, opd2, opd3;
Dwarf_Unsigned offsetforbranch;
int lres;
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
== DW_DLV_ERROR) {
fprintf(stderr, "%s: dwarf_loclist_n: %s\n",
lres = dwarf_get_loclist_c(attr, &loclist_head, &lcount, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr, "%s: dwarf_get_loclist_c: %s\n",
__func__, dwarf_errmsg(*perr));
rc = DW_DLV_ERROR;
goto dealloc_out;
}
if (len != 1 ||
locdescs[0]->ld_cents != 1 ||
(locdescs[0]->ld_s[0]).lr_atom
!= DW_OP_addr) {
if (lcount != 1) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
addr = (locdescs[0]->ld_s[0]).lr_number;
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
if (op != DW_OP_addr) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
addr = opd1;
dwarf_loc_head_c_dealloc(loclist_head);
}
else if (form == DW_FORM_exprloc) {
Dwarf_Half address_size = 0;
Dwarf_Ptr x = 0;
Dwarf_Unsigned tempud = 0;
Dwarf_Locdesc *locdescs = 0;
Dwarf_Signed len = 0;
Dwarf_Loc_Head_c loclist_head = 0;
Dwarf_Unsigned lcount = 0;
Dwarf_Locdesc_c locdesc_entry = 0;
Dwarf_Small op;
Dwarf_Unsigned opd1, opd2, opd3;
Dwarf_Unsigned offsetforbranch;
int lres;
Dwarf_Half version;
Dwarf_Half offset_size;
rc = dwarf_formexprloc(attr, &tempud, &x, perr);
if (rc == DW_DLV_NO_ENTRY) {
fprintf(stderr, "%s: dwarf_formexprloc: no entry?\n",
__func__);
goto dealloc_out;
}
else if (rc == DW_DLV_ERROR) {
if (rc != DW_DLV_OK) {
fprintf(stderr, "%s: dwarf_formexprloc(): %s\n",
__func__, dwarf_errmsg(*perr));
goto dealloc_out;
}
rc = dwarf_get_die_address_size(die, &address_size, perr);
if (rc == DW_DLV_NO_ENTRY) {
fprintf(stderr, "%s: dwarf_get_die_address_size: no entry?\n",
__func__);
goto dealloc_out;
}
else if (rc == DW_DLV_ERROR) {
if (rc != DW_DLV_OK) {
fprintf(stderr, "%s: dwarf_get_die_address_size: %s\n",
__func__, dwarf_errmsg(*perr));
goto dealloc_out;
}
rc = dwarf_loclist_from_expr_a(dbg, x, tempud, address_size,
&locdescs, &len, perr);
if (rc == DW_DLV_ERROR) {
fprintf(stderr, "%s: dwarf_loclist_from_expr_a: %s\n",
rc = dwarf_get_version_of_die(die, &version, &offset_size);
if (rc != DW_DLV_OK) {
fprintf(stderr, "%s: dwarf_get_version_of_die: %s\n",
__func__, dwarf_errmsg(*perr));
goto dealloc_out;
}
else if (rc == DW_DLV_NO_ENTRY) {
fprintf(stderr, "%s: dwarf_loclist_from_expr_a: no entry?\n",
__func__);
rc = dwarf_loclist_from_expr_c(dbg, x, tempud, address_size, offset_size, version,
&loclist_head, &lcount, perr);
if (rc != DW_DLV_OK) {
fprintf(stderr, "%s: dwarf_loclist_from_expr_c: %s\n",
__func__, dwarf_errmsg(*perr));
goto dealloc_out;
}
/* len is always 1 */
if (len != 1 ||
locdescs[0].ld_cents != 1 ||
(locdescs[0].ld_s[0]).lr_atom
!= DW_OP_addr) {
if (lcount != 1) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
addr = (locdescs[0].ld_s[0]).lr_number;
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
if (lres != DW_DLV_OK) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
if (op != DW_OP_addr) {
fprintf(stderr,
"%s: unsupported addr expression\n",
__func__);
dwarf_loc_head_c_dealloc(loclist_head);
rc = DW_DLV_ERROR;
goto dealloc_out;
}
addr = opd1;
dwarf_loc_head_c_dealloc(loclist_head);
}
else {
fprintf(stderr, "%s: unsupported form type?\n",
__func__);
__func__);
goto dealloc_out;
}
@ -888,7 +1007,7 @@ out:
rc = dwarf_walk_tree(dbg, dwarf_global_var_addr, &gva); \
if (rc != DW_DLV_OK) { \
fprintf(stderr, "%s: error: finding addr of %s\n", \
__func__, gva.variable); \
__func__, gva.variable); \
exit(1); \
} \
} \
@ -1210,25 +1329,25 @@ struct option mcinspect_options[] = {
{
.name = "ps",
.has_arg = no_argument,
.flag = &ps,
.flag = &ps,
.val = 1,
},
{
.name = "help",
.has_arg = no_argument,
.flag = &help,
.flag = &help,
.val = 1,
},
{
.name = "debug",
.has_arg = no_argument,
.flag = &debug,
.flag = &debug,
.val = 1,
},
{
.name = "vtop",
.has_arg = no_argument,
.flag = &vtop,
.flag = &vtop,
.val = 1,
},
{
@ -1277,7 +1396,7 @@ int main(int argc, char **argv)
case 'v':
vtop_addr = strtoul(optarg, 0, 16);
if (vtop_addr == 0 ||
errno == EINVAL || errno == ERANGE) {
errno == EINVAL || errno == ERANGE) {
fprintf(stderr, "error: invalid VA? (expected format: 0xXXXX)\n\n");
usage(argv);
exit(1);
@ -1324,7 +1443,7 @@ int main(int argc, char **argv)
exit(1);
}
rc = dwarf_init(dwarffd, DW_DLC_READ, errhand, errarg, &dbg, &error);
rc = dwarf_init_b(dwarffd, DW_DLA_WEAK, errhand, errarg, &dbg, &error);
if (rc != DW_DLV_OK) {
fprintf(stderr, "error: accessing DWARF information\n");
exit(1);
@ -1339,7 +1458,7 @@ int main(int argc, char **argv)
mcvtop(dbg, pid, vtop_addr);
}
dwarf_finish(dbg, &error);
dwarf_finish(dbg);
close(dwarffd);
close(mcfd);
return 0;

2
ihk

Submodule ihk updated: 8fd23109f1...3114d9e710

View File

@ -71,6 +71,8 @@ This package contains headers and libraries required for build apps using IHK/Mc
# We need to remove ld flags like relro for the final mckernel.img link, as well as remove cflags for mckernel
# ideally mckernel should use different environment variables for the user tools and the kernel tools altogether...
%undefine _hardened_build
%define build_ldflags ""
%define __global_ldflags ""
%define optflags -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -grecord-gcc-switches -mtune=generic