@@ -368,7 +368,6 @@ struct AddrExprMap {
368368 }
369369 }
370370
371-
372371 Expression* getStart (BinaryLocation addr) const {
373372 auto iter = startMap.find (addr);
374373 if (iter != startMap.end ()) {
@@ -498,6 +497,10 @@ struct LocationUpdater {
498497 return 0 ;
499498 }
500499
500+ bool hasOldExprEndAddr (BinaryLocation oldAddr) const {
501+ return oldExprAddrMap.getEnd (oldAddr);
502+ }
503+
501504 BinaryLocation getNewFuncStartAddr (BinaryLocation oldAddr) const {
502505 if (auto * func = oldFuncAddrMap.getStart (oldAddr)) {
503506 // The function might have been optimized away, check.
@@ -612,7 +615,6 @@ static void updateDebugLines(llvm::DWARFYAML::Data& data,
612615 } else if (locationUpdater.hasOldExtraAddr (oldAddr)) {
613616 newAddr = locationUpdater.getNewExtraAddr (oldAddr);
614617 }
615- // TODO: last 'end' of a function
616618 if (newAddr) {
617619 // LLVM sometimes emits the same address more than once. We should
618620 // probably investigate that.
@@ -764,6 +766,55 @@ static void updateCompileUnits(const BinaryenDWARFInfo& info,
764766 });
765767}
766768
769+ static void updateRanges (llvm::DWARFYAML::Data& yaml,
770+ const LocationUpdater& locationUpdater) {
771+ // In each range section, try to update the start and end. If we no longer
772+ // have something to map them to, we must skip that part.
773+ size_t skip = 0 ;
774+ for (size_t i = 0 ; i < yaml.Ranges .size (); i++) {
775+ auto & range = yaml.Ranges [i];
776+ BinaryLocation oldStart = range.Start , oldEnd = range.End , newStart = 0 ,
777+ newEnd = 0 ;
778+ // If this was not an end marker, try to find what it should be updated to.
779+ if (oldStart != 0 && oldEnd != 0 ) {
780+ if (locationUpdater.hasOldExprAddr (oldStart)) {
781+ newStart = locationUpdater.getNewExprAddr (oldStart);
782+ } else if (locationUpdater.hasOldFuncStartAddr (oldStart)) {
783+ newStart = locationUpdater.getNewFuncStartAddr (oldStart);
784+ }
785+ if (locationUpdater.hasOldExprEndAddr (oldEnd)) {
786+ newEnd = locationUpdater.getNewExprEndAddr (oldEnd);
787+ } else if (locationUpdater.hasOldFuncEndAddr (oldEnd)) {
788+ newEnd = locationUpdater.getNewFuncEndAddr (oldEnd);
789+ }
790+ if (newStart == 0 || newEnd == 0 ) {
791+ // This part of the range no longer has a mapping, so we must skip it.
792+ skip++;
793+ continue ;
794+ }
795+ // The range start and end markers have been preserved. However, TODO
796+ // instructions in the middle may have moved around, making the range no
797+ // longer contiguous, we should check that, and possibly split/merge
798+ // the range. Or, we may need to have tracking in the IR for this.
799+ } else {
800+ // This was not a valid range in the old binary. It was either two 0's
801+ // (an end marker) or an invalid value that should be ignored. Either way,
802+ // write an end marker and finish the current section of ranges, filling
803+ // it out to the original size (we must fill it out as indexes into
804+ // the ranges section are not updated - we could update them and then
805+ // pack the section, as an optimization TODO).
806+ while (skip) {
807+ auto & writtenRange = yaml.Ranges [i - skip];
808+ writtenRange.Start = writtenRange.End = 0 ;
809+ skip--;
810+ }
811+ }
812+ auto & writtenRange = yaml.Ranges [i - skip];
813+ writtenRange.Start = newStart;
814+ writtenRange.End = newEnd;
815+ }
816+ }
817+
767818void writeDWARFSections (Module& wasm, const BinaryLocations& newLocations) {
768819 BinaryenDWARFInfo info (wasm);
769820
@@ -779,6 +830,8 @@ void writeDWARFSections(Module& wasm, const BinaryLocations& newLocations) {
779830
780831 updateCompileUnits (info, data, locationUpdater);
781832
833+ updateRanges (data, locationUpdater);
834+
782835 // Convert to binary sections.
783836 auto newSections =
784837 EmitDebugSections (data, false /* EmitFixups for debug_info */ );
0 commit comments