forked from OSchip/llvm-project
[ARM] Implement R_ARM_COPY relocation
This adds support of copying objects from shared libraries. llvm-svn: 235705
This commit is contained in:
parent
53e047de9e
commit
c3431bf67b
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
static struct S {
|
||||
} s;
|
||||
|
||||
struct S *const object = &s;
|
|
@ -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
|
||||
...
|
Loading…
Reference in New Issue