Using lazy_static! the size of the defined variable in the symbol table is 0

74 views Asked by At

The following rust code, in x86_64 platform compilation.

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
}

fn main() {
    // First access to `HASHMAP` initializes it
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());

    // Any further access to `HASHMAP` just returns the computed value
    println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap());
}

I use the readelf command to view the size of the HASHMAP variable in the symbol table:

readelf -sW target/debug/deps/section_test-4d7d6a03c56fdde3.o

Symbol table '.symtab' contains 590 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
452: 0000000000000000     0 OBJECT  LOCAL  DEFAULT  498 _ZN12section_test7HASHMAP17hbc6de818c577d166E

We can see The Size is 0.

readelf -SW target/debug/deps/section_test-4d7d6a03c56fdde3.o
There are 527 section headers, starting at offset 0x98690:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
 [498] .rodata._ZN12section_test7HASHMAP17hbc6de818c577d166E PROGBITS        0000000000000000 00b528 000000 00   A  0   0  1

Let's take a look at the section where the symbol is located,The symbol is located in the rodata section and the Size of the section is also 0.

Since the length is 0, does it mean that no data can be stored, and where is the HashMap memory assigned at runtime? Can I define a variable with a length of 0 in the symbol table in C language?

1

There are 1 answers

0
Jmb On

lazy_static creates an empty type and value that are equivalent to:

struct HASHMAP { __private_field: ()}
static HASHMAP: HASHMAP = HASHMAP { __private_field: () }

(Source code)

Then it implements Deref for this type so that it can initialize the real value dynamically the first time you try to access it (the real value is hidden in a static value inside a private function called by deref).

BTW note that the keys and values will be allocated and stored on the heap when the HashMap is initialized, only the HashMap struct itself is in the hidden static value.