Cross toolchain under linux

怎样构建一个不依赖gcc/binutils的llvm/clang Linux工具链

cjacker posted @ 2014年9月10日 16:32 in 代码 , 9826 阅读

本文不讲原理,只讲步骤。需要了解什么是unwind,crtbengin/end,ehtable以及libgcc_s/libgcc_eh或者c++abi/supc++的,请查阅相关文档。

1,Build llvm/clang/lldb/lld 3.5.0等组件

1.0  准备:

至少需要从llvm.org下载llvm, cfe, lldb, compiler-rt,lld等3.5.0版本的代码。

$tar xf llvm-3.5.0.src.tar.gz

$cd llvm-3.5.0.src

$mkdir -p tools/clang
$mkdir -p tools/clang/tools/extra
$mkdir -p tools/lld
$mkdir -p projects/compiler-rt

$tar xf cfe-3.5.0.src.tar.xz -C tools/clang --strip-components=1
$tar xf compiler-rt-3.5.0.src.tar.xz -C projects/compiler-rt --strip-components=1
$tar xf lldb-3.5.0.src.tar.xz -C tools/clang/tools/extra --strip-components=1
$tar xf lld-3.5.0.src.tar.xz -C tools/lld --strip-components=1

 

1.1 【可选】使用clang --stdlib=libc++时,自动添加-lc++abi。

libc++组件可以使用gcc libstdc++的supc++ ABI,也可以使用c++abi,cxxrt等,实际上自动添加-lc++abi是不必要的,这里这么处理,主要是为了方便起见。实际上完全可以在“clang++ -stdlib=libc++”时再手工添加-lc++abi给链接器。

这里涉及到链接时DSO隐式还是显式的问题,早些时候ld在链接库时会自动引入由库引入的依赖动态库,后来因为这个行为的不可控性,所以ld链接器的行为做了修改,需要显式的写明所有需要链接的动态库,才会有手工添加-lc++abi这种情况出现。

--- llvm-3.0.src/tools/clang/lib/Driver/ToolChain.cpp   2012-03-26 18:49:06.663029075 +0800
+++ llvm-3.0.srcn/tools/clang/lib/Driver/ToolChain.cpp  2012-03-26 19:36:04.260071355 +0800
@@ -251,6 +251,7 @@
   switch (Type) {
   case ToolChain::CST_Libcxx:
     CmdArgs.push_back("-lc++");
+    CmdArgs.push_back("-lc++abi");
     break;

   case ToolChain::CST_Libstdcxx:

 

1.2 【必要】给clang++添加-fnolibgcc开关。

这个开关主要用来控制是否连接到libgcc或者libunwind。

注:libgcc不等于libunwind。libgcc_eh以及supc++的一部分跟libunwind功能相当。

注:libgcc_s和compiler_rt的一部分相当。

 

这个补丁是必要的,不会对clang的正常使用造成任何影响,只有在使用“-fnolibgcc"参数时才会起作用。

之所以进行了很多unwind的引入,主要是为了避免不必要的符号缺失麻烦,这里的处理相对来说是干净的,通过as-needed规避了不必要的引入。

--- llvm-static-3.5.0.bak/tools/clang/lib/Driver/Tools.cpp	2014-09-10 13:46:02.581543888 +0800
+++ llvm-static-3.5.0/tools/clang/lib/Driver/Tools.cpp	2014-09-10 16:03:37.559019321 +0800
@@ -2060,9 +2060,15 @@
                                           ".a");
 
   CmdArgs.push_back(Args.MakeArgString(LibClangRT));
-  CmdArgs.push_back("-lgcc_s");
-  if (TC.getDriver().CCCIsCXX())
-    CmdArgs.push_back("-lgcc_eh");
+  if (Args.hasArg(options::OPT_fnolibgcc)) {
+    CmdArgs.push_back("--as-needed");
+    CmdArgs.push_back("-lunwind");
+    CmdArgs.push_back("--no-as-needed");
+  } else {
+    CmdArgs.push_back("-lgcc_s");
+    if (TC.getDriver().CCCIsCXX())
+      CmdArgs.push_back("-lgcc_eh");
+  }
 }
 
 static void addProfileRT(
@@ -7150,24 +7156,50 @@
   bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
   bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
                       Args.hasArg(options::OPT_static);
+
+
+
   if (!D.CCCIsCXX())
-    CmdArgs.push_back("-lgcc");
+    if (Args.hasArg(options::OPT_fnolibgcc)) {
+        CmdArgs.push_back("--as-needed");
+        CmdArgs.push_back("-lunwind");
+        CmdArgs.push_back("--no-as-needed");
+    } else
+        CmdArgs.push_back("-lgcc");
 
   if (StaticLibgcc || isAndroid) {
     if (D.CCCIsCXX())
-      CmdArgs.push_back("-lgcc");
+    if (Args.hasArg(options::OPT_fnolibgcc)) {
+        CmdArgs.push_back("--as-needed");
+        CmdArgs.push_back("-lunwind");
+        CmdArgs.push_back("--no-as-needed");
+    } else
+        CmdArgs.push_back("-lgcc");
   } else {
     if (!D.CCCIsCXX())
       CmdArgs.push_back("--as-needed");
-    CmdArgs.push_back("-lgcc_s");
+    if (Args.hasArg(options::OPT_fnolibgcc))
+        CmdArgs.push_back("-lunwind");
+    else
+        CmdArgs.push_back("-lgcc_s");
     if (!D.CCCIsCXX())
       CmdArgs.push_back("--no-as-needed");
   }
 
   if (StaticLibgcc && !isAndroid)
-    CmdArgs.push_back("-lgcc_eh");
+    if (Args.hasArg(options::OPT_fnolibgcc)) {
+        CmdArgs.push_back("--as-needed");
+        CmdArgs.push_back("-lunwind");
+        CmdArgs.push_back("--no-as-needed");
+    } else
+        CmdArgs.push_back("-lgcc_eh");
   else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
-    CmdArgs.push_back("-lgcc");
+    if (Args.hasArg(options::OPT_fnolibgcc)) {
+        CmdArgs.push_back("--as-needed");
+        CmdArgs.push_back("-lunwind");
+        CmdArgs.push_back("--no-as-needed");
+    } else
+        CmdArgs.push_back("-lgcc");
 
   // According to Android ABI, we have to link with libdl if we are
   // linking with non-static libgcc.
--- llvm-static-3.5.0.bak/tools/clang/include/clang/Driver/Options.td	2014-08-07 12:51:51.000000000 +0800
+++ llvm-static-3.5.0/tools/clang/include/clang/Driver/Options.td	2014-09-10 13:36:34.598511176 +0800
@@ -788,6 +788,7 @@
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
 def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
 def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>;
+def fnolibgcc : Flag<["-"], "fnolibgcc">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
 def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
 def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
 def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;

1.3 llvm的其他补丁。

llvm/clang将gcc toolchain的路径hard code在代码中,请查阅tools/clang/lib/Driver/ToolChains.cpp。

找到x86_64-redhat-linux之类的字符串。

如果没有你系统特有的gcc tripple string,请自行添加。

这个tripple string主要是给llvm/clang搜索gcc头文件等使用的,不影响本文要构建的toolchain

 

1.4 构建clang/llvm/lldb

本文使用ninja。顺便说一下,llvm支持configure和cmake两种构建方式。可能是因为工程太大,这两种构建方式的工程文件都有各种缺陷(主要表现在开关选项上,比如configure有,但是cmake却没有等)。llvm-3.4.1就是因为cmake工程文件的错误而导致了3.4.2版本的发布。

综合而言,cmake+ninja的方式是目前最快的构建方式之一,可以将构建时间缩短一半以上。

mkdir build
cd build

cmake \
    -G Ninja \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_BUILD_TYPE="Release" \
    -DCMAKE_CXX_FLAGS="-std=c++11" \
    -DBUILD_SHARED_LIBS=OFF \
    -DLLVM_ENABLE_PIC=ON \
    -DLLVM_TARGETS_TO_BUILD="all" \
    -DCLANG_VENDOR="MyOS" ..

ninja

ninja install

    

如果系统原来就有clang/clang++的可用版本,可以添加:

    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++ \

这样就会使用系统的clang++来构建llvm/clang

 

2,测试clang/clang++。

自己找几个简单的c/cpp/objc等编译测试一下即可。完整测试可以在构建时作ninja check-all

 

3,libunwind/libc++/libc++abi,一套不依赖libgcc, libstdc++的c++运行库。

3.1 从https://github.com/pathscale/libunwind 获取代码。

libunwind有很多个实现,比如gnu的libunwind, path64的libunwind,还有libcxxabi自带的Unwinder.

这里作下说明:

1),gnu的libunwind会有符号缺失和冲突。

2),libcxxabi自带的Unwinder是给mac和ios用的,也就是只能在darwin体系构建。目前Linux的实现仍然不全,等linux实现完整了或许就不再需要path64的unwind实现了。

暂时建议使用pathscale的unwind实现。

mkdir -p build
cd build
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS="-m64" ..
ninja

mkdir -p /usr/lib
cp src/libunwind.so /usr/lib
cp src/libunwind.a /usr/lib

 

3.2 第一次构建libcxx.

必须先构建一次libcxx,以便后面构建libcxxabi。这里构建的libcxx实际上是使用gcc的libgcc/stdc++/supc++的。

打上这个补丁来禁止libgcc的引入:

diff -Nur libcxx/cmake/config-ix.cmake libcxxn/cmake/config-ix.cmake
--- libcxx/cmake/config-ix.cmake    2014-06-25 06:57:50.000000000 +0800
+++ libcxxn/cmake/config-ix.cmake   2014-06-25 09:05:24.980350544 +0800
@@ -28,5 +28,4 @@
 check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
 check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
 check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
-check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)

 

编译安装:

mkdir build
cd build
cmake \
    -G Ninja \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++  \
    ..
ninja
ninja install


3.3,测试第一次构建的libcxx。

使用"clang++ -stdlib=libc++  -o test test.cpp -lstdc++"编译简单c++代码,检查是否出错。(如果前面构建clang是已经apply了c++abi的链接补丁,这里会出现找不到c++abi的情况,跳过即可)

使用"ldd test"查看test二进制动态库使用情况。可以发现,test依赖于libgcc_s/libc++/libstdc++。(多少有些不爽了吧?使用了libc++居然还要依赖libstdc++?)

 

3.4,构建libcxxabi。

打上以下补丁,让libcxxabi链接到libc++,并生成静态库。

diff -Nur libcxxabi/lib/buildit libcxxabin/lib/buildit
--- libcxxabi/lib/buildit   2013-12-05 20:36:16.000000000 +0800
+++ libcxxabin/lib/buildit  2014-06-25 08:14:25.922459892 +0800
@@ -70,7 +70,7 @@
     SOEXT=so
     LDSHARED_FLAGS="-o libc++abi.so.1.0 \
         -shared -nodefaultlibs -Wl,-soname,libc++abi.so.1 \
-        -lpthread -lrt -lc -lstdc++"
+        -lpthread -lrt -lc -lc++"
     ;;
 esac

@@ -92,6 +92,8 @@
   ;;
 esac
 $CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_FLAGS
+ar rc libc++abi.a *.o
+ranlib libc++abi.a

 if [ -z $RC_XBS ]
 then     

 

编译安装:

cd lib
export CC="clang -fPIC"
export CXX="clang++ -fPIC"
./buildit
install -m 0644 lib/libc++abi.so.1.0 /usr/lib
install -m 0644 lib/libc++abi.a /usr/lib
cp -r include/* /usr/include
cd /usr/lib
ln -s libc++abi.so.1.0 libc++abi.so.1
ln -s libc++abi.so.1.0 libc++abi.so

 

3.5,第二次构建libcxx,使其使用c++abi,并同时构建出静态库。

仍然要打上禁用_gcc_personality_v0的补丁。

mkdir build-shared
cd build-shared
cmake \
    -G Ninja \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++  \
    -DLIBCXX_CXX_ABI=libcxxabi \
    -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="/usr/include" \
    ..
ninja
ninja install
cd ..

mkdir build-static
cd build-static
cmake \
    -G Ninja \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++  \
    -DLIBCXX_CXX_ABI=libcxxabi \
    -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="/usr/include" \
    -DLIBCXX_ENABLE_SHARED=OFF \
    ..
ninja
ninja install
cd ..

 

至此,unwind/libcxx/libcxxabi构建完成,并摆脱了gcc运行时库libgcc/libstdc++的依赖。

3.6,测试验证一下

"ld -lc++ -lc++abi -lgcc_s"

"ld -lc++ -lc++abi -lunwind"

这两种情况都应该可以满足符号依赖,不存在符号找不到的情况。(主要是_Unwind_符号)

至此:

使用:

clang++ -o test test.cpp
ldd test

test将链接到stdc++/gcc_s. 这是默认使用gcc runtime的情况,其二进制也会跟gcc生成的二进制完全兼容。

clang++ -fnolibgcc -o test test.cpp
ldd test

test将链接到stdc++/unwind.(注:gcc_s跟unwind的功能不完全一样,但互有交集实现)

clang++ -stdlib=libc++ -o test test.cpp
ldd test

test将链接到c++/c++abi/gcc_s(已经剥离了stdc++依赖,但仍然使用gcc_s,也是因为_Unwind_符号的原因)

clang++ -stdlib=libc++ -fnolibgcc -o test test.cpp
ldd test

test将链接到c++/c++abi/unwind.(这大概是很多同志想要的。)

 

4. crtbegin.o/crtend.o

 

这两货是什么作用可以查一下文档,gcc默认参数构建的每个二进制中,这两个.o都被链接进去了,具体构建链接参数,可以在clang编译代码时加 -v查看。默认情况下,clang会使用gcc的crtbegin/end。

这里我们用Netbsd的实现替代了gcc的实现。

x86_64的汇编代码从这里下载: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/csu/arch/x86_64/?only_with_tag=MAIN。

注意安装路径,这是clang最优先的搜索路径。

as crtbegin.S -o /usr/lib/clang/3.5.0/crtbegin.o
as crtbegin.S -o /usr/lib/clang/3.5.0/crtbeginS.o
as crtbegin.S -o /usr/lib/clang/3.5.0/crtbeginT.o

as crtend.S -o /usr/lib/clang/3.5.0/crtend.o
as crtend.S -o /usr/lib/clang/3.5.0/crtendS.o
as crtend.S -o /usr/lib/clang/3.5.0/crtendT.o

 

5,至此,我们基本获得了一条不依赖gcc任何组件的clang/llvm工具链。

编译时通过-fnolibgcc参数以及-stdlib=libc++参数的配合,可以完成c/c++代码的编译并脱离对gcc运行时库的依赖。

 

6,使用新的clang toolchain完成上述所有组件的bootstrap。(也就是用新toolchain重新编译llvm/clang)

具体构建过程参考步骤1.

在apply上述补丁的同时,需要apply以下补丁。

主要原因是ehtable支持需要调用register_frame实现,这是libgcc特有的实现。

--- llvm-3.4.2.src.bak/lib/ExecutionEngine/RTDyldMemoryManager.cpp  2013-12-24 14:50:45.000000000 +0800
+++ llvm-3.4.2.src/lib/ExecutionEngine/RTDyldMemoryManager.cpp  2014-06-25 14:11:53.721693229 +0800
@@ -33,12 +33,7 @@
 RTDyldMemoryManager::~RTDyldMemoryManager() {}

 // Determine whether we can register EH tables.
-#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \
-     !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__))
-#define HAVE_EHTABLE_SUPPORT 1
-#else
 #define HAVE_EHTABLE_SUPPORT 0
-#endif

 #if HAVE_EHTABLE_SUPPORT
 extern "C" void __register_frame(void*);


在编译时,注意增加clang/clang++参数如下:

-DCMAKE_CXX_FLAGS="-std=c++11 --stdlib=libc++ -fnolibgcc -fPIC"
-DCMAKE_C_FLAGS="-fPIC" 

 

7,使用lld。

lld的使用方法非常简单,只需要将/usr/bin/lld链接成/usr/bin/ld即可。

更通常的情况,是使用alternatives来管理和切换多个ld(至少,目前我们有binutils的ld.bfd, google的gold以及llvm的lld可用)

根据经验,lld应该可以胜任大部分的链接工作,但毕竟是新生项目,且仍然有大量的gnu ld的参数没有支持,所以,这里不建议未经测试和验证的就在生产环境使用。

此外,完全脱离binutils目前也不太可能,毕竟出了gnu as/ld,binutils也提供了ar,ranlib等utility。虽然llvm提供了llvm-ar等,但这些llvm utility是处理llvm bc IR字节码的,并不是用来处理系统目标文件的工具。

8,__gcc_personality_v0符号问题。

在部分静态库或者动态库链接时,如果强制使用-fnolibgcc参数禁止掉libgcc的使用,可能会出现__gcc_personality_v0符号缺失问题,这个问题的解决方法有以下两个:

7.1 添加--rtlib=compiler-rt, llvm的compiler-rt有该符号的完整实现。

7.2 或者为libunwind打上这个补丁,将实现放到libunwind中。

diff -Nur libunwind/src/CMakeLists.txt libunwindn/src/CMakeLists.txt
--- libunwind/src/CMakeLists.txt	2014-06-25 07:14:23.000000000 +0800
+++ libunwindn/src/CMakeLists.txt	2014-06-25 11:48:55.139999875 +0800
@@ -50,6 +50,8 @@
     dwarf/Lpe.c
     dwarf/Lstep.c
     dwarf/Lfind_proc_info-lsb.c
+    gcc_personality_v0/gcc_personality_v0.c 
+    gcc_personality_v0/int_util.c 
    )
 
 
diff -Nur libunwind/src/gcc_personality_v0/gcc_personality_v0.c libunwindn/src/gcc_personality_v0/gcc_personality_v0.c
--- libunwind/src/gcc_personality_v0/gcc_personality_v0.c	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/gcc_personality_v0.c	2014-06-25 11:47:54.010002060 +0800
@@ -0,0 +1,247 @@
+/* ===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------===
+ *
+ *      	       The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ */
+
+#include "int_lib.h"
+
+/*
+ * _Unwind_* stuff based on C++ ABI public documentation
+ * http://refspecs.freestandards.org/abi-eh-1.21.html
+ */
+
+typedef enum {
+    _URC_NO_REASON = 0,
+    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+    _URC_FATAL_PHASE2_ERROR = 2,
+    _URC_FATAL_PHASE1_ERROR = 3,
+    _URC_NORMAL_STOP = 4,
+    _URC_END_OF_STACK = 5,
+    _URC_HANDLER_FOUND = 6,
+    _URC_INSTALL_CONTEXT = 7,
+    _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef enum {
+    _UA_SEARCH_PHASE = 1,
+    _UA_CLEANUP_PHASE = 2,
+    _UA_HANDLER_FRAME = 4,
+    _UA_FORCE_UNWIND = 8,
+    _UA_END_OF_STACK = 16
+} _Unwind_Action;
+
+typedef struct _Unwind_Context* _Unwind_Context_t;
+
+struct _Unwind_Exception {
+    uint64_t                exception_class;
+    void                    (*exception_cleanup)(_Unwind_Reason_Code reason, 
+                                                 struct _Unwind_Exception* exc);
+    uintptr_t                private_1;    
+    uintptr_t                private_2;    
+};
+
+extern const uint8_t*    _Unwind_GetLanguageSpecificData(_Unwind_Context_t c);
+extern void              _Unwind_SetGR(_Unwind_Context_t c, int i, uintptr_t n);
+extern void              _Unwind_SetIP(_Unwind_Context_t, uintptr_t new_value);
+extern uintptr_t         _Unwind_GetIP(_Unwind_Context_t context);
+extern uintptr_t         _Unwind_GetRegionStart(_Unwind_Context_t context);
+
+
+/*
+ * Pointer encodings documented at:
+ *   http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
+ */
+
+#define DW_EH_PE_omit      0xff  /* no data follows */
+
+#define DW_EH_PE_absptr    0x00
+#define DW_EH_PE_uleb128   0x01
+#define DW_EH_PE_udata2    0x02
+#define DW_EH_PE_udata4    0x03
+#define DW_EH_PE_udata8    0x04
+#define DW_EH_PE_sleb128   0x09
+#define DW_EH_PE_sdata2    0x0A
+#define DW_EH_PE_sdata4    0x0B
+#define DW_EH_PE_sdata8    0x0C
+
+#define DW_EH_PE_pcrel     0x10
+#define DW_EH_PE_textrel   0x20
+#define DW_EH_PE_datarel   0x30
+#define DW_EH_PE_funcrel   0x40
+#define DW_EH_PE_aligned   0x50  
+#define DW_EH_PE_indirect  0x80 /* gcc extension */
+
+
+
+/* read a uleb128 encoded value and advance pointer */
+static uintptr_t readULEB128(const uint8_t** data)
+{
+    uintptr_t result = 0;
+    uintptr_t shift = 0;
+    unsigned char byte;
+    const uint8_t* p = *data;
+    do {
+        byte = *p++;
+        result |= (byte & 0x7f) << shift;
+        shift += 7;
+    } while (byte & 0x80);
+    *data = p;
+    return result;
+}
+
+/* read a pointer encoded value and advance pointer */
+static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)
+{
+    const uint8_t* p = *data;
+    uintptr_t result = 0;
+
+    if ( encoding == DW_EH_PE_omit ) 
+        return 0;
+
+    /* first get value */
+    switch (encoding & 0x0F) {
+        case DW_EH_PE_absptr:
+            result = *((uintptr_t*)p);
+            p += sizeof(uintptr_t);
+            break;
+        case DW_EH_PE_uleb128:
+            result = readULEB128(&p);
+            break;
+        case DW_EH_PE_udata2:
+            result = *((uint16_t*)p);
+            p += sizeof(uint16_t);
+            break;
+        case DW_EH_PE_udata4:
+            result = *((uint32_t*)p);
+            p += sizeof(uint32_t);
+            break;
+        case DW_EH_PE_udata8:
+            result = *((uint64_t*)p);
+            p += sizeof(uint64_t);
+            break;
+        case DW_EH_PE_sdata2:
+            result = *((int16_t*)p);
+            p += sizeof(int16_t);
+            break;
+        case DW_EH_PE_sdata4:
+            result = *((int32_t*)p);
+            p += sizeof(int32_t);
+            break;
+        case DW_EH_PE_sdata8:
+            result = *((int64_t*)p);
+            p += sizeof(int64_t);
+            break;
+        case DW_EH_PE_sleb128:
+        default:
+            /* not supported */
+            compilerrt_abort();
+            break;
+    }
+
+    /* then add relative offset */
+    switch ( encoding & 0x70 ) {
+        case DW_EH_PE_absptr:
+            /* do nothing */
+            break;
+        case DW_EH_PE_pcrel:
+            result += (uintptr_t)(*data);
+            break;
+        case DW_EH_PE_textrel:
+        case DW_EH_PE_datarel:
+        case DW_EH_PE_funcrel:
+        case DW_EH_PE_aligned:
+        default:
+            /* not supported */
+            compilerrt_abort();
+            break;
+    }
+
+    /* then apply indirection */
+    if (encoding & DW_EH_PE_indirect) {
+        result = *((uintptr_t*)result);
+    }
+
+    *data = p;
+    return result;
+}
+
+
+/*
+ * The C compiler makes references to __gcc_personality_v0 in
+ * the dwarf unwind information for translation units that use
+ * __attribute__((cleanup(xx))) on local variables.
+ * This personality routine is called by the system unwinder
+ * on each frame as the stack is unwound during a C++ exception
+ * throw through a C function compiled with -fexceptions.
+ */
+#if __arm__
+// the setjump-longjump based exceptions personality routine has a different name
+_Unwind_Reason_Code __gcc_personality_sj0(int version, _Unwind_Action actions,
+         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
+         _Unwind_Context_t context)
+#else
+_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
+         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
+         _Unwind_Context_t context)
+#endif
+{
+    /* Since C does not have catch clauses, there is nothing to do during */
+    /* phase 1 (the search phase). */
+    if ( actions & _UA_SEARCH_PHASE ) 
+        return _URC_CONTINUE_UNWIND;
+        
+    /* There is nothing to do if there is no LSDA for this frame. */
+    const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context);
+    if ( lsda == (uint8_t*) 0 )
+        return _URC_CONTINUE_UNWIND;
+
+    uintptr_t pc = _Unwind_GetIP(context)-1;
+    uintptr_t funcStart = _Unwind_GetRegionStart(context);
+    uintptr_t pcOffset = pc - funcStart;
+
+    /* Parse LSDA header. */
+    uint8_t lpStartEncoding = *lsda++;
+    if (lpStartEncoding != DW_EH_PE_omit) {
+        readEncodedPointer(&lsda, lpStartEncoding); 
+    }
+    uint8_t ttypeEncoding = *lsda++;
+    if (ttypeEncoding != DW_EH_PE_omit) {
+        readULEB128(&lsda);  
+    }
+    /* Walk call-site table looking for range that includes current PC. */
+    uint8_t         callSiteEncoding = *lsda++;
+    uint32_t        callSiteTableLength = readULEB128(&lsda);
+    const uint8_t*  callSiteTableStart = lsda;
+    const uint8_t*  callSiteTableEnd = callSiteTableStart + callSiteTableLength;
+    const uint8_t* p=callSiteTableStart;
+    while (p < callSiteTableEnd) {
+        uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
+        uintptr_t length = readEncodedPointer(&p, callSiteEncoding);
+        uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding);
+        readULEB128(&p); /* action value not used for C code */
+        if ( landingPad == 0 )
+            continue; /* no landing pad for this entry */
+        if ( (start <= pcOffset) && (pcOffset < (start+length)) ) {
+            /* Found landing pad for the PC.
+             * Set Instruction Pointer to so we re-enter function 
+             * at landing pad. The landing pad is created by the compiler
+             * to take two parameters in registers.
+	     */
+            _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), 
+                                                (uintptr_t)exceptionObject);
+            _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
+            _Unwind_SetIP(context, funcStart+landingPad);
+            return _URC_INSTALL_CONTEXT;
+        }
+    }
+    
+    /* No landing pad found, continue unwinding. */
+    return _URC_CONTINUE_UNWIND;
+}
+
diff -Nur libunwind/src/gcc_personality_v0/int_endianness.h libunwindn/src/gcc_personality_v0/int_endianness.h
--- libunwind/src/gcc_personality_v0/int_endianness.h	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/int_endianness.h	2014-06-25 11:47:54.010002060 +0800
@@ -0,0 +1,111 @@
+/* ===-- int_endianness.h - configuration header for compiler-rt ------------===
+ *
+ *		       The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is a configuration header for compiler-rt.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_ENDIANNESS_H
+#define INT_ENDIANNESS_H
+
+#if defined(__SVR4) && defined(__sun)
+#include <sys/byteorder.h>
+
+#if defined(_BIG_ENDIAN)
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif defined(_LITTLE_ENDIAN)
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#else /* !_LITTLE_ENDIAN */
+#error "unknown endianness"
+#endif /* !_LITTLE_ENDIAN */
+
+#endif /* Solaris and AuroraUX. */
+
+/* .. */
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__minix)
+#include <sys/endian.h>
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif /* _BYTE_ORDER */
+
+#endif /* *BSD */
+
+#if defined(__OpenBSD__) || defined(__Bitrig__)
+#include <machine/endian.h>
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif /* _BYTE_ORDER */
+
+#endif /* OpenBSD and Bitrig. */
+
+/* .. */
+
+/* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the compiler (at least with GCC) */
+#if defined(__APPLE__) && defined(__MACH__) || defined(__ellcc__ )
+
+#ifdef __BIG_ENDIAN__
+#if __BIG_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#endif
+#endif /* __BIG_ENDIAN__ */
+
+#ifdef __LITTLE_ENDIAN__
+#if __LITTLE_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif
+#endif /* __LITTLE_ENDIAN__ */
+
+#endif /* Mac OSX */
+
+/* .. */
+
+#if defined(__linux__)
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif /* __BYTE_ORDER */
+
+#endif /* GNU/Linux */
+
+#if defined(_WIN32)
+
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+
+#endif /* Windows */
+
+/* . */
+
+#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
+#error Unable to determine endian
+#endif /* Check we found an endianness correctly. */
+
+#endif /* INT_ENDIANNESS_H */
diff -Nur libunwind/src/gcc_personality_v0/int_lib.h libunwindn/src/gcc_personality_v0/int_lib.h
--- libunwind/src/gcc_personality_v0/int_lib.h	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/int_lib.h	2014-06-25 11:47:54.009002060 +0800
@@ -0,0 +1,46 @@
+/* ===-- int_lib.h - configuration header for compiler-rt  -----------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is a configuration header for compiler-rt.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_LIB_H
+#define INT_LIB_H
+
+/* Assumption: Signed integral is 2's complement. */
+/* Assumption: Right shift of signed negative is arithmetic shift. */
+/* Assumption: Endianness is little or big (not mixed). */
+
+/* ABI macro definitions */
+
+#if __ARM_EABI__
+# define ARM_EABI_FNALIAS(aeabi_name, name)         \
+  void __aeabi_##aeabi_name() __attribute__((alias("__" #name)));
+# define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
+#else
+# define ARM_EABI_FNALIAS(aeabi_name, name)
+# define COMPILER_RT_ABI
+#endif
+
+/* Include the standard compiler builtin headers we use functionality from. */
+#include <limits.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <float.h>
+
+/* Include the commonly used internal type definitions. */
+#include "int_types.h"
+
+/* Include internal utility function declarations. */
+#include "int_util.h"
+
+#endif /* INT_LIB_H */
diff -Nur libunwind/src/gcc_personality_v0/int_math.h libunwindn/src/gcc_personality_v0/int_math.h
--- libunwind/src/gcc_personality_v0/int_math.h	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/int_math.h	2014-06-25 11:47:54.009002060 +0800
@@ -0,0 +1,67 @@
+/* ===-- int_math.h - internal math inlines ---------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This file is not part of the interface of this library.
+ *
+ * This file defines substitutes for the libm functions used in some of the
+ * compiler-rt implementations, defined in such a way that there is not a direct
+ * dependency on libm or math.h. Instead, we use the compiler builtin versions
+ * where available. This reduces our dependencies on the system SDK by foisting
+ * the responsibility onto the compiler.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#ifndef INT_MATH_H
+#define INT_MATH_H
+
+#ifndef __has_builtin
+#  define  __has_builtin(x) 0
+#endif
+
+#define CRT_INFINITY __builtin_huge_valf()
+
+#define crt_isinf(x) __builtin_isinf((x))
+#define crt_isnan(x) __builtin_isnan((x))
+
+/* Define crt_isfinite in terms of the builtin if available, otherwise provide
+ * an alternate version in terms of our other functions. This supports some
+ * versions of GCC which didn't have __builtin_isfinite.
+ */
+#if __has_builtin(__builtin_isfinite)
+#  define crt_isfinite(x) __builtin_isfinite((x))
+#else
+#  define crt_isfinite(x) \
+  __extension__(({ \
+      __typeof((x)) x_ = (x); \
+      !crt_isinf(x_) && !crt_isnan(x_); \
+    }))
+#endif
+
+#define crt_copysign(x, y) __builtin_copysign((x), (y))
+#define crt_copysignf(x, y) __builtin_copysignf((x), (y))
+#define crt_copysignl(x, y) __builtin_copysignl((x), (y))
+
+#define crt_fabs(x) __builtin_fabs((x))
+#define crt_fabsf(x) __builtin_fabsf((x))
+#define crt_fabsl(x) __builtin_fabsl((x))
+
+#define crt_fmax(x, y) __builtin_fmax((x), (y))
+#define crt_fmaxf(x, y) __builtin_fmaxf((x), (y))
+#define crt_fmaxl(x, y) __builtin_fmaxl((x), (y))
+
+#define crt_logb(x) __builtin_logb((x))
+#define crt_logbf(x) __builtin_logbf((x))
+#define crt_logbl(x) __builtin_logbl((x))
+
+#define crt_scalbn(x, y) __builtin_scalbn((x), (y))
+#define crt_scalbnf(x, y) __builtin_scalbnf((x), (y))
+#define crt_scalbnl(x, y) __builtin_scalbnl((x), (y))
+
+#endif /* INT_MATH_H */
diff -Nur libunwind/src/gcc_personality_v0/int_types.h libunwindn/src/gcc_personality_v0/int_types.h
--- libunwind/src/gcc_personality_v0/int_types.h	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/int_types.h	2014-06-25 11:47:54.009002060 +0800
@@ -0,0 +1,140 @@
+/* ===-- int_lib.h - configuration header for compiler-rt  -----------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is not part of the interface of this library.
+ *
+ * This file defines various standard types, most importantly a number of unions
+ * used to access parts of larger types.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_TYPES_H
+#define INT_TYPES_H
+
+#include "int_endianness.h"
+
+typedef      int si_int;
+typedef unsigned su_int;
+
+typedef          long long di_int;
+typedef unsigned long long du_int;
+
+typedef union
+{
+    di_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        su_int low;
+        si_int high;
+#else
+        si_int high;
+        su_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} dwords;
+
+typedef union
+{
+    du_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        su_int low;
+        su_int high;
+#else
+        su_int high;
+        su_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} udwords;
+
+#if __x86_64
+
+typedef int      ti_int __attribute__ ((mode (TI)));
+typedef unsigned tu_int __attribute__ ((mode (TI)));
+
+typedef union
+{
+    ti_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        du_int low;
+        di_int high;
+#else
+        di_int high;
+        du_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} twords;
+
+typedef union
+{
+    tu_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        du_int low;
+        du_int high;
+#else
+        du_int high;
+        du_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} utwords;
+
+static inline ti_int make_ti(di_int h, di_int l) {
+    twords r;
+    r.s.high = h;
+    r.s.low = l;
+    return r.all;
+}
+
+static inline tu_int make_tu(du_int h, du_int l) {
+    utwords r;
+    r.s.high = h;
+    r.s.low = l;
+    return r.all;
+}
+
+#endif /* __x86_64 */
+
+typedef union
+{
+    su_int u;
+    float f;
+} float_bits;
+
+typedef union
+{
+    udwords u;
+    double  f;
+} double_bits;
+
+typedef struct
+{
+#if _YUGA_LITTLE_ENDIAN
+    udwords low;
+    udwords high;
+#else
+    udwords high;
+    udwords low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+} uqwords;
+
+typedef union
+{
+    uqwords     u;
+    long double f;
+} long_double_bits;
+
+#endif /* INT_TYPES_H */
+
diff -Nur libunwind/src/gcc_personality_v0/int_util.c libunwindn/src/gcc_personality_v0/int_util.c
--- libunwind/src/gcc_personality_v0/int_util.c	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/int_util.c	2014-06-25 11:59:12.934977792 +0800
@@ -0,0 +1,61 @@
+/* ===-- int_util.c - Implement internal utilities --------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_util.h"
+#include "int_lib.h"
+
+/* NOTE: The definitions in this file are declared weak because we clients to be
+ * able to arbitrarily package individual functions into separate .a files. If
+ * we did not declare these weak, some link situations might end up seeing
+ * duplicate strong definitions of the same symbol.
+ *
+ * We can't use this solution for kernel use (which may not support weak), but
+ * currently expect that when built for kernel use all the functionality is
+ * packaged into a single library.
+ */
+
+#ifdef KERNEL_USE
+
+extern void panic(const char *, ...) __attribute__((noreturn));
+#ifndef _WIN32
+__attribute__((visibility("hidden")))
+#endif
+void compilerrt_abort_impl(const char *file, int line, const char *function) {
+  panic("%s:%d: abort in %s", file, line, function);
+}
+
+#elif __APPLE__
+
+/* from libSystem.dylib */
+extern void __assert_rtn(const char *func, const char *file, 
+                     int line, const char * message) __attribute__((noreturn));
+
+#ifndef _WIN32
+__attribute__((weak))
+__attribute__((visibility("hidden")))
+#endif
+void compilerrt_abort_impl(const char *file, int line, const char *function) {
+  __assert_rtn(function, file, line, "libcompiler_rt abort");
+}
+
+#else
+
+/* Get the system definition of abort() */
+#include <stdlib.h>
+
+#ifndef _WIN32
+__attribute__((weak))
+__attribute__((visibility("hidden")))
+#endif
+void compilerrt_abort_impl(const char *file, int line, const char *function) {
+  abort();
+}
+
+#endif
diff -Nur libunwind/src/gcc_personality_v0/int_util.h libunwindn/src/gcc_personality_v0/int_util.h
--- libunwind/src/gcc_personality_v0/int_util.h	1970-01-01 08:00:00.000000000 +0800
+++ libunwindn/src/gcc_personality_v0/int_util.h	2014-06-25 11:47:54.010002060 +0800
@@ -0,0 +1,29 @@
+/* ===-- int_util.h - internal utility functions ----------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This file is not part of the interface of this library.
+ *
+ * This file defines non-inline utilities which are available for use in the
+ * library. The function definitions themselves are all contained in int_util.c
+ * which will always be compiled into any compiler-rt library.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#ifndef INT_UTIL_H
+#define INT_UTIL_H
+
+/** \brief Trigger a program abort (or panic for kernel code). */
+#define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, \
+                                                 __FUNCTION__)
+
+void compilerrt_abort_impl(const char *file, int line,
+                           const char *function) __attribute__((noreturn));
+
+#endif /* INT_UTIL_H */

 

9,其他:

Apple还有自己的Blocks语法实现,以及基于Blocks的GCD(dispatch)等等。以及支持ObjectiveC-2.0语法的gnustep libobjc2运行时库等。

这些内容都可以自行查阅相关文档来尝试,有时间的话再补充吧。

Avatar_small
说:
2014年9月11日 14:35

好像 if (D.CCCIsCXX()) 这一行应该删除?
if (StaticLibgcc || isAndroid) {
if (D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");

Avatar_small
babysitting services 说:
2019年9月24日 15:45

Switching is traumatic and anything you can use to delegate a number that to-do list can certainly make things lots of easier. If it’s a person's old site, your innovative one and also both, we gives your home the latest and healthy and balanced clean with these moving cleaning up service for you to focus traveling. You continue to keep packing plus planning when we deal with the housekeeping.

Avatar_small
monthly maid service 说:
2021年9月07日 17:37

A good deal here can be to not the beginning the glass as well as dead removing all the hard fluids stain. Next you must have a fabulous window wash wand or possibly sponge along with squeegee to clean out the magnifying glaas. In order to clean out the time frame correctly have a very bucket and additionally apply a useful squirt about Dawn dishwash cleaning soap into apprx. 2-3 gallons about water. When you start to sparkling the really difficult water marks dip any wand throughout the cleaning formula and put it to all the glass while the water positions are.

Avatar_small
monthly maid service 说:
2021年9月08日 16:31

Also you can scroll down to check out reviews with particular windows cleaners by Yahoo opinions and location search facts. "Angies List" is additionally a great destination to find information on reputable corporations and purchaser testimonials. Don't hesitate to ask ones neighbors often. You will likely be surprised the best way many persons use products and services and referral marketing is always the most beneficial reference.

Avatar_small
AP 10th Social Model 说:
2022年9月10日 19:18

Social Study is most important students to all students of AP 10th Class, here we have provided the study material with solved question bank for all government and private school TM, EM, UM and HM students in chapter wise from past years old exams and we have provided the AP 10th Social Model Paper 2023 Pdf suggested by subject experts. AP 10th Social Model Paper All BSEAP 10th class regular and private course students can follow the list of chapters under SSC Social Study to practice study material with previous question bank to get a better score in summative assessment (SA) and formative assessment (FA) SA-1, SA-2, FA-1, FA-2, FA-3, FA-4 along with Assignments exams previously called Unit Test-1, Unit Test-2, Unit Test-3, Unit Test-4 and Three Months.

Avatar_small
maid services dubai 说:
2023年8月21日 20:24

In an effort to maintain real estate values, most people wish so as to do a good deep cleaning associated with a house or office constantly. However, isn't always a good practical goal brand-new home theater system. In order to carry out such a good deep maintenance, most people it is fair to rent or simply buy maintenance equipment together with products to apply at your house or office environment.

Avatar_small
house cleaning servi 说:
2023年8月21日 20:27

For you to maintain premises values, most people would love kid do an important deep cleaning to a office or house consistently. However, not necessarily always an important practical goal for many of us. In order you need to do such an important deep maintaining, most people would have to rent and buy maintaining equipment and even products to utilise inside your home or home office.

Avatar_small
SEO 说:
2023年9月05日 17:36

What a fantabulous post this has been. Never seen this kind of useful post. I am grateful to you and expect more number of posts like these. Thank you very much. EuroTogel Login

Avatar_small
seo service UK 说:
2023年12月26日 20:40

This is very interesting content! I have thoroughly enjoyed reading your points and have come to the conclusion that you are right about many of them. You are grea

Avatar_small
안전놀이터코드 说:
2024年1月08日 14:28

his is my first time i visit here. I found so many entertaining stuff in your blog, especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the leisure here! Keep up the excellent work.

Avatar_small
입플사이트추천 说:
2024年1月08日 14:57

i am out of the blue here. I discovered this board and I in discovering It genuinely supportive and it helped me out a ton. I want to introduce something back and help other people, for example, you helped me I think this is an informative post and it is very useful and knowledgeable. therefore. I would like to thank you for the efforts you have made in writing this article.

Avatar_small
퐁 이벤트 혜택 说:
2024年1月08日 15:16

The next time I read a blog, I hope that it doesnt disappoint me as much as this one. I mean, I know it was my choice to read, but I actually thought youd have something interesting to say. All I hear is a bunch of whining about something that you could fix if you werent too busy looking for attention.

Avatar_small
슈어맨 说:
2024年1月08日 15:16

This is extremely intriguing substance! I have altogether delighted in perusing your focuses and have arrived at the resolution that you are ideal about a significant number of them. You are extraordinary What a good blog you have here. Please update it more often. This topics is my interest. Thank you. . .

Avatar_small
에볼루션파워볼배팅 说:
2024年1月08日 15:31

Confusing information, immense and outlandish structure, as offer especially finished with sharp examinations and thoughts, heaps of striking information and inspiration, the two of which I require, because of offer such an incredible information here

Avatar_small
굿모닝 도메인 说:
2024年1月08日 15:34

The next time I read a blog, I hope that it doesnt disappoint me as much as this one. I mean, I know it was my choice to read, but I actually thought youd have something interesting to say. All I hear is a bunch of whining about something that you could fix if you werent too busy looking for attention.

Avatar_small
키톤 가입코드 说:
2024年1月08日 15:46

I just want to tell you that I am very new to blogging and definitely savored your page. Very likely I’m want to bookmark your website . You certainly have incredible articles. Thanks a bunch for revealing your web site.Appreciate it. Plenty of postings! https://canadiantoprxstore.com/# canada pharmacies without script

Avatar_small
아벤카지노가입코드 说:
2024年1月08日 15:48

I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.

Avatar_small
메이저놀이터순위 说:
2024年1月08日 16:12

Appreciative for the strengthening on the web diary posting! Fundamentally put your blog segment to my most esteemed blog list and will channel forward for additional updates. Basically expected to record a word to offer imperative because of you for those incredible tips.

Avatar_small
토큰게임있는사이트 说:
2024年1月08日 16:16

Took me time to read all the comments, but I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It’s always nice when you can not only be informed, but also entertained!

Avatar_small
토토사이트검증 说:
2024年1月08日 16:22

Hi I found your site by mistake when i was searching yahoo for this acne issue, I must say your site is really helpful I also love the design, its amazing!. I don’t have the time at the moment to fully read your site but I have bookmarked it and also add your RSS feeds. I will be back in a day or two. thanks for a great site.

Avatar_small
다음드먹튀검증 说:
2024年1月08日 16:29

I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.So luck to come across your excellent blog. Your blog brings me a great deal of fun.. Good luck with the site.

Avatar_small
제왕카지노 说:
2024年1月08日 16:35

Easily, the article is actually the best topic on this registry related issue. I fit in with your conclusions and will eagerly look forward to your next updates. Just saying thanks will not just be sufficient, for the fantasti c lucidity in your writing. I will instantly grab your rss feed to stay informed of any updates.

Avatar_small
안전놀이터가입 说:
2024年1月08日 16:38

I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work. Thanks for writing such a good article, I stumbled onto your blog and read a few post. I like your style of writing.

Avatar_small
카지노사이트 说:
2024年1月08日 16:52

I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work. Thanks for writing such a good article, I stumbled onto your blog and read a few post. I like your style of writing.

Avatar_small
온카스쿨 说:
2024年1月08日 17:02

I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work. Thanks for writing such a good article, I stumbled onto your blog and read a few post. I like your style of writing.

Avatar_small
메이저놀이터 说:
2024年1月08日 17:05

Took me time to read all the comments, but I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It’s always nice when you can not only be informed, but also entertained!

Avatar_small
꽁머니 说:
2024年1月08日 17:13

I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.

Avatar_small
먹튀사이트 说:
2024年1月08日 17:17

The next time I read a blog, I hope that it doesnt disappoint me as much as this one. I mean, I know it was my choice to read, but I actually thought youd have something interesting to say. All I hear is a bunch of whining about something that you could fix if you werent too busy looking for attention.

Avatar_small
보증업체 说:
2024年1月08日 17:32

Yes i am totally agreed with this article and i just want say that this article is very nice and very informative article.I will make sure to be reading your blog more. You made a good point but I can't help but wonder, what about the other side? !!!!!!THANKS!!!!! ntegrate AI-driven characters and dialogues to enhance user experiences in gaming applications

Avatar_small
동행복권로또 说:
2024年1月08日 17:40

There are a few fascinating points at some point in this post but I do not determine if I see all of them center to heart. There is some validity but I most certainly will take hold opinion until I take a look at it further. Good write-up , thanks so we want much more! Added to FeedBurner also

Avatar_small
메이저놀이터 说:
2024年1月08日 17:42

I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.

Avatar_small
사설토토 说:
2024年1月08日 17:50

i am out of the blue here. I discovered this board and I in discovering It genuinely supportive and it helped me out a ton. I want to introduce something back and help other people, for example, you helped me I think this is an informative post and it is very useful and knowledgeable. therefore. I would like to thank you for the efforts you have made in writing this article.

Avatar_small
에볼루션게이밍 说:
2024年1月08日 18:01

Awesome site you have here but I was curious if you knew of any message boards that cover the same topics talked about here? I’d really like to be a part of group where I can get opinions from other experienced people that share the same interest. If you have any suggestions, please let me know. Bless you!

Avatar_small
먹튀사이트 说:
2024年1月08日 18:02

Appreciative for the strengthening on the web diary posting! Fundamentally put your blog segment to my most esteemed blog list and will channel forward for additional updates. Basically expected to record a word to offer imperative because of you for those incredible tips.

Avatar_small
먹튀검증 说:
2024年1月08日 18:11

Appreciative for the strengthening on the web diary posting! Fundamentally put your blog segment to my most esteemed blog list and will channel forward for additional updates. Basically expected to record a word to offer imperative because of you for those incredible tips.

Avatar_small
파워볼놀이터 说:
2024年1月08日 18:19

Confusing information, immense and outlandish structure, as offer especially finished with sharp examinations and thoughts, heaps of striking information and inspiration, the two of which I require, because of offer such an incredible information here

Avatar_small
먹튀와이가입 说:
2024年1月08日 18:28

his is my first time i visit here. I found so many entertaining stuff in your blog, especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the leisure here! Keep up the excellent work.

Avatar_small
메이저놀이터 说:
2024年1月08日 18:36

My spouse and am enjoy your blog and locate the vast majority of your post’s to be able to be what exactly I’m searching for. can you present guest writers to compose content for you? We wouldn’t mind producing the post or elaborating upon some the subjects jots down concerning here. Once again, awesome weblog!

Avatar_small
카지노게임사이트 说:
2024年1月08日 18:45

My spouse and am enjoy your blog and locate the vast majority of your post’s to be able to be what exactly I’m searching for. can you present guest writers to compose content for you? We wouldn’t mind producing the post or elaborating upon some the subjects jots down concerning here. Once again, awesome weblog!

Avatar_small
카지노게임사이트 说:
2024年1月08日 18:46

My spouse and am enjoy your blog and locate the vast majority of your post’s to be able to be what exactly I’m searching for. can you present guest writers to compose content for you? We wouldn’t mind producing the post or elaborating upon some the subjects jots down concerning here. Once again, awesome weblog!

Avatar_small
메이저놀이터 순위 说:
2024年1月08日 18:48

My spouse and am enjoy your blog and locate the vast majority of your post’s to be able to be what exactly I’m searching for. can you present guest writers to compose content for you? We wouldn’t mind producing the post or elaborating upon some the subjects jots down concerning here. Once again, awesome weblog!

Avatar_small
인터넷바카라 说:
2024年1月08日 18:54

Hey would you mind sharing which blog platform you’re working with? I’m planning to start my own blog soon but I’m having a difficult time selecting between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your layout seems different then most blogs and I’m looking for something unique. P.S Sorry for getting off-topic but I had to ask!|

Avatar_small
홀덤사이트순위 说:
2024年1月08日 19:04

Verygood nice paost. I just stumbled upon ayour weblog and wished to say that I’ve really enjoyed surfing around your blog posts. After all I will be subscribing to your feed and I hope you write again very soon!Some times its a pain in the ass to read wh

Avatar_small
แนะนำ เว็บไซต์บาคาร่ 说:
2024年1月08日 19:12

Pleased to meet up with you! My title is Shonda and I enjoy it. Doing magic is what she enjoys performing. He is at the moment a production and distribution officer but he strategies on modifying it. Some time in the earlier he chose to stay in Louisiana.

Avatar_small
꽁머니토토 说:
2024年1月08日 19:19

Hello there, There’s no doubt that your site could be having web browser compatibility problems. Whenever I take a look at your site in Safari, it looks fine however, when opening in Internet Explorer, it has some overlapping issues. I just wanted to provide you with a quick heads up! Aside from that, excellent blog!

Avatar_small
먹튀검증 说:
2024年1月20日 14:39

A very Wonderful blog. We believe that you have a busy, active lifestyle and also understand you need marijuana products from time to time. We’re ICO sponsored and in collaboration with doctors, deliveries, storefronts and deals worldwide, we offer a delivery service – rated #1 in the cannabis industry – to bring weed strains straight to you, discretely by our men on ground.

Avatar_small
카지노사이트 说:
2024年1月20日 15:39

I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good wor

Avatar_small
카지노 说:
2024年1月20日 16:10

I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good wor

Avatar_small
슬롯커뮤니티 说:
2024年1月20日 16:57

Dae-ho and I have been friends and rivals since we were little. We're both professional ball players and I think he'll want to win as much as I do

Avatar_small
카지노사이트 说:
2024年1月20日 17:12

I read a article under the same title some time ago, but this articles quality is much, much better. How you do this..

Avatar_small
머니맨 说:
2024年1月20日 17:44

Wow, What an Outstanding post. I found this too much informatics. It is what I was seeking for

Avatar_small
바카라 사이트 说:
2024年1月20日 18:23

This is the reason it really is greater you could important examination before creating. It will be possible to create better write-up like this.

Avatar_small
온라인카지노 说:
2024年1月20日 19:16

I am hoping the same best effort from you in the future as well. In fact your creative writing skills has inspired me

Avatar_small
먹튀검증 说:
2024年1月20日 19:57

Will surely come and visit this blog more often. Thanks for sharing.

Avatar_small
슬롯사이트 说:
2024年1月20日 20:36

Great survey, I'm sure you're getting a great response

Avatar_small
industrial outdoor s 说:
2024年1月20日 21:16

I went over this website and I believe you have a lot of wonderful information, saved to my bookmarks

Avatar_small
카지노사이트 说:
2024年1月21日 13:32

Thanks for another wonderful post. Where else could anybody get that type of info in such an ideal way of writing?

Avatar_small
소액결제현금화 说:
2024年1月21日 14:03

Thankyou for this wondrous post, I am glad I observed this website on yahoo.

Avatar_small
스포츠무료중계 说:
2024年1月21日 15:50

Good to become visiting your weblog again, it has been months for me. Nicely this article that i've been waited for so long. I will need this post to total my assignment in the college, and it has exact same topic together with your write-up. Thanks, good share.

Avatar_small
카지노커뮤니티 说:
2024年1月21日 16:35

"Great post. I was checking constantly this blog and I’m impressed!
Very useful info particularly the last part

Avatar_small
하노이 유흥 说:
2024年1月26日 12:32

하노이 꼭 가봐야 할 베스트 업소 추천 안내 및 예약, 하노이 밤문화 에 대해서 정리해 드립니다. 하노이 가라오케, 하노이 마사지, 하노이 풍선바, 하노이 밤문화를 제대로 즐기시기 바랍니다. 하노이 밤문화 베스트 업소 요약 베스트 업소 추천 및 정리.

Avatar_small
카지노사이트 说:
2024年1月26日 12:34

카지노사이트 바카라사이트 우리카지노 카지노는 바카라, 블랙잭, 룰렛 및 슬롯 등 다양한 게임을 즐기실 수 있는 공간입니다. 게임에서 승리하면 큰 환호와 함께 많은 당첨금을 받을 수 있고, 패배하면 아쉬움과 실망을 느끼게 됩니다.

Avatar_small
먹튀사이트 说:
2024年1月29日 11:41

No.1 먹튀검증 사이트, 먹튀사이트, 검증사이트, 토토사이트, 안전사이트, 메이저사이트, 안전놀이터 정보를 제공하고 있습니다. 먹튀해방으로 여러분들의 자산을 지켜 드리겠습니다. 먹튀검증 전문 커뮤니티 먹튀클린만 믿으세요!!

Avatar_small
베트남 유흥 说:
2024年1月29日 11:44

베트남 남성전용 커뮤니티❣️ 베트남 하이에나 에서 베트남 밤문화를 추천하여 드립니다. 베트남 가라오케, 베트남 VIP마사지, 베트남 이발관, 베트남 황제투어 남자라면 꼭 한번은 경험 해 봐야할 화끈한 밤문화로 모시겠습니다.

Avatar_small
홈타이 说:
2024年1月29日 14:00

This is such a great resource that you are providing and you give it away for free

Avatar_small
무료스포츠중계 说:
2024年1月29日 14:13

I really like your take on the issue. I now have a clear idea on what this matter is all about..

Avatar_small
토토사이트 说:
2024年1月29日 14:26

This could be the right blog for everyone who is desires to be familiar with this topic. You already know much its practically not easy to argue along (not that I just would want…HaHa). You certainly put the latest spin with a topic thats been discussing for decades. Excellent stuff, just great!


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter