[lld] r209928 - [mach-o] Add support for custom sections
Nick Kledzik
kledzik at apple.com
Fri May 30 15:51:05 PDT 2014
Author: kledzik
Date: Fri May 30 17:51:04 2014
New Revision: 209928
URL: http://llvm.org/viewvc/llvm-project?rev=209928&view=rev
Log:
[mach-o] Add support for custom sections
Modified:
lld/trunk/lib/ReaderWriter/MachO/Atoms.h
lld/trunk/lib/ReaderWriter/MachO/File.h
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/trunk/test/mach-o/parse-data.yaml
Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Fri May 30 17:51:04 2014
@@ -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:
Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Fri May 30 17:51:04 2014
@@ -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) {
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Fri May 30 17:51:04 2014
@@ -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(DefinedAt
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(DefinedAt
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;
+ }
}
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Fri May 30 17:51:04 2014
@@ -83,8 +83,25 @@ static Atom::Scope atomScope(uint8_t sco
}
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 &norm
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();
}
Modified: lld/trunk/test/mach-o/parse-data.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-data.yaml?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-data.yaml (original)
+++ lld/trunk/test/mach-o/parse-data.yaml Fri May 30 17:51:04 2014
@@ -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: _s1
-# CHECK: type: zero-fill
-# CHECK: size: 4
-
# 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: _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
+
More information about the llvm-commits
mailing list