[mach-o] Make anonymous atom out of section content before any symbol

In sections that are broken into atoms at symbols, if the first symbol in the
section is not at the start of the section, then make an anonymous atom for
the section content that is before the first symbol.

llvm-svn: 210142
This commit is contained in:
Nick Kledzik 2014-06-04 00:34:27 +00:00
parent e9af316423
commit a2d602560b
2 changed files with 35 additions and 22 deletions

View File

@ -209,31 +209,29 @@ void appendSymbolsInSection(const std::vector<Symbol> &inSymbols,
} }
void atomFromSymbol(DefinedAtom::ContentType atomType, const Section &section, void atomFromSymbol(DefinedAtom::ContentType atomType, const Section &section,
MachOFile &file, const Symbol &symbol, MachOFile &file, uint64_t symbolAddr, StringRef symbolName,
bool symbolWeakDef, Atom::Scope symbolScope,
uint64_t nextSymbolAddr, bool copyRefs) { uint64_t nextSymbolAddr, bool copyRefs) {
// Mach-O symbol table does have size in it. Instead the size is the // Mach-O symbol table does have size in it. Instead the size is the
// difference between this and the next symbol. // difference between this and the next symbol.
uint64_t size = nextSymbolAddr - symbol.value; uint64_t size = nextSymbolAddr - symbolAddr;
if (section.type == llvm::MachO::S_ZEROFILL) { if (section.type == llvm::MachO::S_ZEROFILL) {
file.addZeroFillDefinedAtom(symbol.name, atomScope(symbol.scope), file.addZeroFillDefinedAtom(symbolName, symbolScope, size, copyRefs);
size, copyRefs);
} else { } else {
uint64_t offset = symbol.value - section.address; uint64_t offset = symbolAddr - section.address;
ArrayRef<uint8_t> atomContent = section.content.slice(offset, size); ArrayRef<uint8_t> atomContent = section.content.slice(offset, size);
DefinedAtom::Merge merge = DefinedAtom::mergeNo; DefinedAtom::Merge merge = symbolWeakDef
if (symbol.desc & N_WEAK_DEF) ? DefinedAtom::mergeAsWeak : DefinedAtom::mergeNo;
merge = DefinedAtom::mergeAsWeak;
if (atomType == DefinedAtom::typeUnknown) { if (atomType == DefinedAtom::typeUnknown) {
// Mach-O needs a segment and section name. Concatentate those two // Mach-O needs a segment and section name. Concatentate those two
// with a / seperator (e.g. "seg/sect") to fit into the lld model // with a / seperator (e.g. "seg/sect") to fit into the lld model
// of just a section name. // of just a section name.
std::string segSectName = section.segmentName.str() std::string segSectName = section.segmentName.str()
+ "/" + section.sectionName.str(); + "/" + section.sectionName.str();
file.addDefinedAtomInCustomSection(symbol.name, atomScope(symbol.scope), file.addDefinedAtomInCustomSection(symbolName, symbolScope, atomType,
atomType, merge, atomContent, merge, atomContent, segSectName, true);
segSectName, true);
} else { } else {
file.addDefinedAtom(symbol.name, atomScope(symbol.scope), atomType, merge, file.addDefinedAtom(symbolName, symbolScope, atomType, merge,
atomContent, copyRefs); atomContent, copyRefs);
} }
} }
@ -270,20 +268,26 @@ error_code processSymboledSection(DefinedAtom::ContentType atomType,
if (symbols.empty() && section.content.empty()) if (symbols.empty() && section.content.empty())
return error_code(); return error_code();
if (symbols.front()->value != section.address) { const uint64_t firstSymbolAddr = symbols.front()->value;
if (firstSymbolAddr != section.address) {
// Section has anonymous content before first symbol. // Section has anonymous content before first symbol.
// FIXME atomFromSymbol(atomType, section, file, section.address, StringRef(),
false, Atom::scopeTranslationUnit, firstSymbolAddr, copyRefs);
} }
const Symbol *lastSym = nullptr; const Symbol *lastSym = nullptr;
bool lastSymIsWeakDef;
for (const Symbol *sym : symbols) { for (const Symbol *sym : symbols) {
if (lastSym != nullptr) { if (lastSym != nullptr) {
atomFromSymbol(atomType, section, file, *lastSym, sym->value, copyRefs); atomFromSymbol(atomType, section, file, lastSym->value, lastSym->name,
lastSymIsWeakDef, atomScope(lastSym->scope), sym->value, copyRefs);
} }
lastSym = sym; lastSym = sym;
lastSymIsWeakDef = (lastSym->desc & N_WEAK_DEF);
} }
if (lastSym != nullptr) { if (lastSym != nullptr) {
atomFromSymbol(atomType, section, file, *lastSym, atomFromSymbol(atomType, section, file, lastSym->value, lastSym->name,
lastSymIsWeakDef, atomScope(lastSym->scope),
section.address + section.content.size(), copyRefs); section.address + section.content.size(), copyRefs);
} }
return error_code(); return error_code();

View File

@ -16,51 +16,60 @@ sections:
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
alignment: 4 alignment: 4
address: 0x0000000000000000 address: 0x0000000000000000
content: [ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3 ] content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3 ]
local-symbols: local-symbols:
- name: _myStatic - name: _myStatic
type: N_SECT type: N_SECT
sect: 1 sect: 1
value: 0x0000000000000004 value: 0x000000000000000B
global-symbols: global-symbols:
- name: _myGlobal - name: _myGlobal
type: N_SECT type: N_SECT
scope: [ N_EXT ] scope: [ N_EXT ]
sect: 1 sect: 1
value: 0x0000000000000000 value: 0x0000000000000001
- name: _myGlobalWeak - name: _myGlobalWeak
type: N_SECT type: N_SECT
scope: [ N_EXT ] scope: [ N_EXT ]
sect: 1 sect: 1
desc: [ N_WEAK_DEF ] desc: [ N_WEAK_DEF ]
value: 0x0000000000000001 value: 0x0000000000000002
- name: _myHidden - name: _myHidden
type: N_SECT type: N_SECT
scope: [ N_EXT, N_PEXT ] scope: [ N_EXT, N_PEXT ]
sect: 1 sect: 1
value: 0x0000000000000002 value: 0x0000000000000004
- name: _myHiddenWeak - name: _myHiddenWeak
type: N_SECT type: N_SECT
scope: [ N_EXT, N_PEXT ] scope: [ N_EXT, N_PEXT ]
sect: 1 sect: 1
desc: [ N_WEAK_DEF ] desc: [ N_WEAK_DEF ]
value: 0x0000000000000003 value: 0x0000000000000007
... ...
# CHECK-NOT: name:
# CHECK: content: [ CC ]
# CHECK: name: _myGlobal # CHECK: name: _myGlobal
# CHECK: scope: global # CHECK: scope: global
# CHECK: content: [ C3 ]
# CHECK: name: _myGlobalWeak # CHECK: name: _myGlobalWeak
# CHECK: scope: global # CHECK: scope: global
# CHECK: content: [ 90, C3 ]
# CHECK: merge: as-weak # CHECK: merge: as-weak
# CHECK: name: _myHidden # CHECK: name: _myHidden
# CHECK: scope: hidden # CHECK: scope: hidden
# CHECK: content: [ 90, 90, C3 ]
# CHECK: name: _myHiddenWeak # CHECK: name: _myHiddenWeak
# CHECK: scope: hidden # CHECK: scope: hidden
# CHECK: content: [ 90, 90, 90, C3 ]
# CHECK: merge: as-weak # CHECK: merge: as-weak
# CHECK: name: _myStatic # CHECK: name: _myStatic
# CHECK-NOT: scope: global # CHECK-NOT: scope: global
# CHECK-NOT: scope: hidden # CHECK-NOT: scope: hidden
# CHECK: content: [ 90, 90, 90, 90, C3 ]