[lld-macho][nfc] Simplify LC_DATA_IN_CODE generation
1. After D113241, we have the section address easily accessible and no longer need to iterate across the LC_SEGMENT commands to emit LC_DATA_IN_CODE. 2. There's no need to store a pointer to the data in code entries during the parse step; we can just look it up as part of the output step. Reviewed By: #lld-macho, thakis Differential Revision: https://reviews.llvm.org/D115556
This commit is contained in:
parent
40bcbe48e8
commit
098430cd25
|
@ -879,8 +879,6 @@ template <class LP> void ObjFile::parse() {
|
||||||
sections[i].subsections);
|
sections[i].subsections);
|
||||||
|
|
||||||
parseDebugInfo();
|
parseDebugInfo();
|
||||||
if (config->emitDataInCodeInfo)
|
|
||||||
parseDataInCode();
|
|
||||||
if (compactUnwindSection)
|
if (compactUnwindSection)
|
||||||
registerCompactUnwind();
|
registerCompactUnwind();
|
||||||
}
|
}
|
||||||
|
@ -908,19 +906,14 @@ void ObjFile::parseDebugInfo() {
|
||||||
compileUnit = it->get();
|
compileUnit = it->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjFile::parseDataInCode() {
|
ArrayRef<data_in_code_entry> ObjFile::getDataInCode() const {
|
||||||
const auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
const auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
||||||
const load_command *cmd = findCommand(buf, LC_DATA_IN_CODE);
|
const load_command *cmd = findCommand(buf, LC_DATA_IN_CODE);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return;
|
return {};
|
||||||
const auto *c = reinterpret_cast<const linkedit_data_command *>(cmd);
|
const auto *c = reinterpret_cast<const linkedit_data_command *>(cmd);
|
||||||
dataInCodeEntries = {
|
return {reinterpret_cast<const data_in_code_entry *>(buf + c->dataoff),
|
||||||
reinterpret_cast<const data_in_code_entry *>(buf + c->dataoff),
|
|
||||||
c->datasize / sizeof(data_in_code_entry)};
|
c->datasize / sizeof(data_in_code_entry)};
|
||||||
assert(is_sorted(dataInCodeEntries, [](const data_in_code_entry &lhs,
|
|
||||||
const data_in_code_entry &rhs) {
|
|
||||||
return lhs.offset < rhs.offset;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create pointers from symbols to their associated compact unwind entries.
|
// Create pointers from symbols to their associated compact unwind entries.
|
||||||
|
|
|
@ -108,12 +108,13 @@ private:
|
||||||
class ObjFile final : public InputFile {
|
class ObjFile final : public InputFile {
|
||||||
public:
|
public:
|
||||||
ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName);
|
ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName);
|
||||||
|
ArrayRef<llvm::MachO::data_in_code_entry> getDataInCode() const;
|
||||||
|
|
||||||
static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
|
static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
|
||||||
|
|
||||||
llvm::DWARFUnit *compileUnit = nullptr;
|
llvm::DWARFUnit *compileUnit = nullptr;
|
||||||
const uint32_t modTime;
|
const uint32_t modTime;
|
||||||
std::vector<ConcatInputSection *> debugSections;
|
std::vector<ConcatInputSection *> debugSections;
|
||||||
ArrayRef<llvm::MachO::data_in_code_entry> dataInCodeEntries;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Section *compactUnwindSection = nullptr;
|
Section *compactUnwindSection = nullptr;
|
||||||
|
@ -130,7 +131,6 @@ private:
|
||||||
void parseRelocations(ArrayRef<SectionHeader> sectionHeaders,
|
void parseRelocations(ArrayRef<SectionHeader> sectionHeaders,
|
||||||
const SectionHeader &, Subsections &);
|
const SectionHeader &, Subsections &);
|
||||||
void parseDebugInfo();
|
void parseDebugInfo();
|
||||||
void parseDataInCode();
|
|
||||||
void registerCompactUnwind();
|
void registerCompactUnwind();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -733,35 +733,30 @@ DataInCodeSection::DataInCodeSection()
|
||||||
|
|
||||||
template <class LP>
|
template <class LP>
|
||||||
static std::vector<MachO::data_in_code_entry> collectDataInCodeEntries() {
|
static std::vector<MachO::data_in_code_entry> collectDataInCodeEntries() {
|
||||||
using SegmentCommand = typename LP::segment_command;
|
|
||||||
using SectionHeader = typename LP::section;
|
|
||||||
|
|
||||||
std::vector<MachO::data_in_code_entry> dataInCodeEntries;
|
std::vector<MachO::data_in_code_entry> dataInCodeEntries;
|
||||||
for (const InputFile *inputFile : inputFiles) {
|
for (const InputFile *inputFile : inputFiles) {
|
||||||
if (!isa<ObjFile>(inputFile))
|
if (!isa<ObjFile>(inputFile))
|
||||||
continue;
|
continue;
|
||||||
const ObjFile *objFile = cast<ObjFile>(inputFile);
|
const ObjFile *objFile = cast<ObjFile>(inputFile);
|
||||||
const auto *c = reinterpret_cast<const SegmentCommand *>(
|
ArrayRef<MachO::data_in_code_entry> entries = objFile->getDataInCode();
|
||||||
findCommand(objFile->mb.getBufferStart(), LP::segmentLCType));
|
|
||||||
if (!c)
|
|
||||||
continue;
|
|
||||||
ArrayRef<SectionHeader> sectionHeaders{
|
|
||||||
reinterpret_cast<const SectionHeader *>(c + 1), c->nsects};
|
|
||||||
|
|
||||||
ArrayRef<MachO::data_in_code_entry> entries = objFile->dataInCodeEntries;
|
|
||||||
if (entries.empty())
|
if (entries.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
assert(is_sorted(dataInCodeEntries, [](const data_in_code_entry &lhs,
|
||||||
|
const data_in_code_entry &rhs) {
|
||||||
|
return lhs.offset < rhs.offset;
|
||||||
|
}));
|
||||||
// For each code subsection find 'data in code' entries residing in it.
|
// For each code subsection find 'data in code' entries residing in it.
|
||||||
// Compute the new offset values as
|
// Compute the new offset values as
|
||||||
// <offset within subsection> + <subsection address> - <__TEXT address>.
|
// <offset within subsection> + <subsection address> - <__TEXT address>.
|
||||||
for (size_t i = 0, n = sectionHeaders.size(); i < n; ++i) {
|
for (const Section §ion : objFile->sections) {
|
||||||
for (const Subsection &subsec : objFile->sections[i].subsections) {
|
for (const Subsection &subsec : section.subsections) {
|
||||||
const InputSection *isec = subsec.isec;
|
const InputSection *isec = subsec.isec;
|
||||||
if (!isCodeSection(isec))
|
if (!isCodeSection(isec))
|
||||||
continue;
|
continue;
|
||||||
if (cast<ConcatInputSection>(isec)->shouldOmitFromOutput())
|
if (cast<ConcatInputSection>(isec)->shouldOmitFromOutput())
|
||||||
continue;
|
continue;
|
||||||
const uint64_t beginAddr = sectionHeaders[i].addr + subsec.offset;
|
const uint64_t beginAddr = section.address + subsec.offset;
|
||||||
auto it = llvm::lower_bound(
|
auto it = llvm::lower_bound(
|
||||||
entries, beginAddr,
|
entries, beginAddr,
|
||||||
[](const MachO::data_in_code_entry &entry, uint64_t addr) {
|
[](const MachO::data_in_code_entry &entry, uint64_t addr) {
|
||||||
|
|
Loading…
Reference in New Issue