mirror of
https://github.com/rui314/mold.git
synced 2026-11-09 04:49:33 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6695c49379 | ||
|
|
dd116fb3a7 | ||
|
|
6c2df40850 | ||
|
|
09f01b4377 | ||
|
|
683bae0ec5 | ||
|
|
19fd8fc80c | ||
|
|
165f74e43c | ||
|
|
8de8ab49ca | ||
|
|
14078d38ab | ||
|
|
87204bf7bf | ||
|
|
e526945f5d | ||
|
|
6a5626e3a7 | ||
|
|
e2c0d36c3e | ||
|
|
16c23858fd | ||
|
|
4565d27c14 | ||
|
|
c611fb05c0 | ||
|
|
1191627942 | ||
|
|
776f9ee6e0 |
No files matched your search
@@ -1,15 +1,14 @@
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
|
||||
MIMALLOC_LIB = mimalloc/out/release/libmimalloc.a
|
||||
GIT_HASH = $(shell [ -d .git ] && git rev-parse HEAD)
|
||||
GIT_HASH ?= $(shell [ -d .git ] && git rev-parse HEAD)
|
||||
|
||||
CPPFLAGS = -g -Imimalloc/include -pthread -std=c++20 \
|
||||
-Wno-deprecated-volatile \
|
||||
-DMOLD_VERSION=\"0.9.1\" \
|
||||
-DMOLD_VERSION=\"0.9.2\" \
|
||||
-DGIT_HASH=\"$(GIT_HASH)\" \
|
||||
$(EXTRA_CPPFLAGS)
|
||||
LDFLAGS = $(EXTRA_LDFLAGS)
|
||||
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||
LIBS = -Wl,-as-needed -lcrypto -pthread -ltbb -lz -lxxhash -ldl
|
||||
OBJS = main.o object_file.o input_sections.o output_chunks.o \
|
||||
mapfile.o perf.o linker_script.o archive_file.o output_file.o \
|
||||
@@ -41,7 +40,12 @@ else
|
||||
# By default, we want to use mimalloc as a memory allocator.
|
||||
# Since replacing the standard malloc is not compatible with ASAN,
|
||||
# we do that only when ASAN is not enabled.
|
||||
LDFLAGS += -Wl,-whole-archive $(MIMALLOC_LIB) -Wl,-no-whole-archive
|
||||
ifdef SYSTEM_MIMALLOC
|
||||
LIBS += -lmimalloc
|
||||
else
|
||||
MIMALLOC_LIB = mimalloc/out/release/libmimalloc.a
|
||||
LIBS += -Wl,-whole-archive $(MIMALLOC_LIB) -Wl,-no-whole-archive
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TSAN), 1)
|
||||
@@ -52,7 +56,7 @@ endif
|
||||
all: mold mold-wrapper.so
|
||||
|
||||
mold: $(OBJS) $(MIMALLOC_LIB)
|
||||
$(CXX) $(CFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LIBS)
|
||||
$(CXX) $(CXXFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LIBS)
|
||||
|
||||
mold-wrapper.so: mold-wrapper.c Makefile
|
||||
$(CC) -fPIC -shared -o $@ $< -ldl
|
||||
@@ -68,20 +72,23 @@ test tests check: all
|
||||
$(MAKE) -C test --output-sync --no-print-directory
|
||||
|
||||
install: all
|
||||
install -m 755 mold $(PREFIX)/bin
|
||||
strip $(PREFIX)/bin/mold
|
||||
install -m 755 -d $(DESTDIR)$(PREFIX)/bin
|
||||
install -m 755 mold $(DESTDIR)$(PREFIX)/bin
|
||||
strip $(DESTDIR)$(PREFIX)/bin/mold
|
||||
|
||||
install -m 755 -d $(PREFIX)/lib/mold
|
||||
install -m 644 mold-wrapper.so $(PREFIX)/lib/mold
|
||||
strip $(PREFIX)/lib/mold/mold-wrapper.so
|
||||
install -m 755 -d $(DESTDIR)$(PREFIX)/lib/mold
|
||||
install -m 644 mold-wrapper.so $(DESTDIR)$(PREFIX)/lib/mold
|
||||
strip $(DESTDIR)$(PREFIX)/lib/mold/mold-wrapper.so
|
||||
|
||||
install -m 644 docs/mold.1 $(PREFIX)/share/man/man1
|
||||
rm -f $(PREFIX)/share/man/man1/mold.1.gz
|
||||
gzip -9 $(PREFIX)/share/man/man1/mold.1
|
||||
install -m 755 -d $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
install -m 644 docs/mold.1 $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/man/man1/mold.1.gz
|
||||
gzip -9 $(DESTDIR)$(PREFIX)/share/man/man1/mold.1
|
||||
|
||||
uninstall:
|
||||
rm -rf $(PREFIX)/bin/mold $(PREFIX)/share/man/man1/mold.1.gz \
|
||||
$(PREFIX)/lib/mold
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/mold
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/man/man1/mold.1.gz
|
||||
rm -rf $(DESTDIR)$(PREFIX)/lib/mold
|
||||
|
||||
clean:
|
||||
rm -rf *.o *~ mold mold-wrapper.so test/tmp
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
enum {
|
||||
R_TLS_GOTIE = R_END + 1,
|
||||
R_TLS_LE,
|
||||
R_TLS_IE,
|
||||
R_TLS_GD,
|
||||
R_TLS_LD,
|
||||
R_TLS_GOTDESC,
|
||||
@@ -133,6 +134,7 @@ static void write_val(Context<I386> &ctx, u64 r_type, u8 *loc, u64 val) {
|
||||
case R_386_TLS_LDM:
|
||||
case R_386_TLS_GOTIE:
|
||||
case R_386_TLS_LE:
|
||||
case R_386_TLS_IE:
|
||||
case R_386_TLS_GD:
|
||||
case R_386_TLS_LDO_32:
|
||||
case R_386_SIZE32:
|
||||
@@ -207,6 +209,9 @@ void InputSection<I386>::apply_reloc_alloc(Context<I386> &ctx, u8 *base) {
|
||||
case R_TLS_LE:
|
||||
write(S + A - ctx.tls_end);
|
||||
break;
|
||||
case R_TLS_IE:
|
||||
write(sym.get_gottp_addr(ctx) + A);
|
||||
break;
|
||||
case R_TLS_GD:
|
||||
write(sym.get_tlsgd_addr(ctx) + A - GOTPLT);
|
||||
break;
|
||||
@@ -405,6 +410,10 @@ void InputSection<I386>::scan_relocations(Context<I386> &ctx) {
|
||||
sym.flags |= NEEDS_GOTTP;
|
||||
rel_types[i] = R_TLS_LE;
|
||||
break;
|
||||
case R_386_TLS_IE:
|
||||
sym.flags |= NEEDS_GOTTP;
|
||||
rel_types[i] = R_TLS_IE;
|
||||
break;
|
||||
case R_386_TLS_GD:
|
||||
sym.flags |= NEEDS_TLSGD;
|
||||
rel_types[i] = R_TLS_GD;
|
||||
|
||||
@@ -358,6 +358,7 @@ public:
|
||||
OutputEhdr() : OutputChunk<E>(this->HEADER) {
|
||||
this->shdr.sh_flags = SHF_ALLOC;
|
||||
this->shdr.sh_size = sizeof(ElfEhdr<E>);
|
||||
this->shdr.sh_addralign = E::wordsize;
|
||||
}
|
||||
|
||||
void copy_buf(Context<E> &ctx) override;
|
||||
@@ -367,7 +368,9 @@ public:
|
||||
template <typename E>
|
||||
class OutputShdr : public OutputChunk<E> {
|
||||
public:
|
||||
OutputShdr() : OutputChunk<E>(this->HEADER) {}
|
||||
OutputShdr() : OutputChunk<E>(this->HEADER) {
|
||||
this->shdr.sh_addralign = E::wordsize;
|
||||
}
|
||||
|
||||
void update_shdr(Context<E> &ctx) override;
|
||||
void copy_buf(Context<E> &ctx) override;
|
||||
@@ -379,6 +382,7 @@ class OutputPhdr : public OutputChunk<E> {
|
||||
public:
|
||||
OutputPhdr() : OutputChunk<E>(this->HEADER) {
|
||||
this->shdr.sh_flags = SHF_ALLOC;
|
||||
this->shdr.sh_addralign = E::wordsize;
|
||||
}
|
||||
|
||||
void update_shdr(Context<E> &ctx) override;
|
||||
@@ -2099,6 +2103,8 @@ inline std::span<ElfRel<E>> InputSection<E>::get_rels(Context<E> &ctx) const {
|
||||
|
||||
template <typename E>
|
||||
inline std::span<FdeRecord<E>> InputSection<E>::get_fdes() const {
|
||||
if (fde_begin == -1)
|
||||
return {};
|
||||
std::span<FdeRecord<E>> span(file.fdes);
|
||||
return span.subspan(fde_begin, fde_end - fde_begin);
|
||||
}
|
||||
@@ -2142,7 +2148,7 @@ inline std::string_view InputFile<E>::get_string(Context<E> &ctx, i64 idx) {
|
||||
template <typename E>
|
||||
inline i64 ObjectFile<E>::get_shndx(const ElfSym<E> &esym) {
|
||||
assert(&elf_syms[0] <= &esym);
|
||||
assert(&esym < &elf_syms[elf_syms.size()]);
|
||||
assert(&esym <= &elf_syms[elf_syms.size() - 1]);
|
||||
|
||||
if (esym.st_shndx == SHN_XINDEX)
|
||||
return symtab_shndx_sec[&esym - &elf_syms[0]];
|
||||
|
||||
+2
-1
@@ -330,7 +330,7 @@ void ObjectFile<E>::read_ehframe(Context<E> &ctx, InputSection<E> &isec) {
|
||||
i64 rel_begin = rel_idx;
|
||||
while (rel_idx < rels.size() && rels[rel_idx].r_offset < end_offset)
|
||||
rel_idx++;
|
||||
assert(begin_offset <= rels[rel_begin].r_offset);
|
||||
assert(rel_idx == rels.size() || begin_offset <= rels[rel_begin].r_offset);
|
||||
|
||||
if (id == 0) {
|
||||
// This is CIE.
|
||||
@@ -836,6 +836,7 @@ void ObjectFile<E>::resolve_lazy_symbols(Context<E> &ctx) {
|
||||
std::lock_guard lock(sym.mu);
|
||||
if (get_rank(this, esym, true) < get_rank(sym)) {
|
||||
sym.file = this;
|
||||
sym.sym_idx = i;
|
||||
sym.is_lazy = true;
|
||||
sym.is_weak = false;
|
||||
if (sym.traced)
|
||||
|
||||
+1
-2
@@ -969,8 +969,6 @@ void DynsymSection<E>::copy_buf(Context<E> &ctx) {
|
||||
|
||||
memset(&esym, 0, sizeof(esym));
|
||||
esym.st_type = sym.esym().st_type;
|
||||
if (esym.st_type == STT_GNU_IFUNC)
|
||||
esym.st_type = STT_FUNC;
|
||||
esym.st_size = sym.esym().st_size;
|
||||
|
||||
if (sym.is_weak)
|
||||
@@ -1003,6 +1001,7 @@ void DynsymSection<E>::copy_buf(Context<E> &ctx) {
|
||||
} else {
|
||||
esym.st_shndx = sym.input_section->output_section->shndx;
|
||||
esym.st_value = sym.get_addr(ctx, false);
|
||||
esym.st_visibility = sym.visibility;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-11
@@ -252,6 +252,27 @@ static std::string get_self_path(Context<E> &ctx) {
|
||||
return {buf, n};
|
||||
}
|
||||
|
||||
static bool is_regular_file(const std::string &path) {
|
||||
struct stat st;
|
||||
return !stat(path.c_str(), &st) && (st.st_mode & S_IFMT) == S_IFREG;
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
std::string find_dso(Context<E> &ctx, const std::string &self) {
|
||||
// Look for mold-wrapper.so from the same directory as the executable is.
|
||||
std::string path = std::string(path_dirname(self)) + "/mold-wrapper.so";
|
||||
if (is_regular_file(path))
|
||||
return path;
|
||||
|
||||
// If not exist, mold might be installed as $PREFIX/bin/mold and the
|
||||
// DSO as $PREFIX/lib/mold/mold-wrapper.so.
|
||||
path = path_clean(self + "/../../lib/mold/mold-wrapper.so");
|
||||
if (is_regular_file(path))
|
||||
return path;
|
||||
|
||||
Fatal(ctx) << "mold-wrapper.so is missing";
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
[[noreturn]]
|
||||
void process_run_subcommand(Context<E> &ctx, int argc, char **argv) {
|
||||
@@ -262,17 +283,7 @@ void process_run_subcommand(Context<E> &ctx, int argc, char **argv) {
|
||||
|
||||
// Get the mold-wrapper.so path
|
||||
std::string self = get_self_path(ctx);
|
||||
std::string dso_path;
|
||||
if (self == "/usr/bin/mold")
|
||||
dso_path = "/usr/lib/mold/mold-wrapper.so";
|
||||
else if (self == "/usr/local/bin/mold")
|
||||
dso_path = "/usr/local/lib/mold/mold-wrapper.so";
|
||||
else
|
||||
dso_path = std::string(path_dirname(self)) + "/mold-wrapper.so";
|
||||
|
||||
struct stat st;
|
||||
if (stat(dso_path.c_str(), &st) || (st.st_mode & S_IFMT) != S_IFREG)
|
||||
Fatal(ctx) << dso_path << " is missing";
|
||||
std::string dso_path = find_dso(ctx, self);
|
||||
|
||||
// Set environment variables
|
||||
putenv(strdup(("LD_PRELOAD=" + dso_path).c_str()));
|
||||
|
||||
@@ -22,9 +22,7 @@ EOF
|
||||
clang -fuse-ld=`pwd`/../mold $t/a.o $t/b.so -o $t/exe
|
||||
readelf -a $t/exe > $t/log
|
||||
|
||||
fgrep -q '[21] .dynbss.rel.ro' $t/log
|
||||
fgrep -q '[24] .dynbss' $t/log
|
||||
fgrep -q '100 OBJECT GLOBAL DEFAULT 21 readonly' $t/log
|
||||
fgrep -q '100 OBJECT GLOBAL DEFAULT 24 readwrite' $t/log
|
||||
grep -Pqz '(?s)\[(\d+)\] .dynbss.rel.ro .* \1 readonly' $t/log
|
||||
grep -Pqz '(?s)\[(\d+)\] .dynbss .* \1 readwrite' $t/log
|
||||
|
||||
echo OK
|
||||
+6
-8
@@ -18,17 +18,15 @@ EOF
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o
|
||||
readelf -a $t/exe > $t/log
|
||||
|
||||
grep -Pq '\(INIT\)\s+0x201010' $t/log
|
||||
grep -Pq '\(FINI\)\s+0x201000' $t/log
|
||||
grep -Pq '0000000000201010\s+0 FUNC GLOBAL HIDDEN \d+ _init$' $t/log
|
||||
grep -Pq '0000000000201000\s+0 FUNC GLOBAL HIDDEN \d+ _fini$' $t/log
|
||||
grep -Pqz '(?s)\(INIT\)\s+0x([0-9a-f]+)\b.*\1\s+0 FUNC GLOBAL HIDDEN\s+\d+ _init\b' $t/log
|
||||
|
||||
grep -Pqz '(?s)\(FINI\)\s+0x([0-9a-f]+)\b.*\1\s+0 FUNC GLOBAL HIDDEN\s+\d+ _fini\b' $t/log
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o -Wl,-init,init -Wl,-fini,fini
|
||||
readelf -a $t/exe > $t/log
|
||||
|
||||
grep -Pq '\(INIT\)\s+0x201119' $t/log
|
||||
grep -Pq '\(FINI\)\s+0x20111a' $t/log
|
||||
grep -Pq '0000000000201119\s+0 NOTYPE GLOBAL DEFAULT \d+ init$' $t/log
|
||||
grep -Pq '000000000020111a\s+0 NOTYPE GLOBAL DEFAULT \d+ fini$' $t/log
|
||||
grep -Pqz '(?s)\(INIT\)\s+0x([0-9a-f]+)\b.*\1\s+0 NOTYPE GLOBAL DEFAULT\s+\d+ init\b' $t/log
|
||||
|
||||
grep -Pqz '(?s)\(FINI\)\s+0x([0-9a-f]+)\b.*\1\s+0 NOTYPE GLOBAL DEFAULT\s+\d+ fini\b' $t/log
|
||||
|
||||
echo OK
|
||||
+4
-15
@@ -7,25 +7,14 @@ mkdir -p $t
|
||||
|
||||
echo '.globl main; main:' | cc -o $t/a.o -c -x assembler -
|
||||
|
||||
../mold -o $t/exe /usr/lib/x86_64-linux-gnu/crt1.o \
|
||||
/usr/lib/x86_64-linux-gnu/crti.o \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o \
|
||||
$t/a.o \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o \
|
||||
/usr/lib/x86_64-linux-gnu/crtn.o \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a \
|
||||
/usr/lib/x86_64-linux-gnu/libgcc_s.so.1 \
|
||||
/lib/x86_64-linux-gnu/libc.so.6 \
|
||||
/usr/lib/x86_64-linux-gnu/libc_nonshared.a \
|
||||
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o
|
||||
|
||||
readelf --dynamic $t/exe > $t/log
|
||||
fgrep -q 'Shared library: [libgcc_s.so.1]' $t/log
|
||||
fgrep -q 'Shared library: [libc.so.6]' $t/log
|
||||
fgrep -q 'Shared library: [ld-linux-x86-64.so.2]' $t/log
|
||||
|
||||
readelf --symbols --use-dynamic $t/exe > $t/log2
|
||||
fgrep -q 'FUNC GLOBAL DEFAULT UND __libc_start_main' $t/log2
|
||||
readelf -W --symbols --use-dynamic $t/exe > $t/log2
|
||||
grep -Pq 'FUNC\s+GLOBAL\s+DEFAULT\s+UND\s+__libc_start_main' $t/log2
|
||||
|
||||
cat <<EOF | clang -c -fPIC -o $t/b.o -xc -
|
||||
#include <stdio.h>
|
||||
@@ -37,6 +26,6 @@ EOF
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe -pie $t/b.o
|
||||
count=$(readelf --relocs $t/exe | grep R_X86_64_RELATIVE | wc -l)
|
||||
readelf --dynamic $t/exe | grep -q "RELACOUNT.*\b$count\b"
|
||||
readelf -W --dynamic $t/exe | grep -q "RELACOUNT.*\b$count\b"
|
||||
|
||||
echo OK
|
||||
+1
-14
@@ -20,20 +20,7 @@ msg:
|
||||
.string "Hello world\n"
|
||||
EOF
|
||||
|
||||
../mold -o $t/exe \
|
||||
-dynamic-linker=/lib64/ld-linux-x86-64.so.2 \
|
||||
/usr/lib/x86_64-linux-gnu/crt1.o \
|
||||
/usr/lib/x86_64-linux-gnu/crti.o \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o \
|
||||
$t/a.o \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a \
|
||||
/usr/lib/x86_64-linux-gnu/libgcc_s.so.1 \
|
||||
/lib/x86_64-linux-gnu/libc.so.6 \
|
||||
/usr/lib/x86_64-linux-gnu/libc_nonshared.a \
|
||||
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o \
|
||||
/usr/lib/x86_64-linux-gnu/crtn.o
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o
|
||||
$t/exe | grep -q 'Hello world'
|
||||
|
||||
echo OK
|
||||
@@ -32,6 +32,6 @@ resolve_foobar:
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -shared -o $t/b.so $t/a.o
|
||||
readelf --dyn-syms $t/b.so | grep -Pq '0 FUNC GLOBAL DEFAULT \d+ foobar'
|
||||
readelf --dyn-syms $t/b.so | grep -Pq '0 (IFUNC|<OS specific>: 10)\s+GLOBAL DEFAULT \d+ foobar'
|
||||
|
||||
echo OK
|
||||
+1
-1
@@ -16,6 +16,6 @@ EOF
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o -Wl,--image-base=0x8000000
|
||||
$t/exe | grep -q 'Hello world'
|
||||
readelf --sections $t/exe | grep -Pq '.interp\s+PROGBITS\s+00000000080002e0'
|
||||
readelf -W --sections $t/exe | grep -Pq '.interp\s+PROGBITS\s+0000000008000...\b'
|
||||
|
||||
echo OK
|
||||
+2
-2
@@ -5,7 +5,7 @@ echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/tmp/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | clang -c -o $t/a.o -x assembler -
|
||||
cat <<EOF | cc -c -o $t/a.o -x assembler -Wa,-no-warn -
|
||||
.globl init1, init2, fini1, fini2
|
||||
|
||||
.section .init_array,"aw",@progbits
|
||||
@@ -25,7 +25,7 @@ cat <<EOF | clang -c -o $t/a.o -x assembler -
|
||||
.quad fini2
|
||||
EOF
|
||||
|
||||
cat <<EOF | clang -c -o $t/b.o -xc -
|
||||
cat <<EOF | cc -c -o $t/b.o -xc -
|
||||
#include <stdio.h>
|
||||
|
||||
void init1() { printf("init1 "); }
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/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 -o $t/a.o -c -x assembler -
|
||||
.text
|
||||
.globl main
|
||||
main:
|
||||
lea msg(%rip), %rdi
|
||||
xor %rax, %rax
|
||||
call printf
|
||||
xor %rax, %rax
|
||||
ret
|
||||
|
||||
.data
|
||||
msg:
|
||||
.string "Hello world\n"
|
||||
EOF
|
||||
|
||||
|
||||
../mold -static -o $t/exe \
|
||||
/usr/lib/x86_64-linux-gnu/crt1.o \
|
||||
/usr/lib/x86_64-linux-gnu/crti.o \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o \
|
||||
-L/usr/lib/gcc/x86_64-linux-gnu/9 \
|
||||
-L/usr/lib/x86_64-linux-gnu \
|
||||
-L/usr/lib64 \
|
||||
-L/lib/x86_64-linux-gnu \
|
||||
-L/lib64 \
|
||||
-L/usr/lib/x86_64-linux-gnu \
|
||||
-L/usr/lib64 \
|
||||
-L/usr/lib64 \
|
||||
-L/usr/lib \
|
||||
-L/lib \
|
||||
-L/usr/lib \
|
||||
$t/a.o \
|
||||
-lgcc \
|
||||
-lgcc_eh \
|
||||
-lc \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o \
|
||||
/usr/lib/x86_64-linux-gnu/crtn.o
|
||||
|
||||
$t/exe | grep -q 'Hello world'
|
||||
|
||||
echo OK
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd $(dirname $0)
|
||||
echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/tmp/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
rm -rf $t
|
||||
mkdir -p $t/bin $t/lib/mold
|
||||
cp ../mold $t/bin
|
||||
|
||||
$t/bin/mold -run true 2>&1 | grep -q 'mold-wrapper.so is missing'
|
||||
|
||||
rm -rf $t
|
||||
mkdir -p $t/bin $t/lib/mold
|
||||
cp ../mold $t/bin
|
||||
cp ../mold-wrapper.so $t/bin
|
||||
|
||||
$t/bin/mold -run bash -c 'echo $LD_PRELOAD' | grep -q '/bin/mold-wrapper.so'
|
||||
|
||||
rm -rf $t
|
||||
mkdir -p $t/bin $t/lib/mold
|
||||
cp ../mold $t/bin
|
||||
cp ../mold-wrapper.so $t/lib/mold
|
||||
|
||||
$t/bin/mold -run bash -c 'echo $LD_PRELOAD' | grep -q '/lib/mold/mold-wrapper.so'
|
||||
|
||||
rm -rf $t
|
||||
mkdir -p $t/bin $t/lib/mold
|
||||
cp ../mold $t/bin
|
||||
cp ../mold-wrapper.so $t/bin
|
||||
cp ../mold-wrapper.so $t/lib/mold
|
||||
|
||||
$t/bin/mold -run bash -c 'echo $LD_PRELOAD' | grep -q '/bin/mold-wrapper.so'
|
||||
|
||||
echo OK
|
||||
@@ -6,21 +6,17 @@ t=$(pwd)/tmp/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | clang -fcf-protection=branch -c -o $t/a.o -xc -
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
void _start() {}
|
||||
EOF
|
||||
|
||||
cat <<EOF | clang -fcf-protection=none -c -o $t/b.o -xc -
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
void _start() {}
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o
|
||||
../mold -o $t/exe $t/a.o
|
||||
readelf -n $t/exe | grep -q 'x86 feature: IBT'
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/b.o
|
||||
../mold -o $t/exe $t/b.o
|
||||
! readelf -n $t/exe | grep -q 'x86 feature: IBT' || false
|
||||
|
||||
echo OK
|
||||
+1
-1
@@ -5,7 +5,7 @@ echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/tmp/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | cc -o $t/a.o -c -xc -
|
||||
cat <<EOF | cc -o $t/a.o -c -xc -fPIE -
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
|
||||
+4
-4
@@ -14,21 +14,21 @@ int main() {
|
||||
}
|
||||
EOF
|
||||
|
||||
gcc -o $t/exe $t/a.o
|
||||
gcc -fuse-ld=bfd -o $t/exe $t/a.o
|
||||
readelf -p .comment $t/exe > $t/log
|
||||
! grep -q mold $t/log || false
|
||||
|
||||
clang -o $t/exe $t/a.o
|
||||
clang -fuse-ld=bfd -o $t/exe $t/a.o
|
||||
readelf -p .comment $t/exe > $t/log
|
||||
! grep -q mold $t/log || false
|
||||
|
||||
LD_PRELOAD=`pwd`/../mold-wrapper.so MOLD_PATH=`pwd`/../mold \
|
||||
gcc -o $t/exe $t/a.o
|
||||
gcc -o $t/exe $t/a.o -B/usr/bin
|
||||
readelf -p .comment $t/exe > $t/log
|
||||
grep -q mold $t/log
|
||||
|
||||
LD_PRELOAD=`pwd`/../mold-wrapper.so MOLD_PATH=`pwd`/../mold \
|
||||
clang -o $t/exe $t/a.o
|
||||
clang -o $t/exe $t/a.o -fuse-ld=/usr/bin/ld
|
||||
readelf -p .comment $t/exe > $t/log
|
||||
grep -q mold $t/log
|
||||
|
||||
|
||||
+28
-14
@@ -5,24 +5,38 @@ echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/tmp/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | clang -c -fPIC -o $t/a.o -x assembler -
|
||||
.globl main
|
||||
.align 8192
|
||||
main:
|
||||
call hello
|
||||
xor %eax, %eax
|
||||
ret
|
||||
EOF
|
||||
|
||||
cat <<EOF | clang -c -fPIC -o $t/b.o -xc -
|
||||
cat <<'EOF' | clang -c -o $t/a.o -xc -
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void hello() {
|
||||
printf("Hello world\n");
|
||||
__attribute__((aligned(8192))) int foo = 1;
|
||||
|
||||
typedef struct {
|
||||
uint8_t e_ident[16];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
uint64_t e_entry;
|
||||
uint64_t e_phoff;
|
||||
uint64_t e_shoff;
|
||||
uint32_t e_flags;
|
||||
uint16_t e_ehsize;
|
||||
uint16_t e_phentsize;
|
||||
uint16_t e_phnum;
|
||||
uint16_t e_shentsize;
|
||||
uint16_t e_shnum;
|
||||
uint16_t e_shstrndx;
|
||||
} Ehdr;
|
||||
|
||||
char __ehdr_start;
|
||||
|
||||
int main() {
|
||||
Ehdr *e = (Ehdr *)&__ehdr_start;
|
||||
printf("%lu %lu %lu\n", e->e_phoff % 8, e->e_shoff % 8, (uint64_t)&foo % 8192);
|
||||
}
|
||||
EOF
|
||||
|
||||
clang -fPIE -o $t/exe $t/a.o $t/b.o
|
||||
$t/exe | grep -q 'Hello world'
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o
|
||||
$t/exe | grep -q '^0 0 0$'
|
||||
|
||||
echo OK
|
||||
+1
-1
@@ -19,7 +19,7 @@ clang -shared -fuse-ld=`pwd`/../mold -o $t/b.so $t/a.o
|
||||
readelf --dyn-syms $t/b.so > $t/log
|
||||
|
||||
grep -q '0000000000000000 0 NOTYPE GLOBAL DEFAULT UND fn2' $t/log
|
||||
grep -q '000000000000111c 0 NOTYPE GLOBAL DEFAULT 15 fn1' $t/log
|
||||
grep -Pq '0 NOTYPE GLOBAL DEFAULT \d+ fn1' $t/log
|
||||
|
||||
cat <<EOF | clang -fPIC -c -o $t/c.o -xc -
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -8,11 +8,12 @@ mkdir -p $t
|
||||
echo '.globl main; main:' | cc -o $t/a.o -c -x assembler -
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o
|
||||
readelf --wide --sections $t/exe > $t/log
|
||||
grep -Pq '\.dynamic.*\b0001b0\b' $t/log
|
||||
size_before=$((16#$(readelf --wide --sections $t/exe | grep .dynamic | tr -s ' ' | cut -d ' ' -f7)))
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o -Wl,-spare-dynamic-tags=100
|
||||
readelf --wide --sections $t/exe > $t/log
|
||||
grep -Pq '\.dynamic.*\b002010\b' $t/log
|
||||
size_after=$((16#$(readelf --wide --sections $t/exe | grep .dynamic | tr -s ' ' | cut -d ' ' -f7)))
|
||||
|
||||
# Ensure space for 95 additional spare tags has been added (default: 5)
|
||||
[[ $(( $size_after - $size_before )) == $(( 16*95 )) ]]
|
||||
|
||||
echo OK
|
||||
Reference in new issue
Block a user