[PECOFF] Move more code from Atoms.h to ReaderCOFF.cpp.

llvm-svn: 187688
This commit is contained in:
Rui Ueyama 2013-08-02 22:58:22 +00:00
parent 8d7e6906d1
commit 707754f3e8
2 changed files with 81 additions and 78 deletions

View File

@ -58,25 +58,19 @@ private:
class COFFAbsoluteAtom : public AbsoluteAtom {
public:
COFFAbsoluteAtom(const File &f, StringRef n, const coff_symbol *s)
: _owningFile(f), _name(n), _symbol(s) {}
COFFAbsoluteAtom(const File &f, StringRef name, Scope scope, uint64_t value)
: _owningFile(f), _name(name), _scope(scope), _value(value) {}
virtual const File &file() const { return _owningFile; }
virtual Scope scope() const {
if (_symbol->StorageClass == llvm::COFF::IMAGE_SYM_CLASS_STATIC)
return scopeTranslationUnit;
return scopeGlobal;
}
virtual Scope scope() const { return _scope; }
virtual StringRef name() const { return _name; }
virtual uint64_t value() const { return _symbol->Value; }
virtual uint64_t value() const { return _value; }
private:
const File &_owningFile;
StringRef _name;
const coff_symbol *_symbol;
Scope _scope;
uint64_t _value;
};
class COFFUndefinedAtom : public UndefinedAtom {
@ -85,9 +79,7 @@ public:
: _owningFile(f), _name(n) {}
virtual const File &file() const { return _owningFile; }
virtual StringRef name() const { return _name; }
virtual CanBeNull canBeNull() const { return CanBeNull::canBeNullNever; }
private:
@ -156,71 +148,40 @@ private:
/// subclasses; one for the regular atom and another for the BSS atom.
class COFFDefinedFileAtom : public COFFBaseDefinedAtom {
public:
COFFDefinedFileAtom(const File &file, StringRef name,
const coff_symbol *symbol, const coff_section *section,
StringRef sectionName, uint64_t ordinal)
: COFFBaseDefinedAtom(file, name, Kind::File), _symbol(symbol),
_section(section), _sectionName(sectionName),
COFFDefinedFileAtom(const File &file, StringRef name, StringRef sectionName,
Scope scope, ContentType contentType,
ContentPermissions perms, uint64_t ordinal)
: COFFBaseDefinedAtom(file, name, Kind::File), _sectionName(sectionName),
_scope(scope), _contentType(contentType), _permissions(perms),
_ordinal(ordinal) {}
virtual uint64_t ordinal() const { return _ordinal; }
virtual StringRef getSectionName() const { return _sectionName; }
static bool classof(const COFFBaseDefinedAtom *atom) {
return atom->getKind() == Kind::File;
}
virtual Scope scope() const {
if (!_symbol)
return scopeTranslationUnit;
switch (_symbol->StorageClass) {
case llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL:
return scopeGlobal;
case llvm::COFF::IMAGE_SYM_CLASS_STATIC:
case llvm::COFF::IMAGE_SYM_CLASS_LABEL:
return scopeTranslationUnit;
}
llvm_unreachable("Unknown scope!");
}
virtual ContentType contentType() const {
if (_section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE)
return typeCode;
if (_section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
return typeData;
if (_section->Characteristics &
llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
return typeZeroFill;
return typeUnknown;
}
virtual ContentPermissions permissions() const {
if (_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ &&
_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_WRITE)
return permRW_;
if (_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ &&
_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
return permR_X;
if (_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ)
return permR__;
return perm___;
}
virtual StringRef getSectionName() const { return _sectionName; }
virtual Scope scope() const { return _scope; }
virtual ContentType contentType() const { return _contentType; }
virtual ContentPermissions permissions() const { return _permissions; }
virtual uint64_t ordinal() const { return _ordinal; }
private:
const coff_symbol *_symbol;
const coff_section *_section;
StringRef _sectionName;
std::vector<std::unique_ptr<COFFReference>> _references;
Scope _scope;
ContentType _contentType;
ContentPermissions _permissions;
uint64_t _ordinal;
std::vector<std::unique_ptr<COFFReference>> _references;
};
// A COFFDefinedAtom represents an atom read from a file and has contents.
class COFFDefinedAtom : public COFFDefinedFileAtom {
public:
COFFDefinedAtom(const File &file, StringRef name, const coff_symbol *symbol,
const coff_section *section, ArrayRef<uint8_t> data,
StringRef sectionName, uint64_t ordinal)
: COFFDefinedFileAtom(file, name, symbol, section, sectionName, ordinal),
COFFDefinedAtom(const File &file, StringRef name, StringRef sectionName,
Scope scope, ContentType type, ContentPermissions perms,
ArrayRef<uint8_t> data, uint64_t ordinal)
: COFFDefinedFileAtom(file, name, sectionName, scope, type, perms,
ordinal),
_dataref(data) {}
virtual uint64_t size() const { return _dataref.size(); }
@ -233,13 +194,12 @@ private:
// A COFFDefinedAtom represents an atom for BSS section.
class COFFBSSAtom : public COFFDefinedFileAtom {
public:
COFFBSSAtom(const File &file, StringRef name, const coff_symbol *symbol,
uint32_t size, uint64_t ordinal)
: COFFDefinedFileAtom(file, name, symbol, nullptr, "", ordinal),
COFFBSSAtom(const File &file, StringRef name, Scope scope,
ContentPermissions perms, uint32_t size, uint64_t ordinal)
: COFFDefinedFileAtom(file, name, "", scope, typeZeroFill, perms,
ordinal),
_size(size) {}
virtual ContentPermissions permissions() const { return permRW_; }
virtual ContentType contentType() const { return typeZeroFill; }
virtual Merge merge() const { return mergeNo; }
virtual uint64_t size() const { return _size; }
virtual ArrayRef<uint8_t> rawContent() const { return _contents; }

View File

@ -44,7 +44,40 @@ using llvm::object::coff_symbol;
using namespace lld;
namespace { // anonymous
namespace {
Atom::Scope getScope(const coff_symbol *symbol) {
switch (symbol->StorageClass) {
case llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL:
return Atom::scopeGlobal;
case llvm::COFF::IMAGE_SYM_CLASS_STATIC:
case llvm::COFF::IMAGE_SYM_CLASS_LABEL:
return Atom::scopeTranslationUnit;
}
llvm_unreachable("Unknown scope");
}
DefinedAtom::ContentType getContentType(const coff_section *section) {
if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE)
return DefinedAtom::typeCode;
if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
return DefinedAtom::typeData;
if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
return DefinedAtom::typeZeroFill;
return DefinedAtom::typeUnknown;
}
DefinedAtom::ContentPermissions getPermissions(const coff_section *section) {
if (section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ &&
section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_WRITE)
return DefinedAtom::permRW_;
if (section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ &&
section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
return DefinedAtom::permR_X;
if (section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ)
return DefinedAtom::permR__;
return DefinedAtom::perm___;
}
class FileCOFF : public File {
private:
@ -143,7 +176,9 @@ private:
for (const coff_symbol *sym : symbols) {
if (sym->SectionNumber != llvm::COFF::IMAGE_SYM_ABSOLUTE)
continue;
auto *atom = new (_alloc) COFFAbsoluteAtom(*this, _symbolName[sym], sym);
auto *atom = new (_alloc) COFFAbsoluteAtom(
*this, _symbolName[sym], getScope(sym), sym->Value);
result.push_back(atom);
_symbolAtom[sym] = atom;
}
@ -177,7 +212,8 @@ private:
sym->Value > 0) {
StringRef name = _symbolName[sym];
uint32_t size = sym->Value;
auto *atom = new (_alloc) COFFBSSAtom(*this, name, sym, size, 0);
auto *atom = new (_alloc) COFFBSSAtom(
*this, name, getScope(sym), DefinedAtom::permRW_, size, 0);
result.push_back(atom);
continue;
}
@ -242,7 +278,8 @@ private:
? section->SizeOfRawData - sym->Value
: si[1]->Value - sym->Value;
auto *atom = new (_alloc) COFFBSSAtom(
*this, _symbolName[sym], sym, size, ++ordinal);
*this, _symbolName[sym], getScope(sym), getPermissions(section),
size, ++ordinal);
atoms.push_back(atom);
_symbolAtom[sym] = atom;
}
@ -265,11 +302,15 @@ private:
if (section->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
return error_code::success();
DefinedAtom::ContentType type = getContentType(section);
DefinedAtom::ContentPermissions perms = getPermissions(section);
// Create an atom for the entire section.
if (symbols.empty()) {
ArrayRef<uint8_t> Data(secData.data(), secData.size());
auto *atom = new (_alloc) COFFDefinedAtom(*this, "", nullptr, section,
Data, sectionName, 0);
ArrayRef<uint8_t> data(secData.data(), secData.size());
auto *atom = new (_alloc) COFFDefinedAtom(
*this, "", sectionName, Atom::scopeTranslationUnit, type, perms,
data, 0);
atoms.push_back(atom);
_definedAtomLocations[section][0] = atom;
return error_code::success();
@ -281,7 +322,8 @@ private:
uint64_t size = symbols[0]->Value;
ArrayRef<uint8_t> data(secData.data(), size);
auto *atom = new (_alloc) COFFDefinedAtom(
*this, "", nullptr, section, data, sectionName, ++ordinal);
*this, "", sectionName, Atom::scopeTranslationUnit, type, perms,
data, ++ordinal);
atoms.push_back(atom);
_definedAtomLocations[section][0] = atom;
}
@ -294,7 +336,8 @@ private:
: secData.data() + (*(si + 1))->Value;
ArrayRef<uint8_t> data(start, end);
auto *atom = new (_alloc) COFFDefinedAtom(
*this, _symbolName[*si], *si, section, data, sectionName, ++ordinal);
*this, _symbolName[*si], sectionName, getScope(*si), type, perms,
data, ++ordinal);
atoms.push_back(atom);
_symbolAtom[*si] = atom;
_definedAtomLocations[section][(*si)->Value] = atom;