PE Binding
"GLOBAL" and "NONE" are values of the "Bind" column in radare2's symbol table. As @blabb correctly described, whenever you look at the "Exports" through radare2 you'll see the value "GLOBAL"
assigned to ptr->bind
and you'll see "NONE"
assigned to each import. The thing is, that this is only relevant for PE files and I'll soon explain it deeper. For now, let's look at the implemented code in radare2.
@blabb mentioned that you can easily spot this in the code, that's true. Here's how the implementation of bind
is for PE exports:
if ((symbols = PE_(r_bin_pe_get_exports)(bf->o->bin_obj))) {
for (i = 0; !symbols[i].last; i++) {
if (!(ptr = R_NEW0 (RBinSymbol))) {
break;
}
ptr->name = strdup ((char *)symbols[i].name);
...
ptr->bind = r_str_const ("GLOBAL");
ptr->type = r_str_const ("FUNC");
ptr->size = 0;
...
...
You can see that ptr->bind
is unconditionally assigned to be "GLOBAL".
That's how the implementation of bind
is looking like for PE import:
if ((imports = PE_(r_bin_pe_get_imports)(bf->o->bin_obj))) {
for (i = 0; !imports[i].last; i++) {
if (!(ptr = R_NEW0 (RBinSymbol))) {
break;
}
...
ptr->name = r_str_newf ("imp.%s", imports[i].name);
ptr->bind = r_str_const ("NONE");
ptr->type = r_str_const ("FUNC");
ptr->size = 0;
...
...
Again, it is unconditionally assigned to "NONE".
Symbol Binding
Symbol binding is a subject that thoroughly was already answered by @SYS_V in this incredibly good answer.
To quote from his answer:
There must be a way for the link editor (ld) to determine the scope of
a symbol during link-time. In other words, symbol binding allows the
link editor to differentiate between symbols visible only within a
particular file being linked (local scope) vs. symbols that can be
referenced from within functions located in other files (global
scope).
For ELF files, GLOBAL binding means the symbol is visible outside the file. LOCAL binding is visible only in the file. WEAK is like global, the symbol can be overridden.
There are many more binding values for ELF as you can see in this table:
+------------+-------+
| Name | Value |
+------------+-------+
| STB_LOCAL | 0 |
| STB_GLOBAL | 1 |
| STB_WEAK | 2 |
| STB_LOOS | 10 |
| STB_HIOS | 12 |
| STB_LOPROC | 13 |
| STB_HIPROC | 15 |
+------------+-------+
And radare2 implemented it as well in fill_symbol_bind_and_type
:
switch (ELF_ST_BIND(sym->st_info)) {
case STB_LOCAL: s_bind ("LOCAL"); break;
case STB_GLOBAL: s_bind ("GLOBAL"); break;
case STB_WEAK: s_bind ("WEAK"); break;
case STB_NUM: s_bind ("NUM"); break;
case STB_LOOS: s_bind ("LOOS"); break;
case STB_HIOS: s_bind ("HIOS"); break;
case STB_LOPROC: s_bind ("LOPROC"); break;
case STB_HIPROC: s_bind ("HIPROC"); break;
default: s_bind ("UNKNOWN");
}
Further reading
I highly recommend @SYS_V's answer for more information. You can also read more about Symbol Resolution here and you can find more information about Symbol visibility in this link.