[ARM] Implement R_ARM_COPY relocation

This adds support of copying objects from shared libraries.

llvm-svn: 235705
This commit is contained in:
Denis Protivensky 2015-04-24 08:53:02 +00:00
parent 53e047de9e
commit c3431bf67b
5 changed files with 106 additions and 2 deletions

View File

@ -39,12 +39,20 @@ public:
assert(r.kindArch() == Reference::KindArch::ARM);
switch (r.kindValue()) {
case llvm::ELF::R_ARM_TLS_TPOFF32:
case llvm::ELF::R_ARM_COPY:
return true;
default:
return false;
}
}
bool isCopyRelocation(const Reference &r) const override {
if (r.kindNamespace() != Reference::KindNamespace::ELF)
return false;
assert(r.kindArch() == Reference::KindArch::ARM);
return r.kindValue() == llvm::ELF::R_ARM_COPY;
}
bool isPLTRelocation(const Reference &r) const override {
if (r.kindNamespace() != Reference::KindNamespace::ELF)
return false;

View File

@ -304,6 +304,14 @@ public:
Alignment alignment() const override { return 4; }
};
/// \brief Atom which represents an object for which a COPY relocation will
/// be generated.
class ARMObjectAtom : public ObjectAtom {
public:
ARMObjectAtom(const File &f) : ObjectAtom(f) {}
Alignment alignment() const override { return 4; }
};
class ELFPassFile : public SimpleFile {
public:
ELFPassFile(const ELFLinkingContext &eti) : SimpleFile("ELFPassFile") {
@ -732,6 +740,11 @@ public:
got->setOrdinal(ordinal++);
mf->addAtom(*got);
}
for (auto &objectKV : _objectAtoms) {
auto &obj = objectKV.second;
obj->setOrdinal(ordinal++);
mf->addAtom(*obj);
}
for (auto &veneerKV : _veneerAtoms) {
auto &veneer = veneerKV.second;
auto *m = veneer._mapping;
@ -751,6 +764,9 @@ protected:
/// \brief Map Atoms to their GOT entries.
llvm::MapVector<const Atom *, GOTAtom *> _gotAtoms;
/// \brief Map Atoms to their Object entries.
llvm::MapVector<const Atom *, ObjectAtom *> _objectAtoms;
/// \brief Map Atoms to their PLT entries depending on the code model.
struct PLTWithVeneer {
PLTWithVeneer(PLTAtom *p = nullptr, PLTAtom *v = nullptr)
@ -857,11 +873,26 @@ public:
return g;
}
const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
if (auto obj = _objectAtoms.lookup(a))
return obj;
auto oa = new (_file._alloc) ARMObjectAtom(_file);
oa->addReferenceELF_ARM(R_ARM_COPY, 0, oa, 0);
oa->_name = a->name();
oa->_size = a->size();
_objectAtoms[a] = oa;
return oa;
}
/// \brief Handle ordinary relocation references.
std::error_code handlePlain(bool fromThumb, const Reference &ref) {
if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
if (sla->type() == SharedLibraryAtom::Type::Data) {
llvm_unreachable("Handle object entries");
if (sla->type() == SharedLibraryAtom::Type::Data &&
_ctx.getOutputELFType() == llvm::ELF::ET_EXEC) {
const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
} else if (sla->type() == SharedLibraryAtom::Type::Code) {
const_cast<Reference &>(ref).setTarget(getPLTEntry(sla, fromThumb));
}

BIN
lld/test/elf/ARM/Inputs/libobj.so Executable file

Binary file not shown.

View File

@ -0,0 +1,4 @@
static struct S {
} s;
struct S *const object = &s;

View File

@ -0,0 +1,61 @@
# Check handling of R_ARM_COPY relocation.
# RUN: yaml2obj -format=elf %s > %t-o.o
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi \
# RUN: --noinhibit-exec %t-o.o -lobj -L%p/Inputs -o %t
# RUN: llvm-objdump -s -t %t | FileCheck %s
# RUN: llvm-readobj -relocations %t | FileCheck -check-prefix=READOBJ %s
# CHECK: Contents of section .rel.dyn:
# CHECK-NEXT: 400138 00104000 14010000
# addr = 0x401000 ^^ ^^ rel_type = 0x14 => R_ARM_COPY
# CHECK: SYMBOL TABLE:
# CHECK: 00401000 g .bss 00000004 object
#
# READOBJ: 0x401000 R_ARM_COPY object
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_ARM
Flags: [ EF_ARM_EABI_VER5 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000004
Content: 80B483B000AF40F20003C0F200031B687B60002318460C37BD465DF8047B7047
- Name: .rel.text
Type: SHT_REL
Link: .symtab
AddressAlign: 0x0000000000000004
Info: .text
Relocations:
- Offset: 0x0000000000000006
Symbol: object
Type: R_ARM_THM_MOVW_ABS_NC
- Offset: 0x000000000000000A
Symbol: object
Type: R_ARM_THM_MOVT_ABS
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x0000000000000001
Content: ''
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x0000000000000001
Content: ''
Symbols:
Local:
- Name: '$t'
Section: .text
Global:
- Name: main
Type: STT_FUNC
Section: .text
Value: 0x0000000000000001
- Name: object
...