@@ -531,20 +531,40 @@ BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF,
531531}
532532
533533MCSymbol *BinaryContext::handleExternalBranchTarget (uint64_t Address,
534- BinaryFunction &BF) {
535- if (BF.isInConstantIsland (Address)) {
536- BF.setIgnored ();
537- this ->outs () << " BOLT-WARNING: ignoring entry point at address 0x"
538- << Twine::utohexstr (Address)
539- << " in constant island of function " << BF << ' \n ' ;
540- return nullptr ;
534+ BinaryFunction &Source,
535+ BinaryFunction &Target) {
536+ const uint64_t Offset = Address - Target.getAddress ();
537+ assert (Offset < Target.getSize () &&
538+ " Address should be inside the referenced function" );
539+
540+ bool IsValid = true ;
541+ if (Source.NeedBranchValidation ) {
542+ if (Target.CurrentState == BinaryFunction::State::Disassembled &&
543+ !Target.getInstructionAtOffset (Offset)) {
544+ this ->errs ()
545+ << " BOLT-WARNING: corrupted control flow detected in function "
546+ << Source
547+ << " : an external branch/call targets an invalid instruction "
548+ << " in function " << Target << " at address 0x"
549+ << Twine::utohexstr (Address) << " ; ignoring both functions\n " ;
550+ IsValid = false ;
551+ }
552+ if (Target.isInConstantIsland (Address)) {
553+ this ->errs () << " BOLT-WARNING: ignoring entry point at address 0x"
554+ << Twine::utohexstr (Address)
555+ << " in constant island of function " << Target << ' \n ' ;
556+ IsValid = false ;
557+ }
541558 }
542559
543- const uint64_t Offset = Address - BF.getAddress ();
544- assert (Offset < BF.getSize () &&
545- " Address should be inside the referenced function" );
560+ if (!IsValid) {
561+ Source.NeedBranchValidation = false ;
562+ Source.setIgnored ();
563+ Target.setIgnored ();
564+ return nullptr ;
565+ }
546566
547- return Offset ? BF .addEntryPointAtOffset (Offset) : BF .getSymbol ();
567+ return Offset ? Target .addEntryPointAtOffset (Offset) : Target .getSymbol ();
548568}
549569
550570MemoryContentsType BinaryContext::analyzeMemoryAt (uint64_t Address,
@@ -1433,7 +1453,7 @@ void BinaryContext::processInterproceduralReferences() {
14331453
14341454 // Create an extra entry point if needed. Can also render the target
14351455 // function ignored if the reference is invalid.
1436- handleExternalBranchTarget (Address, *TargetFunction);
1456+ handleExternalBranchTarget (Address, Function, *TargetFunction);
14371457
14381458 continue ;
14391459 }
@@ -1868,6 +1888,9 @@ void BinaryContext::preprocessDebugInfo() {
18681888
18691889 preprocessDWODebugInfo ();
18701890
1891+ // Check if required DWO files are missing.
1892+ uint64_t NumMissingDWOs = 0 ;
1893+
18711894 // Populate MCContext with DWARF files from all units.
18721895 StringRef GlobalPrefix = AsmInfo->getPrivateGlobalPrefix ();
18731896 for (const std::unique_ptr<DWARFUnit> &CU : DwCtx->compile_units ()) {
@@ -1889,19 +1912,23 @@ void BinaryContext::preprocessDebugInfo() {
18891912 std::optional<MD5::MD5Result> Checksum;
18901913 if (LineTable->Prologue .ContentTypes .HasMD5 )
18911914 Checksum = LineTable->Prologue .FileNames [0 ].Checksum ;
1892- std::optional< const char *> Name =
1915+ const char *Name =
18931916 dwarf::toString (CU->getUnitDIE ().find (dwarf::DW_AT_name), nullptr );
18941917 if (std::optional<uint64_t > DWOID = CU->getDWOId ()) {
18951918 auto Iter = DWOCUs.find (*DWOID);
18961919 if (Iter == DWOCUs.end ()) {
1897- this ->errs () << " BOLT-ERROR: DWO CU was not found for " << Name
1898- << ' \n ' ;
1899- exit (1 );
1920+ const char *DWOName =
1921+ dwarf::toString (CU->getUnitDIE ().find (dwarf::DW_AT_dwo_name),
1922+ " <missing DW_AT_dwo_name>" );
1923+ this ->errs () << " BOLT-ERROR: unable to load " << DWOName
1924+ << " for DWO_id 0x" << Twine::utohexstr (*DWOID) << ' \n ' ;
1925+ NumMissingDWOs++;
1926+ continue ;
19001927 }
19011928 Name = dwarf::toString (
19021929 Iter->second ->getUnitDIE ().find (dwarf::DW_AT_name), nullptr );
19031930 }
1904- BinaryLineTable.setRootFile (CU->getCompilationDir (), * Name, Checksum,
1931+ BinaryLineTable.setRootFile (CU->getCompilationDir (), Name, Checksum,
19051932 std::nullopt );
19061933 }
19071934
@@ -1936,6 +1963,14 @@ void BinaryContext::preprocessDebugInfo() {
19361963 DwarfVersion));
19371964 }
19381965 }
1966+
1967+ if (NumMissingDWOs) {
1968+ this ->errs () << " BOLT-ERROR: " << NumMissingDWOs
1969+ << " required DWO file(s) not found. Unable to update debug"
1970+ " info. Use --comp-dir-override to locate the file(s) or"
1971+ " --update-debug-sections=0 to remove debug info\n " ;
1972+ exit (1 );
1973+ }
19391974}
19401975
19411976bool BinaryContext::shouldEmit (const BinaryFunction &Function) const {
0 commit comments