summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2014-06-04 00:34:27 +0000
committerNick Kledzik <kledzik@apple.com>2014-06-04 00:34:27 +0000
commita2d602560beb335cd443ccc03a41ecf714f337bb (patch)
treee314524adb62f47d9d3a03a8ab6b16320dbf090b
parente9af3164237f16a35e6f57c06f09b20cb7b4b622 (diff)
downloadbcm5719-llvm-a2d602560beb335cd443ccc03a41ecf714f337bb.tar.gz
bcm5719-llvm-a2d602560beb335cd443ccc03a41ecf714f337bb.zip
[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
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp36
-rw-r--r--lld/test/mach-o/parse-function.yaml21
2 files changed, 35 insertions, 22 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 9be4d0ec410..e5ce190f924 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 &section,
- 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 5eb721da386..19a935adb55 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 ]
OpenPOWER on IntegriCloud