–localize-symbol在Windows上与mingw-w64不起作用

huangapple go评论62阅读模式
英文:

--localize-symbol does not work on windows with mingw-w64

问题

我有两个文件

foo_var.c

int global_var = 1;

foo_print.c

#include <stdio.h>

extern int global_var;

void print_foo(void)
{
    printf("print_foo = %d\n", global_var);
}

它们编译并链接成foo.o,并本地化global_var

gcc -c foo.c foo_print.c
ld -r -o foo.o foo_print.o foo_var.o
objcopy -L global_var foo.o

还有两个文件

bar_var.c

int global_var = 2;

bar_print.c

#include <stdio.h>

extern int global_var;

void print_bar(void)
{
    printf("print_bar = %d\n", global_var);
}

编译并链接成bar.o,并本地化global_var

gcc -c bar.c bar_print.c
ld -r -o bar.o bar_print.o bar_var.o
objcopy -L global_var bar.o

还有一个main,在其中我调用print_fooprint_bar

main.c

void print_foo(void);
void print_bar(void);

int main(int argc, char const *argv[])
{
    print_foo();
    print_bar();

    return 0;
}

当我将所有内容编译并链接在一起时

gcc -c main.c
gcc main.o foo.o bar.o

运行a.exe后,我得到了这个结果

print_foo = 1
print_bar = 1

而不是

print_foo = 1
print_bar = 2

如何在mingw-w64中正确本地化符号?

英文:

I have two files

foo_var.c

int global_var = 1;

foo_print.c

#include <stdio.h>

extern int global_var;

void print_foo(void)
{
	printf("print_foo = %d\n", global_var);
}

that compile and link into foo.o and localize global_var

gcc -c foo.c foo_print.c
ld -r -o foo.o foo_print.o foo_var.o
objcopy -L global_var foo.o

And two files

bar_var.c

int global_var = 2;

bar_print.c

#include <stdio.h>

extern int global_var;

void print_bar(void)
{
	printf("print_bar = %d\n", global_var);
}

compile and link into bar.o and localize global_var too

gcc -c bar.c bar_print.c
ld -r -o bar.o bar_print.o bar_var.o
objcopy -L global_var bar.o

also I have main, where I call print_foo and print_bar

main.c

void print_foo(void);
void print_bar(void);

int main(int argc, char const *argv[])
{
	print_foo();
	print_bar();

	return 0;
}

When I compile and link all together

gcc -c main.c
gcc main.o foo.o bar.o

and run a.exe I get this

print_foo = 1
print_bar = 1

instead

print_foo = 1
print_bar = 2

How localize symbols in mingw-w64 correctly?

gcc version 12.2.0 (x86_64-win32-seh-rev2, Built by MinGW-W64 project)

答案1

得分: 0

全局变量符号本地化不足,因为foo.o(和bar.o)还有另一个符号.refptr.global_var,它也需要本地化。

objcopy -L global_var -L .refptr.global_var foo.o
objcopy -L global_var -L .refptr.global_var bar.o

但这种方法会导致一个带有未解析链接的破损的a.exe(而且没有来自gcc和ld的警告和错误!)

U .refptr.global_var

然后在foo.o中,我找到了符号.rdata$.refptr.global_var,重新定义它

objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.foo_global_var foo.o
objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.bar_global_var bar.o

并收到了ld的警告:

ld: foo.o: warning: COMDAT 符号 '.rdata$.refptr.foo_global_var' 不匹配节名称 '.rdata$.refptr.global_var'

这给了我一个重新定义节.rdata$.refptr.global_var的想法,以类似的方式

objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.foo_global_var --rename-section .rdata$.refptr.global_var=.rdata$.refptr.foo_global_var foo.o
objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.bar_global_var --rename-section .rdata$.refptr.global_var=.rdata$.refptr.bar_global_var bar.o

最后它起作用了,但难道不应该由objcopy自己完成吗?

英文:

localization global_var symbol is not enough, because foo.o (and bar.o) have another symbol .refptr.global_var and it also needs localization

    objcopy -L global_var -L .refptr.global_var foo.o
    objcopy -L global_var -L .refptr.global_var bar.o

but this approach leads to a broken a.exe with unresolved links (without warning and errors from gcc and ld!)

    U .refptr.global_var

then in the foo.o I found the symbol .rdata$.refptr.global_var, redefined it

    objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.foo_global_var foo.o
    objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.bar_global_var bar.o

and got a warning from ld:

    ld: foo.o: warning: COMDAT symbol '.rdata$.refptr.foo_global_var' does not match section name '.rdata$.refptr.global_var'

that gave me an idea to redefine section .rdata$.refptr.global_var in a similar way

    objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.foo_global_var --rename-section .rdata$.refptr.global_var=.rdata$.refptr.foo_global_var foo.o
    objcopy -L global_var -L .refptr.global_var --redefine-sym .rdata$.refptr.global_var=.rdata$.refptr.bar_global_var --rename-section .rdata$.refptr.global_var=.rdata$.refptr.bar_global_var bar.o

finally it worked, but shouldn't objcopy do it itself?

huangapple
  • 本文由 发表于 2023年2月10日 04:08:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定