cmingw-w64objcopy

--localize-symbol does not work on windows with 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)


Solution

  • 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?