我有一个16字节的数组,其中包含可执行文件的段名.
char segname[16];
Run Code Online (Sandbox Code Playgroud)
如果段名长度小于16个字节,则其余部分用空字节填充.否则,没有终止空字节.
我想比较segname各种字符串,例如__text.
strncmp使用非空终止字符串调用是否合法?
这篇文章假设它是合法的.此源代码也使其合法化.但是我的男人的页面说:
该
strncmp()函数按字典顺序比较以null结尾的字符串s1和s2.
传递给strncmp的大小将是segname.
我想知道我应该参考什么.
char s1[] = "0";
char s2[] = "9";
printf("%d\n", strcmp(s1, s2)); // Prints -9
printf("%d\n", strcmp("0", "9")); // Prints -1
Run Code Online (Sandbox Code Playgroud)
为什么strcmp在收到相同参数时会返回不同的值?
这些值仍然合法,因为strcmp的手册页说strcmp的返回值可以小于,大于或等于0,但我不明白为什么它们在这个例子中是不同的.
我很惊讶这个编译没有任何警告:
int main()
{
*"abc" = '\0';
}
Run Code Online (Sandbox Code Playgroud)
用gcc main.c -Wall -Wextra和clang main.c -Weverything.
为什么没有这个警告?有没有办法不会引起分段错误?
我想这两个cpp foo.c和gcc -E foo.c做预处理源文件相同的方式,但我得到了他们的输出为同一个文件的不同.
$ cat foo.c
#define VARIABLE 3
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define NAME(fun) EVALUATOR(fun, VARIABLE)
extern void NAME(mine);
Run Code Online (Sandbox Code Playgroud)
结果cpp:
$ cpp foo.c
# 1 "foo.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 329 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "foo.c" 2
extern void mine ## _ ## 3;
$
Run Code Online (Sandbox Code Playgroud)
结果gcc -E和clang -E: …
我想非ASCII字符(写0xfe,0xed等),以一个程序的标准输入。
有很多类似的问题,但我没有找到答案,因为:
echo什么的在 OS X¹ 上,您可以测试:
nm - -
Run Code Online (Sandbox Code Playgroud)
我想将目标文件魔术字节(例如0xfeedface)写入nm使用标准输入,以便我可以看到它的行为方式并且可以重新编码。
如果我使用管道,则第二个参数-(即stdin)将永远不会匹配任何字节,因为所有标准输入都将转到第一个。当使用终端而不是管道时,我可以输入Ctrl + D第一个“关闭”,第二个开始读取。
我尝试使用Ctrl + Shift + UOS X 的 Unicode 十六进制输入,但它不起作用——我无法用它写出所需的字符。
我也尝试过使用剪贴板,pbcopy但它无法读取/粘贴非 ASCII 或非 unicode 字符。
我怎样才能实现我的目标?
不要犹豫编辑,因为这是一个难以表达的问题。
¹nm在 linux 上不处理stdin。
我想知道ret从程序的入口点返回是否合法.
NASM示例:
section .text
global _start
_start:
ret
; Linux: nasm -f elf64 foo.asm -o foo.o && ld foo.o
; OS X: nasm -f macho64 foo.asm -o foo.o && ld foo.o -lc -macosx_version_min 10.12.0 -e _start -o foo
Run Code Online (Sandbox Code Playgroud)
ret 从堆栈中弹出一个返回地址并跳转到它.
但是堆栈的顶部字节是程序入口点的有效返回地址,还是我必须调用exit?
此外,上面的程序不会在OS X上发生段错误.它在哪里返回?
我无法找到在 MacOS 上编写 64 位程序集的良好文档。
64位 SysV ABI在 A.2.1 节中说了以下内容,并且此 SO 帖子引用了它:
系统调用是通过 syscall 指令完成的。内核销毁寄存器%rcx 和%r11。
从系统调用返回,寄存器 %rax 包含系统调用的结果。-4095 到 -1 之间的值表示错误,它是 -errno。
这两句话在 Linux 上没问题,但在 macOS Sierra 上却是错误的,代码如下:
global _start
extern _exit
section .text
_start:
; Align stack to 16 bytes for libc
and rsp, 0xFFFFFFFFFFFFFFF0
; Call write
mov rdx, 12 ; size
mov rsi, hello ; buf
mov edi, 1 ; fd
mov rax, 0x2000004 ; write ; replace to mov rax, 0x1 …Run Code Online (Sandbox Code Playgroud) 我正在尝试重新编写printf的一部分.
setlocale(LC_ALL, "en_US.UTF-8");
int ret = printf("%S\n", "??????");
printf("Printf returned %d\n", ret);
Run Code Online (Sandbox Code Playgroud)
如果格式为%s,则printf写入宽字符并返回19.
如果格式为%S,则printf返回-1,因为参数不是宽字符串(在""之前没有L).
在我自己的printf实现中,如何确定参数中传递的字符串是否宽,所以如果不是,我可以返回-1?
编辑
我有一个简单的内核模块,它创建了一个字符设备并且什么都不做。
我编写了这个测试字符设备的用户空间程序。
int main()
{
int fd;
fd = open("/dev/ebbchar", O_RDWR);
if (fd < 0)
err(1, "open");
sleep(10);
ret = close(fd);
if (ret < 0)
err(1, "close");
}
Run Code Online (Sandbox Code Playgroud)
程序在 10 秒后退出。
但是如果同时我用 rmmod 或 modprobe 删除了模块,那么 10 秒后程序段错误或挂起,并且有一个内核 oops。
如何导致 rmmod 失败,或者是否有安全删除模块的方法?
我的模块可以在其 __exit 函数中关闭文件描述符吗?
我假设崩溃是由在字符文件操作中close()间接调用release回调的函数引起的,该release函数不再存在,因为模块已被删除。
可以在此处找到内核模块的源代码(搜索清单 2)。