[mach-o] Add support for zero-fill sections.

llvm-svn: 208928
This commit is contained in:
Nick Kledzik 2014-05-15 23:03:50 +00:00
parent 966abe7614
commit e09cfc5f8a
5 changed files with 64 additions and 18 deletions

View File

@ -16,24 +16,36 @@ namespace lld {
namespace mach_o {
class MachODefinedAtom : public SimpleDefinedAtom {
public:
// FIXME: This constructor should also take the ContentType.
MachODefinedAtom(const File &f, const StringRef name,
const ArrayRef<uint8_t> content, Scope scope)
: SimpleDefinedAtom(f), _name(name), _content(content), _scope(scope) {}
MachODefinedAtom(const File &f, const StringRef name, Scope scope,
ContentType type, const ArrayRef<uint8_t> content)
: SimpleDefinedAtom(f), _name(name), _content(content),
_contentType(type), _scope(scope) {}
uint64_t size() const override { return rawContent().size(); }
// Constructor for zero-fill content
MachODefinedAtom(const File &f, const StringRef name, Scope scope,
uint64_t size)
: SimpleDefinedAtom(f), _name(name),
_content(ArrayRef<uint8_t>(nullptr, size)),
_contentType(DefinedAtom::typeZeroFill), _scope(scope) {}
ContentType contentType() const override { return DefinedAtom::typeCode; }
uint64_t size() const override { return _content.size(); }
ContentType contentType() const override { return _contentType; }
StringRef name() const override { return _name; }
Scope scope() const override { return _scope; }
ArrayRef<uint8_t> rawContent() const override { return _content; }
ArrayRef<uint8_t> rawContent() const override {
// Zerofill atoms have a content pointer which is null.
assert(_content.data() != nullptr);
return _content;
}
private:
const StringRef _name;
const ArrayRef<uint8_t> _content;
const ContentType _contentType;
const Scope _scope;
};

View File

@ -21,15 +21,27 @@ class MachOFile : public SimpleFile {
public:
MachOFile(StringRef path) : SimpleFile(path) {}
void addDefinedAtom(StringRef name, ArrayRef<uint8_t> content,
Atom::Scope scope, bool copyRefs) {
void addDefinedAtom(StringRef name, Atom::Scope scope,
DefinedAtom::ContentType type,
ArrayRef<uint8_t> content, bool copyRefs) {
if (copyRefs) {
// Make a copy of the atom's name and content that is owned by this file.
name = name.copy(_allocator);
content = content.copy(_allocator);
}
MachODefinedAtom *atom =
new (_allocator) MachODefinedAtom(*this, name, content, scope);
new (_allocator) MachODefinedAtom(*this, name, scope, type, content);
addAtom(*atom);
}
void addZeroFillDefinedAtom(StringRef name, Atom::Scope scope, uint64_t size,
bool copyRefs) {
if (copyRefs) {
// Make a copy of the atom's name and content that is owned by this file.
name = name.copy(_allocator);
}
MachODefinedAtom *atom =
new (_allocator) MachODefinedAtom(*this, name, scope, size);
addAtom(*atom);
}

View File

@ -74,6 +74,11 @@ static Atom::Scope atomScope(uint8_t scope) {
llvm_unreachable("unknown scope value!");
}
static DefinedAtom::ContentType atomTypeFromSection(const Section &section) {
// FIX ME
return DefinedAtom::typeCode;
}
static void processSymbol(const NormalizedFile &normalizedFile, MachOFile &file,
const Symbol &sym, bool copyRefs) {
// Mach-O symbol table does have size in it, so need to scan ahead
@ -81,8 +86,13 @@ static void processSymbol(const NormalizedFile &normalizedFile, MachOFile &file,
const Section &section = normalizedFile.sections[sym.sect - 1];
uint64_t offset = sym.value - section.address;
uint64_t size = nextSymbolAddress(normalizedFile, sym) - sym.value;
ArrayRef<uint8_t> atomContent = section.content.slice(offset, size);
file.addDefinedAtom(sym.name, atomContent, atomScope(sym.scope), copyRefs);
if (section.type == llvm::MachO::S_ZEROFILL){
file.addZeroFillDefinedAtom(sym.name, atomScope(sym.scope), size, copyRefs);
} else {
ArrayRef<uint8_t> atomContent = section.content.slice(offset, size);
file.addDefinedAtom(sym.name, atomScope(sym.scope),
atomTypeFromSection(section), atomContent, copyRefs);
}
}

View File

@ -278,9 +278,19 @@ struct MappingTraits<Section> {
io.mapOptional("attributes", sect.attributes);
io.mapOptional("alignment", sect.alignment, 0U);
io.mapRequired("address", sect.address);
MappingNormalization<NormalizedContent, ArrayRef<uint8_t>> content(
if (sect.type == llvm::MachO::S_ZEROFILL) {
// S_ZEROFILL sections use "size:" instead of "content:"
uint64_t size = sect.content.size();
io.mapOptional("size", size);
if (!io.outputting()) {
uint8_t *bytes = nullptr;
sect.content = makeArrayRef(bytes, size);
}
} else {
MappingNormalization<NormalizedContent, ArrayRef<uint8_t>> content(
io, sect.content);
io.mapOptional("content", content->_normalizedContent);
io.mapOptional("content", content->_normalizedContent);
}
io.mapOptional("relocations", sect.relocations);
io.mapOptional("indirect-syms", sect.indirectSymbols);
}

View File

@ -33,7 +33,7 @@ sections:
attributes: [ ]
alignment: 2
address: 0x0000000000000014
content: [ 0x00, 0x00, 0x00, 0x00 ]
size: 4
local-symbols:
- name: _s1
type: N_SECT
@ -62,6 +62,11 @@ global-symbols:
...
# CHECK: defined-atoms:
# CHECK: - name: _s1
# CHECK: type: zero-fill
# CHECK: size: 4
# CHECK: - name: _a
# CHECK: scope: global
# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
@ -74,8 +79,5 @@ global-symbols:
# CHECK: scope: global
# CHECK: content: [ 21, 22, 23, 24 ]
# CHECK: - name: _s1
# CHECK: content: [ 00, 00, 00, 00 ]
# CHECK: - name: _s2
# CHECK: content: [ 31, 32, 33, 34 ]