From 3366dbe7740c609c3005527861384f81b0910bc9 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Thu, 17 Nov 2011 08:44:12 -0800 Subject: [PATCH] Integrate cctools-809 changes --- include/mach/arm/_structs.h | 76 +++++++++++++++++++++++++++ include/mach/arm/thread_state.h | 17 ++++++ include/mach/arm/thread_status.h | 90 +++++++++++++++++++++----------- include/mach/machine.h | 3 +- include/stuff/bytesex.h | 2 +- include/stuff/lto.h | 11 ++-- include/stuff/ofile.h | 7 +++ libstuff/arch.c | 2 + libstuff/bytesex.c | 26 ++++----- libstuff/get_arch_from_host.c | 24 +++++++++ libstuff/lto.c | 110 +++++++++++++++++++++++++++------------ libstuff/ofile.c | 4 ++ preinc.h | 10 ++++ strip.c | 4 +- tease.c | 4 +- 15 files changed, 301 insertions(+), 89 deletions(-) create mode 100644 include/mach/arm/_structs.h create mode 100644 include/mach/arm/thread_state.h rewrite include/mach/arm/thread_status.h (94%) diff --git a/include/mach/arm/_structs.h b/include/mach/arm/_structs.h new file mode 100644 index 0000000..9c7b338 --- /dev/null +++ b/include/mach/arm/_structs.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004-2007 Apple Inc. All rights reserved. + */ +/* + * @OSF_COPYRIGHT@ + */ +#ifndef _MACH_ARM__STRUCTS_H_ +#define _MACH_ARM__STRUCTS_H_ + +#if __DARWIN_UNIX03 +#define _STRUCT_ARM_EXCEPTION_STATE struct __darwin_arm_exception_state +_STRUCT_ARM_EXCEPTION_STATE +{ + __uint32_t __exception; /* number of arm exception taken */ + __uint32_t __fsr; /* Fault status */ + __uint32_t __far; /* Virtual Fault Address */ +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_ARM_EXCEPTION_STATE struct arm_exception_state +_STRUCT_ARM_EXCEPTION_STATE +{ + __uint32_t exception; /* number of arm exception taken */ + __uint32_t fsr; /* Fault status */ + __uint32_t far; /* Virtual Fault Address */ +}; +#endif /* __DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_ARM_THREAD_STATE struct __darwin_arm_thread_state +_STRUCT_ARM_THREAD_STATE +{ + __uint32_t __r[13]; /* General purpose register r0-r12 */ + __uint32_t __sp; /* Stack pointer r13 */ + __uint32_t __lr; /* Link register r14 */ + __uint32_t __pc; /* Program counter r15 */ + __uint32_t __cpsr; /* Current program status register */ +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_ARM_THREAD_STATE struct arm_thread_state +_STRUCT_ARM_THREAD_STATE +{ + __uint32_t r[13]; /* General purpose register r0-r12 */ + __uint32_t sp; /* Stack pointer r13 */ + __uint32_t lr; /* Link register r14 */ + __uint32_t pc; /* Program counter r15 */ + __uint32_t cpsr; /* Current program status register */ +}; +#endif /* __DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_ARM_VFP_STATE struct __darwin_arm_vfp_state +_STRUCT_ARM_VFP_STATE +{ + __uint32_t __r[64]; + __uint32_t __fpscr; + +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_ARM_VFP_STATE struct arm_vfp_state +_STRUCT_ARM_VFP_STATE +{ + __uint32_t r[64]; + __uint32_t fpscr; +}; +#endif /* __DARWIN_UNIX03 */ + +#define _STRUCT_ARM_DEBUG_STATE struct __darwin_arm_debug_state +_STRUCT_ARM_DEBUG_STATE +{ + __uint32_t __bvr[16]; + __uint32_t __bcr[16]; + __uint32_t __wvr[16]; + __uint32_t __wcr[16]; +}; + +#endif /* _MACH_ARM__STRUCTS_H_ */ diff --git a/include/mach/arm/thread_state.h b/include/mach/arm/thread_state.h new file mode 100644 index 0000000..2dbcb07 --- /dev/null +++ b/include/mach/arm/thread_state.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_ARM_THREAD_STATE_H_ +#define _MACH_ARM_THREAD_STATE_H_ + +#define ARM_THREAD_STATE_MAX (272) + +#if defined (__arm__) +#define THREAD_STATE_MAX ARM_THREAD_STATE_MAX +#endif + +#endif /* _MACH_ARM_THREAD_STATE_H_ */ diff --git a/include/mach/arm/thread_status.h b/include/mach/arm/thread_status.h dissimilarity index 94% index e18ca13..aae2cb2 100644 --- a/include/mach/arm/thread_status.h +++ b/include/mach/arm/thread_status.h @@ -1,29 +1,61 @@ -#ifndef _ARM_THREAD_STATUS_H_ -#define _ARM_THREAD_STATUS_H_ - -#define ARM_THREAD_STATE 1 - -typedef struct arm_thread_state { - unsigned int r0; - unsigned int r1; - unsigned int r2; - unsigned int r3; - unsigned int r4; - unsigned int r5; - unsigned int r6; - unsigned int r7; - unsigned int r8; - unsigned int r9; - unsigned int r10; - unsigned int r11; - unsigned int r12; - unsigned int r13; - unsigned int r14; - unsigned int r15; - unsigned int r16; -} arm_thread_state_t; - -#define ARM_THREAD_STATE_COUNT \ - (sizeof(struct arm_thread_state) / sizeof(int)) - -#endif /* _ARM_THREAD_STATUS_H_ */ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + */ +/* + * FILE_ID: thread_status.h + */ + + +#ifndef _ARM_THREAD_STATUS_H_ +#define _ARM_THREAD_STATUS_H_ + +#include +#include +#include + +/* + * Support for determining the state of a thread + */ + + +/* + * Flavors + */ + +#define ARM_THREAD_STATE 1 +#define ARM_VFP_STATE 2 +#define ARM_EXCEPTION_STATE 3 +#define ARM_DEBUG_STATE 4 +#define THREAD_STATE_NONE 5 + +#define VALID_THREAD_STATE_FLAVOR(x)\ +((x == ARM_THREAD_STATE) || \ + (x == ARM_VFP_STATE) || \ + (x == ARM_EXCEPTION_STATE) || \ + (x == ARM_DEBUG_STATE) || \ + (x == THREAD_STATE_NONE)) + +typedef _STRUCT_ARM_THREAD_STATE arm_thread_state_t; +typedef _STRUCT_ARM_VFP_STATE arm_vfp_state_t; +typedef _STRUCT_ARM_EXCEPTION_STATE arm_exception_state_t; +typedef _STRUCT_ARM_DEBUG_STATE arm_debug_state_t; + +#define ARM_THREAD_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof (arm_thread_state_t)/sizeof(uint32_t))) + +#define ARM_VFP_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof (arm_vfp_state_t)/sizeof(uint32_t))) + +#define ARM_EXCEPTION_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof (arm_exception_state_t)/sizeof(uint32_t))) + +#define ARM_DEBUG_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof (arm_debug_state_t)/sizeof(uint32_t))) + +/* + * Largest state on this machine: + */ +#define THREAD_MACHINE_STATE_MAX THREAD_STATE_MAX + + +#endif /* _ARM_THREAD_STATUS_H_ */ diff --git a/include/mach/machine.h b/include/mach/machine.h index d9268e4..0bca89b 100644 --- a/include/mach/machine.h +++ b/include/mach/machine.h @@ -159,7 +159,6 @@ extern vm_offset_t interrupt_stack[]; #define CPU_ARCH_ABI64 0x1000000 #define CPU_TYPE_POWERPC64 ((cpu_type_t)(CPU_TYPE_POWERPC | CPU_ARCH_ABI64)) #define CPU_TYPE_VEO ((cpu_type_t) 255) - /* * Machine subtypes (these are defined here, instead of in a machine @@ -307,6 +306,8 @@ extern vm_offset_t interrupt_stack[]; #define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) #define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) #define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) +#define CPU_SUBTYPE_ARM_V7F ((cpu_subtype_t) 10) /* Cortex A9 */ +#define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t) 12) /* * MC88000 subtypes diff --git a/include/stuff/bytesex.h b/include/stuff/bytesex.h index 238e67d..698547e 100644 --- a/include/stuff/bytesex.h +++ b/include/stuff/bytesex.h @@ -304,7 +304,7 @@ __private_extern__ void swap_sparc_thread_state_fpu( enum byte_sex target_byte_order); __private_extern__ void swap_arm_thread_state_t( - struct arm_thread_state *cpu, + arm_thread_state_t *cpu, enum byte_sex target_byte_sex); __private_extern__ void swap_ident_command( diff --git a/include/stuff/lto.h b/include/stuff/lto.h index 73f8bab..b64ff09 100644 --- a/include/stuff/lto.h +++ b/include/stuff/lto.h @@ -1,14 +1,15 @@ #ifndef _STUFF_LTO_H_ #define _STUFF_LTO_H_ -#ifdef LTO_SUPPORT +#include "stuff/arch.h" -#include "stuff/ofile.h" +#ifdef LTO_SUPPORT -__private_extern__ int is_llvm_bitcode( - struct ofile *ofile, +__private_extern__ int is_llvm_bitcode_from_memory( char *addr, - size_t size); + uint32_t size, + struct arch_flag *arch_flag, + void **mod); /* maybe NULL */ __private_extern__ uint32_t lto_get_nsyms( void *mod); diff --git a/include/stuff/ofile.h b/include/stuff/ofile.h index b528e6b..0b97e7e 100644 --- a/include/stuff/ofile.h +++ b/include/stuff/ofile.h @@ -216,4 +216,11 @@ __private_extern__ void Mach_O_error( #endif ; +#ifdef LTO_SUPPORT +__private_extern__ int is_llvm_bitcode( + struct ofile *ofile, + char *addr, + size_t size); +#endif /* LTO_SUPPORT */ + #endif /* _STUFF_OFILE_H_ */ diff --git a/libstuff/arch.c b/libstuff/arch.c index 689e0d6..10488c1 100644 --- a/libstuff/arch.c +++ b/libstuff/arch.c @@ -95,6 +95,8 @@ static const struct arch_flag arch_flags[] = { { "xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE}, { "armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 }, { "armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 }, + { "armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F }, + { "armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K }, { NULL, 0, 0 } }; diff --git a/libstuff/bytesex.c b/libstuff/bytesex.c index 71d7927..9f6a311 100644 --- a/libstuff/bytesex.c +++ b/libstuff/bytesex.c @@ -2332,25 +2332,17 @@ enum byte_sex target_byte_sex) __private_extern__ void swap_arm_thread_state_t( -struct arm_thread_state *cpu, +arm_thread_state_t *cpu, enum byte_sex target_byte_sex) { - cpu->r0 = SWAP_INT(cpu->r0); - cpu->r1 = SWAP_INT(cpu->r1); - cpu->r2 = SWAP_INT(cpu->r2); - cpu->r3 = SWAP_INT(cpu->r3); - cpu->r4 = SWAP_INT(cpu->r4); - cpu->r5 = SWAP_INT(cpu->r5); - cpu->r6 = SWAP_INT(cpu->r6); - cpu->r7 = SWAP_INT(cpu->r7); - cpu->r8 = SWAP_INT(cpu->r8); - cpu->r9 = SWAP_INT(cpu->r9); - cpu->r10 = SWAP_INT(cpu->r10); - cpu->r11 = SWAP_INT(cpu->r11); - cpu->r12 = SWAP_INT(cpu->r12); - cpu->r13 = SWAP_INT(cpu->r13); - cpu->r14 = SWAP_INT(cpu->r14); - cpu->r15 = SWAP_INT(cpu->r15); + int i; + + for(i = 0; i < 13; i++) + cpu->__r[i] = SWAP_INT(cpu->__r[i]); + cpu->__sp = SWAP_INT(cpu->__sp); + cpu->__lr = SWAP_INT(cpu->__lr); + cpu->__pc = SWAP_INT(cpu->__pc); + cpu->__cpsr = SWAP_INT(cpu->__cpsr); } __private_extern__ diff --git a/libstuff/get_arch_from_host.c b/libstuff/get_arch_from_host.c index 5ea5516..38a5329 100644 --- a/libstuff/get_arch_from_host.c +++ b/libstuff/get_arch_from_host.c @@ -439,6 +439,30 @@ struct arch_flag *specific_arch_flag) if(specific_arch_flag != NULL) specific_arch_flag->name = "armv6"; return(1); + case CPU_SUBTYPE_ARM_V7: + if(family_arch_flag != NULL){ + family_arch_flag->name = "arm"; + family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL; + } + if(specific_arch_flag != NULL) + specific_arch_flag->name = "armv7"; + return(1); + case CPU_SUBTYPE_ARM_V7F: + if(family_arch_flag != NULL){ + family_arch_flag->name = "arm"; + family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL; + } + if(specific_arch_flag != NULL) + specific_arch_flag->name = "armv7f"; + return(1); + case CPU_SUBTYPE_ARM_V7K: + if(family_arch_flag != NULL){ + family_arch_flag->name = "arm"; + family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL; + } + if(specific_arch_flag != NULL) + specific_arch_flag->name = "armv7k"; + return(1); } break; } diff --git a/libstuff/lto.c b/libstuff/lto.c index abb27c1..b96a804 100644 --- a/libstuff/lto.c +++ b/libstuff/lto.c @@ -12,8 +12,8 @@ #include #include -static int set_lto_cputype( - struct ofile *ofile, +static int get_lto_cputype( + struct arch_flag *arch_flag, char *target_triple); static int tried_to_load_lto = 0; @@ -39,9 +39,7 @@ struct ofile *ofile, char *addr, size_t size) { - size_t bufsize; - char *p, *prefix, *lto_path, buf[MAXPATHLEN], resolved_name[PATH_MAX]; - int i; + struct arch_flag arch_flag; /* * If this is an llvm bitcode file these will be filled in. @@ -55,6 +53,35 @@ size_t size) *"llvm bitcode file" could be in an archive or fat file. */ + if(is_llvm_bitcode_from_memory(addr, size, &arch_flag, + &ofile->lto) != 0){ + ofile->lto_cputype = arch_flag.cputype; + ofile->lto_cpusubtype = arch_flag.cpusubtype; + return(1); + } + return(0); +} + +/* + * is_llvm_bitcode_from_memory() is passed a pointer and size of a memory + * buffer, a pointer to an arch_flag struct and an pointer to return the lto + * module if not NULL. If it the memory is an llvm bit code it returns 1 and + * sets the fields in the arch flag. If pmod is not NULL it stores the lto + * module in their, if not it frees the lto module. If the memory buffer is + * not an llvm bit code it returns 0. + */ +__private_extern__ int is_llvm_bitcode_from_memory( +char *addr, +uint32_t size, +struct arch_flag *arch_flag, +void **pmod) /* maybe NULL */ +{ + + size_t bufsize; + char *p, *prefix, *lto_path, buf[MAXPATHLEN], resolved_name[PATH_MAX]; + int i; + void *mod; + /* * The libLTO API's can't handle empty files. So return 0 to indicate * this is not a bitcode file if it has a zero size. @@ -131,33 +158,40 @@ size_t size) if(!lto_is_object(addr, size)) return(0); - ofile->lto = lto_create(addr, size); - if(ofile->lto == NULL) + mod = lto_create(addr, size); + if(mod == NULL) return(0); /* * It is possible for new targets to be added to lto that are not yet * known to this code. So we will try to get lucky and let them pass - * through with the lto_cputype set to 0. This should work for things + * through with the cputype set to 0. This should work for things * like libtool(1) as long as we don't get two different unknown * targets. But we'll hope that just doesn't happen. */ - set_lto_cputype(ofile, lto_get_target(ofile->lto)); + arch_flag->cputype = 0; + arch_flag->cpusubtype = 0; + arch_flag->name = NULL; + (void)get_lto_cputype(arch_flag, lto_get_target(mod)); + + if(pmod != NULL) + *pmod = mod; + else + lto_free(mod); return(1); } /* - * set_lto_cputype() takes an ofile pointer and the target_triple string - * returned from lto_module_get_target_triple() and sets the fields lto_cputype - * and lto_cpusubtype in the ofile pointer. If it can parse and knows the - * strings values it returns 1 and the fields are set. Otherwise it returns 0 - * and the fields are not set. + * get_lto_cputype() takes an arch_flag pointer and the target_triple string + * returned from lto_module_get_target_triple() and sets the fields in the + * arch_flag. If it can parse and knows the strings values it returns 1 and + * the fields are set. Otherwise it returns 0 and the fields are not set. */ static int -set_lto_cputype( -struct ofile *ofile, +get_lto_cputype( +struct arch_flag *arch_flag, char *target_triple) { char *p; @@ -171,45 +205,57 @@ char *target_triple) n = p - target_triple; if(strncmp(target_triple, "i686", n) == 0 || strncmp(target_triple, "i386", n) == 0){ - ofile->lto_cputype = CPU_TYPE_I386; - ofile->lto_cpusubtype = CPU_SUBTYPE_I386_ALL; + arch_flag->cputype = CPU_TYPE_I386; + arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL; } else if(strncmp(target_triple, "x86_64", n) == 0){ - ofile->lto_cputype = CPU_TYPE_X86_64; - ofile->lto_cpusubtype = CPU_SUBTYPE_X86_64_ALL; + arch_flag->cputype = CPU_TYPE_X86_64; + arch_flag->cpusubtype = CPU_SUBTYPE_X86_64_ALL; } else if(strncmp(target_triple, "powerpc", n) == 0){ - ofile->lto_cputype = CPU_TYPE_POWERPC; - ofile->lto_cpusubtype = CPU_SUBTYPE_POWERPC_ALL; + arch_flag->cputype = CPU_TYPE_POWERPC; + arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL; } else if(strncmp(target_triple, "powerpc64", n) == 0){ - ofile->lto_cputype = CPU_TYPE_POWERPC64; - ofile->lto_cpusubtype = CPU_SUBTYPE_POWERPC_ALL; + arch_flag->cputype = CPU_TYPE_POWERPC64; + arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL; } else if(strncmp(target_triple, "arm", n) == 0){ - ofile->lto_cputype = CPU_TYPE_ARM; - ofile->lto_cpusubtype = CPU_SUBTYPE_ARM_V4T; + arch_flag->cputype = CPU_TYPE_ARM; + arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V4T; } else if(strncmp(target_triple, "armv5", n) == 0 || strncmp(target_triple, "armv5e", n) == 0 || strncmp(target_triple, "thumbv5", n) == 0 || strncmp(target_triple, "thumbv5e", n) == 0){ - ofile->lto_cputype = CPU_TYPE_ARM; - ofile->lto_cpusubtype = CPU_SUBTYPE_ARM_V5TEJ; + arch_flag->cputype = CPU_TYPE_ARM; + arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V5TEJ; } else if(strncmp(target_triple, "armv6", n) == 0 || strncmp(target_triple, "thumbv6", n) == 0){ - ofile->lto_cputype = CPU_TYPE_ARM; - ofile->lto_cpusubtype = CPU_SUBTYPE_ARM_V6; + arch_flag->cputype = CPU_TYPE_ARM; + arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V6; } else if(strncmp(target_triple, "armv7", n) == 0 || strncmp(target_triple, "thumbv7", n) == 0){ - ofile->lto_cputype = CPU_TYPE_ARM; - ofile->lto_cpusubtype = CPU_SUBTYPE_ARM_V7; + arch_flag->cputype = CPU_TYPE_ARM; + arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7; + } + else if(strncmp(target_triple, "armv7f", n) == 0 || + strncmp(target_triple, "thumbv7f", n) == 0){ + arch_flag->cputype = CPU_TYPE_ARM; + arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7F; + } + else if(strncmp(target_triple, "armv7k", n) == 0 || + strncmp(target_triple, "thumbv7k", n) == 0){ + arch_flag->cputype = CPU_TYPE_ARM; + arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7K; } else{ return(0); } + arch_flag->name = (char *)get_arch_name_from_types(arch_flag->cputype, + arch_flag->cpusubtype); return(1); } diff --git a/libstuff/ofile.c b/libstuff/ofile.c index 1b96bab..d9fdd92 100644 --- a/libstuff/ofile.c +++ b/libstuff/ofile.c @@ -52,6 +52,10 @@ #include #import #import +#undef MACHINE_THREAD_STATE /* need to undef these to avoid warnings */ +#undef MACHINE_THREAD_STATE_COUNT +#undef THREAD_STATE_NONE +#undef VALID_THREAD_STATE_FLAVOR #import #import #import diff --git a/preinc.h b/preinc.h index 325f824..565a113 100644 --- a/preinc.h +++ b/preinc.h @@ -28,4 +28,14 @@ /* This is a hack to compile and build a 10.4 compatible version * without tons of warnings */ +#include struct __darwin_i386_float_state; +#define __DARWIN_UNIX03 1 +#define __uint32_t uint32_t +#define __lr lr +#define __pc pc +#include "mach/arm/_structs.h" +#undef __pc +#undef __lr +#undef __uint32_t +#undef __DARWIN_UNIX03 diff --git a/strip.c b/strip.c index f7c3e9f..e18560d 100644 --- a/strip.c +++ b/strip.c @@ -2676,8 +2676,8 @@ uint32_t nextrefsyms) * For x86_64 .o files we have run ld -r on them and are stuck * keeping all resulting symbols. */ - if(object->mh == NULL && - object->mh64->cputype == CPU_TYPE_X86_64 && + if(object->mh == NULL && ( + object->mh64->cputype == CPU_TYPE_X86_64) && object->mh64->filetype == MH_OBJECT){ if(n_strx != 0) new_strsize += strlen(strings + n_strx) + 1; diff --git a/tease.c b/tease.c index 4a5e8f8..8ac9bde 100644 --- a/tease.c +++ b/tease.c @@ -2710,8 +2710,8 @@ uint32_t nextrefsyms) * For x86_64 .o files we have run ld -r on them and are stuck * keeping all resulting symbols. */ - else if(object->mh == NULL && - object->mh64->cputype == CPU_TYPE_X86_64 && + else if(object->mh == NULL && ( + object->mh64->cputype == CPU_TYPE_X86_64) && object->mh64->filetype == MH_OBJECT){ if(n_strx != 0) new_strsize += strlen(strings + n_strx) + 1; -- 2.11.4.GIT