小编Cel*_*ibi的帖子

GCC/x86内联asm:你怎么告诉gcc内联汇编部分会修改%esp?

在试图让一些旧代码再次运行时(https://github.com/chaos4ever/chaos/blob/master/libraries/system/system_calls.h#L387,FWIW)我发现一些语义gcc似乎已经改变了在最近10到15年间,以一种非常微妙但仍然危险的方式......:P

该代码曾用于旧版本gcc,如2.95.无论如何,这是代码:

static inline return_type system_call_service_get(const char *protocol_name, service_parameter_type *service_parameter,
    tag_type *identification)
{
    return_type return_value;

    asm volatile("pushl %2\n"
                 "pushl %3\n"
                 "pushl %4\n"
                 "lcall %5, $0"
                 : "=a" (return_value),
                   "=g" (*service_parameter)
                 : "g" (identification),
                   "g" (service_parameter),
                   "g" (protocol_name),
                   "n" (SYSTEM_CALL_SERVICE_GET << 3));

    return return_value;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码的问题是gcc(在我的情况下为4.7)将编译为以下asm代码(AT&T语法):

# 392 "../system/system_calls.h" 1
pushl 68(%esp)  # This pointer (%esp + 0x68) is valid when the inline asm is entered.
pushl %eax
pushl 48(%esp)  # ...but this …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly gcc inline-assembly

11
推荐指数
1
解决办法
1096
查看次数

gdb add-symbol-file所有部分和加载地址

我正在使用gdb和qemu的gdb-stub调试引导加载程序(syslinux).在某些时候,主文件加载共享对象ldlinux.elf.

我想在gdb中为该文件添加符号.这个命令add-symbol-file似乎是要走的路.但是,作为可重定位文件,我必须指定它已加载的内存地址.这就是问题所在.

虽然我知道LOAD加载段的基址,但是按部分方式add-symbol-file工作并希望我指定每个段加载的地址.

我可以告诉gdb加载我在内存中指定文件基址的所有部分的所有符号吗?

gdb的行为是否有效?节标题不用于运行ELF,甚至是可选的.我看不到一个用例,指定段的加载地址会很有用.


以下是共享对象的程序头和节头.

Elf file type is DYN (Shared object file)
Entry point 0x4c60
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x1db10 0x20bfc RWE 0x1000
  DYNAMIC        0x01d618 0x0001d618 0x0001d618 0x00098 0x00098 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10

 Section to Segment mapping:
  Segment Sections...
   00     .gnu.hash .dynsym .dynstr .rel.dyn …

gdb debug-symbols

9
推荐指数
2
解决办法
7809
查看次数

Smullyan数值机器的解决方案

在这里,我建议找到这里定义的 Smullyan数值机器的解决方案.

问题陈述

它们是将数字列表作为输入的机器,并根据输入模式将其转换为遵循某些规则的另一个数字列表.以下是上面链接中给出的机器规则,更正式地表达了一下.假设M是机器,M(X)是X的变换.我们定义了一些这样的规则:

M(2X) = X
M(3X) = M(X)2M(X)
M(4X) = reverse(M(X)) // reverse the order of the list.
M(5X) = M(X)M(X)
Run Code Online (Sandbox Code Playgroud)

任何与任何规则都不匹配的内容都会被拒绝.这里有一些例子:

  • M(245)= 45
  • M(3245)= M(245)2M(245)= 45245
  • M(43245)=反向(M(3245))=反向(45245)= 54254
  • M(543245)= M(43245)M(43245)= 5425454254

问题是,找到X这样:

  • M(X)= 2
  • M(X)= X.
  • M(X)= X2X
  • M(X)=反向(X)
  • M(X)=反向(X2X)反向(X2X)

这是第二个例子,与穷举搜索相比有点复杂(特别是如果我想要前10或100个解决方案).

M(1X2) = X
M(3X) = M(X)M(X)
M(4X) = reverse(M(X))
M(5X) = truncate(M(X)) // remove the first element of the list truncate(1234) = 234. Only valid if M(X) has at least 2 elements.
M(6X) = 1M(X) …
Run Code Online (Sandbox Code Playgroud)

prolog constraint-programming

6
推荐指数
2
解决办法
297
查看次数

使用gnu make正确构建git子模块

我目前正在尝试编写一个Makefile,以正确构建包含git子模块的项目。该子模块具有自己的makefile集,并一次生成多个目标,包括一些库。

此Makefile应该具有以下属性。

  • 即使使用并行构建,也不要两次重建子模块。
  • 子模块代码已更改时更新子模块目标(可能是因为我浏览了主存储库的修订版)。
  • 子模块库更改后,重新链接主项目。
  • 不要在顶层项目中复制粘贴子模块的Makefile(即保持Makefile递归)。

只是为了设定想法,这似乎是可行的。

FOO_SUBDIR := $(CURDIR)/foo
LDFLAGS := -L$(FOO_SUBDIR)

FOO_LIBSFILES := $(FOO_SUBDIR)/libfoo.a $(FOO_SUBDIR)/libgnufoo.a
FOO_LDLIBS := -lfoo -lgnufoo


.PHONY: all
all: main

# There are theoretically 3 main binaries
main: main.c $(FOO_LIBSFILES)
    gcc -o $@ $< $(LDFLAGS) $(FOO_LDLIBS)

$(FOO_LIBSFILES): libfoo
    @# Do nothing

.PHONY: libfoo
libfoo:
    $(MAKE) -C $(FOO_SUBDIR)
Run Code Online (Sandbox Code Playgroud)

我添加了空食谱似乎很有效,但我不明白为什么。

这个想法是始终依靠子模块的Makefile进行重建(或不重建)libfoo.alibgnufoo.a,并让主Makefile决定是否main需要重建。没有空食谱,它是行不通的。当foo/foo.c被修改,然后libfoo.a重新生成,但make不重建main

我有一种空的配方强制检查目标文件的日期的感觉。但是我找不到有关此行为的文档。

这是正确的方法吗?我应该注意的任何陷阱?还有什么比较晦涩的方法吗?或有关此行为的任何文档?

提前致谢。

git makefile gnu-make git-submodules

5
推荐指数
1
解决办法
1917
查看次数

配方改变后如何重建

如果这个问题已经被问过,我深表歉意。寻找起来并不容易。

make设计时假设 Makefile 有点像神一样。它对您项目的未来了如指掌,除了添加新的源文件之外,永远不需要任何修改。这显然是不正确的。

我曾经使 Makefile 中的所有目标都依赖于 Makefile 本身。这样,如果我更改 Makefile 中的任何内容,整个项目都会重建。

这有两个主要限制:

  1. 它重建得太频繁了。添加链接器选项或新的源文件会重建所有内容。
  2. 如果我在命令行上传递变量(例如make CFLAGS=-O3.

我看到了几种正确执行此操作的方法,但乍一看似乎没有一种方法令人满意。

  1. 使每个目标都依赖于包含配方内容的文件。
  2. 将整个规则及其配方生成到一个要包含在 Makefile 中的文件中。
  3. 有条件地向目标添加依赖项,以在必要时强制重建它们。
  4. 使用eval函数生成规则。

但所有这些解决方案都需要一种不常见的编写方法。要么将整个规则作为字符串放入变量中,要么将配方包装在一个可以发挥一些魔力的函数中。

我正在寻找一种以尽可能简单的方式编写规则的解决方案。尽可能少的额外垃圾。人们通常如何做到这一点?

makefile gnu-make

5
推荐指数
1
解决办法
1838
查看次数