zoukankan      html  css  js  c++  java
  • 【记录一个问题】没用任何用处的解决了libtask的context.c在32位NDK下的编译问题

    32位下用ndk编译libtask出现这样的错误:

    [armeabi-v7a] Compile thumb  : task <= context.c
    /Users/ahfu/code/android/android-ndk-r14b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -MMD -MP -MF /Users/ahfu/code/gitcode/ahfuzhang/daily_coding/source_code/libtask-master/libtask//obj/local/armeabi-v7a/objs-debug/task/context.o.d -gcc-toolchain /Users/ahfu/code/android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv7-none-linux-androideabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -O0 -UNDEBUG -fno-limit-debug-info  -mfpu=neon -I./ -I./ -DANDROID -g -pie -fPIC -DANDROID_ARM_NEON=TRUE -DANDROID_TOOLCHAIN=arm-linux-androideabi-gcc -O2 -Wa,--noexecstack -Wformat -Werror=format-security    --sysroot /Users/ahfu/code/android/android-ndk-r14b/platforms/android-21/arch-arm  -c  .//context.c -o /Users/ahfu/code/gitcode/ahfuzhang/daily_coding/source_code/libtask-master/libtask//obj/local/armeabi-v7a/objs-debug/task/context.o
    .//context.c:124:19: error: no member named 'regs' in 'struct sigcontext'
                    uc->uc_mcontext.regs[i] = va_arg(arg, uint);
                    ~~~~~~~~~~~~~~~ ^
    .//context.c:127:18: error: no member named 'regs' in 'struct sigcontext'
            uc->uc_mcontext.regs[13] = (uint)sp;
            ~~~~~~~~~~~~~~~ ^
    .//context.c:128:18: error: no member named 'regs' in 'struct sigcontext'
            uc->uc_mcontext.regs[14] = (uint)fn;
            ~~~~~~~~~~~~~~~ ^
    3 errors generated.
    

    通过查看头文件 /Users/ahfu/code/android/android-ndk-r14b/platforms/android-24/arch-arm/usr/include/asm/sigcontext.h
    发现结构体的定义与上面使用的结构体并不相同:

    #ifndef _ASMARM_SIGCONTEXT_H
    #define _ASMARM_SIGCONTEXT_H 
    struct sigcontext {
     unsigned long trap_no;
    /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long error_code;
     unsigned long oldmask;
     unsigned long arm_r0;
     unsigned long arm_r1;
    /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long arm_r2;
     unsigned long arm_r3;
     unsigned long arm_r4;
     unsigned long arm_r5;
    /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long arm_r6;
     unsigned long arm_r7;
     unsigned long arm_r8;
     unsigned long arm_r9;
    /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long arm_r10;
     unsigned long arm_fp;
     unsigned long arm_ip;
     unsigned long arm_sp;
    /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long arm_lr;
     unsigned long arm_pc;
     unsigned long arm_cpsr;
     unsigned long fault_address;
    /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
    };
    #endif
    

    于是context.c中这样修改代码,解决了32位下的编译问题:

    #ifdef NEEDARMMAKECONTEXT
    
    #if defined(__linux__) && defined(__arm__)
    
    void
    makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
    {
    	int i, *sp;
    	va_list arg;
    	sp = (int *)uc->uc_stack.ss_sp + uc->uc_stack.ss_size / 4;
    	va_start(arg, argc);
    	for (i = 0; i < 4 && i < argc; ++i) {
    		switch (i){
    		case 0:
    			uc->uc_mcontext.arm_r0 = va_arg(arg, uint);
    			break;	
    		case 1:
    			uc->uc_mcontext.arm_r1 = va_arg(arg, uint);
    			break;	
    		case 2:
    			uc->uc_mcontext.arm_r2 = va_arg(arg, uint);
    			break;	
    		case 3:
    			uc->uc_mcontext.arm_r3 = va_arg(arg, uint);
    			break;	
    		}
    	}
    	va_end(arg);
    	uc->uc_mcontext.arm_sp = (uint)sp;
    	uc->uc_mcontext.arm_lr = (uint)fn;
    }
    
    #elif defined(__linux__) && (defined(__arm64__) || defined(__aarch64__))
    
    void
    makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
    {
    	int i, *sp;
    	va_list arg;
    	sp = (int *)uc->uc_stack.ss_sp + uc->uc_stack.ss_size / 4;
    	va_start(arg, argc);
    	for (i = 0; i < 4 && i < argc; ++i) {
    		uc->uc_mcontext.regs[i] = va_arg(arg, uint);
    	}
    	va_end(arg);
    	uc->uc_mcontext.regs[13] = (uint)sp;
    	uc->uc_mcontext.regs[14] = (uint)fn;
    }
    
    #else
    #error unknown platform
    #endif
    
    #endif
    

    总结:

    • arm32与arm64的寄存器结构差异较大
    • libtask号称支持ARM,但是ndk编译的时候一堆问题。
    • 相比之下,32位的libtask有可能编译并最终投入使用;arm64因为无法访问pc寄存器,这个难度略高。
  • 相关阅读:
    lua 语言基础
    C语言基础
    文件夹目录排序
    C#调用Server_SQL
    SQL语言基础
    批量修改文件名
    快捷键Alt、Shift、Ctrl 点击事件
    第一节:基础语法
    一:ASP.NET基础知识(二)
    孩子,我首先希望你自始至终都是一个理想主义者!
  • 原文地址:https://www.cnblogs.com/ahfuzhang/p/11290935.html
Copyright © 2011-2022 走看看