我在嵌入式系统(xtensa 处理器)中遇到这样的情况,我需要手动覆盖一个符号,但该符号恰好位于另一个符号的中间。当我尝试使用-Wl,--wrap=symbol
它时,它不起作用,因为该符号不是它自己的东西。
我需要做的是指定(最好在 GCC .S 中,尽管 .c 也可以)代码的最终位置。尽管实际的符号将被编译器随机放置在某个位置,但我会将memcpy
代码放置到正确的位置。
40101388 <replacement_user_vect>:
40101388: 13d100 wsr.excsave1 a0
4010138b: 002020 esync
4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>
我的问题是 GCC 创建具有相对跳转的程序集,假设代码位于闪存中的位置,而最终位置将固定在中断向量中。我如何告诉 GCC / GNU“将代码放在您想要的任何地方,但是,相信我,它实际上会从{这里}执行”
虽然我的代码位于 0x40101388(GCC 决定),但它最终将从 0x40100050 驻留并执行。如何通过告诉 GCC“将代码放在此处”来欺骗 GCC,但假装它位于“此处”
编辑:我能够解决这个问题,事实证明,我需要修改的函数单独保存在链接器脚本中。我可以在链接器脚本中将其切换出来。虽然我仍然很想知道答案,但我现在有一个解决方法。
我对汇编语言完全陌生。我尝试编写简单的程序来破译凯撒密码。问题是链接后我收到以下错误:
cezar.o: In function `loop':
(.text+0xbf): relocation truncated to fit: R_X86_64_8 against `.data'
cezar.o: In function `check_letter':
(.text+0xd5): relocation truncated to fit: R_X86_64_8 against `.data'
Run Code Online (Sandbox Code Playgroud)
老实说 - 我不知道这意味着什么。有谁能够帮助我?相反,#explainMeLikeI'm5 ;P
如果需要的话我的代码:
.data
STDIN = 0
STDOUT = 1
SYSWRITE = 0
SYSREAD = 1
SYSEXIT = 60
EXIT_SUCCESS = 0
BUFLEN = 512
BASE = 10
BASE_NUM = 10
BASE_CHAR = 26
NUM_BEG = 48
error_msg: .ascii "Bad characters in key\n"
error_msg_len = .-error_msg
key: .ascii "-128"
key_len = .-key
.bss …
Run Code Online (Sandbox Code Playgroud) 我注意到我正在编写的一些代码中存在潜在的错误。
我认为,如果我使用mov ax, seg segment_name
,该程序可能是不可移植的,并且只能在特定配置的一台机器上运行,因为加载位置可能因机器而异。
所以我决定在两台运行 DOS 的不同机器上反汇编一个只包含一条指令的程序,我发现问题神奇地解决了。
一号机上的调试输出:0C7A:014C B8BB0C MOV AX,0CBB
二号机器上的调试输出:06CA:014C B80B07 MOV AX,070B
十六进制转储程序后,我发现未更改的字节实际上是B84200
.
手动将这些字节插入到程序中会导致mov ax, 0042
那么 PE 格式是否存储对这些指令的引用并在运行时更新它们?
dos relocation portable-executable memory-segmentation x86-16
我已经在Eclipse插件项目上工作了一段时间,而且我遇到了需要将项目拆分为从插件包中分离测试用例的情况.我正在使用git作为版本控制.
简单地描述一下,我正在对这个旧项目进行版本化:
workspace/
|
+-- myplugin/
|
+-- .git/ <-- Here be the git repository
|
+-- /* Source code, project stuff, etc. */
Run Code Online (Sandbox Code Playgroud)
...我正处于需要在单独的项目中处理插件测试的情况下(因此不需要jUnit作为插件的必需包).我希望存储库能够对工作区中的所有内容进行版本控制.像这样:
workspace/
|
+-- .git/ <-- The repository should be relocated here instead…
|
+-- myplugin/
| |
| +-- /* Source code, project stuff, etc. */
|
+-- myplugin-test/
|
+-- /* Unit tests and stuff… */
Run Code Online (Sandbox Code Playgroud)
有没有一种简单的方法可以做到这一点而不会丢失旧项目的历史?
我正在使用配备Intel Core 2 CPU和2GB RAM的计算机.SO是Ubuntu 9.04.当我尝试编译此代码时:
;programma per la simulazione di un terminale su PC, ottenuto utilizzando l'8250
;in condizione di loopback , cioè Tx=Rx
section .code64
section .data
TXDATA EQU 03F8H ;TRASMETTITORE
RXDATA EQU 03F8H ;RICEVITORE
BAUDLSB EQU 03F8H ;DIVISORE DI BAUD RATE IN LSB
BAUDMSB EQU 03F9H ;DIVISORE DI BAUD RATE IN MSB
INTENABLE EQU 03F9H ;REGISTRO DI ABILITAZIONE DELL'INTERRUZIONE
INTIDENTIF EQU 03FAH ;REGISTRO DI IDENTIFICAZIONE DELL'INTERRUZIONE
LINECTRL EQU 03FBH ;REGISTRO DI CONTROLLO DELLA LINEA
MODEMCTRL EQU 03FCH …
Run Code Online (Sandbox Code Playgroud) 使用Ulrich Drepper的relinfo.pl
脚本,可以轻松计算DSO的重定位次数,但它不适用于.o
文件.
假设我有一个大型共享库,我对它的重定位数量感到不满意.有没有办法找出它们来自哪里(符号,或至少.o
),检查它们是否是易于修复的类型(例如:const char * str = "Hello World";'
- > const char str[] = "Hello World";
)?
我有一个Subversion存储库的本地工作副本。该项目的服务器不再存在,但我想使用工作副本,我必须创建一个新的本地存储库,该存储库将尽可能保留该项目的日志和历史记录。
我尝试了很多事情,花了几天的时间尝试执行此操作,但无法解决。由于我在重定位和file:///协议方面遇到问题,因此我尝试使用svnserve并创建Windows服务。但是似乎我的文件夹结构不好。我的存储库中只有一个.svn文件夹,但是我发现的信息告诉我应该有conf,db,hooks文件夹等。因此,我的文件夹未被识别为svn存储库。
有可能做到这一点,什么是正确的方法。
我最初的目标是将项目转换为Git,但是由于转换失败,我首先尝试使其成为可用的Subversion版本库。稍后将其转换为有效。
我读了很多文章,但是大多数都解释了如何使用服务器上的工作仓库。就我而言,我只有一个旧的工作副本,而我自己未维护的服务器已关闭。
谢谢你的帮助
当我在阅读http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/#id1时, 问题来了:
在进程的虚拟地址空间中加载后,PIC共享库如何知道如何引用外部变量?
这是有问题的共享库的代码:
#include <stdio.h>
extern long var;
void
shara_func(void)
{
printf("%ld\n", var);
}
Run Code Online (Sandbox Code Playgroud)
生成对象代码,然后生成共享对象(库):
gcc -fPIC -c lib1.c # produce PIC lib1.o
gcc -fPIC -shared lib1.o -o liblib1.so # produce PIC shared library
Run Code Online (Sandbox Code Playgroud)
shara_func
在共享库中反汇编:
objdump -d liblib1.so
...
00000000000006d0 <shara_func>:
6d0: 55 push %rbp
6d1: 48 89 e5 mov %rsp,%rbp
6d4: 48 8b 05 fd 08 20 00 mov 0x2008fd(%rip),%rax # 200fd8 <_DYNAMIC+0x1c8>
6db: 48 8b 00 mov (%rax),%rax
6de: 48 89 c6 mov %rax,%rsi
6e1: …
Run Code Online (Sandbox Code Playgroud) linux shared-libraries relocation extern position-independent-code
问题是将可移植可执行映像加载到随机地址。
我们以kernel32.dll为例,加载于0x75A00000。
我可以看到在图像的偏移 0x10e15 处有一条汇编指令,这取决于图像所在的位置。
地址:75A10E13 字节:8B 35 18 03 AE 75 命令:MOV ESI,DWORD PTR DS:[75AE0318]
事实证明,通过启动可执行文件,我们必须告诉系统我们需要重定位到这个地址。
系统查看可执行文件中的重定位表,并看到以下内容: 基本重定位表
为了获取要移动的第一个元素的绝对地址,我执行以下操作:将虚拟地址添加到图像的地址,然后将块的第一个元素添加到结果数字。
0x75A00000 + 0x10000 + 0x3E15 = 75A10E15
这是一个很好的数字,但总是比我预期多 0x3000。我只需减去 0x3000 就可以了。请帮我找到答案,x86 的 0x3000 从哪里来?