void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, SymbolTableMap &SymbolTable) { // Allocate memory for the section unsigned SectionID = Sections.size(); uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void*), SectionID); if (!Addr) report_fatal_error("Unable to allocate memory for common symbols!"); uint64_t Offset = 0; Sections.push_back(SectionEntry(StringRef(), Addr, TotalSize, TotalSize, 0)); memset(Addr, 0, TotalSize); DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: " << format("%p", Addr) << " DataSize: " << TotalSize << "\n"); // Assign the address of each symbol for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(), itEnd = CommonSymbols.end(); it != itEnd; it++) { uint64_t Size = it->second.first; uint64_t Align = it->second.second; StringRef Name; it->first.getName(Name); if (Align) { // This symbol has an alignment requirement. uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align); Addr += AlignOffset; Offset += AlignOffset; DEBUG(dbgs() << "Allocating common symbol " << Name << " address " << format("%p\n", Addr)); } Obj.updateSymbolAddress(it->first, (uint64_t)Addr); SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); Offset += Size; Addr += Size; } }
/// Emit the debug_aranges contribution of a unit and /// if \p DoDebugRanges is true the debug_range contents for a /// compile_unit level DW_AT_ranges attribute (Which are basically the /// same thing with a different base address). /// Just aggregate all the ranges gathered inside that unit. void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit, bool DoDebugRanges) { unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); // Gather the ranges in a vector, so that we can simplify them. The // IntervalMap will have coalesced the non-linked ranges, but here // we want to coalesce the linked addresses. std::vector<std::pair<uint64_t, uint64_t>> Ranges; const auto &FunctionRanges = Unit.getFunctionRanges(); for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end(); Range != End; ++Range) Ranges.push_back(std::make_pair(Range.start() + Range.value(), Range.stop() + Range.value())); // The object addresses where sorted, but again, the linked // addresses might end up in a different order. llvm::sort(Ranges.begin(), Ranges.end()); if (!Ranges.empty()) { MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); MCSymbol *BeginLabel = Asm->createTempSymbol("Barange"); MCSymbol *EndLabel = Asm->createTempSymbol("Earange"); unsigned HeaderSize = sizeof(int32_t) + // Size of contents (w/o this field sizeof(int16_t) + // DWARF ARange version number sizeof(int32_t) + // Offset of CU in the .debug_info section sizeof(int8_t) + // Pointer Size (in bytes) sizeof(int8_t); // Segment Size (in bytes) unsigned TupleSize = AddressSize * 2; unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize); Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length Asm->OutStreamer->EmitLabel(BeginLabel); Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number Asm->emitInt32(Unit.getStartOffset()); // Corresponding unit's offset Asm->emitInt8(AddressSize); // Address size Asm->emitInt8(0); // Segment size Asm->OutStreamer->emitFill(Padding, 0x0); for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) { uint64_t RangeStart = Range->first; MS->EmitIntValue(RangeStart, AddressSize); while ((Range + 1) != End && Range->second == (Range + 1)->first) ++Range; MS->EmitIntValue(Range->second - RangeStart, AddressSize); } // Emit terminator Asm->OutStreamer->EmitIntValue(0, AddressSize); Asm->OutStreamer->EmitIntValue(0, AddressSize); Asm->OutStreamer->EmitLabel(EndLabel); } if (!DoDebugRanges) return; MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); // Offset each range by the right amount. int64_t PcOffset = -Unit.getLowPc(); // Emit coalesced ranges. for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) { MS->EmitIntValue(Range->first + PcOffset, AddressSize); while (Range + 1 != End && Range->second == (Range + 1)->first) ++Range; MS->EmitIntValue(Range->second + PcOffset, AddressSize); RangesSectionSize += 2 * AddressSize; } // Add the terminator entry. MS->EmitIntValue(0, AddressSize); MS->EmitIntValue(0, AddressSize); RangesSectionSize += 2 * AddressSize; }