ELF: Don't use LayoutPass.

Previously we applied the LayoutPass to order atoms and then
apply elf::ArrayOrderPass to sort them again. The first pass is
basically supposed to sort atoms in the normal fashion (which
is to sort symbols in the same order as the input files).
The second pass sorts atoms in {init,fini}_array.<priority> by
priority.

The problem is that the LayoutPass is overkill. It analyzes
references between atoms to make a decision how to sort them.
It's slow, hard to understand, and above all, it doesn't seem
that we need its feature for ELF in the first place.

This patch remove the LayoutPass from ELF pass list. Now all
reordering is done in elf::OrderPass. That pass sorts atoms by
{init,fini}_array, and if they are not in the special section,
they are ordered as the same order as they appear in the command
line. The new code is far easier to understand, faster, and
still able to create valid executables.

Unlike the previous layout pass, elf::OrderPass doesn't count
any attributes of an atom (e.g. permissions) except its
position. It's OK because the writer takes care of them if we
have to.

This patch changes the order of final output, although that's
benign. Tests are updated.

http://reviews.llvm.org/D7278

llvm-svn: 227666
This commit is contained in:
Rui Ueyama 2015-01-31 02:05:01 +00:00
parent e41a26e4b4
commit 33ab83bc4b
27 changed files with 308 additions and 333 deletions

View File

@ -349,6 +349,10 @@ public:
atomContentType == DefinedAtom::typeGnuLinkOnce);
}
// Returns true if lhs should be placed before rhs in the final output.
static bool compareByPosition(const DefinedAtom *lhs,
const DefinedAtom *rhs);
protected:
// DefinedAtom is an abstract base class. Only subclasses can access
// constructor.

View File

@ -9,11 +9,10 @@
#include "llvm/Support/ErrorHandling.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/File.h"
namespace lld {
DefinedAtom::ContentPermissions DefinedAtom::permissions() const {
// By default base permissions on content type.
return permissions(this->contentType());
@ -82,6 +81,14 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
llvm_unreachable("unknown content type");
}
bool DefinedAtom::compareByPosition(const DefinedAtom *lhs,
const DefinedAtom *rhs) {
const File *lhsFile = &lhs->file();
const File *rhsFile = &rhs->file();
if (lhsFile->ordinal() != rhsFile->ordinal())
return lhsFile->ordinal() < rhsFile->ordinal();
assert(lhs->ordinal() != rhs->ordinal());
return lhs->ordinal() < rhs->ordinal();
}
} // namespace

View File

@ -1,56 +0,0 @@
//===- lib/ReaderWriter/ELF/ArrayOrderPass.cpp ----------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ArrayOrderPass.h"
#include <algorithm>
#include <limits>
namespace lld {
namespace elf {
void ArrayOrderPass::perform(std::unique_ptr<MutableFile> &f) {
auto definedAtoms = f->definedAtoms();
// Move sections need to be sorted into the separate continious group.
// That reduces a number of sorting elements and simplifies conditions
// in the sorting predicate.
auto last = std::stable_partition(definedAtoms.begin(), definedAtoms.end(),
[](const DefinedAtom *atom) {
if (atom->sectionChoice() != DefinedAtom::sectionCustomRequired)
return false;
StringRef name = atom->customSectionName();
return name.startswith(".init_array") || name.startswith(".fini_array");
});
std::stable_sort(definedAtoms.begin(), last,
[](const DefinedAtom *left, const DefinedAtom *right) {
StringRef leftSec = left->customSectionName();
StringRef rightSec = right->customSectionName();
// Drop the front dot from the section name and get
// an optional section's number starting after the second dot.
StringRef leftNum = leftSec.drop_front().rsplit('.').second;
StringRef rightNum = rightSec.drop_front().rsplit('.').second;
// Sort {.init_array, .fini_array}[.<num>] sections
// according to their number. Sections without optional
// numer suffix should go last.
uint32_t leftPriority;
uint32_t rightPriority;
if (leftNum.getAsInteger(10, leftPriority))
leftPriority = std::numeric_limits<uint32_t>::max();
if (rightNum.getAsInteger(10, rightPriority))
rightPriority = std::numeric_limits<uint32_t>::max();
return leftPriority < rightPriority;
});
}
} // end namespace elf
} // end namespace lld

View File

@ -1,26 +0,0 @@
//===- lib/ReaderWriter/ELF/ArrayOrderPass.h ------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_ELF_ARRAY_ORDER_PASS_H
#define LLD_READER_WRITER_ELF_ARRAY_ORDER_PASS_H
#include "lld/Core/Pass.h"
namespace lld {
namespace elf {
/// \brief This pass sorts atoms in .{init,fini}_array.<priority> sections.
class ArrayOrderPass : public Pass {
public:
ArrayOrderPass() : Pass() {}
void perform(std::unique_ptr<MutableFile> &mergedFile) override;
};
}
}
#endif

View File

@ -1,5 +1,4 @@
add_llvm_library(lldELF
ArrayOrderPass.cpp
ELFLinkingContext.cpp
Reader.cpp
Writer.cpp

View File

@ -8,12 +8,11 @@
//===----------------------------------------------------------------------===//
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "ArrayOrderPass.h"
#include "ELFFile.h"
#include "OrderPass.h"
#include "TargetHandler.h"
#include "lld/Core/Instrumentation.h"
#include "lld/Core/SharedLibraryFile.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Config/config.h"
@ -66,8 +65,7 @@ ELFLinkingContext::ELFLinkingContext(
_finiFunction("_fini"), _sysrootPath("") {}
void ELFLinkingContext::addPasses(PassManager &pm) {
pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
pm.add(std::unique_ptr<Pass>(new elf::ArrayOrderPass()));
pm.add(std::unique_ptr<Pass>(new elf::OrderPass()));
}
uint16_t ELFLinkingContext::getOutputMachine() const {

View File

@ -0,0 +1,70 @@
//===- lib/ReaderWriter/ELF/OrderPass.h -----------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_ELF_ORDER_PASS_H
#define LLD_READER_WRITER_ELF_ORDER_PASS_H
#include "lld/Core/Parallel.h"
#include <algorithm>
#include <limits>
namespace lld {
namespace elf {
/// \brief This pass sorts atoms by file and atom ordinals.
/// .{init,fini}_array.<priority> sections are handled specially.
class OrderPass : public Pass {
public:
void perform(std::unique_ptr<MutableFile> &file) override {
MutableFile::DefinedAtomRange defined = file->definedAtoms();
auto last = std::partition(defined.begin(), defined.end(), isInitFini);
parallel_sort(defined.begin(), last, compareInitFini);
parallel_sort(last, defined.end(), DefinedAtom::compareByPosition);
}
private:
static bool isInitFini(const DefinedAtom *atom) {
if (atom->sectionChoice() != DefinedAtom::sectionCustomRequired)
return false;
StringRef name = atom->customSectionName();
return name.startswith(".init_array") || name.startswith(".fini_array");
}
static bool compareInitFini(const DefinedAtom *lhs, const DefinedAtom *rhs) {
StringRef lhsSec = lhs->customSectionName();
StringRef rhsSec = rhs->customSectionName();
// Drop the front dot from the section name and get
// an optional section's number starting after the second dot.
StringRef lhsNum = lhsSec.drop_front().rsplit('.').second;
StringRef rhsNum = rhsSec.drop_front().rsplit('.').second;
// Sort {.init_array, .fini_array}[.<num>] sections
// according to their number. Sections without optional
// numer suffix should go last.
uint32_t lhsPriority;
uint32_t rhsPriority;
if (lhsNum.getAsInteger(10, lhsPriority))
lhsPriority = std::numeric_limits<uint32_t>::max();
if (rhsNum.getAsInteger(10, rhsPriority))
rhsPriority = std::numeric_limits<uint32_t>::max();
if (lhsPriority != rhsPriority)
return lhsPriority < rhsPriority;
// If both atoms have the same priority, fall back to default.
return DefinedAtom::compareByPosition(lhs, rhs);
}
};
}
}
#endif

View File

@ -37,15 +37,6 @@
namespace lld {
namespace pecoff {
static bool compareByPosition(const DefinedAtom *lhs, const DefinedAtom *rhs) {
const File *lhsFile = &lhs->file();
const File *rhsFile = &rhs->file();
if (lhsFile->ordinal() != rhsFile->ordinal())
return lhsFile->ordinal() < rhsFile->ordinal();
assert(lhs->ordinal() != rhs->ordinal());
return lhs->ordinal() < rhs->ordinal();
}
static bool compare(const DefinedAtom *lhs, const DefinedAtom *rhs) {
bool lhsCustom = (lhs->sectionChoice() == DefinedAtom::sectionCustomRequired);
bool rhsCustom = (rhs->sectionChoice() == DefinedAtom::sectionCustomRequired);
@ -53,13 +44,13 @@ static bool compare(const DefinedAtom *lhs, const DefinedAtom *rhs) {
int cmp = lhs->customSectionName().compare(rhs->customSectionName());
if (cmp != 0)
return cmp < 0;
return compareByPosition(lhs, rhs);
return DefinedAtom::compareByPosition(lhs, rhs);
}
if (lhsCustom && !rhsCustom)
return true;
if (!lhsCustom && rhsCustom)
return false;
return compareByPosition(lhs, rhs);
return DefinedAtom::compareByPosition(lhs, rhs);
}
class OrderPass : public lld::Pass {

View File

@ -12,7 +12,7 @@ CHECK: Other: 0
CHECK: Section: .text (0x5)
CHECK: }
CHECK: Symbol {
CHECK: Name: fn (6)
CHECK: Name: fn (11)
CHECK: Value: 0x4001A4
CHECK: Size: 8
CHECK: Binding: Global (0x1)

View File

@ -3,6 +3,63 @@ RUN: lld -flavor gnu -target hexagon %p/Inputs/dynobj.o \
RUN: -o %t --output-filetype=yaml -shared --noinhibit-exec
RUN: FileCheck -check-prefix=CHECKGOTPLT %s < %t
- name: .PLT0
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 1C, C0, 49, 6A, 0E, 42, 9C, E2,
CHECKGOTPLT: 4F, 40, 9C, 91, 3C, C0, 9C, 91, 0E, 42, 0E, 8C,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got0
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got0
CHECKGOTPLT: addend: 4
- name: __plt_fn
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn
CHECKGOTPLT: addend: 4
- name: __plt_fn1
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn1
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn1
CHECKGOTPLT: addend: 4
- name: __plt_fn2
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn2
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn2
CHECKGOTPLT: addend: 4
- name: __got0
CHECKGOTPLT: type: got
CHECKGOTPLT: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
@ -69,60 +126,3 @@ CHECKGOTPLT: target: fn2
CHECKGOTPLT: - kind: R_HEX_32
CHECKGOTPLT: offset: 0
target: .PLT0
- name: .PLT0
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 1C, C0, 49, 6A, 0E, 42, 9C, E2,
CHECKGOTPLT: 4F, 40, 9C, 91, 3C, C0, 9C, 91, 0E, 42, 0E, 8C,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got0
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got0
CHECKGOTPLT: addend: 4
- name: __plt_fn
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn
CHECKGOTPLT: addend: 4
- name: __plt_fn1
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn1
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn1
CHECKGOTPLT: addend: 4
- name: __plt_fn2
CHECKGOTPLT: type: stub
CHECKGOTPLT: content: [ 00, 40, 00, 00, 0E, C0, 49, 6A, 1C, C0, 8E, 91,
CHECKGOTPLT: 00, C0, 9C, 52 ]
CHECKGOTPLT: alignment: 2^4
CHECKGOTPLT: section-name: .plt
CHECKGOTPLT: references:
CHECKGOTPLT: - kind: R_HEX_B32_PCREL_X
CHECKGOTPLT: offset: 0
target: __got_fn2
CHECKGOTPLT: - kind: R_HEX_6_PCREL_X
CHECKGOTPLT: offset: 4
target: __got_fn2
CHECKGOTPLT: addend: 4

View File

@ -9,7 +9,7 @@ CHECKSECTIONSANDSIZE: Section {
CHECKSECTIONSANDSIZE: Name: .sdata (13)
CHECKSECTIONSANDSIZE: Address: 0x1000
CHECKSECTIONSANDSIZE: Offset: 0x1000
CHECKSECTIONSANDSIZE: Size: 20
CHECKSECTIONSANDSIZE: Size: 24
CHECKSECTIONSANDSIZE: }
CHECKSECTIONSANDSIZE: Section {
CHECKSECTIONSANDSIZE: Name: .bss (20)

View File

@ -78,6 +78,17 @@
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: - ref-name: L000
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L007
# CHECK-GOT: - ref-name: L002
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
@ -88,7 +99,7 @@
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L003
# CHECK-GOT: target: L008
# CHECK-GOT: - ref-name: L004
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
@ -97,21 +108,10 @@
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L005
# CHECK-GOT: - ref-name: L006
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_GLOBAL_GOT
# CHECK-GOT: offset: 0
# CHECK-GOT: target: foo
# CHECK-GOT: - ref-name: L007
# CHECK-GOT: - ref-name: L005
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
@ -122,7 +122,7 @@
# CHECK-GOT: - kind: LLD_R_MIPS_GLOBAL_GOT
# CHECK-GOT: offset: 0
# CHECK-GOT: target: ext1
# CHECK-GOT: - ref-name: L008
# CHECK-GOT: - ref-name: L006
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2

View File

@ -74,6 +74,17 @@
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: - ref-name: L000
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L007
# CHECK-GOT: - ref-name: L002
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
@ -84,7 +95,7 @@
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L003
# CHECK-GOT: target: L008
# CHECK-GOT: - ref-name: L004
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
@ -93,21 +104,10 @@
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L005
# CHECK-GOT: - ref-name: L006
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_GLOBAL_GOT
# CHECK-GOT: offset: 0
# CHECK-GOT: target: foo
# CHECK-GOT: - ref-name: L007
# CHECK-GOT: - ref-name: L005
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
@ -118,7 +118,7 @@
# CHECK-GOT: - kind: LLD_R_MIPS_GLOBAL_GOT
# CHECK-GOT: offset: 0
# CHECK-GOT: target: ext1
# CHECK-GOT: - ref-name: L008
# CHECK-GOT: - ref-name: L006
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2

View File

@ -10,8 +10,39 @@
# RUN: llvm-objdump -t -disassemble -mattr=micromips %t2 \
# RUN: | FileCheck -check-prefix RAW %s
# Function glob
# YAML: - name: main
# YAML: scope: global
# YAML: content: [ 5C, FC, 00, 00, 42, 30, 00, 00, 5C, FC, 00, 00,
# YAML: 42, 30, 00, 00, 5C, FC, 00, 00, 5C, FC, 00, 00,
# YAML: 5C, FC, 00, 00 ]
# YAML: alignment: 4 mod 2^4
# YAML: code-model: mips-micro
# YAML: references:
# YAML-NEXT: - kind: R_MICROMIPS_GOT16
# YAML-NEXT: offset: 0
# YAML-NEXT: target: L000
# YAML-NEXT: - kind: R_MICROMIPS_LO16
# YAML-NEXT: offset: 4
# YAML-NEXT: target: data_1
# YAML-NEXT: - kind: R_MICROMIPS_GOT16
# YAML-NEXT: offset: 8
# YAML-NEXT: target: L001
# YAML-NEXT: - kind: R_MICROMIPS_LO16
# YAML-NEXT: offset: 12
# YAML-NEXT: target: data_2
# YAML-NEXT: - kind: R_MICROMIPS_GOT16
# YAML-NEXT: offset: 16
# YAML-NEXT: target: L002
# YAML-NEXT: - kind: R_MICROMIPS_CALL16
# YAML-NEXT: offset: 20
# YAML-NEXT: target: L003
# YAML-NEXT: - kind: R_MICROMIPS_CALL16
# YAML-NEXT: offset: 24
# YAML-NEXT: target: L004
# Local GOT entries:
# YAML: - ref-name: L001
# YAML: - ref-name: L000
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -22,7 +53,7 @@
# YAML-NEXT: - kind: LLD_R_MIPS_32_HI16
# YAML-NEXT: offset: 0
# YAML-NEXT: target: data_1
# YAML-NEXT: - ref-name: L002
# YAML-NEXT: - ref-name: L001
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -33,7 +64,7 @@
# YAML-NEXT: - kind: LLD_R_MIPS_32_HI16
# YAML-NEXT: offset: 0
# YAML-NEXT: target: data_2
# YAML-NEXT: - ref-name: L003
# YAML-NEXT: - ref-name: L002
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -46,7 +77,7 @@
# YAML-NEXT: target: data_h
# Global GOT entries:
# YAML-NEXT: - ref-name: L004
# YAML-NEXT: - ref-name: L003
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -60,7 +91,7 @@
# YAML-NEXT: - kind: R_MIPS_32
# YAML-NEXT: offset: 0
# YAML-NEXT: target: bar
# YAML-NEXT: - ref-name: L005
# YAML-NEXT: - ref-name: L004
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -72,37 +103,6 @@
# YAML-NEXT: offset: 0
# YAML-NEXT: target: foo
# Function glob
# YAML: - name: main
# YAML: scope: global
# YAML: content: [ 5C, FC, 00, 00, 42, 30, 00, 00, 5C, FC, 00, 00,
# YAML: 42, 30, 00, 00, 5C, FC, 00, 00, 5C, FC, 00, 00,
# YAML: 5C, FC, 00, 00 ]
# YAML: alignment: 4 mod 2^4
# YAML: code-model: mips-micro
# YAML: references:
# YAML-NEXT: - kind: R_MICROMIPS_GOT16
# YAML-NEXT: offset: 0
# YAML-NEXT: target: L001
# YAML-NEXT: - kind: R_MICROMIPS_LO16
# YAML-NEXT: offset: 4
# YAML-NEXT: target: data_1
# YAML-NEXT: - kind: R_MICROMIPS_GOT16
# YAML-NEXT: offset: 8
# YAML-NEXT: target: L002
# YAML-NEXT: - kind: R_MICROMIPS_LO16
# YAML-NEXT: offset: 12
# YAML-NEXT: target: data_2
# YAML-NEXT: - kind: R_MICROMIPS_GOT16
# YAML-NEXT: offset: 16
# YAML-NEXT: target: L003
# YAML-NEXT: - kind: R_MICROMIPS_CALL16
# YAML-NEXT: offset: 20
# YAML-NEXT: target: L004
# YAML-NEXT: - kind: R_MICROMIPS_CALL16
# YAML-NEXT: offset: 24
# YAML-NEXT: target: L005
# RAW: Disassembly of section .text:
# RAW: main:
# RAW-NEXT: 164: 5c fc 18 80 lw $2, -32744($gp)

View File

@ -8,8 +8,40 @@
# RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec -o %t2 %t.o
# RUN: llvm-objdump -t -disassemble %t2 | FileCheck -check-prefix RAW %s
# Function glob
# YAML: - name: glob
# YAML: scope: global
# YAML: content: [ 00, 00, 84, 8F, 00, 00, 84, 24, 01, 00, 84, 8F,
# YAML: 00, 02, 84, 24, 00, 00, 84, 8F, 00, 00, 84, 8F,
# YAML: 00, 00, 84, 8F ]
# YAML: alignment: 2^2
# YAML: references:
# YAML: - kind: R_MIPS_GOT16
# YAML: offset: 0
# YAML: target: L000
# YAML: - kind: R_MIPS_LO16
# YAML: offset: 4
# YAML: target: L009
# YAML: - kind: R_MIPS_GOT16
# YAML: offset: 8
# YAML: target: L002
# YAML: addend: 66048
# YAML: - kind: R_MIPS_LO16
# YAML: offset: 12
# YAML: target: L009
# YAML: addend: 512
# YAML: - kind: R_MIPS_GOT16
# YAML: offset: 16
# YAML: target: L004
# YAML: - kind: R_MIPS_CALL16
# YAML: offset: 20
# YAML: target: L005
# YAML: - kind: R_MIPS_CALL16
# YAML: offset: 24
# YAML: target: L006
# Local GOT entries:
# YAML: - ref-name: L003
# YAML: - ref-name: L000
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -19,8 +51,8 @@
# YAML-NEXT: references:
# YAML-NEXT: - kind: LLD_R_MIPS_32_HI16
# YAML-NEXT: offset: 0
# YAML-NEXT: target: L006
# YAML-NEXT: - ref-name: L005
# YAML-NEXT: target: L009
# YAML-NEXT: - ref-name: L002
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -30,9 +62,9 @@
# YAML-NEXT: references:
# YAML-NEXT: - kind: LLD_R_MIPS_32_HI16
# YAML-NEXT: offset: 0
# YAML-NEXT: target: L006
# YAML-NEXT: target: L009
# YAML-NEXT: addend: 66048
# YAML-NEXT: - ref-name: L007
# YAML-NEXT: - ref-name: L004
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -45,7 +77,7 @@
# YAML-NEXT: target: hidden
# Global GOT entries:
# YAML-NEXT: - ref-name: L008
# YAML-NEXT: - ref-name: L005
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -59,7 +91,7 @@
# YAML-NEXT: - kind: R_MIPS_32
# YAML-NEXT: offset: 0
# YAML-NEXT: target: glob
# YAML-NEXT: - ref-name: L009
# YAML-NEXT: - ref-name: L006
# YAML-NEXT: type: got
# YAML-NEXT: content: [ 00, 00, 00, 00 ]
# YAML-NEXT: alignment: 2^2
@ -71,38 +103,6 @@
# YAML-NEXT: offset: 0
# YAML-NEXT: target: extern
# Function glob
# YAML: - name: glob
# YAML: scope: global
# YAML: content: [ 00, 00, 84, 8F, 00, 00, 84, 24, 01, 00, 84, 8F,
# YAML: 00, 02, 84, 24, 00, 00, 84, 8F, 00, 00, 84, 8F,
# YAML: 00, 00, 84, 8F ]
# YAML: alignment: 2^2
# YAML: references:
# YAML: - kind: R_MIPS_GOT16
# YAML: offset: 0
# YAML: target: L003
# YAML: - kind: R_MIPS_LO16
# YAML: offset: 4
# YAML: target: L006
# YAML: - kind: R_MIPS_GOT16
# YAML: offset: 8
# YAML: target: L005
# YAML: addend: 66048
# YAML: - kind: R_MIPS_LO16
# YAML: offset: 12
# YAML: target: L006
# YAML: addend: 512
# YAML: - kind: R_MIPS_GOT16
# YAML: offset: 16
# YAML: target: L007
# YAML: - kind: R_MIPS_CALL16
# YAML: offset: 20
# YAML: target: L008
# YAML: - kind: R_MIPS_CALL16
# YAML: offset: 24
# YAML: target: L009
# RAW: Disassembly of section .text:
# RAW: glob:
# RAW-NEXT: 12c: 18 80 84 8f lw $4, -32744($gp)

View File

@ -15,8 +15,8 @@
#
# PLT-SYM: Relocations [
# PLT-SYM-NEXT: Section (4) .rel.dyn {
# PLT-SYM-NEXT: 0x2000 R_MIPS_REL32 T1 0x0
# PLT-SYM-NEXT: 0x140 R_MIPS_REL32 T1 0x0
# PLT-SYM-NEXT: 0x2000 R_MIPS_REL32 T1 0x0
# PLT-SYM-NEXT: }
# PLT-SYM-NEXT: ]
#

View File

@ -17,8 +17,8 @@
#
# PLT-SYM: Relocations [
# PLT-SYM-NEXT: Section (4) .rel.dyn {
# PLT-SYM-NEXT: 0x2000 R_MIPS_REL32 T1 0x0
# PLT-SYM-NEXT: 0x150 R_MIPS_REL32 T1 0x0
# PLT-SYM-NEXT: 0x2000 R_MIPS_REL32 T1 0x0
# PLT-SYM-NEXT: }
# PLT-SYM-NEXT: ]
#

View File

@ -1,8 +0,0 @@
# This testcase tests the behaviour of the layoutpass so that the atoms that
# appear by their override take preference before proceeding to default behaviour
RUN: lld -flavor gnu -target x86_64 %p/Inputs/rwint.o \
RUN: %p/Inputs/constint.o --output-filetype=yaml -o %t --noinhibit-exec
RUN: FileCheck %s -check-prefix=CHECKORDER < %t
CHECKORDER: - name: b
CHECKORDER: - name: a

View File

@ -8,28 +8,28 @@ RUN: %p/Inputs/object-test.elf-hexagon -o %t1
RUN: FileCheck %s -check-prefix ELF-hexagon < %t1
ELF-i386: defined-atoms:
ELF-i386: - name: global_variable
ELF-i386: - name: uninitialized_static_variable
ELF-i386: - name: global_func
ELF-i386: - name: static_func
ELF-i386: - name: weak_func
ELF-i386: - name: hidden_func
ELF-i386: - name: no_dead_strip
ELF-i386: - name: no_special_section_func
ELF-i386: - name: global_variable
ELF-i386: - name: uninitialized_static_variable
ELF-i386: - name: special_section_func
ELF-i386: undefined-atoms:
ELF-i386: - name: puts
ELF-i386: absolute-atoms:
ELF-i386: - name: sample.c
ELF-hexagon: - name: global_variable
ELF-hexagon: - name: uninitialized_static_variable
ELF-hexagon: - name: global_func
ELF-hexagon: - name: static_func
ELF-hexagon: - name: weak_func
ELF-hexagon: - name: hidden_func
ELF-hexagon: - name: no_dead_strip
ELF-hexagon: - name: no_special_section_func
ELF-hexagon: - name: global_variable
ELF-hexagon: - name: uninitialized_static_variable
ELF-hexagon: - name: special_section_func
ELF-hexagon: undefined-atoms:
ELF-hexagon: - name: puts

View File

@ -9,10 +9,6 @@ RUN: llvm-objdump -p %t >> %t2
RUN: llvm-readobj -s -dyn-symbols -dynamic-table %t >> %t2
RUN: FileCheck %s < %t2
CHECK: type: got
CHECK: references:
CHECK: kind: R_X86_64_JUMP_SLOT
CHECK: name: main
CHECK: kind: R_X86_64_PC32
CHECK: offset: 18
@ -21,6 +17,10 @@ CHECK: target: [[PLTNAME:[-a-zA-Z0-9_]+]]
CHECK: name: [[PLTNAME]]
CHECK: type: stub
CHECK: type: got
CHECK: references:
CHECK: kind: R_X86_64_JUMP_SLOT
CHECK: shared-library-atoms:
CHECK: name: foo
CHECK: load-name: shared.so-x86-64

View File

@ -3,20 +3,19 @@ RUN: lld -flavor gnu -target x86_64-linux -static -e main --output-filetype=yaml
RUN: --noinhibit-exec %p/Inputs/gotpcrel.x86-64 \
RUN: | FileCheck %s -check-prefix=YAML
YAML: name: [[NULLGOT:[a-zA-Z0-9_]+]]
YAML: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
YAML-NOT: references:
YAML: name: [[MAINGOT:[a-zA-Z0-9_]+]]
YAML: kind: R_X86_64_64
YAML: target: main
YAML: name: main
YAML: references:
YAML: kind: R_X86_64_GOTPCREL
YAML: offset: 3
YAML: target: [[NULLGOT]]
YAML: target: [[NULLGOT:[a-zA-Z0-9_]+]]
YAML: kind: R_X86_64_GOTPCREL
YAML: offset: 10
YAML: target: [[MAINGOT]]
YAML: target: [[MAINGOT:[a-zA-Z0-9_]+]]
YAML: name: [[NULLGOT]]
YAML: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
YAML-NOT: references:
YAML: name: [[MAINGOT]]
YAML: kind: R_X86_64_64
YAML: target: main

View File

@ -1,12 +1,12 @@
RUN: lld -flavor gnu -target hexagon %p/Inputs/quickdata-sort-test.o.elf-hexagon -o %t1 --noinhibit-exec
RUN: llvm-nm -n %t1 | FileCheck %s -check-prefix=quickdataSort
quickdataSort: 00002000 D AA1
quickdataSort: 00002001 D A1
quickdataSort: 00002002 D BB1
quickdataSort: 00002004 D B1
quickdataSort: 00002008 D CC1
quickdataSort: 0000200c D C1
quickdataSort: 00002010 D DD1
quickdataSort: 00002018 D D1
quickdataSort: 00002000 D A1
quickdataSort: 00002001 D AA1
quickdataSort: 00002002 D B1
quickdataSort: 00002004 D BB1
quickdataSort: 00002008 D C1
quickdataSort: 0000200c D CC1
quickdataSort: 00002010 D D1
quickdataSort: 00002018 D DD1

View File

@ -2,15 +2,15 @@ RUN: lld -flavor gnu -target hexagon -o %t1 --noinhibit-exec \
RUN: %p/Inputs/quickdata-sortcommon-test.o.elf-hexagon
RUN: llvm-nm -n %t1 | FileCheck %s -check-prefix=quickdataSortCommon
quickdataSortCommon: 00002000 D AA1
quickdataSortCommon: 00002001 D A1
quickdataSortCommon: 00002000 D A1
quickdataSortCommon: 00002001 D AA1
quickdataSortCommon: 00002002 D AAA1
quickdataSortCommon: 00002004 D BB1
quickdataSortCommon: 00002006 D B1
quickdataSortCommon: 00002004 D B1
quickdataSortCommon: 00002006 D BB1
quickdataSortCommon: 00002008 D BBB1
quickdataSortCommon: 0000200c D CC1
quickdataSortCommon: 00002010 D C1
quickdataSortCommon: 0000200c D C1
quickdataSortCommon: 00002010 D CC1
quickdataSortCommon: 00002014 D CCC1
quickdataSortCommon: 00002018 D DD1
quickdataSortCommon: 00002020 D D1
quickdataSortCommon: 00002018 D D1
quickdataSortCommon: 00002020 D DD1
quickdataSortCommon: 00002028 D DDD1

View File

@ -21,12 +21,6 @@ RUN: | FileCheck %s --check-prefix=SHARED
PLT: defined-atoms:
// Make sure there's a got entry with a IRELATIVE relocation.
PLT: type: got
PLT: references:
PLT: kind: R_X86_64_IRELATIVE
PLT: target: hey
PLT: name: plt
PLT: scope: global
PLT: references:
@ -47,6 +41,12 @@ PLT: type: stub
PLT: references
PLT: kind: R_X86_64_PC32
// Make sure there's a got entry with a IRELATIVE relocation.
PLT: type: got
PLT: references:
PLT: kind: R_X86_64_IRELATIVE
PLT: target: hey
CHECK: name: hey
CHECK: scope: global
CHECK: type: resolver

View File

@ -1,14 +1,14 @@
RUN: lld -flavor gnu -target hexagon --output-filetype=yaml %p/Inputs/quickdata-test.elf-hexagon \
RUN: --noinhibit-exec | FileCheck %s -check-prefix hexagon
hexagon: - name: init
hexagon: scope: global
hexagon: type: quick-data
hexagon: - name: ac1
hexagon: scope: global
hexagon: type: zero-fill-quick
hexagon: size: 1
hexagon: merge: as-tentative
hexagon: - name: init
hexagon: scope: global
hexagon: type: quick-data
hexagon: - name: bss1
hexagon: scope: global
hexagon: type: zero-fill-quick

View File

@ -9,11 +9,6 @@ RUN: --noinhibit-exec -e main -static && llvm-objdump -d %t | FileCheck %s
// Verify that the TLS accesses have the correct offsets.
YAML: type: got
YAML: references:
YAML: kind: R_X86_64_TPOFF64
YAML: target: tls2
YAML: name: main
YAML: references:
YAML: kind: R_X86_64_TPOFF32
@ -30,6 +25,10 @@ YAML: name: GOTTPOFF
YAML: kind: R_X86_64_PC32
YAML: target: [[GOTNAME:[a-zA-Z0-9_]+]]
YAML: type: got
YAML: references:
YAML: kind: R_X86_64_TPOFF64
YAML: target: tls2
// main
CHECK: addl %fs:-4

View File

@ -8,17 +8,6 @@ RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared-32s.x86-64 \
RUN: %p/Inputs/shared.so-x86-64 --output-filetype=yaml --noinhibit-exec \
RUN: | FileCheck %s --check-prefix=32S
// Don't check the GOT and PLT names as they are only present in assert builds.
CHECK: type: got
CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECK: section-choice: custom-required
CHECK: section-name: .got.dyn
CHECK: permissions: rw-
CHECK: references:
CHECK: - kind: R_X86_64_GLOB_DAT
CHECK: offset: 0
CHECK: target: i
CHECK: - name: main
CHECK: scope: global
CHECK: references:
@ -67,7 +56,16 @@ CHECK: offset: 12
target: .PLT0
CHECK: addend: -4
// Don't check the GOT and PLT names as they are only present in assert builds.
CHECK: type: got
CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
CHECK: section-choice: custom-required
CHECK: section-name: .got.dyn
CHECK: permissions: rw-
CHECK: references:
CHECK: - kind: R_X86_64_GLOB_DAT
CHECK: offset: 0
CHECK: target: i
CHECK:shared-library-atoms:
CHECK: - name: foo