forked from OSchip/llvm-project
[mach-o] Add support for custom sections
llvm-svn: 209928
This commit is contained in:
parent
5435224a53
commit
acfad80250
|
@ -62,6 +62,26 @@ private:
|
|||
const Merge _merge;
|
||||
};
|
||||
|
||||
class MachODefinedCustomSectionAtom : public MachODefinedAtom {
|
||||
public:
|
||||
MachODefinedCustomSectionAtom(const File &f, const StringRef name,
|
||||
Scope scope, ContentType type, Merge merge,
|
||||
const ArrayRef<uint8_t> content,
|
||||
StringRef sectionName)
|
||||
: MachODefinedAtom(f, name, scope, type, merge, content),
|
||||
_sectionName(sectionName) {}
|
||||
|
||||
SectionChoice sectionChoice() const override {
|
||||
return DefinedAtom::sectionCustomRequired;
|
||||
}
|
||||
|
||||
StringRef customSectionName() const override {
|
||||
return _sectionName;
|
||||
}
|
||||
private:
|
||||
StringRef _sectionName;
|
||||
};
|
||||
|
||||
|
||||
class MachOTentativeDefAtom : public SimpleDefinedAtom {
|
||||
public:
|
||||
|
|
|
@ -35,6 +35,22 @@ public:
|
|||
addAtom(*atom);
|
||||
}
|
||||
|
||||
void addDefinedAtomInCustomSection(StringRef name, Atom::Scope scope,
|
||||
DefinedAtom::ContentType type, DefinedAtom::Merge merge,
|
||||
ArrayRef<uint8_t> content, StringRef sectionName,
|
||||
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);
|
||||
sectionName = sectionName.copy(_allocator);
|
||||
}
|
||||
MachODefinedCustomSectionAtom *atom =
|
||||
new (_allocator) MachODefinedCustomSectionAtom(*this, name, scope, type,
|
||||
merge, content, sectionName);
|
||||
addAtom(*atom);
|
||||
}
|
||||
|
||||
void addZeroFillDefinedAtom(StringRef name, Atom::Scope scope, uint64_t size,
|
||||
bool copyRefs) {
|
||||
if (copyRefs) {
|
||||
|
|
|
@ -149,6 +149,7 @@ private:
|
|||
std::vector<SectionInfo*> _sectionInfos;
|
||||
std::vector<SegmentInfo*> _segmentInfos;
|
||||
TypeToSection _sectionMap;
|
||||
std::vector<SectionInfo*> _customSections;
|
||||
AtomToAddress _atomToAddress;
|
||||
DylibPathToInfo _dylibInfo;
|
||||
const DefinedAtom *_entryAtom;
|
||||
|
@ -206,6 +207,18 @@ SectionInfo *Util::makeSection(DefinedAtom::ContentType type) {
|
|||
case DefinedAtom::typeCompactUnwindInfo:
|
||||
return new (_allocator) SectionInfo("__LD", "__compact_unwind",
|
||||
S_REGULAR);
|
||||
case DefinedAtom::typeConstant:
|
||||
return new (_allocator) SectionInfo("__TEXT", "__const",
|
||||
S_REGULAR);
|
||||
case DefinedAtom::typeData:
|
||||
return new (_allocator) SectionInfo("__DATA", "__data",
|
||||
S_REGULAR);
|
||||
case DefinedAtom::typeConstData:
|
||||
return new (_allocator) SectionInfo("__DATA", "__const",
|
||||
S_REGULAR);
|
||||
case DefinedAtom::typeLSDA:
|
||||
return new (_allocator) SectionInfo("__TEXT", "__gcc_except_tab",
|
||||
S_REGULAR);
|
||||
default:
|
||||
llvm_unreachable("TO DO: add support for more sections");
|
||||
break;
|
||||
|
@ -215,14 +228,36 @@ SectionInfo *Util::makeSection(DefinedAtom::ContentType type) {
|
|||
|
||||
|
||||
SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
|
||||
DefinedAtom::ContentType type = atom->contentType();
|
||||
auto pos = _sectionMap.find(type);
|
||||
if ( pos != _sectionMap.end() )
|
||||
return pos->second;
|
||||
SectionInfo *si = makeSection(type);
|
||||
_sectionInfos.push_back(si);
|
||||
_sectionMap[type] = si;
|
||||
return si;
|
||||
if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
|
||||
// Section for this atom is derived from content type.
|
||||
DefinedAtom::ContentType type = atom->contentType();
|
||||
auto pos = _sectionMap.find(type);
|
||||
if ( pos != _sectionMap.end() )
|
||||
return pos->second;
|
||||
SectionInfo *si = makeSection(type);
|
||||
_sectionInfos.push_back(si);
|
||||
_sectionMap[type] = si;
|
||||
return si;
|
||||
} else {
|
||||
// This atom needs to be in a custom section.
|
||||
StringRef customName = atom->customSectionName();
|
||||
// Look to see if we have already allocated the needed custom section.
|
||||
for(SectionInfo *sect : _customSections) {
|
||||
const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
|
||||
if (firstAtom->customSectionName().equals(customName)) {
|
||||
return sect;
|
||||
}
|
||||
}
|
||||
// Not found, so need to create a new custom section.
|
||||
size_t seperatorIndex = customName.find('/');
|
||||
assert(seperatorIndex != StringRef::npos);
|
||||
StringRef segName = customName.slice(0, seperatorIndex-1);
|
||||
StringRef sectName = customName.drop_front(seperatorIndex);
|
||||
SectionInfo *sect = new (_allocator) SectionInfo(segName, sectName,
|
||||
S_REGULAR);
|
||||
_customSections.push_back(sect);
|
||||
return sect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -83,8 +83,25 @@ static Atom::Scope atomScope(uint8_t scope) {
|
|||
}
|
||||
|
||||
static DefinedAtom::ContentType atomTypeFromSection(const Section §ion) {
|
||||
// FIX ME
|
||||
return DefinedAtom::typeCode;
|
||||
if (section.attributes & S_ATTR_PURE_INSTRUCTIONS)
|
||||
return DefinedAtom::typeCode;
|
||||
if (section.segmentName.equals("__TEXT")) {
|
||||
if (section.sectionName.equals("__StaticInit"))
|
||||
return DefinedAtom::typeCode;
|
||||
if (section.sectionName.equals("__gcc_except_tab"))
|
||||
return DefinedAtom::typeLSDA;
|
||||
if (section.sectionName.startswith("__text"))
|
||||
return DefinedAtom::typeCode;
|
||||
if (section.sectionName.startswith("__const"))
|
||||
return DefinedAtom::typeConstant;
|
||||
} else if (section.segmentName.equals("__DATA")) {
|
||||
if (section.sectionName.startswith("__data"))
|
||||
return DefinedAtom::typeData;
|
||||
if (section.sectionName.startswith("__const"))
|
||||
return DefinedAtom::typeConstData;
|
||||
}
|
||||
|
||||
return DefinedAtom::typeUnknown;
|
||||
}
|
||||
|
||||
static error_code
|
||||
|
@ -124,8 +141,19 @@ processSymbol(const NormalizedFile &normalizedFile, MachOFile &file,
|
|||
DefinedAtom::Merge m = DefinedAtom::mergeNo;
|
||||
if (sym.desc & N_WEAK_DEF)
|
||||
m = DefinedAtom::mergeAsWeak;
|
||||
file.addDefinedAtom(sym.name, atomScope(sym.scope),
|
||||
atomTypeFromSection(section), m, atomContent, copyRefs);
|
||||
DefinedAtom::ContentType type = atomTypeFromSection(section);
|
||||
if (type == DefinedAtom::typeUnknown) {
|
||||
// Mach-O needs a segment and section name. Concatentate those two
|
||||
// with a / seperator (e.g. "seg/sect") to fit into the lld model
|
||||
// of just a section name.
|
||||
std::string segSectName = section.segmentName.str()
|
||||
+ "/" + section.sectionName.str();
|
||||
file.addDefinedAtomInCustomSection(sym.name, atomScope(sym.scope), type,
|
||||
m, atomContent, segSectName, true);
|
||||
} else {
|
||||
file.addDefinedAtom(sym.name, atomScope(sym.scope), type, m, atomContent,
|
||||
copyRefs);
|
||||
}
|
||||
}
|
||||
return error_code::success();
|
||||
}
|
||||
|
|
|
@ -27,18 +27,25 @@ sections:
|
|||
content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24,
|
||||
0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44 ]
|
||||
- segment: __CUST
|
||||
section: __custom
|
||||
type: S_REGULAR
|
||||
attributes: [ ]
|
||||
alignment: 3
|
||||
address: 0x0000000000000018
|
||||
content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]
|
||||
- segment: __DATA
|
||||
section: __bss
|
||||
type: S_ZEROFILL
|
||||
attributes: [ ]
|
||||
alignment: 2
|
||||
address: 0x0000000000000018
|
||||
address: 0x0000000000000020
|
||||
size: 4
|
||||
local-symbols:
|
||||
- name: _s1
|
||||
type: N_SECT
|
||||
sect: 2
|
||||
value: 0x0000000000000018
|
||||
sect: 3
|
||||
value: 0x0000000000000020
|
||||
- name: _s2
|
||||
type: N_SECT
|
||||
sect: 1
|
||||
|
@ -65,30 +72,48 @@ global-symbols:
|
|||
sect: 1
|
||||
desc: [ N_WEAK_DEF ]
|
||||
value: 0x0000000000000014
|
||||
- name: _kustom
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 2
|
||||
value: 0x0000000000000018
|
||||
...
|
||||
|
||||
# CHECK: defined-atoms:
|
||||
|
||||
# CHECK: - name: _a
|
||||
# CHECK: scope: global
|
||||
# CHECK: type: data
|
||||
# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
|
||||
|
||||
# CHECK: - name: _b
|
||||
# CHECK: scope: global
|
||||
# CHECK: type: data
|
||||
# CHECK: content: [ 11, 12, 13, 14 ]
|
||||
|
||||
# CHECK: - name: _c
|
||||
# CHECK: scope: global
|
||||
# CHECK: type: data
|
||||
# CHECK: content: [ 21, 22, 23, 24 ]
|
||||
|
||||
# CHECK: - name: _cWeak
|
||||
# CHECK: scope: global
|
||||
# CHECK: type: data
|
||||
# CHECK: content: [ 41, 42, 43, 44 ]
|
||||
# CHECK: merge: as-weak
|
||||
|
||||
# CHECK: - name: _s2
|
||||
# CHECK: type: data
|
||||
# CHECK: content: [ 31, 32, 33, 34 ]
|
||||
|
||||
# CHECK: - name: _s1
|
||||
# CHECK: type: zero-fill
|
||||
# CHECK: size: 4
|
||||
|
||||
# CHECK: - name: _a
|
||||
# CHECK: - name: _kustom
|
||||
# CHECK: scope: global
|
||||
# CHECK: type: unknown
|
||||
# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
|
||||
# CHECK: section-choice: custom-required
|
||||
# CHECK: section-name: __CUST/__custom
|
||||
|
||||
# CHECK: - name: _b
|
||||
# CHECK: scope: global
|
||||
# CHECK: content: [ 11, 12, 13, 14 ]
|
||||
|
||||
# CHECK: - name: _c
|
||||
# CHECK: scope: global
|
||||
# CHECK: content: [ 21, 22, 23, 24 ]
|
||||
|
||||
# CHECK: - name: _cWeak
|
||||
# CHECK: scope: global
|
||||
# CHECK: content: [ 41, 42, 43, 44 ]
|
||||
# CHECK: merge: as-weak
|
||||
|
||||
# CHECK: - name: _s2
|
||||
# CHECK: content: [ 31, 32, 33, 34 ]
|
||||
|
|
Loading…
Reference in New Issue