1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-13 09:39:13 +03:00
This commit is contained in:
Rui Ueyama 2021-03-31 20:18:12 +09:00
parent 97f02b1eb3
commit f9af6357df
6 changed files with 47 additions and 27 deletions

View File

@ -138,10 +138,10 @@ void InputSection<I386>::apply_reloc_alloc(Context<I386> &ctx, u8 *base) {
write(G + GOT + A - P);
break;
case R_GOTTP:
write(sym.get_gottpoff_addr(ctx) + A);
write(sym.get_gottp_addr(ctx) + A);
break;
case R_NTPOFF:
write(sym.get_gottpoff_addr(ctx) + A - GOT);
write(sym.get_gottp_addr(ctx) + A - GOT);
break;
case R_SIZE:
write(sym.esym->st_size + A);
@ -295,11 +295,11 @@ void InputSection<I386>::scan_relocations(Context<I386> &ctx) {
Error(ctx) << "TLS reloc is not supported yet: "
<< rel_to_string<I386>(rel.r_type);
case R_386_TLS_GOTIE:
sym.flags |= NEEDS_GOTTPOFF;
sym.flags |= NEEDS_GOTTP;
rel_types[i] = R_GOTTP;
break;
case R_386_TLS_LE:
sym.flags |= NEEDS_GOTTPOFF;
sym.flags |= NEEDS_GOTTP;
rel_types[i] = R_NTPOFF;
break;
case R_386_TLS_GD:

View File

@ -301,7 +301,7 @@ void InputSection<X86_64>::apply_reloc_alloc(Context<X86_64> &ctx, u8 *base) {
write(S + A - ctx.tls_end);
break;
case R_GOTTPOFF:
write(sym.get_gottpoff_addr(ctx) + A - P);
write(sym.get_gottp_addr(ctx) + A - P);
break;
case R_GOTTPOFF_RELAX: {
u32 insn = relax_gottpoff(loc - 3);
@ -575,13 +575,13 @@ void InputSection<X86_64>::scan_relocations(Context<X86_64> &ctx) {
rel_types[i] = R_TPOFF;
break;
case R_X86_64_GOTTPOFF:
ctx.has_gottpoff = true;
ctx.has_gottp_rel = true;
if (ctx.arg.relax && !ctx.arg.shared && !sym.is_imported &&
relax_gottpoff(loc - 3)) {
rel_types[i] = R_GOTTPOFF_RELAX;
} else {
sym.flags |= NEEDS_GOTTPOFF;
sym.flags |= NEEDS_GOTTP;
rel_types[i] = R_GOTTPOFF;
}
break;

18
mold.h
View File

@ -114,7 +114,7 @@ struct SectionFragmentRef {
enum {
NEEDS_GOT = 1 << 0,
NEEDS_PLT = 1 << 1,
NEEDS_GOTTPOFF = 1 << 2,
NEEDS_GOTTP = 1 << 2,
NEEDS_TLSGD = 1 << 3,
NEEDS_TLSLD = 1 << 4,
NEEDS_COPYREL = 1 << 5,
@ -139,7 +139,7 @@ public:
inline u64 get_addr(Context<E> &ctx) const;
inline u64 get_got_addr(Context<E> &ctx) const;
inline u64 get_gotplt_addr(Context<E> &ctx) const;
inline u64 get_gottpoff_addr(Context<E> &ctx) const;
inline u64 get_gottp_addr(Context<E> &ctx) const;
inline u64 get_tlsgd_addr(Context<E> &ctx) const;
inline u64 get_tlsdesc_addr(Context<E> &ctx) const;
inline u64 get_plt_addr(Context<E> &ctx) const;
@ -164,7 +164,7 @@ public:
u64 value = -1;
u32 got_idx = -1;
u32 gotplt_idx = -1;
u32 gottpoff_idx = -1;
u32 gottp_idx = -1;
u32 tlsgd_idx = -1;
u32 tlsdesc_idx = -1;
u32 plt_idx = -1;
@ -435,7 +435,7 @@ public:
}
void add_got_symbol(Context<E> &ctx, Symbol<E> *sym);
void add_gottpoff_symbol(Context<E> &ctx, Symbol<E> *sym);
void add_gottp_symbol(Context<E> &ctx, Symbol<E> *sym);
void add_tlsgd_symbol(Context<E> &ctx, Symbol<E> *sym);
void add_tlsdesc_symbol(Context<E> &ctx, Symbol<E> *sym);
void add_tlsld(Context<E> &ctx);
@ -449,7 +449,7 @@ public:
void copy_buf(Context<E> &ctx) override;
std::vector<Symbol<E> *> got_syms;
std::vector<Symbol<E> *> gottpoff_syms;
std::vector<Symbol<E> *> gottp_syms;
std::vector<Symbol<E> *> tlsgd_syms;
std::vector<Symbol<E> *> tlsdesc_syms;
u32 tlsld_idx = -1;
@ -1302,7 +1302,7 @@ struct Context {
u8 *buf = nullptr;
std::vector<OutputChunk<E> *> chunks;
std::atomic_bool has_gottpoff = false;
std::atomic_bool has_gottp_rel = false;
std::atomic_bool has_textrel = false;
// Output chunks
@ -1599,9 +1599,9 @@ inline u64 Symbol<E>::get_gotplt_addr(Context<E> &ctx) const {
}
template <typename E>
inline u64 Symbol<E>::get_gottpoff_addr(Context<E> &ctx) const {
assert(gottpoff_idx != -1);
return ctx.got->shdr.sh_addr + gottpoff_idx * E::got_size;
inline u64 Symbol<E>::get_gottp_addr(Context<E> &ctx) const {
assert(gottp_idx != -1);
return ctx.got->shdr.sh_addr + gottp_idx * E::got_size;
}
template <typename E>

View File

@ -481,7 +481,7 @@ static std::vector<typename E::word> create_dynamic_section(Context<E> &ctx) {
if (!ctx.arg.z_delete)
flags1 |= DF_1_NODELETE;
if (ctx.has_gottpoff)
if (ctx.has_gottp_rel)
flags |= DF_STATIC_TLS;
if (flags)
@ -605,11 +605,11 @@ void GotSection<E>::add_got_symbol(Context<E> &ctx, Symbol<E> *sym) {
}
template <typename E>
void GotSection<E>::add_gottpoff_symbol(Context<E> &ctx, Symbol<E> *sym) {
assert(sym->gottpoff_idx == -1);
sym->gottpoff_idx = this->shdr.sh_size / E::got_size;
void GotSection<E>::add_gottp_symbol(Context<E> &ctx, Symbol<E> *sym) {
assert(sym->gottp_idx == -1);
sym->gottp_idx = this->shdr.sh_size / E::got_size;
this->shdr.sh_size += E::got_size;
gottpoff_syms.push_back(sym);
gottp_syms.push_back(sym);
if (sym->is_imported)
ctx.dynsym->add_symbol(ctx, sym);
@ -651,7 +651,7 @@ i64 GotSection<E>::get_reldyn_size(Context<E> &ctx) const {
n += tlsgd_syms.size() * 2;
n += tlsdesc_syms.size() * 2;
for (Symbol<E> *sym : gottpoff_syms)
for (Symbol<E> *sym : gottp_syms)
if (sym->is_imported)
n++;
@ -706,12 +706,12 @@ void GotSection<E>::copy_buf(Context<E> &ctx) {
*rel++ = reloc<E>(sym->get_tlsdesc_addr(ctx), E::R_TLSDESC,
sym->dynsym_idx, 0);
for (Symbol<E> *sym : gottpoff_syms) {
for (Symbol<E> *sym : gottp_syms) {
if (sym->is_imported)
*rel++ = reloc<E>(sym->get_gottpoff_addr(ctx), E::R_TPOFF,
*rel++ = reloc<E>(sym->get_gottp_addr(ctx), E::R_TPOFF,
sym->dynsym_idx, 0);
else
buf[sym->gottpoff_idx] = sym->get_addr(ctx) - ctx.tls_end;
buf[sym->gottp_idx] = sym->get_addr(ctx) - ctx.tls_end;
}
if (tlsld_idx != -1)

View File

@ -436,8 +436,8 @@ void scan_rels(Context<E> &ctx) {
ctx.plt->add_symbol(ctx, sym);
}
if (sym->flags & NEEDS_GOTTPOFF)
ctx.got->add_gottpoff_symbol(ctx, sym);
if (sym->flags & NEEDS_GOTTP)
ctx.got->add_gottp_symbol(ctx, sym);
if (sym->flags & NEEDS_TLSGD)
ctx.got->add_tlsgd_symbol(ctx, sym);

20
test/i386-hello-static.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
set -e
cd $(dirname $0)
echo -n "Testing $(basename -s .sh $0) ... "
t=$(pwd)/tmp/$(basename -s .sh $0)
mkdir -p $t
cat <<EOF | cc -m32 -o $t/a.o -c -xc -
#include <stdio.h>
int main() {
printf("Hello world\n");
return 0;
}
EOF
clang -fuse-ld=`pwd`/../mold -m32 -o $t/exe $t/a.o -static
$t/exe | grep -q 'Hello world'
echo OK