0

Why are there duplicate symbols in the same static object file? What does it mean in practice?

after running nm /lib64/libc.so.6 | cut -d' ' -f 3 | uniq -c | sort -rn, which looks at the symbols in the file and prints the number of times that the symbol occurs. I get the following output.

 59 lock
 38 buffer
 15 free_mem
 15 __elf_set___libc_subfreeres_element_free_mem__
  2 __strftime_internal
  2 startp_initialized.9864
  2 startp_initialized.11643
  2 null
  2 nbits.11331

update

00000000003c1b98 b lock
00000000003c1bb0 b lock
...
00000000003c2690 b lock
00000000003c1710 b buffer
00000000003c1718 b buffer
...
00000000003c1720 b buffer
00000000003bc768 d __elf_set___libc_subfreeres_element_free_mem__
...
00000000003bc770 d __elf_set___libc_subfreeres_element_free_mem__
00000000003bc778 d __elf_set___libc_subfreeres_element_free_mem__
...
00000000001899de r null
0000000000191e70 r null

update 2(possibly helpful):

readelf -Ws /lib64/libc.so.6 | grep .*\ buffer$
Num:    Value           Size Type    Bind   Vis      Ndx Name
1277: 00000000003c1710     8 OBJECT  LOCAL  DEFAULT   35 buffer
1289: 00000000003c1718     8 OBJECT  LOCAL  DEFAULT   35 buffer
1293: 00000000003c1720     8 OBJECT  LOCAL  DEFAULT   35 buffer
1298: 00000000003c1728     8 OBJECT  LOCAL  DEFAULT   35 buffer
1319: 00000000003c1730     8 OBJECT  LOCAL  DEFAULT   35 buffer
...
daniel
  • 1
  • 2
  • 1
    Some of the "duplicates" might be a definition (typically one only) and the other may be references to that single definition. You don't know that since you cut away that information from the `nm` output. – Some programmer dude Feb 20 '17 at 07:02
  • In particular forgot to filter all occurrences of external references (`U`) and week objects (`w`, `W`, `v`, `V`). Those are cross-references and not duplicates. – dhke Feb 20 '17 at 07:04
  • Or maybe the symbols you are seing are `static` global symbols? So even if there are duplicates they don't clash since they are local to a single translation unit. The *storage* for these variables must be put somewhere though, typically in the global data or bss segments. – Some programmer dude Feb 20 '17 at 07:12
  • "static object library" is a weird way to call a dynamic library. – Art Feb 20 '17 at 07:19
  • Thanks. I've been having trouble finding documentation to help discern between the difference. Do you have any helpful sources which cover this topic? – daniel Feb 20 '17 at 07:20
  • This is not an answer since I'm not entirely sure: I suspect what you're seeing is debugging symbols. I'm seeing the same thing on my system and also with `objdump -t` (objdump is much better for looking at symbol tables since it gives more information). But when looking at the actual dynamic symbol table with `objdump -T` those symbols don't appear. – Art Feb 20 '17 at 07:26
  • @Art I just ran `objdump -t` and `objdump -T` and my output is identical to your findings. Is there more information that I should be providing to make this more clear? – daniel Feb 20 '17 at 07:32

1 Answers1

0

Why are there duplicate symbols in the same static object file?

  1. What you call "static object file", others call a dynamic shared object, or a shared library for short.
  2. Most shared libraries are linked from multiple relocatable object files.
  3. It is not uncommon to have static data in such object files (such data has internal linkage, i.e. is accessible only from the given object file). When you link multiple such files together into a shared library, you end up with multiple instances of such data. The names of these data items don't matter -- they don't conflict with each other by virtue of internal linkage, and it is not uncommon for the names to be the same in different source files.

Example:

// main.c
extern int foo();

static buffer[10];

int main()
{
  buffer[0] = 'a';
  foo();
  return buffer[0];
}

// foo.c
static buffer[5];
int foo() { buffer[0] = 'b'; return 0; }

When you link the two files above together, you'll have two completely separate buffer variables, and the return code for the program will be 0x61 (ASCII for 'a'), and not 0x62, despite foo assigning 0x62 to buffer[0].

Employed Russian
  • 199,314
  • 34
  • 295
  • 362