+ // Absolutize symbol differences between defined symbols when we have a
+ // layout object and the target requests it.
+
+ assert((!Layout || Asm) &&
+ "Must have an assembler object if layout is given!");
+
+ if (Asm && A && B) {
+ if (A->getSymbol().isDefined() && B->getSymbol().isDefined() &&
+ Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B,
+ InSet)) {
+ MCSymbolData &AD = Asm->getSymbolData(A->getSymbol());
+ MCSymbolData &BD = Asm->getSymbolData(B->getSymbol());
+
+ if (AD.getFragment() == BD.getFragment()) {
+ Res = MCValue::get(+ AD.getOffset()
+ - BD.getOffset()
+ + Result_Cst);
+ return true;
+ }
+
+ if (Layout) {
+ const MCSectionData &SecA = *AD.getFragment()->getParent();
+ const MCSectionData &SecB = *BD.getFragment()->getParent();
+ int64_t Val = + Layout->getSymbolOffset(&AD)
+ - Layout->getSymbolOffset(&BD)
+ + Result_Cst;
+ if (&SecA != &SecB) {
+ if (!Addrs)
+ return false;
+ Val += Addrs->lookup(&SecA);
+ Val -= Addrs->lookup(&SecB);
+ }
+ Res = MCValue::get(Val);
+ return true;
+ }
+ }
+ }
+