This is a re-commit of r264022 with a fix for MSVC. The issue there was that the code was running DefinedAtom::~Atom() for some value and instead needed to cast to Atom before running ~Atom. Original commit message follows. Currently each File contains an BumpPtrAllocator in which Atom's are allocated. Some Atom's contain data structures like std::vector which leak as we don't run ~Atom when they are BumpPtrAllocate'd. Now each File actually owns its Atom's using an OwningAtomPtr. This is analygous to std::unique_ptr and may be replaced by it if possible. An Atom can therefore only be owned by a single File, so the Resolver now moves them from one File to another. The MachOLinkingContext owns the File's and so clears all the Atom's in ~MachOLinkingContext, then delete's all the File's. This makes sure all Atom's have been destructed before any of the BumpPtrAllocator's in which they run have gone away. Should hopefully fix the remaining leaks. Will keep an eye on the bots to make sure. llvm-svn: 264067
129 lines
3.3 KiB
C++
129 lines
3.3 KiB
C++
//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
|
|
//
|
|
// The LLVM Linker
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ArchHandler.h"
|
|
#include "File.h"
|
|
#include "MachOPasses.h"
|
|
#include "lld/Core/DefinedAtom.h"
|
|
#include "lld/Core/File.h"
|
|
#include "lld/Core/LLVM.h"
|
|
#include "lld/Core/Reference.h"
|
|
#include "lld/Core/Simple.h"
|
|
#include "lld/ReaderWriter/MachOLinkingContext.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
namespace lld {
|
|
namespace mach_o {
|
|
|
|
///
|
|
/// ObjC Image Info Atom created by the ObjC pass.
|
|
///
|
|
class ObjCImageInfoAtom : public SimpleDefinedAtom {
|
|
public:
|
|
ObjCImageInfoAtom(const File &file,
|
|
MachOLinkingContext::ObjCConstraint objCConstraint,
|
|
uint32_t swiftVersion)
|
|
: SimpleDefinedAtom(file) {
|
|
|
|
Data.info.version = 0;
|
|
|
|
switch (objCConstraint) {
|
|
case MachOLinkingContext::objc_unknown:
|
|
llvm_unreachable("Shouldn't run the objc pass without a constraint");
|
|
case MachOLinkingContext::objc_supports_gc:
|
|
case MachOLinkingContext::objc_gc_only:
|
|
llvm_unreachable("GC is not supported");
|
|
case MachOLinkingContext::objc_retainReleaseForSimulator:
|
|
// The retain/release for simulator flag is already the correct
|
|
// encoded value for the data so just set it here.
|
|
Data.info.flags = (uint32_t)objCConstraint;
|
|
break;
|
|
case MachOLinkingContext::objc_retainRelease:
|
|
// We don't need to encode this flag, so just leave the flags as 0.
|
|
Data.info.flags = 0;
|
|
break;
|
|
}
|
|
|
|
Data.info.flags |= (swiftVersion << 8);
|
|
}
|
|
|
|
~ObjCImageInfoAtom() override = default;
|
|
|
|
ContentType contentType() const override {
|
|
return DefinedAtom::typeObjCImageInfo;
|
|
}
|
|
|
|
Alignment alignment() const override {
|
|
return 4;
|
|
}
|
|
|
|
uint64_t size() const override {
|
|
return 8;
|
|
}
|
|
|
|
ContentPermissions permissions() const override {
|
|
return DefinedAtom::permR__;
|
|
}
|
|
|
|
ArrayRef<uint8_t> rawContent() const override {
|
|
return llvm::makeArrayRef(Data.bytes, size());
|
|
}
|
|
|
|
private:
|
|
|
|
struct objc_image_info {
|
|
uint32_t version;
|
|
uint32_t flags;
|
|
};
|
|
|
|
union {
|
|
objc_image_info info;
|
|
uint8_t bytes[8];
|
|
} Data;
|
|
};
|
|
|
|
class ObjCPass : public Pass {
|
|
public:
|
|
ObjCPass(const MachOLinkingContext &context)
|
|
: _ctx(context),
|
|
_file(*_ctx.make_file<MachOFile>("<mach-o objc pass>")) {
|
|
_file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
|
|
}
|
|
|
|
std::error_code perform(SimpleFile &mergedFile) override {
|
|
// Add the image info.
|
|
mergedFile.addAtom(*getImageInfo());
|
|
|
|
return std::error_code();
|
|
}
|
|
|
|
private:
|
|
|
|
const DefinedAtom* getImageInfo() {
|
|
return new (_file.allocator()) ObjCImageInfoAtom(_file,
|
|
_ctx.objcConstraint(),
|
|
_ctx.swiftVersion());
|
|
}
|
|
|
|
const MachOLinkingContext &_ctx;
|
|
MachOFile &_file;
|
|
};
|
|
|
|
|
|
|
|
void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx) {
|
|
pm.add(llvm::make_unique<ObjCPass>(ctx));
|
|
}
|
|
|
|
} // end namespace mach_o
|
|
} // end namespace lld
|