C++学习(三九四)relocation R_AARCH64_ADR_PREL_PG_HI21 undefined reference to `__dso_handle‘

在Android环境下编译C++代码时遇到`undefined reference to `__dso_handle'`错误,原因是缺少`-fPIC`编译选项。解决方案包括在源码中添加`extern "C"{ void * __dso_handle = 0 ;}`或者在编译选项中增加`-fno-use-cxa-atexit`。另外,修改libtool的配置,避免使用`nostdlib`选项,确保生成动态链接库。成功编译的关键在于正确设置编译选项和链接参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误原因:geotiff.cpp使用了static std::mutex oDeleteMutex;将其注释掉即正常。将getotiff.cpp改为如下进行编译和链接,仍会报错。

#include <mutex>

std::mutex oDeleteMutex;

如果换成如下则可成功

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -g -O2  -Wall  -fPIC -c -o gt_wkt_srs.lo gt_wkt_srs.cpp

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gcore -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gnm -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/apps -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wshorten-64-to-32 -Wshadow -Werror=vla -Wdate-time -Wnull-dereference -Wextra-semi -Wcomma -Wfloat-conversion -Wdocumentation -Wno-documentation-deprecated-sync -Wunused-private-field -Wmissing-prototypes -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wimplicit-fallthrough  -fno-use-cxa-atexit -I..  -I../jpeg -DHAVE_LIBJPEG -I../jpeg/libjpeg   -DINTERNAL_LIBGEOTIFF -Ilibgeotiff -DINTERNAL_LIBTIFF -Ilibtiff -DBIGTIFF_SUPPORT -DGNM_ENABLED -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port  -DGDAL_COMPILATION -c -o gt_wkt_srs.lo gt_wkt_srs.cpp


 
  /bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.la e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/frmts/gtiff/gt_wkt_srs.lo

经对比,是rpath的原因,删除掉就可以了,修改这个值不可以;将其改为相对路径也不可以(报错error: only absolute run-paths are allowed)。去掉rpath后将不会生成动态链接库了。

是libtool链接时出问题了,如果用clang++命令直接生成动态链接库,则没有问题。libtool中使用了nostdlib选项。

D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ gt_wkt_srs.o -shared -fPIC -o libgdal.so

在使用动态库时也不会出现C++学习(四零四)中的问题。

libtool文件中有如下两句话:

archive_cmds="\$CC \$pic_flag -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \$wl-soname \$wl\$soname -o \$lib"
archive_expsym_cmds="\$CC \$pic_flag -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \$wl-soname \$wl\$soname \$wl-retain-symbols-file \$wl\$export_symbols -o \$lib"

其它解决办法:

1、在gt_wkt_srs.cpp前添加extern "C"{ void * __dso_handle = 0 ;},重新编译链接,正常设置rpath即可生成动态库和静态库。缺点是需要修改每一个相关的cpp文件。

__dso_handle是glibc的一个函数,有诸如增加extern C{ void * __dso_handle = 0 ;}这样的解决办法。

2、在编译选项中增加-fno-use-cxa-atexit,这会造成应用在链接时有问题C++学习(四零四)hidden symbol `atexit‘ in XXX is referenced by DSOhttps://mp.csdn.net/mp_blog/creation/editor/121068290

有可能是cpp的原因(并不是)

E:\osg-osgearth-source\other_3rdParty\gdal-2.3.2\frmts\gtiff/geotiff.cpp:106: undefined reference to `__dso_handle'

geotiff.cpp没有__dso_handle

D:\android-ndk-r19c\toolchains\llvm\prebuilt\windows-x86_64\bin/../lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin\ld: e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/frmts/o/.libs/geotiff.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against external symbol `__dso_handle' can not be used when making a shared object; recompile with -fPIC

__dso_handle句柄是一个“guard”,用于在全局销毁期间识别动态共享对象。

如果您试图通过弄乱__dso_handle句柄来挫败对象识别,那么很可能是出了什么问题。

问题原因:

动态链接器在共享库中找不到此符号(__dso_handle)

解决办法:

extern "C"{ void * __dso_handle = 0 ;}

在gdal-2.3.2\frmts\gtiff\libtiff\dump_symbols.sh中找到这么一句话

data_symbol_list=$(objdump -t libtiff.so  | grep "\.data"  | grep -v __dso_handle | grep -v __TMC_END__ |  awk '{print $6}' | grep -v "\.")
for symbol in $data_symbol_list
do
    echo "#define $symbol gdal_$symbol" >> $OUT_FILE
done

执行

D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-objdump.exe  -t geotiff.o | grep "\.data"  | grep -v __dso_handle | grep -v __TMC_END__ |  awk '{print $6}' | grep -v "\.">aa.txt

结果为

_ZL10asTIFFTags
_ZTI12GTiffDataset
_ZTI13GTiffRGBABand
_ZTI14GTiffSplitBand
_ZTI15GTiffBitmapBand
_ZTI15GTiffRasterBand
_ZTI16GTiffOddBitsBand
_ZTI19GTiffJPEGOverviewDS
_ZTI20GTiffSplitBitmapBand
_ZTI21GTiffJPEGOverviewBand
_ZTV12GTiffDataset
_ZTV13GTiffRGBABand
_ZTV14GTiffSplitBand
_ZTV15GTiffBitmapBand
_ZTV15GTiffRasterBand
_ZTV16GTiffOddBitsBand
_ZTV19GTiffJPEGOverviewDS
_ZTV20GTiffSplitBitmapBand
_ZTV21GTiffJPEGOverviewBand

geotiff.o的反汇编D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-objdump.exe -d geotiff.o >aa.txt

Disassembly of section .text.startup:

0000000000000000 <_GLOBAL__sub_I_geotiff.cpp>:
   0:	a9be4ff4 	stp	x20, x19, [sp,#-32]!
   4:	a9017bfd 	stp	x29, x30, [sp,#16]
   8:	910043fd 	add	x29, sp, #0x10
   c:	90000013 	adrp	x19, 0 <_ZNSt6__ndk15mutexD1Ev>
  10:	f9400273 	ldr	x19, [x19]
  14:	90000014 	adrp	x20, 0 <__dso_handle>
  18:	90000001 	adrp	x1, 0 <_GLOBAL__sub_I_geotiff.cpp>
  1c:	91000294 	add	x20, x20, #0x0
  20:	91000021 	add	x1, x1, #0x0
  24:	aa1303e0 	mov	x0, x19
  28:	aa1403e2 	mov	x2, x20
  2c:	94000000 	bl	0 <__cxa_atexit>
  30:	a9417bfd 	ldp	x29, x30, [sp,#16]
  34:	90000001 	adrp	x1, 0 <_GLOBAL__sub_I_geotiff.cpp>
  38:	91000021 	add	x1, x1, #0x0
  3c:	aa1303e0 	mov	x0, x19
  40:	aa1403e2 	mov	x2, x20
  44:	a8c24ff4 	ldp	x20, x19, [sp],#32
  48:	14000000 	b	0 <__cxa_atexit>

查看段信息D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-objdump.exe -h geotiff.o >aa.txt

Idx Name          Size      VMA               LMA               File off  Algn
97 .text.startup 0000004c  0000000000000000  0000000000000000  00025a90  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

查看段信息D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-readelf.exe -S geotiff.o >aa.txt

[Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align  
[136] .text.startup     PROGBITS         0000000000000000  00025a90
       000000000000004c  0000000000000000  AX       0     0     4

查看符号,D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-objdump.exe -t geotiff.o >aa.txt

0000000000000000         *UND*	0000000000000000 .hidden __dso_handle

以下方法不可以:

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gcore -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gnm -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/apps -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wshorten-64-to-32 -Wshadow -Werror=vla -Wdate-time -Wnull-dereference -Wextra-semi -Wcomma -Wfloat-conversion -Wdocumentation -Wno-documentation-deprecated-sync -Wunused-private-field -Wmissing-prototypes -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wimplicit-fallthrough  -I..  -I../jpeg -DHAVE_LIBJPEG -I../jpeg/libjpeg   -DINTERNAL_LIBGEOTIFF -Ilibgeotiff -DINTERNAL_LIBTIFF -Ilibtiff -DBIGTIFF_SUPPORT -DGNM_ENABLED -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port  -DGDAL_COMPILATION -c -o geotiff.lo geotiff.cpp

修改gdal根目录下的GDALmake.opt,在CXXFLAGS中增加-fPIC,在CFLAGS中增加-fPIC

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gcore -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gnm -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/apps -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wshorten-64-to-32 -Wshadow -Werror=vla -Wdate-time -Wnull-dereference -Wextra-semi -Wcomma -Wfloat-conversion -Wdocumentation -Wno-documentation-deprecated-sync -Wunused-private-field -Wmissing-prototypes -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wimplicit-fallthrough  -fPIC -I..  -I../jpeg -DHAVE_LIBJPEG -I../jpeg/libjpeg   -DINTERNAL_LIBGEOTIFF -Ilibgeotiff -DINTERNAL_LIBTIFF -Ilibtiff -DBIGTIFF_SUPPORT -DGNM_ENABLED -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port  -DGDAL_COMPILATION -c -o geotiff.lo geotiff.cpp

成功
/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.la ./ogr/gml2ogrgeometry.lo  -rpath /cygdrive/E/Projects/QT5.12/osg_earth_android_build/3rdpartyAndroid/gdal/obj/local/armeabi-v8a/lib  -no-undefined  -version-info 24:2:4

gml2ogrgeometry.lo是如下方法生成的

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gcore -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gnm -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/apps -Wold-style-cast -DHAVE_MITAB -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wshorten-64-to-32 -Wshadow -Werror=vla -Wdate-time -Wnull-dereference -Wextra-semi -Wcomma -Wfloat-conversion -Wdocumentation -Wno-documentation-deprecated-sync -Wunused-private-field -Wmissing-prototypes -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wimplicit-fallthrough  -Iogrsf_frmts -Iogrsf_frmts/mem -Iogrsf_frmts/geojson -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts/geojson/libjson -I.    -DGNM_ENABLED -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port  -DGDAL_COMPILATION -I../frmts/zlib -c -o gml2ogrgeometry.lo gml2ogrgeometry.cpp

失败
/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.la e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/frmts/o/geotiff.lo  -rpath /cygdrive/E/Projects/QT5.12/osg_earth_android_build/3rdpartyAndroid/gdal/obj/local/armeabi-v8a/lib  -no-undefined  -version-info 24:2:4

如果改为生成静态库则能成功

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.a e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/frmts/o/geotiff.lo  -rpath /cygdrive/E/Projects/QT5.12/osg_earth_android_build/3rdpartyAndroid/gdal/obj/local/armeabi-v8a/lib  -no-undefined  -version-info 24:2:4

失败
/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.la ./ogr/gml2ogrgeometry.lo e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/frmts/o/geotiff.lo  -rpath /cygdrive/E/Projects/QT5.12/osg_earth_android_build/3rdpartyAndroid/gdal/obj/local/armeabi-v8a/lib  -no-undefined  -version-info 24:2:4 -Wl,--no-undefined -Wl,-z,noexecstack -shared -Wl -llog -lz -lm -ldl

成功

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.la e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/frmts/o/gt_citation.lo  -rpath /cygdrive/E/Projects/QT5.12/osg_earth_android_build/3rdpartyAndroid/gdal/obj/local/armeabi-v8a/lib  -no-undefined  -version-info 24:2:4

geotiff.cpp和gt_citation.cpp同样的配方不一样的味道(gt_citation.lo能link成功)

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gcore -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gnm -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/apps -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wshorten-64-to-32 -Wshadow -Werror=vla -Wdate-time -Wnull-dereference -Wextra-semi -Wcomma -Wfloat-conversion -Wdocumentation -Wno-documentation-deprecated-sync -Wunused-private-field -Wmissing-prototypes -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wimplicit-fallthrough  -I..  -I../jpeg -DHAVE_LIBJPEG -I../jpeg/libjpeg   -DINTERNAL_LIBGEOTIFF -Ilibgeotiff -DINTERNAL_LIBTIFF -Ilibtiff -DBIGTIFF_SUPPORT -DGNM_ENABLED -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port  -DGDAL_COMPILATION -c -o geotiff.lo geotiff.cpp
/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=compile --silent --tag=CXX D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++ -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gcore -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/ogr/ogrsf_frmts -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/gnm -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/apps -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wshorten-64-to-32 -Wshadow -Werror=vla -Wdate-time -Wnull-dereference -Wextra-semi -Wcomma -Wfloat-conversion -Wdocumentation -Wno-documentation-deprecated-sync -Wunused-private-field -Wmissing-prototypes -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wimplicit-fallthrough  -I..  -I../jpeg -DHAVE_LIBJPEG -I../jpeg/libjpeg   -DINTERNAL_LIBGEOTIFF -Ilibgeotiff -DINTERNAL_LIBTIFF -Ilibtiff -DBIGTIFF_SUPPORT -DGNM_ENABLED -Ie:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/port  -DGDAL_COMPILATION -c -o gt_citation.lo gt_citation.cpp

错误是在执行以下link语句时遇到的

/bin/sh e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/libtool --mode=link --silent D:/android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android28-clang++    -lm -ldl                    -o libgdal.la ./ogr/gml2ogrgeometry.lo ./ogr/ogr2gmlgeometry.lo ./ogr/ogr_api.lo ./ogr/ogr_expat.lo ./ogr/ogr_fromepsg.lo ./ogr/ogr_geo_utils.lo ./ogr/ogr_geocoding.lo ./ogr/ogr_opt.lo ./ogr/ogr_srs_dict.lo ./ogr/ogr_srs_erm.lo ./ogr/ogr_srs_esri.lo ./ogr/ogr_srs_ozi.lo ./ogr/ogr_srs_panorama.lo ./ogr/ogr_srs_pci.lo ./ogr/ogr_srs_proj4.lo ./ogr/ogr_srs_usgs.lo ./ogr/ogr_srs_validate.lo ./ogr/ogr_srs_xml.lo ./ogr/ogr_srsnode.lo ./ogr/ogr_xerces.lo ./ogr/ograpispy.lo ./ogr/ograssemblepolygon.lo ./ogr/ogrcircularstring.lo ./ogr/ogrcompoundcurve.lo ./ogr/ogrct.lo ./ogr/ogrcurve.lo ./ogr/ogrcurvecollection.lo ./ogr/ogrcurvepolygon.lo ./ogr/ogrfeature.lo ./ogr/ogrfeaturedefn.lo ./ogr/ogrfeaturequery.lo ./ogr/ogrfeaturestyle.lo ./ogr/ogrfielddefn.lo ./ogr/ogrgeomediageometry.lo ./ogr/ogrgeometry.lo ./ogr/ogrgeometrycollection.lo ./ogr/ogrgeometryfactory.lo ./ogr/ogrgeomfielddefn.lo ./ogr/ogrlinearring.lo ./ogr/ogrlinestring.lo ./ogr/ogrmulticurve.lo ./ogr/ogrmultilinestring.lo ./ogr/ogrmultipoint.lo ./ogr/ogrmultipolygon.lo ./ogr/ogrmultisurface.lo ./ogr/ogrpgeogeometry.lo ./ogr/ogrpoint.lo ./ogr/ogrpolygon.lo ./ogr/ogrpolyhedralsurface.lo ./ogr/ogrspatialreference.lo ./ogr/ogrsurface.lo ./ogr/ogrtriangle.lo ./ogr/ogrtriangulatedsurface.lo ./ogr/ogrutils.lo ./ogr/osr_cs_wkt.lo ./ogr/osr_cs_wkt_parser.lo ./ogr/swq.lo ./ogr/swq_expr_node.lo ./ogr/swq_op_general.lo ./ogr/swq_op_registrar.lo ./ogr/swq_parser.lo ./ogr/swq_select.lo e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg/contour.lo e:/osg-osgearth-source/other_3rdParty/gdal-2.3.2/alg/delaunay.lo e:/osg-osgearth-source/other_3r

<think>好的,我现在需要解决用户提出的关于AArch64架构中R_AARCH64_ADR_PREL_PG_HI21重定位错误以及.bss段相关的截断问题。用户提到了引用中的几个情况,我需要结合这些信息来找到解决方法。 首先,用户提供的引用[1]提到,旧的uboot(2019.04之前)只能处理21位的重定位,导致代码段超过1MB就会报错。解决方法是通过4K对齐,利用高位计算重定位,实现32位寻址。这涉及到修改start.S和relocate_64.S文件。这说明可能需要调整代码段的对齐方式或者重定位的计算方法。 引用[2]指出问题明确是由ADRP指令引起的,而ADRP指令在AArch64中用于生成地址的高位部分,结合ADD等指令形成完整地址。如果地址偏移超过ADRP能表示的范围(±4GB),就会导致重定位错误。这可能意味着代码或数据的位置超出了ADRP指令的寻址范围,需要调整内存布局或使用不同的指令。 引用[3]提到AArch64虽然有64位的相对PC寻址指令,但缺少对应的重定位方式,导致链接器无法正确处理某些情况。这可能涉及到工具链的支持问题,需要检查编译器或链接器的版本,或者使用特定的编译选项。 接下来,我需要将这些信息整合起来,形成解决方案。可能的步骤包括: 1. **检查工具链版本**:确保使用的编译器、链接器版本较新,支持AArch64的更大地址范围。 2. **调整内存布局**:确保.bss段或其他相关段的位置在ADRP指令的寻址范围内,可能需要修改链接脚本,将关键段放置在4GB范围内。 3. **代码段对齐**:按照引用[1]的建议,将代码段4K对齐,从而允许使用高位地址计算,扩展寻址范围。 4. **修改重定位代码**:在start.S和relocate_64.S中调整重定位的逻辑,使用高位计算方式,避免截断。 5. **替换ADRP指令**:如果可能,使用LDR指令结合文字池(literal pool)来加载大地址,避免依赖ADRP的寻址限制。 6. **链接脚本优化**:在链接脚本中明确分配.bss段的位置,避免其超出ADRP的寻址范围,或者调整段的对齐方式。 需要验证这些步骤的有效性。例如,在修改链接脚本时,可能需要将.bss段放置在靠近代码段的位置,或者确保其地址在±4GB范围内。同时,代码中的ADRP指令如果引用了超出范围的符号,可能需要替换为其他寻址方式,或者调整符号的位置。 另外,可能需要查阅更多关于AArch64重定位类型的文档,了解R_AARCH64_ADR_PREL_PG_HI21的具体限制和处理方法。比如,该重定位类型是否允许更大的偏移,或者是否有其他重定位类型可以替代。 最后,可能需要实际编译和链接代码,观察错误是否解决,并根据调试信息进一步调整。例如,使用编译选项-ffunction-sections和-fdata-sections来优化段的分布,或者使用链接器选项--fix-cortex-a53-843419来应对特定的处理器问题,虽然这可能不直接相关,但有时能提供线索。</think>### 解决R_AARCH64_ADR_PREL_PG_HI21重定位截断问题的分步方法 #### 问题本质 此错误由AArch64架构的`ADRP`指令寻址范围限制引发,当`.bss`段或其他关键段与代码段距离超过`ADRP`指令的4GB寻址范围时,会导致重定位失败[^2][^3]。 --- #### 解决方案 1. **调整链接脚本(关键步骤)** - **目标**:确保`.bss`段与代码段距离在4GB范围内。 - **修改方法**:在链接脚本中强制指定`.bss`段紧邻代码段: ```ld .bss : { __bss_start = .; *(.bss*) __bss_end = .; } >RAM AT>RAM ``` 添加`>RAM AT>RAM`约束内存区域连续性[^1]。 2. **代码段4K对齐优化** - **原理**:4K对齐后,低位地址可忽略,利用高位地址扩展寻址范围。 - **修改文件**:`arch/arm/cpu/armv8/start.S` ```asm .align 12 /* 4K对齐 */ _start: ... ``` 3. **重定位逻辑修正** - **修改文件**:`arch/arm/lib/relocate_64.S` ```asm ldr x0, =__rel_dyn_start ldr x1, =__rel_dyn_end sub x2, x1, x0 lsr x2, x2, #3 /* 右移3位,实现高位寻址计算 */ ``` 4. **替代ADRP指令(可选)** - **使用文字池加载地址**: ```asm ldr x0, =symbol_name // 替代ADRP+ADD组合 ``` --- #### 验证方法 1. 使用`aarch64-linux-gnu-objdump -d u-boot`检查`.bss`段与代码段偏移 2. 观察编译日志是否出现`relocation truncated`警告 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值