使用GNU ld 2.21运行Debian/Linux x86_64.
很简单,如果我链接
ld -o main main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
Run Code Online (Sandbox Code Playgroud)
它有效,但是当我链接时
ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
Run Code Online (Sandbox Code Playgroud)
它抱怨
ld: cannot find -lc
ld: cannot find -lm
Run Code Online (Sandbox Code Playgroud)
我实际上并没有尝试以这种方式编译代码,而是我试图弄清楚为什么别人的测试看看库是否存在无效.(因此我真的不明白发生了什么ld......通常我只是用GCC来链接)
为什么要ld以可重定位的方式链接使它突然无法找到库?如果我只是想测试它-lm存在,我还应该做些什么
ld -r -lm
Run Code Online (Sandbox Code Playgroud)
这样它会找到图书馆吗?
如果你想查看我正在处理的源代码,可以在这里下载:https://github.com/jeremysalwen/ESPS (注意,第一次提交是原始源代码,后续的是更改我亲自做过.)
我正在尝试建立一个完全近期和最新的gcc环境......基本上是gcc 4.6.3和binutils 2.22.不是Xcode 4.2.1附带的相当老的gcc 4.2.1(llvm).我的问题不在于编译(至少目前为止).我可以完美地同时编译binutils,gcc和两者.但是每次我尝试编译时,我都会在configure的输出结束时看到这样的内容
检查在哪里找到目标ar ...只是编译
检查在哪里找到目标为...主机工具
检查在哪里找到目标cc ...只是编译
检查在哪里找到目标c ++ ...只是编译
检查在哪里找到libstdc ++的目标c ++ ...只是编译
检查在哪里找到目标dlltool ...只是编译
检查在哪里找到目标gcc ...只是编译
检查在哪里找到目标gcj ...只是编译
检查在哪里找到目标gfortran ...只是编译
检查在哪里找到目标gccgo ...主机工具
检查在哪里找到目标ld ...主机工具
检查在哪里找到目标脂肪...主机工具
检查在哪里找到目标nm ...只是编译
检查在哪里找到目标objdump ...只是编译
检查在哪里找到目标ranlib ...只是编译
检查在哪里找到目标条...只是编译
检查在哪里找到目标windres ...刚编译
检查在哪里找到目标windmc ... jus 编译
我在gcc源文件夹中为ld,opcodes,bfd,gas,gprof和binutils创建了一个符号链接以获得此输出...(如果这有帮助)
正如你所看到的,我可以获得大多数软件的"刚编译"版本,我只是无法弄清楚如何编译为和ld.我已经阅读了ld文件夹中的README文件(在binutils包中)并且它说要执行:
make all-ld
我这样做,因为我已经"制造"了它的来源,它告诉我什么都不做......
我现在唯一能想到的就是暂时修改我的路径,不包括ld.这很容易......
又快速检查
在哪里ld
无论如何,在我想到这一点之后立即重新认识它将是愚蠢的现在我没有任何东西可以链接gcc(甚至是ld的新版本(如果我完全工作))
所以,最后,我正在尝试编译ld的新副本,并作为...
事实:
我正在尝试使用mingw构建GNU binutils中包含的黄金链接器.我采取的步骤 -
我已经将./configure的完整输出包含在了一个pastebin中:http: //pastebin.com/1XLkZVVm
但重要的是这个:
make[2]: Entering directory `c:/binutils-2.23.1/binutils-2.23.1/gold'
g++ -DHAVE_CONFIG_H -I. -I. -I./../include -I./../elfcpp -DLOCALEDIR="\"/usr/lo
cal/share/locale\"" -DBINDIR="\"/usr/local/bin\"" -DTOOLBINDIR="\"/usr/local//bi
n\"" -DTOOLLIBDIR="\"/usr/local//lib\"" -W -Wall -Wno-format -Werror -D_LAR
GEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -frandom-seed=expression.o -MT expression.
o -MD -MP -MF .deps/expression.Tpo -c -o expression.o expression.cc
In file included from expression.cc:33:0:
script-c.h:221:7: ???: 'yylex' initialized and declared 'extern' [-Werror]
script-c.h:221:7: ???: 'YYSTYPE' was not declared in this scope
script-c.h:221:15: ???: expected primary-expression before ',' token
script-c.h:221:17: ???: expected …Run Code Online (Sandbox Code Playgroud) 当我尝试安装ruby gem json 1.8.3时,我看到类似于C编译器错误的东西
这是我正在运行的命令:
gem install json -v '1.8.3'
Run Code Online (Sandbox Code Playgroud)
我的输出是:
Building native extensions. This could take a while...
ERROR: Error installing json:
ERROR: Failed to build gem native extension.
/usr/local/rvm/rubies/ruby-2.2.1/bin/ruby -r ./siteconf20160327-27188-189i1cj.rb extconf.rb
creating Makefile
make "DESTDIR=" clean
make "DESTDIR="
compiling generator.c
linking shared-object json/ext/generator.so
/usr/bin/ld: BFD (GNU Binutils for Debian) 2.22 internal error, aborting at ../../bfd/reloc.c line 443 in bfd_get_reloc_size
/usr/bin/ld: Please report this bug.
collect2: error: ld returned 1 exit status
make: *** [generator.so] Error …Run Code Online (Sandbox Code Playgroud) 我正在寻求有关我尝试添加的扩展的帮助 riscv。
我的工作基线是riscv-toolsrepo的克隆,包含常用工具,其中包括:
注意:我克隆的最后一次提交是c6d58cecb3862deb742e1a5cc9d1c682f2c50ba9(2018-04-24)。
我的工作基于一个riscv32-ima核心。我想向该处理器添加一条指令,该指令ISA将激活我的处理器中的特定组件。
从 proc 本身的行为来看,我没有问题:我修改了尖峰并且我的指令(以及我添加到处理器的组件)工作得很好。
在汇编程序中,指令如下所示:
addi a0, a0, 0
... // other code
setupcomp // activate my component ...
... // other code
Run Code Online (Sandbox Code Playgroud)
看到这条指令没有任何操作数。
我躲了一会儿,发现这个教程有点旧。
所以我:
riscv-tools/riscv-opcodes/将opcode及其掩码添加到riscv-tools/riscv-opcodes/opcodes. 我的看起来像这样:
setupcomp 31..28=ignore 27..20=ignore 19..15=ignore 14..12=0 11..7=ignore 6..2=0x1a 1..0=3
Run Code Online (Sandbox Code Playgroud)从那里,我重建必要的.h文件:
make install
Run Code Online (Sandbox Code Playgroud)现在,我将必要的添加stucts到riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h,并且我还正式声明了指令:
#define MATCH_SETUPCOMP 0x6b
#define …Run Code Online (Sandbox Code Playgroud)我正在学习可执行二进制文件的布局。我的最终目标是分析可以重构(在其源代码中)以减少编译输出大小的特定可执行文件。
我一直在使用https://www.embeddedrelated.com/showarticle/900.php和https://www.geeksforgeeks.org/memory-layout-of-c-program/作为这个初步学习的参考。
据我所知,链接器脚本指定了放置已编译二进制文件部分的地址。例如
> ld --verbose | grep text
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
Run Code Online (Sandbox Code Playgroud)
我认为这意味着text编译二进制文件的段从内存地址开始0x400000- 真的吗?
这个值0x400000代表什么?我可能没有正确理解某些东西,但肯定0x400000不代表物理内存位置,是吗?例如,如果我跑我的编译的两个实例a.out可并行执行,他们不可能都同时占据的空间0x400000,对不对?
从任何自动生成的STM32CubeMx生成的链接器脚本的底部:
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
Run Code Online (Sandbox Code Playgroud)
从GNU Binutils ld(链接程序脚本)手册中,3.6.7输出节丢弃:
特殊输出节名称“ / DISCARD /”可用于丢弃输入节。分配给名为“ / DISCARD /”的输出节的任何输入节均不包含在输出文件中。
这3个输入目标文件包含什么,为什么我们丢弃它们中的所有内容(所有输入部分)?
GNU ld(链接器脚本)手册第3.5.5节源代码参考有一些关于如何访问 C 源代码中的链接器脚本“变量”(实际上只是整数地址)的非常重要的信息。我用了这个信息。广泛使用链接器脚本变量,我在这里写了这个答案:How to get value of variable defined in ld linker script from C。
然而,很容易做错,并尝试访问链接描述文件变量的值(错误地)而不是它的地址,因为这有点深奥。手册(上面的链接)说:
这意味着,你不能访问 值链接脚本定义符号的-它没有价值-所有你能做的就是访问的地址链接脚本定义的符号。
因此,当您在源代码中使用链接描述文件定义的符号时,您应该始终获取该符号的地址,并且永远不要尝试使用其 value。
问题:那么,如果您确实尝试访问链接描述文件变量的value,这是“未定义的行为”吗?
想象一下在链接脚本(例如:STM32F103RBTx_FLASH.ld)中你有:
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* Some custom variables (addresses) I intend to access …Run Code Online (Sandbox Code Playgroud) 我正在为我的某个项目编写一些汇编代码,我看到了一些有趣的东西。链接时二进制文件的大小是如此之大。所以我进行了测试和测试,即使使用尽可能少的代码行,输出 Elf 二进制文件也是如此之大。例如:
.section .text
.global _start
_start:
movl $1,%eax
movl $0,%ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
组装和链接以上代码后,结果二进制文件超过 4kb!有趣的是,大多数二进制文件都填充了零。
我尝试了很多事情来找出没有成功的原因。
有人可以向我解释这里有什么问题吗?
我只是组装和链接文件:
.section .text
.global _start
_start:
movl $1,%eax
movl $0,%ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
推荐任何形式的资源以供进一步阅读会很好。
你可能猜到了,我使用 64 位 GNU/Linux
谢谢。
我正在为 PIC32MX 微控制器开发固件。程序存储器应分为三段:
startup_region)program1)program2)固件仅存储在第 2 节或第 3 节中。另一个保留用于将来的更新。因此,活动区域可以安全地覆盖另一个区域以存储更新。一个配置位被翻转,第 0 部分的 main() 函数现在在重启时跳转到另一个程序。
因此,我需要链接器将除isr和之外的所有函数main放入第 1 节,将其他所有函数放入第 2 节。第 3 节必须完全留空,因为将来可能会覆盖它。
我已经尝试通过修改默认链接器脚本来实现这一点,但是我没有成功。
链接脚本.ld:
/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
/* [...] */
.text :
{
/* isr() and main() should be at the very first locations in program memory */
*(.text.isr)
*(.text.main)
/* [...] */
. = …Run Code Online (Sandbox Code Playgroud) binutils ×10
ld ×6
linker ×5
c ×3
linux ×2
assembly ×1
binaryfiles ×1
c++ ×1
compilation ×1
elf ×1
flex-lexer ×1
gcc ×1
gold-linker ×1
json ×1
macos ×1
mingw ×1
relocation ×1
riscv ×1
ruby ×1
stm32 ×1