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 {
: _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:
/// 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(); }
// 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; }
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:
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;
}
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;
}
? 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;
}
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();
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;
}
: 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;