前言:所有踩过的坑,都是前进的必须;进坑并不可怕,训练一种脱坑的思维和办法才“可怕”。
最近在Ubuntu做项目移植,用gcc、g++编译程序,总是卡在一个出错的地方:
/usr/bin/ld: 2: Syntax error: newline unexpected collect2: error: ld returned 2 exit status
开始还怀疑是程序的问题,后来感觉是这个ld不正常;因为之前没有遇到过此类的问题,而且对这个ld比较陌生,仅仅知道是个链接器。
好歹做过逆向,对于逆向人员遇到问题的直接反应,可能就是“砸烂这个旧世界”,看看里边究竟什么鬼在作祟:
//ld 为何报的是语法错误?????
先看看这个ld是个什么鬼:
linux的迷人之处,或许binutils组件库是其一,这个东西里边提供了许多可以对文件动手术的工具,file就是一个。
file /usr/bin/ld /usr/bin/ld: symbolic link to x86_64-linux-gnu-ld
其实就是GNU的标准链接器,但是还不清楚这个文件的格式;
接下来,看看报错的字符串在不在ld中:
strings /usr/bin/ld ! / 0 0 0 0 39634 ` }Z_ZN5E ……
好像不太对,里边有奇怪的字符。
其实ld就是个脚本文件,那不如看看脚本究竟问题出在哪里:
/usr/bin/ld verbose usr/bin/ld 1 : 非法字符串,
这里基本确定就是ld文件出错了,这个链接器脚本被篡改了。恍然想起来,之前用“Xlinker”参数把错误的文件当作链接脚本了,导致默认的ld脚本被冲刷了;这是问题的根本原因。
既然找到了原因,其实解决起来很简单,卸载这个ld重新安装一个不就可以了么?这里就是简单的linux命令操作了;但是一番操作后,问题并没有改变。
这时,意识到:是不是这个 “sudo apt install --reinstall binutils“是不是用的不对?还是本身这个ld安装中需要初始化,初始化数据却存在系统不知道的地方?其实到这里,基本可以重做系统了。如果有虚拟机的话可能相对轻松一些,但我是实机;或许重新编译一个内核也可以,这个我没试过。
重装系统,查看ld,一切正常了:
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
.lbss :
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(ConSTANT (MAXPAGESIZE)) + (. & (ConSTANT (MAXPAGESIZE) - 1)) :
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
.ldata ALIGN(ConSTANT (MAXPAGESIZE)) + (. & (ConSTANT (MAXPAGESIZE) - 1)) :
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
其实,在这个过程中,翻了一下ld的官方文档,算是对ld有个进一步的了解,同时也了解了如何自己动手写链接器脚本。这也算是linux系统的乐趣之一,和不同之处。



