Sorry that this email is going to be long. In summary, what Johannes said is right: what objcopy does is not sufficient, and with ld it transforms as we expected.
More goes to below. On Sat, 06 Mar 2021 05:22:19 +0900, Johannes Berg wrote: > > On Thu, 2021-03-04 at 14:38 +0900, Hajime Tazaki wrote: > > > > objcopy (from binutils) can localize symbols (i.e., objcopy -L > > sem_init $orig_file $new_file). > > This doesn't seem to be sufficient. > > > It also does renaming symbols. But > > not sure this is the ideal solution. > > Even that doesn't seem to actually work/help? I still get libcom_err > trying to call UML's sem_init, even after doing > objcopy --redefine-sym sem_init=uml_sem_init > > > > How does UML handle symbol conflicts between userspace code and Linux > > kernel (like this case sem_init) ? AFAIK, libnl has a same symbol as > > Linux kernel (genlmsg_put) and others can possibly do as well. > > I think like I said it just doesn't but since you don't have much > userspace code linked with UML it never really mattered? > > We only link a 'linux' binary, after all. How does LKL handle this > though? It should be far more affected? > > > Despite the objcopy *not* fixing it, this does seem to: with slightly old version: - objcopy/ld version 2.29.1-23.fc28 I confirmed that objcopy (both --redefine-sym and --localize-symbol) only changes symbols of .symtab table. But there is another table, .dynsym table, which is used to resolve. So, the original file looks like this: 1) before objcopy (vmlinux) % readelf -s obj-x86-um/vmlinux |grep -E "sem_init|Symbol table|Num:" Symbol table '.dynsym' contains 179 entries: Num: Value Size Type Bind Vis Ndx Name 129: 0000000060011d38 72 FUNC GLOBAL DEFAULT 2 sem_init Symbol table '.symtab' contains 38474 entries: Num: Value Size Type Bind Vis Ndx Name 28515: 0000000060011d38 72 FUNC GLOBAL DEFAULT 2 sem_init 37798: 00000000601e30d5 62 FUNC GLOBAL DEFAULT 13 sem_init_ns the result object looks like 2) after objcopy (linux) % readelf -s obj-x86-um/linux |grep -E "sem_init|Symbol table|Num:" Symbol table '.dynsym' contains 179 entries: Num: Value Size Type Bind Vis Ndx Name 129: 0000000060011d38 72 FUNC GLOBAL DEFAULT 2 sem_init Symbol table '.symtab' contains 38474 entries: Num: Value Size Type Bind Vis Ndx Name 28455: 0000000060011d38 72 FUNC LOCAL DEFAULT 2 sem_init 37798: 00000000601e30d5 62 FUNC GLOBAL DEFAULT 13 sem_init_ns Only .symtab symbol table is changed to local while .dynsym table is not changed. So, sem_init call from libcom_err.so still can resolve the Linux symbol. On the other hand, ld --version script solution does as we wish. 3) localized with ld % readelf -s obj-x86-um/linux G -E "sem_init|Symbol table|Num:" Symbol table '.dynsym' contains 142 entries: Num: Value Size Type Bind Vis Ndx Name Symbol table '.symtab' contains 38474 entries: Num: Value Size Type Bind Vis Ndx Name 28512: 0000000060011d38 72 FUNC LOCAL DEFAULT 2 sem_init 37669: 00000000601e2b45 62 FUNC LOCAL DEFAULT 13 sem_init_ns Only .symtab table is generated for the sem_init symbol and it's localized. Because the way to build is different from what UML currently does, LKL (and UML binaries) do not have this issue, with a quick check. LKL applies objcopy before generating intermediate file (linux.o), and the symbols of the final binary (linux) are localized and have no .dynsym entries, thus no issue in this case. refs: https://stackoverflow.com/questions/54332797/binding-failure-with-objcopy-redefine-syms https://sourceware.org/legacy-ml/binutils/2019-01/msg00254.html -- Hajime