Exemplo n.º 1
0
        public override Address ReadStub(Address addrStub, MemoryArea mem)
        {
            var offsetInSection = (uint)(addrStub - mem.BaseAddress);
            var opcode          = mem.ReadBeUInt16(offsetInSection);

            // Expect move.l offset(pc),a0
            if (opcode != 0x207B)
            {
                return(null);
            }
            var offsetToGotEntry = mem.ReadBeInt32(offsetInSection + 4);
            var addrGotEntry     = addrStub + 2 + offsetToGotEntry;

            return(addrGotEntry);
        }
Exemplo n.º 2
0
        public void AddResourcesToImageMap(
            Address addrLoad,
            MemoryArea mem,
            SegmentMap segmentMap,
            List <ImageSymbol> entryPoints,
            SortedList <Address, ImageSymbol> symbols)
        {
            JumpTable jt       = null;
            var       codeSegs = new Dictionary <int, ImageSegment>();

            foreach (ResourceType type in ResourceTypes)
            {
                foreach (ResourceReference rsrc in type.References)
                {
                    uint uSegOffset  = rsrc.DataOffset + rsrcDataOff;
                    int  segmentSize = mem.ReadBeInt32(uSegOffset);

                    // Skip the size longword at the beginning of the segment, and an extra 4
                    // if it is a code segement other than CODE#0.
                    int bytesToSkip = 4;
                    if (type.Name == "CODE" && rsrc.ResourceID != 0)
                    {
                        bytesToSkip += 4;
                    }
                    var abSegment = new byte[segmentSize];
                    Array.Copy(mem.Bytes, uSegOffset + bytesToSkip, abSegment, 0, segmentSize);

                    Address addrSegment = addrLoad + uSegOffset + bytesToSkip;    //$TODO pad to 16-byte boundary?
                    var     memSeg      = new MemoryArea(addrSegment, abSegment);
                    var     segment     = segmentMap.AddSegment(new ImageSegment(
                                                                    ResourceDescriptiveName(type, rsrc),
                                                                    memSeg,
                                                                    AccessMode.Read));
                    if (type.Name == "CODE")
                    {
                        if (rsrc.ResourceID == 0)
                        {
                            jt = ProcessJumpTable(memSeg, symbols);
                        }
                        else
                        {
                            codeSegs.Add(rsrc.ResourceID, segment);
                            var macsBug   = new MacsBugSymbolScanner(arch, segment.MemoryArea);
                            var mbSymbols = macsBug.ScanForSymbols();
                            foreach (var symbol in mbSymbols)
                            {
                                symbols[symbol.Address] = symbol;
                            }
                        }
                    }
                }
            }

            // We have found a jump table, so we allocate an A5World.
            if (jt != null)
            {
                // Find an address beyond all known segments.
                var addr    = segmentMap.Segments.Values.Max(s => s.Address + s.Size).Align(0x10);
                var a5world = LoadA5World(jt, addr, codeSegs, symbols);
                platform.A5World  = a5world;
                platform.A5Offset = jt.BelowA5Size;
                segmentMap.AddSegment(a5world);


                // Find first (and only!) segment containing the name %A5Init.
                var a5dataSegment = segmentMap.Segments.Values.SingleOrDefault(SegmentNamedA5Init);
                if (a5dataSegment == null)
                {
                    return;
                }

                // Get an image reader to the start of the data.
                var a5dr = GetA5InitImageReader(a5dataSegment);
                if (a5dr == null)
                {
                    return;
                }

                var a5dbelow    = a5dr.ReadBeUInt32();
                var a5dbankSize = a5dr.ReadBeUInt32();
                var a5doffset   = a5dr.ReadBeUInt32();
                var a5dreloc    = a5dr.ReadBeUInt32();
                var a5dhdrend   = a5dr.ReadBeUInt32();
                if (a5dbankSize != 0x00010000)
                {
                    // bank size not supported for compressed global data
                    return;
                }
                A5Expand(a5dr, a5dbelow);
            }
        }