diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 9be4d0ec4106..e5ce190f924e 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -209,31 +209,29 @@ void appendSymbolsInSection(const std::vector<Symbol> &inSymbols, } void atomFromSymbol(DefinedAtom::ContentType atomType, const Section §ion, - MachOFile &file, const Symbol &symbol, + MachOFile &file, uint64_t symbolAddr, StringRef symbolName, + bool symbolWeakDef, Atom::Scope symbolScope, uint64_t nextSymbolAddr, bool copyRefs) { // Mach-O symbol table does have size in it. Instead the size is the // 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) { - file.addZeroFillDefinedAtom(symbol.name, atomScope(symbol.scope), - size, copyRefs); + file.addZeroFillDefinedAtom(symbolName, symbolScope, size, copyRefs); } else { - uint64_t offset = symbol.value - section.address; + uint64_t offset = symbolAddr - section.address; ArrayRef<uint8_t> atomContent = section.content.slice(offset, size); - DefinedAtom::Merge merge = DefinedAtom::mergeNo; - if (symbol.desc & N_WEAK_DEF) - merge = DefinedAtom::mergeAsWeak; + DefinedAtom::Merge merge = symbolWeakDef + ? DefinedAtom::mergeAsWeak : DefinedAtom::mergeNo; if (atomType == 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(symbol.name, atomScope(symbol.scope), - atomType, merge, atomContent, - segSectName, true); + file.addDefinedAtomInCustomSection(symbolName, symbolScope, atomType, + merge, atomContent, segSectName, true); } else { - file.addDefinedAtom(symbol.name, atomScope(symbol.scope), atomType, merge, + file.addDefinedAtom(symbolName, symbolScope, atomType, merge, atomContent, copyRefs); } } @@ -270,20 +268,26 @@ error_code processSymboledSection(DefinedAtom::ContentType atomType, if (symbols.empty() && section.content.empty()) 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. - // FIXME + atomFromSymbol(atomType, section, file, section.address, StringRef(), + false, Atom::scopeTranslationUnit, firstSymbolAddr, copyRefs); } const Symbol *lastSym = nullptr; + bool lastSymIsWeakDef; for (const Symbol *sym : symbols) { 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; + lastSymIsWeakDef = (lastSym->desc & N_WEAK_DEF); } 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); } return error_code(); diff --git a/lld/test/mach-o/parse-function.yaml b/lld/test/mach-o/parse-function.yaml index 5eb721da3865..19a935adb552 100644 --- a/lld/test/mach-o/parse-function.yaml +++ b/lld/test/mach-o/parse-function.yaml @@ -16,51 +16,60 @@ sections: attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] alignment: 4 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: - name: _myStatic type: N_SECT sect: 1 - value: 0x0000000000000004 + value: 0x000000000000000B global-symbols: - name: _myGlobal type: N_SECT scope: [ N_EXT ] sect: 1 - value: 0x0000000000000000 + value: 0x0000000000000001 - name: _myGlobalWeak type: N_SECT scope: [ N_EXT ] sect: 1 desc: [ N_WEAK_DEF ] - value: 0x0000000000000001 + value: 0x0000000000000002 - name: _myHidden type: N_SECT scope: [ N_EXT, N_PEXT ] sect: 1 - value: 0x0000000000000002 + value: 0x0000000000000004 - name: _myHiddenWeak type: N_SECT scope: [ N_EXT, N_PEXT ] sect: 1 desc: [ N_WEAK_DEF ] - value: 0x0000000000000003 + value: 0x0000000000000007 ... +# CHECK-NOT: name: +# CHECK: content: [ CC ] + # CHECK: name: _myGlobal # CHECK: scope: global +# CHECK: content: [ C3 ] # CHECK: name: _myGlobalWeak # CHECK: scope: global +# CHECK: content: [ 90, C3 ] # CHECK: merge: as-weak # CHECK: name: _myHidden # CHECK: scope: hidden +# CHECK: content: [ 90, 90, C3 ] # CHECK: name: _myHiddenWeak # CHECK: scope: hidden +# CHECK: content: [ 90, 90, 90, C3 ] # CHECK: merge: as-weak # CHECK: name: _myStatic # CHECK-NOT: scope: global # CHECK-NOT: scope: hidden +# CHECK: content: [ 90, 90, 90, 90, C3 ]