mirror of
https://github.com/rui314/mold.git
synced 2024-11-13 09:39:13 +03:00
wip
This commit is contained in:
parent
97f02b1eb3
commit
f9af6357df
@ -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:
|
||||
|
@ -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
18
mold.h
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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
20
test/i386-hello-static.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user