1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-11 16:58:12 +03:00
This commit is contained in:
Rui Ueyama 2021-03-05 15:36:08 +09:00
parent 41f8cba844
commit 5af16edfcf
2 changed files with 81 additions and 74 deletions

View File

@ -407,38 +407,48 @@ void InputSection::scan_relocations() {
continue;
}
auto none = []() {};
auto error = [&]() {
Error() << *this << ": " << rel_to_string(rel.r_type)
<< " relocation against symbol `" << sym
<< "' can not be used; recompile with -fPIE";
};
auto copyrel = [&]() {
sym.flags |= NEEDS_COPYREL;
};
typedef enum { NONE, ERROR, COPYREL, PLT, DYNREL, BASEREL } Action;
auto plt = [&]() {
sym.flags |= NEEDS_PLT;
};
auto dynrel = [&]() {
if (is_readonly)
auto dispatch = [&](Action action, RelType rel_type) {
switch (action) {
case NONE:
rel_types[i] = rel_type;
return;
case ERROR:
error();
sym.flags |= NEEDS_DYNSYM;
rel_types[i] = R_DYN;
file->num_dynrel++;
return;
case COPYREL:
sym.flags |= NEEDS_COPYREL;
rel_types[i] = rel_type;
return;
case PLT:
sym.flags |= NEEDS_PLT;
rel_types[i] = rel_type;
return;
case DYNREL:
if (is_readonly)
error();
sym.flags |= NEEDS_DYNSYM;
rel_types[i] = R_DYN;
file->num_dynrel++;
return;
case BASEREL:
if (is_readonly)
error();
rel_types[i] = R_BASEREL;
file->num_dynrel++;
return;
}
unreachable();
};
auto baserel = [&]() {
if (is_readonly)
error();
rel_types[i] = R_BASEREL;
file->num_dynrel++;
};
if (sym.get_type() == STT_GNU_IFUNC)
if (sym.esym->st_type == STT_GNU_IFUNC)
sym.flags |= NEEDS_PLT;
switch (rel.r_type) {
@ -449,53 +459,49 @@ void InputSection::scan_relocations() {
case R_X86_64_16:
case R_X86_64_32:
case R_X86_64_32S: {
std::function<void()> table[][4] = {
Action table[][4] = {
// Absolute Local Imported data Imported code
{ none, none, copyrel, plt }, // PDE
{ none, error, error, error }, // PIE
{ none, error, error, error }, // DSO
{ NONE, NONE, COPYREL, PLT }, // PDE
{ NONE, ERROR, ERROR, ERROR }, // PIE
{ NONE, ERROR, ERROR, ERROR }, // DSO
};
rel_types[i] = R_ABS;
table[output_type][get_sym_type(sym)]();
dispatch(table[output_type][get_sym_type(sym)], R_ABS);
break;
}
case R_X86_64_64: {
std::function<void()> table[][4] = {
Action table[][4] = {
// Absolute Local Imported data Imported code
{ none, none, copyrel, plt }, // PDE
{ none, baserel, dynrel, dynrel }, // PIE
{ none, baserel, dynrel, dynrel }, // DSO
{ NONE, NONE, COPYREL, PLT }, // PDE
{ NONE, BASEREL, DYNREL, DYNREL }, // PIE
{ NONE, BASEREL, DYNREL, DYNREL }, // DSO
};
rel_types[i] = R_ABS;
table[output_type][get_sym_type(sym)]();
dispatch(table[output_type][get_sym_type(sym)], R_ABS);
break;
}
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32: {
std::function<void()> table[][4] = {
Action table[][4] = {
// Absolute Local Imported data Imported code
{ none, none, copyrel, plt }, // PDE
{ error, none, copyrel, plt }, // PIE
{ error, none, error, error }, // DSO
{ NONE, NONE, COPYREL, PLT }, // PDE
{ ERROR, NONE, COPYREL, PLT }, // PIE
{ ERROR, NONE, ERROR, ERROR }, // DSO
};
rel_types[i] = R_PC;
table[output_type][get_sym_type(sym)]();
dispatch(table[output_type][get_sym_type(sym)], R_PC);
break;
}
case R_X86_64_PC64: {
std::function<void()> table[][4] = {
Action table[][4] = {
// Absolute Local Imported data Imported code
{ none, none, copyrel, plt }, // PDE
{ baserel, none, copyrel, plt }, // PIE
{ baserel, none, error, error }, // DSO
{ NONE, NONE, COPYREL, PLT }, // PDE
{ BASEREL, NONE, COPYREL, PLT }, // PIE
{ BASEREL, NONE, ERROR, ERROR }, // DSO
};
rel_types[i] = R_PC;
table[output_type][get_sym_type(sym)]();
dispatch(table[output_type][get_sym_type(sym)], R_PC);
break;
}
case R_X86_64_GOT32:

57
main.cc
View File

@ -313,40 +313,41 @@ static void check_duplicate_symbols() {
}
static void compute_visibility() {
if (!config.shared)
return;
Timer t("compute_visibility");
if (config.shared) {
tbb::parallel_for_each(out::objs, [&](ObjectFile *file) {
for (Symbol *sym : std::span(file->symbols).subspan(file->first_global)) {
if (sym->file != file)
continue;
tbb::parallel_for_each(out::objs, [&](ObjectFile *file) {
for (Symbol *sym : std::span(file->symbols).subspan(file->first_global)) {
if (sym->file != file)
continue;
u8 visibility = sym->visibility;
bool bsymbolic = config.Bsymbolic ||
(config.Bsymbolic_functions && sym->get_type() == STT_FUNC);
u8 visibility = sym->visibility;
bool bsymbolic = config.Bsymbolic ||
(config.Bsymbolic_functions && sym->get_type() == STT_FUNC);
if (visibility == STV_DEFAULT && bsymbolic)
visibility = STV_PROTECTED;
if (visibility == STV_DEFAULT && bsymbolic)
visibility = STV_PROTECTED;
switch (visibility) {
case STV_DEFAULT:
sym->is_imported = true;
sym->is_exported = true;
break;
case STV_PROTECTED:
sym->is_imported = false;
sym->is_exported = true;
break;
case STV_HIDDEN:
sym->is_imported = false;
sym->is_exported = false;
break;
default:
unreachable();
}
switch (visibility) {
case STV_DEFAULT:
sym->is_imported = true;
sym->is_exported = true;
break;
case STV_PROTECTED:
sym->is_imported = false;
sym->is_exported = true;
break;
case STV_HIDDEN:
sym->is_imported = false;
sym->is_exported = false;
break;
default:
unreachable();
}
});
}
}
});
}
static void set_isec_offsets() {