3232#include " llvm/MC/MCAssembler.h"
3333#include " llvm/MC/MCObjectWriter.h"
3434#include " llvm/MC/MCStreamer.h"
35+ #include " llvm/MC/MCTargetOptionsCommandFlags.h"
3536#include " llvm/Object/ObjectFile.h"
3637#include " llvm/Support/Casting.h"
3738#include " llvm/Support/CommandLine.h"
5657#undef DEBUG_TYPE
5758#define DEBUG_TYPE " bolt"
5859
60+ static mc::RegisterMCTargetOptionsFlags MOF;
61+
5962static void printDie (const DWARFDie &DIE) {
6063 DIDumpOptions DumpOpts;
6164 DumpOpts.ShowForm = true ;
@@ -328,14 +331,8 @@ static cl::opt<bool> KeepARanges(
328331
329332static cl::opt<std::string> DwarfOutputPath (
330333 " dwarf-output-path" ,
331- cl::desc (" Path to where .dwo files or dwp file will be written out to." ),
332- cl::init(" " ), cl::cat(BoltCategory));
333-
334- static cl::opt<bool >
335- WriteDWP (" write-dwp" ,
336- cl::desc (" output a single dwarf package file (dwp) instead of "
337- " multiple non-relocatable dwarf object files (dwo)." ),
338- cl::init(false ), cl::cat(BoltCategory));
334+ cl::desc (" Path to where .dwo files will be written out to." ), cl::init(" " ),
335+ cl::cat(BoltCategory));
339336
340337static cl::opt<bool > CreateDebugNames (
341338 " create-debug-names-section" ,
@@ -478,12 +475,13 @@ emitUnit(DIEBuilder &DIEBldr, DIEStreamer &Streamer, DWARFUnit &Unit) {
478475 return {U.UnitOffset , U.UnitLength , TypeHash};
479476}
480477
481- static void
482- emitDWOBuilder (const std::string &DWOName, DIEBuilder &DWODIEBuilder,
483- DWARFRewriter &Rewriter, DWARFUnit &SplitCU, DWARFUnit &CU,
484- DWARFRewriter::DWPState &State, DebugLocWriter &LocWriter,
485- DebugStrOffsetsWriter &StrOffstsWriter,
486- DebugStrWriter &StrWriter, GDBIndex &GDBIndexSection) {
478+ static void emitDWOBuilder (const std::string &DWOName,
479+ DIEBuilder &DWODIEBuilder, DWARFRewriter &Rewriter,
480+ DWARFUnit &SplitCU, DWARFUnit &CU,
481+ DebugLocWriter &LocWriter,
482+ DebugStrOffsetsWriter &StrOffstsWriter,
483+ DebugStrWriter &StrWriter,
484+ GDBIndex &GDBIndexSection) {
487485 // Populate debug_info and debug_abbrev for current dwo into StringRef.
488486 DWODIEBuilder.generateAbbrevs ();
489487 DWODIEBuilder.finish ();
@@ -544,12 +542,8 @@ emitDWOBuilder(const std::string &DWOName, DIEBuilder &DWODIEBuilder,
544542 continue ;
545543 OverriddenSections[Kind] = Contents;
546544 }
547- if (opts::WriteDWP)
548- Rewriter.updateDWP (CU, OverriddenSections, CUMI, TUMetaVector, State,
549- LocWriter, StrOffstsWriter, StrWriter);
550- else
551- Rewriter.writeDWOFiles (CU, OverriddenSections, DWOName, LocWriter,
552- StrOffstsWriter, StrWriter);
545+ Rewriter.writeDWOFiles (CU, OverriddenSections, DWOName, LocWriter,
546+ StrOffstsWriter, StrWriter);
553547}
554548
555549using DWARFUnitVec = std::vector<DWARFUnit *>;
@@ -662,9 +656,6 @@ void DWARFRewriter::updateDebugInfo() {
662656 DWARF5AcceleratorTable DebugNamesTable (opts::CreateDebugNames, BC,
663657 *StrWriter);
664658 GDBIndex GDBIndexSection (BC);
665- DWPState State;
666- if (opts::WriteDWP)
667- initDWPState (State);
668659 auto processSplitCU = [&](DWARFUnit &Unit, DWARFUnit &SplitCU,
669660 DIEBuilder &DIEBlder,
670661 DebugRangesSectionWriter &TempRangesSectionWriter,
@@ -688,7 +679,7 @@ void DWARFRewriter::updateDebugInfo() {
688679 if (Unit.getVersion () >= 5 )
689680 TempRangesSectionWriter.finalizeSection ();
690681
691- emitDWOBuilder (DWOName, DWODIEBuilder, *this , SplitCU, Unit, State,
682+ emitDWOBuilder (DWOName, DWODIEBuilder, *this , SplitCU, Unit,
692683 DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter,
693684 GDBIndexSection);
694685 };
@@ -768,9 +759,6 @@ void DWARFRewriter::updateDebugInfo() {
768759
769760 DebugNamesTable.emitAccelTable ();
770761
771- if (opts::WriteDWP)
772- finalizeDWP (State);
773-
774762 finalizeDebugSections (DIEBlder, DebugNamesTable, *Streamer, *ObjOS, OffsetMap,
775763 *FinalAddrWriter);
776764 GDBIndexSection.updateGdbIndexSection (OffsetMap, CUIndex,
@@ -1816,220 +1804,6 @@ std::optional<StringRef> updateDebugData(
18161804
18171805} // namespace
18181806
1819- void DWARFRewriter::initDWPState (DWPState &State) {
1820- SmallString<0 > OutputNameStr;
1821- StringRef OutputName;
1822- if (opts::DwarfOutputPath.empty ()) {
1823- OutputName =
1824- Twine (opts::OutputFilename).concat (" .dwp" ).toStringRef (OutputNameStr);
1825- } else {
1826- StringRef ExeFileName = llvm::sys::path::filename (opts::OutputFilename);
1827- OutputName = Twine (opts::DwarfOutputPath)
1828- .concat (" /" )
1829- .concat (ExeFileName)
1830- .concat (" .dwp" )
1831- .toStringRef (OutputNameStr);
1832- errs () << " BOLT-WARNING: dwarf-output-path is in effect and .dwp file will "
1833- " possibly be written to another location that is not the same as "
1834- " the executable\n " ;
1835- }
1836- std::error_code EC;
1837- State.Out =
1838- std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None);
1839- const object::ObjectFile *File = BC.DwCtx ->getDWARFObj ().getFile ();
1840- State.TmpBC = createDwarfOnlyBC (*File);
1841- State.Streamer = State.TmpBC ->createStreamer (State.Out ->os ());
1842- State.MCOFI = State.Streamer ->getContext ().getObjectFileInfo ();
1843- State.KnownSections = createKnownSectionsMap (*State.MCOFI );
1844- MCSection *const StrSection = State.MCOFI ->getDwarfStrDWOSection ();
1845-
1846- // Data Structures for DWP book keeping
1847- // Size of array corresponds to the number of sections supported by DWO format
1848- // in DWARF4/5.
1849-
1850- State.Strings = std::make_unique<DWPStringPool>(*State.Streamer , StrSection);
1851-
1852- // Setup DWP code once.
1853- DWARFContext *DWOCtx = BC.getDWOContext ();
1854-
1855- if (DWOCtx) {
1856- State.CUIndex = &DWOCtx->getCUIndex ();
1857- State.IsDWP = !State.CUIndex ->getRows ().empty ();
1858- }
1859- }
1860-
1861- void DWARFRewriter::finalizeDWP (DWPState &State) {
1862- if (State.Version < 5 ) {
1863- // Lie about there being no info contributions so the TU index only includes
1864- // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
1865- // contribution to the info section, so we do not want to lie about it.
1866- State.ContributionOffsets [0 ] = 0 ;
1867- }
1868- writeIndex (*State.Streamer .get (), State.MCOFI ->getDwarfTUIndexSection (),
1869- State.ContributionOffsets , State.TypeIndexEntries ,
1870- State.IndexVersion );
1871-
1872- if (State.Version < 5 ) {
1873- // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
1874- // section does not exist, so no need to do anything about this.
1875- State.ContributionOffsets [getContributionIndex (DW_SECT_EXT_TYPES, 2 )] = 0 ;
1876- // Unlie about the info contribution
1877- State.ContributionOffsets [0 ] = 1 ;
1878- }
1879- writeIndex (*State.Streamer .get (), State.MCOFI ->getDwarfCUIndexSection (),
1880- State.ContributionOffsets , State.IndexEntries , State.IndexVersion );
1881-
1882- State.Streamer ->finish ();
1883- State.Out ->keep ();
1884- }
1885-
1886- void DWARFRewriter::updateDWP (DWARFUnit &CU,
1887- const OverriddenSectionsMap &OverridenSections,
1888- const DWARFRewriter::UnitMeta &CUMI,
1889- DWARFRewriter::UnitMetaVectorType &TUMetaVector,
1890- DWPState &State, DebugLocWriter &LocWriter,
1891- DebugStrOffsetsWriter &StrOffstsWriter,
1892- DebugStrWriter &StrWriter) {
1893- const uint64_t DWOId = *CU.getDWOId ();
1894- MCSection *const StrOffsetSection = State.MCOFI ->getDwarfStrOffDWOSection ();
1895- assert (StrOffsetSection && " StrOffsetSection does not exist." );
1896- // Skipping CUs that we failed to load.
1897- std::optional<DWARFUnit *> DWOCU = BC.getDWOCU (DWOId);
1898- if (!DWOCU)
1899- return ;
1900-
1901- if (State.Version == 0 ) {
1902- State.Version = CU.getVersion ();
1903- State.IndexVersion = State.Version < 5 ? 2 : 5 ;
1904- } else if (State.Version != CU.getVersion ()) {
1905- errs () << " BOLT-ERROR: incompatible DWARF compile unit versions\n " ;
1906- exit (1 );
1907- }
1908-
1909- UnitIndexEntry CurEntry = {};
1910- CurEntry.DWOName = dwarf::toString (
1911- CU.getUnitDIE ().find ({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
1912- " " );
1913- const char *Name = CU.getUnitDIE ().getShortName ();
1914- if (Name)
1915- CurEntry.Name = Name;
1916- StringRef CurStrSection;
1917- StringRef CurStrOffsetSection;
1918-
1919- // This maps each section contained in this file to its length.
1920- // This information is later on used to calculate the contributions,
1921- // i.e. offset and length, of each compile/type unit to a section.
1922- std::vector<std::pair<DWARFSectionKind, uint32_t >> SectionLength;
1923-
1924- const DWARFUnitIndex::Entry *CUDWOEntry = nullptr ;
1925- if (State.IsDWP )
1926- CUDWOEntry = State.CUIndex ->getFromHash (DWOId);
1927-
1928- bool StrSectionWrittenOut = false ;
1929- const object::ObjectFile *DWOFile =
1930- (*DWOCU)->getContext ().getDWARFObj ().getFile ();
1931-
1932- DebugRangeListsSectionWriter *RangeListssWriter = nullptr ;
1933- if (CU.getVersion () == 5 ) {
1934- assert (RangeListsWritersByCU.count (DWOId) != 0 &&
1935- " No RangeListsWriter for DWO ID." );
1936- RangeListssWriter = RangeListsWritersByCU[DWOId].get ();
1937- }
1938- auto AddType = [&](unsigned int Index, uint32_t IndexVersion, uint64_t Offset,
1939- uint64_t Length, uint64_t Hash) -> void {
1940- UnitIndexEntry TUEntry = CurEntry;
1941- if (IndexVersion < 5 )
1942- TUEntry.Contributions [0 ] = {};
1943- TUEntry.Contributions [Index].setOffset (Offset);
1944- TUEntry.Contributions [Index].setLength (Length);
1945- State.ContributionOffsets [Index] +=
1946- TUEntry.Contributions [Index].getLength32 ();
1947- State.TypeIndexEntries .insert (std::make_pair (Hash, TUEntry));
1948- };
1949- std::unique_ptr<DebugBufferVector> StrOffsetsOutputData;
1950- std::unique_ptr<DebugBufferVector> StrOutputData;
1951- for (const SectionRef &Section : DWOFile->sections ()) {
1952- std::unique_ptr<DebugBufferVector> OutputData = nullptr ;
1953- StringRef SectionName = getSectionName (Section);
1954- Expected<StringRef> ContentsExp = Section.getContents ();
1955- assert (ContentsExp && " Invalid contents." );
1956- std::optional<StringRef> TOutData =
1957- updateDebugData ((*DWOCU)->getContext (), SectionName, *ContentsExp,
1958- State.KnownSections , *State.Streamer , *this , CUDWOEntry,
1959- DWOId, OutputData, RangeListssWriter, LocWriter,
1960- StrOffstsWriter, StrWriter, OverridenSections);
1961- if (!TOutData)
1962- continue ;
1963-
1964- StringRef OutData = *TOutData;
1965- if (SectionName == " debug_types.dwo" ) {
1966- State.Streamer ->emitBytes (OutData);
1967- continue ;
1968- }
1969-
1970- if (SectionName == " debug_str.dwo" ) {
1971- CurStrSection = OutData;
1972- StrOutputData = std::move (OutputData);
1973- } else {
1974- // Since handleDebugDataPatching returned true, we already know this is
1975- // a known section.
1976- auto SectionIter = State.KnownSections .find (SectionName);
1977- if (SectionIter->second .second == DWARFSectionKind::DW_SECT_STR_OFFSETS) {
1978- CurStrOffsetSection = OutData;
1979- StrOffsetsOutputData = std::move (OutputData);
1980- } else {
1981- State.Streamer ->emitBytes (OutData);
1982- }
1983- unsigned int Index =
1984- getContributionIndex (SectionIter->second .second , State.IndexVersion );
1985- uint64_t Offset = State.ContributionOffsets [Index];
1986- uint64_t Length = OutData.size ();
1987- if (CU.getVersion () >= 5 &&
1988- SectionIter->second .second == DWARFSectionKind::DW_SECT_INFO) {
1989- for (UnitMeta &MI : TUMetaVector)
1990- MI.Offset += State.DebugInfoSize ;
1991-
1992- Offset = State.DebugInfoSize + CUMI.Offset ;
1993- Length = CUMI.Length ;
1994- State.DebugInfoSize += OutData.size ();
1995- }
1996- CurEntry.Contributions [Index].setOffset (Offset);
1997- CurEntry.Contributions [Index].setLength (Length);
1998- State.ContributionOffsets [Index] +=
1999- CurEntry.Contributions [Index].getLength32 ();
2000- }
2001-
2002- // Strings are combined in to a new string section, and de-duplicated
2003- // based on hash.
2004- if (!StrSectionWrittenOut && !CurStrOffsetSection.empty () &&
2005- !CurStrSection.empty ()) {
2006- // If debug_str.dwo section was modified storing it until dwp is written
2007- // out. DWPStringPool stores raw pointers to strings.
2008- if (StrOutputData)
2009- State.StrSections .push_back (std::move (StrOutputData));
2010- writeStringsAndOffsets (*State.Streamer .get (), *State.Strings .get (),
2011- StrOffsetSection, CurStrSection,
2012- CurStrOffsetSection, CU.getVersion ());
2013- StrSectionWrittenOut = true ;
2014- }
2015- }
2016- CompileUnitIdentifiers CUI{DWOId, CurEntry.Name .c_str (),
2017- CurEntry.DWOName .c_str ()};
2018- auto P = State.IndexEntries .insert (std::make_pair (CUI.Signature , CurEntry));
2019- if (!P.second ) {
2020- Error Err = buildDuplicateError (*P.first , CUI, " " );
2021- errs () << " BOLT-ERROR: " << toString (std::move (Err)) << " \n " ;
2022- return ;
2023- }
2024-
2025- // Handling TU
2026- const unsigned Index = getContributionIndex (
2027- State.IndexVersion < 5 ? DW_SECT_EXT_TYPES : DW_SECT_INFO,
2028- State.IndexVersion );
2029- for (UnitMeta &MI : TUMetaVector)
2030- AddType (Index, State.IndexVersion , MI.Offset , MI.Length , MI.TUHash );
2031- }
2032-
20331807void DWARFRewriter::writeDWOFiles (
20341808 DWARFUnit &CU, const OverriddenSectionsMap &OverridenSections,
20351809 const std::string &DWOName, DebugLocWriter &LocWriter,
0 commit comments