Skip to content

ThinLTO exposes too many symbols #46374

Closed
@alexcrichton

Description

@alexcrichton

For example given this code:

pub mod a {                 
    static mut A: i32 = 0;  
    pub fn foo() -> i32 {   
        unsafe { A }        
    }                       
                            
    pub fn set_foo(a: i32) {
        unsafe { A = a; }   
    }                       
}                           
                            
pub mod b {                 
    pub fn bar() {}         
}                           

Let's compile without ThinLTO and take a look at the symbols:

$ rustc +nightly -C codegen-units=8 foo.rs --crate-type lib
$ readelf -s libfoo.rlib
File: libfoo.rlib(foo.foo0.rcgu.o)

Symbol table '.symtab' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foo0-8787f43e282added3762
     2: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    7 _ZN3foo1a1A17h6d4d0e10f3b
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     6: 0000000000000000     7 FUNC    GLOBAL DEFAULT    3 _ZN3foo1a3foo17hb1e13e720
     7: 0000000000000000     7 FUNC    GLOBAL DEFAULT    5 _ZN3foo1a7set_foo17h5e0b4

File: libfoo.rlib(foo.foo1.rcgu.o)

Symbol table '.symtab' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foo1-8787f43e282added3762
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     3: 0000000000000000     1 FUNC    GLOBAL DEFAULT    3 _ZN3foo1b3bar17h8ae358bf9

File: libfoo.rlib(rust.metadata.bin)
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

File: libfoo.rlib(foo.foo0.rcgu.bytecode.encoded)
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

File: libfoo.rlib(foo.foo1.rcgu.bytecode.encoded)
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

Here we're particularly interested in ZN3foo1a1A17h6d4d0e10f3b, the a::A constant from above. As expected this is LOCAL and DEFAULT, notably not exported from the object file as it's still internalized.

Let's instead compile with ThinLTO:

$ rustc +nightly -C codegen-units=8 foo.rs --crate-type lib -Z thinlto
$ readelf -s libfoo.rlib
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

File: libfoo.rlib(foo.foo0-8787f43e282added376259c1adb08b80.rs.rcgu.o)

Symbol table '.symtab' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foo0-8787f43e282added3762
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     4: 0000000000000000     4 OBJECT  GLOBAL HIDDEN     7 _ZN3foo1a1A17h6d4d0e10f3b
     5: 0000000000000000     7 FUNC    GLOBAL DEFAULT    3 _ZN3foo1a3foo17hb1e13e720
     6: 0000000000000000     7 FUNC    GLOBAL DEFAULT    5 _ZN3foo1a7set_foo17h5e0b4

File: libfoo.rlib(foo.foo1-8787f43e282added376259c1adb08b80.rs.rcgu.o)

Symbol table '.symtab' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foo1-8787f43e282added3762
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     3: 0000000000000000     1 FUNC    GLOBAL DEFAULT    3 _ZN3foo1b3bar17h8ae358bf9

File: libfoo.rlib(rust.metadata.bin)

File: libfoo.rlib(foo.foo0-8787f43e282added376259c1adb08b80.rs.rcgu.bytecode.encoded)

File: libfoo.rlib(foo.foo1-8787f43e282added376259c1adb08b80.rs.rcgu.bytecode.encoded)

Oh dear! Our _ZN3foo1a1A17h6d4d0e10f3b symbol has been promoted to GLOBAL and HIDDEN. That's not good! This symbol, a::A, should stay internalized even when compiling with ThinLTO

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions