forked from OSchip/llvm-project
lld elf2: Diagnose trying to mix incompatible files.
This is also a step in instantiating the writer with the correct template argument. llvm-svn: 244035
This commit is contained in:
parent
9f5a9b0d91
commit
3c9cb4b3d3
|
|
@ -18,6 +18,14 @@ using namespace llvm::ELF;
|
||||||
using namespace lld;
|
using namespace lld;
|
||||||
using namespace lld::elf2;
|
using namespace lld::elf2;
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
bool ObjectFile<ELFT>::isCompatibleWith(const ObjectFileBase &Other) const {
|
||||||
|
if (kind() != Other.kind())
|
||||||
|
return false;
|
||||||
|
return getObj()->getHeader()->e_machine ==
|
||||||
|
cast<ObjectFile<ELFT>>(Other).getObj()->getHeader()->e_machine;
|
||||||
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
|
template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
|
||||||
// Parse a memory buffer as a ELF file.
|
// Parse a memory buffer as a ELF file.
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class Chunk;
|
||||||
// The root class of input files.
|
// The root class of input files.
|
||||||
class InputFile {
|
class InputFile {
|
||||||
public:
|
public:
|
||||||
enum Kind { ObjectKind };
|
enum Kind { Object32LEKind, Object32BEKind, Object64LEKind, Object64BEKind };
|
||||||
Kind kind() const { return FileKind; }
|
Kind kind() const { return FileKind; }
|
||||||
virtual ~InputFile() {}
|
virtual ~InputFile() {}
|
||||||
|
|
||||||
|
|
@ -31,6 +31,8 @@ public:
|
||||||
// Reads a file (constructors don't do that).
|
// Reads a file (constructors don't do that).
|
||||||
virtual void parse() = 0;
|
virtual void parse() = 0;
|
||||||
|
|
||||||
|
StringRef getName() const { return MB.getBufferIdentifier(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
|
explicit InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
|
||||||
MemoryBufferRef MB;
|
MemoryBufferRef MB;
|
||||||
|
|
@ -42,12 +44,17 @@ private:
|
||||||
// .o file.
|
// .o file.
|
||||||
class ObjectFileBase : public InputFile {
|
class ObjectFileBase : public InputFile {
|
||||||
public:
|
public:
|
||||||
explicit ObjectFileBase(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
|
explicit ObjectFileBase(Kind K, MemoryBufferRef M) : InputFile(K, M) {}
|
||||||
static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
|
static bool classof(const InputFile *F) {
|
||||||
|
Kind K = F->kind();
|
||||||
|
return K >= Object32LEKind && K <= Object64BEKind;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayRef<Chunk *> getChunks() { return Chunks; }
|
ArrayRef<Chunk *> getChunks() { return Chunks; }
|
||||||
ArrayRef<SymbolBody *> getSymbols() override { return SymbolBodies; }
|
ArrayRef<SymbolBody *> getSymbols() override { return SymbolBodies; }
|
||||||
|
|
||||||
|
virtual bool isCompatibleWith(const ObjectFileBase &Other) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// List of all chunks defined by this file. This includes both section
|
// List of all chunks defined by this file. This includes both section
|
||||||
// chunks and non-section chunks for common symbols.
|
// chunks and non-section chunks for common symbols.
|
||||||
|
|
@ -65,11 +72,26 @@ template <class ELFT> class ObjectFile : public ObjectFileBase {
|
||||||
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
|
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ObjectFile(MemoryBufferRef M) : ObjectFileBase(M) {}
|
bool isCompatibleWith(const ObjectFileBase &Other) const override;
|
||||||
|
|
||||||
|
static Kind getKind() {
|
||||||
|
if (!ELFT::Is64Bits) {
|
||||||
|
if (ELFT::TargetEndianness == llvm::support::little)
|
||||||
|
return Object32LEKind;
|
||||||
|
return Object32BEKind;
|
||||||
|
}
|
||||||
|
if (ELFT::TargetEndianness == llvm::support::little)
|
||||||
|
return Object64LEKind;
|
||||||
|
return Object64BEKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const InputFile *F) { return F->kind() == getKind(); }
|
||||||
|
|
||||||
|
explicit ObjectFile(MemoryBufferRef M) : ObjectFileBase(getKind(), M) {}
|
||||||
void parse() override;
|
void parse() override;
|
||||||
|
|
||||||
// Returns the underying ELF file.
|
// Returns the underying ELF file.
|
||||||
llvm::object::ELFFile<ELFT> *getObj() { return ELFObj.get(); }
|
llvm::object::ELFFile<ELFT> *getObj() const { return ELFObj.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeChunks();
|
void initializeChunks();
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@ void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolTable::addObject(ObjectFileBase *File) {
|
void SymbolTable::addObject(ObjectFileBase *File) {
|
||||||
|
if (!ObjectFiles.empty()) {
|
||||||
|
ObjectFileBase &Old = *ObjectFiles[0];
|
||||||
|
if (!Old.isCompatibleWith(*File))
|
||||||
|
error(Twine(Old.getName() + " is incompatible with " + File->getName()));
|
||||||
|
}
|
||||||
|
|
||||||
ObjectFiles.emplace_back(File);
|
ObjectFiles.emplace_back(File);
|
||||||
for (SymbolBody *Body : File->getSymbols())
|
for (SymbolBody *Body : File->getSymbols())
|
||||||
if (Body->isExternal())
|
if (Body->isExternal())
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %ta.o
|
||||||
|
// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tb.o
|
||||||
|
// RUN: llvm-mc -filetype=obj -triple=arm-unknown-linux %s -o %tc.o
|
||||||
|
|
||||||
|
// RUN: not lld -flavor gnu2 %ta.o %tb.o -o %t 2>&1 | \
|
||||||
|
// RUN: FileCheck --check-prefix=A-AND-B %s
|
||||||
|
// A-AND-B: a.o is incompatible with {{.*}}b.o
|
||||||
|
|
||||||
|
// RUN: not lld -flavor gnu2 %tb.o %tc.o -o %t 2>&1 | \
|
||||||
|
// RUN: FileCheck --check-prefix=B-AND-C %s
|
||||||
|
// B-AND-C: b.o is incompatible with {{.*}}c.o
|
||||||
|
|
||||||
|
// REQUIRES: x86,arm
|
||||||
Loading…
Reference in New Issue