private bool IsFloatingPointEmulatorFixup(Fixup fixup)
        {
            ExternalSymbol symbol = fixup.Target.Referent as ExternalSymbol;

            if (symbol == null)
            {
                return(false);
            }

            switch (symbol.Name)
            {
            case "FIARQQ":
            case "FICRQQ":
            case "FIDRQQ":
            case "FIERQQ":
            case "FISRQQ":
            case "FIWRQQ":
            case "FJARQQ":
            case "FJCRQQ":
            case "FJSRQQ":
                return(true);

            default:
                return(false);
            }
        }
Esempio n. 2
0
        private static Fixup ConvertFixupDefinition(
            FixupDefinition def, Dictionary <object, object> objectMap)
        {
            Fixup fixup = new Fixup();

            fixup.StartIndex = def.DataOffset;
            switch (def.Location)
            {
            case FixupLocation.LowByte:
                fixup.LocationType = FixupLocationType.LowByte;
                break;

            case FixupLocation.Offset:
            case FixupLocation.LoaderResolvedOffset:
                fixup.LocationType = FixupLocationType.Offset;
                break;

            case FixupLocation.Base:
                fixup.LocationType = FixupLocationType.Base;
                break;

            case FixupLocation.Pointer:
                fixup.LocationType = FixupLocationType.Pointer;
                break;

            default:
                throw new InvalidDataException("The fixup location is not supported.");
            }
            fixup.Mode = def.Mode;

            IAddressReferent referent;

            if (def.Target.Referent is UInt16)
            {
                referent = new PhysicalAddress((UInt16)def.Target.Referent, 0);
            }
            else
            {
                referent = (IAddressReferent)objectMap[def.Target.Referent];
            }
            fixup.Target = new SymbolicTarget
            {
                Referent     = (IAddressReferent)referent,
                Displacement = def.Target.Displacement
            };
            //f.Frame = null;
            return(fixup);
        }
        protected override Instruction DecodeInstruction(Address address)
        {
            Instruction instruction = base.DecodeInstruction(address);

            if (instruction == null)
            {
                return(instruction);
            }

            // Find the first fixup that covers the instruction. If no
            // fix-up covers the instruction, find the closest fix-up
            // that comes after.
            FixupCollection fixups     = library.Image.GetSegment(address.Segment).Segment.Fixups;
            int             fixupIndex = fixups.BinarySearch(address.Offset);

            // If there's a fixup right at the beginning of the instruction,
            // it is likely that the location is actually data, unless the
            // fixup is a floating point emulator which use a trick to change
            // the opcode.
            if (fixupIndex >= 0 && fixups[fixupIndex].StartIndex == address.Offset)
            {
                if (!IsFloatingPointEmulatorFixup(fixups[fixupIndex]))
                {
                    AddError(address, ErrorCode.BrokenFixup,
                             "Cannot decode instruction at a fix-up location: {0}",
                             fixups[fixupIndex]);
                    return(null);
                }
            }

            if (fixupIndex < 0)
            {
                fixupIndex = ~fixupIndex;
            }

            for (int i = 0; i < instruction.Operands.Length; i++)
            {
                if (fixupIndex >= fixups.Count) // no more fixups
                {
                    break;
                }

                Fixup fixup = fixups[fixupIndex];
                if (fixup.StartIndex >= address.Offset + instruction.EncodedLength) // past end
                {
                    break;
                }

                Operand operand = instruction.Operands[i];
                if (operand.FixableLocation.Length > 0)
                {
                    int start = address.Offset + operand.FixableLocation.StartOffset;
                    int end   = start + operand.FixableLocation.Length;

                    if (fixup.StartIndex >= end)
                    {
                        continue;
                    }

                    if (fixup.StartIndex != start || fixup.EndIndex != end)
                    {
                        // throw new BrokenFixupException(fixup);
                        if (IsFloatingPointEmulatorFixup(fixup))
                        {
                            AddError(new Address(address.Segment, fixup.StartIndex),
                                     ErrorCode.FixupDiscarded,
                                     "Floating point emulator fix-up discarded: {0}", fixup);
                        }
                        else
                        {
                            AddError(new Address(address.Segment, fixup.StartIndex),
                                     ErrorCode.BrokenFixup, "Broken fix-up: {0}", fixup);
                        }
                        continue;
                    }

                    instruction.Operands[i].Tag = fixup.Target;
                    ++fixupIndex;
                }
            }

            if (fixupIndex < fixups.Count)
            {
                Fixup fixup = fixups[fixupIndex];
                if (fixup.StartIndex < address.Offset + instruction.EncodedLength)
                {
                    if (IsFloatingPointEmulatorFixup(fixup))
                    {
                        AddError(new Address(address.Segment, fixup.StartIndex),
                                 ErrorCode.FixupDiscarded,
                                 "Floating point emulator fix-up discarded: {0}", fixup);
                    }
                    else
                    {
                        AddError(new Address(address.Segment, fixup.StartIndex),
                                 ErrorCode.BrokenFixup, "Broken fix-up: {0}", fixup);
                    }
                }
            }
            return(instruction);
        }
Esempio n. 4
0
 public BrokenFixupException(Fixup fixup)
 {
     this.Fixup = fixup;
 }