0. 概况
本文记录了gdb交叉编译的流程,其中也包含texinfo的交叉编译。解决了一些编译问题,以及MIPS平台下unrecognized real-time signal问题。arm平台换下工具链即可。
1. 下载最新源码
wget http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
2. 解压
tar xzvf gdb-10.2.tar.gz
cd gdb-10.2
mkdir build
3. 配置
会提示没有Makefileinfo,
安装texinfo,有sudo权限,直接apt安装即可;否则要使用源码安装
3.1 glibc
CC=mips-linux-gnu-gcc ./configure --target=mips-linux-gnu --host=mips-linux-gnu --prefix=/home_a/xxx/test/gdb-10.2/build/
3.2 uclibc
CC=mips-linux-gnu-gcc CFLAGS="-O2 -muclibc" CPPFLAGS="-O2 -muclibc" CXXFLAGS="-O2 -muclibc" LDFLAGS="-O2 -muclibc" ./configure --target=mips-linux-gnu --host=mips-linux-gnu --prefix=/home_a/xxx/test/gdb-10.2/build/
4. 编译、安装
make -j16
make install
5. 问题
5.1 提示没有Makefileinfo
wget http://ftp.gnu.org/gnu/texinfo/texinfo-6.7.tar.gz
tar xzvf texinfo-6.7.tar.gz
cd texinfo-6.7
./configure --prefix=/home_a/wlli/bin
make -j16
make install
//设置texinfo的环境变量
5.2 编译glibc时没什么问题,uclibc会出现几个问题,解决方法如下
问题1
getprogname.c:249:4: error: #error "getprogname module not ported to this OS"
# error "getprogname module not ported to this OS"
打开出错文件
❯ find -name "getprogname.c"
vim gnulib/import/getprogname.c
由
#include "dirname.h"
#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
char const *
getprogname (void)
{
# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
return program_invocation_short_name;
# elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */
改为
#include "dirname.h"
#define MIPS 1
#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
char const *
getprogname (void)
{
# if MIPS
char strProcessPath[1024] = {0};
if(readlink("/proc/self/exe", strProcessPath,1024) <=0)
{
return NULL;
}
char *strProcessName = strrchr(strProcessPath, '/');
if(strProcessName)
{
size_t nameLen = strlen(strProcessName);
char* namecopy = malloc(nameLen + 1);
if (namecopy)
{
namecopy[nameLen] = 0;
return memcpy(namecopy, strProcessName, nameLen);
}
}
return NULL;
# elif HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
return program_invocation_short_name;
# elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */
接着执行make -j16
问题2
接着迎来第二个问题
dwarf2/index-write.c: In member function 'void debug_names::build()':
dwarf2/index-write.c:780:37: error: 'log2' is not a member of 'std'
(std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
^~~~
dwarf2/index-write.c:780:37: note: suggested alternative: 'log'
(std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
打开出错文件
find -name "index-write.c"
vim gdb/dwarf2/index-write.c
把所有的log2改为log
接着执行make -j16
问题3
接着又迎来第三个问题
ada-lang.o: In function `ada_clear_symbol_cache()':
ada-lang.c:(.text+0x1708): undefined reference to `_obstack_free'
ada-lang.o: In function `ada_lookup_symbol_list_worker(lookup_name_info const&, block const*, domain_enum_tag, std::vector<block_symbol, std::allocator<block_symbol> >*, int)':
ada-lang.c:(.text+0x8590): undefined reference to `_obstack_free'
ada-lang.c:(.text+0x8d78): undefined reference to `_obstack_free'
ada-lang.o: In function `program_space_key<ada_pspace_data, std::default_delete<ada_pspace_data> >::cleanup(program_space*, void*)':
ada-lang.c:(.text._ZN17program_space_keyI15ada_pspace_dataSt14default_deleteIS0_EE7cleanupEP13program_spacePv[_ZN17program_space_keyI15ada_pspace_dataSt14default_deleteIS0_EE7cleanupEP13program_spacePv]+0x28): undefined reference to `_obstack_free'
dwarf2/frame.o: In function `dwarf2_build_frame_info(objfile*)':
frame.c:(.text+0x4850): undefined reference to `_obstack_free'
dwarf2/frame.o:frame.c:(.text._ZN11objfile_keyI9comp_unitSt14default_deleteIS0_EE7cleanupEP7objfilePv[_ZN11objfile_keyI9comp_unitSt14default_deleteIS0_EE7cleanupEP7objfilePv]+0x1c): more undefined references to `_obstack_free' follow
collect2: error: ld returned 1 exit status
打开出错文件
find -name "obstack.h"
vim include/obstack.h
加上以下内容
#ifndef obstack_free
#define _obstack_free obstack_free
#endif
接着执行make -j16
编译成功
5.3 mips平台bug
运行gdb出现下面问题
[root@Ingenic-uc1_1:mnt]# ./gdb ./codec
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "mips-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./codec...
(gdb)
(gdb) run
Starting program: /mnt/codec
GDB bug: target.c (gdb_signal_from_host): unrecognized real-time signal
打开出错文件
grep -rin "GDB bug: target.c (gdb_signal_from_host)"
vim gdbsupport/signals.cc
由
#if defined (REALTIME_LO)
if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
{
/* This block of GDB_SIGNAL_REALTIME value is in order. */
if (33 <= hostsig && hostsig <= 63)
return (enum gdb_signal)
(hostsig - 33 + (int) GDB_SIGNAL_REALTIME_33);
else if (hostsig == 32)
return GDB_SIGNAL_REALTIME_32;
else if (64 <= hostsig && hostsig <= 127)
return (enum gdb_signal)
(hostsig - 64 + (int) GDB_SIGNAL_REALTIME_64);
else
error (_("GDB bug: target.c (gdb_signal_from_host): "
"unrecognized real-time signal"));
}
#endif
改为
#if defined (REALTIME_LO)
if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
{
/* This block of GDB_SIGNAL_REALTIME value is in order. */
if (33 <= hostsig && hostsig <= 63)
return (enum gdb_signal)
(hostsig - 33 + (int) GDB_SIGNAL_REALTIME_33);
else if (hostsig == 32)
return GDB_SIGNAL_REALTIME_32;
else if (64 <= hostsig && hostsig <= 127)
return (enum gdb_signal)
(hostsig - 64 + (int) GDB_SIGNAL_REALTIME_64);
else if (hostsig == 128)
/* Some platforms, such as Linux MIPS, have NSIG == 128, in which case
signal 128 is the highest realtime signal. There is no constant for
that though. */
return GDB_SIGNAL_UNKNOWN;
else
error (_("GDB bug: target.c (gdb_signal_from_host): "
"unrecognized real-time signal"));
}
#endif