Compare commits

...
Author SHA1 Message Date
Rui Ueyama e82942b3b3 Allow sysroot to be a relative path
Chromium cannot be built with out this patch.
2021-07-14 18:20:29 +09:00
Rui Ueyama ef6e4df81c Fix sysroot handling
Fix https://github.com/rui314/mold/issues/59
2021-07-14 18:20:21 +09:00
Rui Ueyama 5386ece824 Fix handling of --sysroot
Fixes https://github.com/rui314/mold/issues/59
2021-07-14 18:20:16 +09:00
Rui Ueyama 191a69e36f Fix a broken test
Fixes https://github.com/rui314/mold/issues/89
2021-07-13 19:33:33 +09:00
Rui Ueyama 6695c49379 Bump mold version to 0.9.2 2021-07-12 13:51:34 +09:00
Artur Sinila dd116fb3a7 Fix test/run.sh for cases when /usr/bin/ld -> /usr/bin/mold
Signed-off-by: Artur Sinila <[email protected]>
2021-07-12 13:50:53 +09:00
Rui Ueyama 6c2df40850 Align section header to a E::wordsize boundary
Fixes https://github.com/rui314/mold/issues/80
2021-07-08 17:45:36 +09:00
Rui Ueyama 09f01b4377 Fix regexp 2021-07-08 17:45:28 +09:00
Nehal J Wani 683bae0ec5 Do not replace IFUNC with FUNC in .dynsym
This is a partial revert of dd04357

Signed-off-by: Nehal J Wani <[email protected]>
2021-07-08 17:45:12 +09:00
Nehal J Wani 19fd8fc80c Ensure correct visibility of symbols in .dynsym section
Signed-off-by: Nehal J Wani <[email protected]>
2021-07-08 17:45:04 +09:00
Rui Ueyama 165f74e43c Fix assertion failures
mold failed with `make EXTRA_CPPFLAGS="-Wp,-D_GLIBCXX_ASSERTIONS" test`,
which enables extra assertions.

Thanks for @nehaljwani to find out the flag.
2021-07-08 17:44:34 +09:00
Nehal J Wani 8de8ab49ca Fix out of bound check in get_shndx()
Assert failure:
/usr/include/c++/11.1.0/span:276:
  std::span::reference
  std::span<ElfSym<X86_64>, 18446744073709551615>
     ::operator[](std::span::size_type)
         const [_Type = ElfSym<X86_64>, _Extent = 18446744073709551615]:
           Assertion '__idx < size()' failed.

GDB stacktrace:
Thread 2.4 "mold" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fabc3d3f640 (LWP 17804)]
0x00007fabc496fd22 in raise () from /usr/lib/libc.so.6
(gdb) bt
 #0  0x00007fabc496fd22 in raise () from /usr/lib/libc.so.6
 #1  0x00007fabc4959862 in abort () from /usr/lib/libc.so.6
 #2  0x000055a9685eb018 in std::__replacement_assert (...)
     at /usr/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/c++config.h:504
 #3  0x000055a968614c47 in std::span<ElfSym<X86_64>, ...>::operator[] (...)
     at /usr/include/c++/11.1.0/span:276
 #4  ObjectFile<X86_64>::get_shndx (this=<...>, esym=...) at ./mold.h:2145
 #5  ObjectFile<X86_64>::get_section (this=<...>, esym=...) at ./mold.h:2154

Signed-off-by: Nehal J Wani <[email protected]>
2021-07-08 17:44:24 +09:00
Nehal J Wani 14078d38ab [tests] Improve test for -spare-dynamic-tags
The default size and offsets of the .dynamic section are not necessarily
same with different builds of clang. For example, some builds can make
clang pass --hash-style=gnu to the linker and some --hash-style=both.

This change updates the test to compute the difference in size of the
.dynamic section before and after using the flag -spare-dynamic-tags,
making it independent of the compiler build.

Signed-off-by: Nehal J Wani <[email protected]>
2021-07-08 17:43:57 +09:00
Rui Ueyama 87204bf7bf Create $PREFIX/bin if not exists 2021-07-08 17:43:19 +09:00
Rui Ueyama e526945f5d Fix tests for non-Ubuntu-20 systems
Fixes https://github.com/rui314/mold/issues/67
2021-07-04 00:29:27 +09:00
Nehal J Wani 6a5626e3a7 [tests] Fix pie test when cc isn't built with --enable-default-pie
mold: /__w/mold/mold/test/tmp/pie/a.o:(.text): R_X86_64_32 relocation
       against symbol `.rodata' can not be used; recompile with -fPIE
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Signed-off-by: Nehal J Wani <[email protected]>
2021-07-04 00:28:57 +09:00
Rui Ueyama e2c0d36c3e Support R_386_TLS_IE relocation 2021-07-04 00:28:29 +09:00
Rui Ueyama 16c23858fd Split a function and add tests 2021-07-04 00:28:05 +09:00
Mitsuo Heijo 4565d27c14 Fix DSO detection for installed with PREFIX
Signed-off-by: Mitsuo Heijo <[email protected]>
2021-07-04 00:27:54 +09:00
Artur Sinila c611fb05c0 Makefile: add $(DESTDIR) to strip 2021-07-02 17:03:59 +09:00
Rui Ueyama 1191627942 Do not set a variable instead of undefine it later 2021-07-02 17:03:41 +09:00
Artur Sinila 776f9ee6e0 Various fixes in Makefile
Signed-off-by: Artur Sinila <[email protected]>
2021-07-02 17:03:29 +09:00
29 changed files with 301 additions and 171 deletions

No files matched your search

+23 -16
View File
@@ -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
+9
View File
@@ -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;
+10 -1
View File
@@ -497,7 +497,7 @@ void parse_nonpositional_args(Context<E> &ctx,
ctx.arg.filler = parse_hex(ctx, "filler", arg);
} else if (read_arg(ctx, args, arg, "L") ||
read_arg(ctx, args, arg, "library-path")) {
ctx.arg.library_paths.push_back(arg);
ctx.arg.library_paths.push_back(std::string(arg));
} else if (read_arg(ctx, args, arg, "sysroot")) {
ctx.arg.sysroot = arg;
} else if (read_arg(ctx, args, arg, "unique")) {
@@ -797,6 +797,15 @@ void parse_nonpositional_args(Context<E> &ctx,
}
}
if (!ctx.arg.sysroot.empty()) {
for (std::string &path : ctx.arg.library_paths) {
if (std::string_view(path).starts_with('='))
path = std::string(ctx.arg.sysroot) + path.substr(1);
else if (std::string_view(path).starts_with("$SYSROOT"))
path = std::string(ctx.arg.sysroot) + path.substr(8);
}
}
if (ctx.arg.shared) {
ctx.arg.pic = true;
ctx.arg.dynamic_linker = "";
+11 -7
View File
@@ -139,26 +139,30 @@ read_output_format(Context<E> &ctx, std::span<std::string_view> tok) {
return tok.subspan(1);
}
template <typename E>
static bool is_in_sysroot(Context<E> &ctx, std::string path) {
std::string sysroot = path_clean(path_to_absolute(ctx.arg.sysroot));
path = path_clean(path_to_absolute(path));
return path_dirname(path).starts_with(sysroot);
}
template <typename E>
static MemoryMappedFile<E> *resolve_path(Context<E> &ctx, std::string_view tok) {
std::string str(unquote(tok));
if (str.starts_with("/"))
// GNU ld prepends the sysroot if a pathname starts with '/' and the
// script being processed is in the sysroot. We do the same.
if (str.starts_with('/') && is_in_sysroot(ctx, current_file<E>->name))
return MemoryMappedFile<E>::must_open(ctx, ctx.arg.sysroot + str);
if (str.starts_with("-l"))
return find_library(ctx, str.substr(2));
if (std::string dir(path_dirname(current_file<E>->name));
MemoryMappedFile<E> *mb = MemoryMappedFile<E>::open(ctx, dir + "/" + str))
return mb;
if (MemoryMappedFile<E> *mb = MemoryMappedFile<E>::open(ctx, str))
return mb;
for (std::string_view dir : ctx.arg.library_paths) {
std::string root = dir.starts_with("/") ? ctx.arg.sysroot : "";
std::string path = root + std::string(dir) + "/" + str;
std::string path = std::string(dir) + "/" + str;
if (MemoryMappedFile<E> *mb = MemoryMappedFile<E>::open(ctx, path))
return mb;
}
+2 -4
View File
@@ -196,8 +196,7 @@ template <typename E>
MemoryMappedFile<E> *find_library(Context<E> &ctx, std::string name) {
if (name.starts_with(':')) {
for (std::string_view dir : ctx.arg.library_paths) {
std::string root = dir.starts_with("/") ? ctx.arg.sysroot : "";
std::string path = root + std::string(dir) + "/" + name.substr(1);
std::string path = std::string(dir) + "/" + name.substr(1);
if (MemoryMappedFile<E> *mb = open_library(ctx, path))
return mb;
}
@@ -205,8 +204,7 @@ MemoryMappedFile<E> *find_library(Context<E> &ctx, std::string name) {
}
for (std::string_view dir : ctx.arg.library_paths) {
std::string root = dir.starts_with("/") ? ctx.arg.sysroot : "";
std::string stem = root + std::string(dir) + "/lib" + name;
std::string stem = std::string(dir) + "/lib" + name;
if (!ctx.is_static)
if (MemoryMappedFile<E> *mb = open_library(ctx, stem + ".so"))
return mb;
+9 -3
View File
@@ -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;
@@ -1467,10 +1471,10 @@ struct Context {
std::unique_ptr<std::unordered_set<std::string_view>> retain_symbols_file;
std::unordered_set<std::string_view> wrap;
std::vector<VersionPattern> version_patterns;
std::vector<std::string> library_paths;
std::vector<std::string_view> auxiliary;
std::vector<std::string_view> exclude_libs;
std::vector<std::string_view> filter;
std::vector<std::string_view> library_paths;
std::vector<std::string_view> trace_symbol;
std::vector<std::string_view> undefined;
std::vector<std::string_view> version_definitions;
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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()));
+1 -1
View File
@@ -21,7 +21,7 @@ int main() {
}
EOF
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.so $t/b.o
clang -fuse-ld=`pwd`/../mold -no-pie -o $t/exe $t/a.so $t/b.o
$t/exe | grep -q 1
echo OK
+2 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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 "); }
-48
View File
@@ -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
+22
View File
@@ -0,0 +1,22 @@
#!/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 -xc -
int main() {}
EOF
mkdir -p $t/foo/bar
rm -f $t/foo/bar/libfoo.a
ar rcs $t/foo/bar/libfoo.a $t/a.o
cat <<EOF > $t/b.script
INPUT(-lfoo)
EOF
clang -o $t/exe -L$t/foo/bar $t/b.script
echo OK
+20
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
mkdir -p $t/foo
cat <<EOF | cc -o $t/foo/a.o -c -xc -
int main() {}
EOF
cat <<EOF > $t/b.script
INPUT(a.o)
EOF
clang -o $t/exe -L$t/foo $t/b.script
echo OK
+36
View File
@@ -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
+4 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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>
+5 -4
View File
@@ -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
+29
View File
@@ -0,0 +1,29 @@
#!/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 -xc -
void foo() {}
EOF
mkdir -p $t/foo/bar
rm -f $t/foo/bar/libfoo.a
ar rcs $t/foo/bar/libfoo.a $t/a.o
cat <<EOF > $t/foo/bar/b.script
INPUT(/foo/bar/libfoo.a)
EOF
cat <<EOF | cc -o $t/c.o -c -xc -
void foo();
int main() { foo(); }
EOF
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=$t/ $t/foo/bar/b.script
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=tmp/$(basename -s .sh $0)/ $t/foo/bar/b.script
echo OK
+44
View File
@@ -0,0 +1,44 @@
#!/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 | clang -c -o $t/a.o -xc -
void foo() {}
EOF
cat <<EOF | clang -c -o $t/b.o -xc -
void bar() {}
EOF
mkdir -p $t/foo/bar
rm -f $t/foo/bar/libfoo.a
ar rcs $t/foo/bar/libfoo.a $t/a.o $t/b.o
cat <<EOF | clang -c -o $t/c.o -xc -
void foo();
int main() {
foo();
}
EOF
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=$t/ \
-Wl,-L=foo/bar -lfoo
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=$t/ \
-Wl,-L=/foo/bar -lfoo
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=$t/ \
'-Wl,-L$SYSROOTfoo/bar' -lfoo
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=$t/ \
'-Wl,-L$SYSROOT/foo/bar' -lfoo
! clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -lfoo >& /dev/null
! clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.o -Wl,--sysroot=$t \
-Wl,-Lfoo/bar -lfoo >& /dev/null
echo OK