Exemple #1
0
        public void GenerateImports()
        {
            _imports.Clear();
            Dictionary <uint, ImportData> data = new Dictionary <uint, ImportData>();

            foreach (ModuleSectionNode s in _sections)
            {
                foreach (ImportData e in data.Values)
                {
                    e._first      = true;
                    e._lastOffset = 0;
                }
                uint           i      = 0;
                uint           offset = 0;
                List <RELLink> cmds;
                foreach (Relocation loc in s._relocations)
                {
                    if (loc.Command != null)
                    {
                        RelCommand cmd = loc.Command;
                        ImportData d;
                        uint       id = cmd._moduleID;

                        if (_imports.ContainsKey(id))
                        {
                            cmds = _imports[id];
                            d    = data[id];
                        }
                        else
                        {
                            _imports.Add(id, cmds = new List <RELLink>());
                            data.Add(id, d        = new ImportData()
                            {
                                _first = true, _lastOffset = 0
                            });
                        }

                        if (d._first)
                        {
                            cmds.Add(new RELLink()
                            {
                                _type = RELLinkType.Section, _section = (byte)s.Index
                            });
                            d._first = false;
                        }

                        offset = i * 4 + (cmd.IsHalf ? 2u : 0);
                        uint diff = offset - d._lastOffset;
                        while (offset - d._lastOffset > 0xFFFF)
                        {
                            d._lastOffset += 0xFFFF;
                            cmds.Add(new RELLink()
                            {
                                _type = RELLinkType.IncrementOffset, _section = 0, _value = 0, _prevOffset = 0xFFFF
                            });
                        }

                        byte        targetSection = (byte)cmd._targetSectionId;
                        RELLinkType type          = (RELLinkType)cmd._command;
                        uint        val           = cmd._addend;

                        cmds.Add(new RELLink()
                        {
                            _type = type, _section = targetSection, _value = val, _prevOffset = (ushort)diff
                        });

                        d._lastOffset = offset;
                    }
                    i++;
                }
            }

            foreach (List <RELLink> cmds in _imports.Values)
            {
                cmds.Add(new RELLink()
                {
                    _type = RELLinkType.End
                });
            }
        }
Exemple #2
0
        public void GenerateImports()
        {
            _imports.Clear();
            Dictionary <uint, ImportData> tempImports = new Dictionary <uint, ImportData>();

            foreach (ModuleSectionNode s in _sections)
            {
                foreach (ImportData e in tempImports.Values)
                {
                    e._newSection = true;
                    e._lastOffset = 0;
                }

                uint           offset = 0;
                List <RELLink> links;

                //Iterate through each command in the section
                var commands = s._manager.GetCommands();
                foreach (var r in commands)
                {
                    RelCommand command = r.Value;
                    int        index   = r.Key;

                    ImportData impData;
                    uint       moduleID = command._moduleID;

                    //Check if an import has been created for the target module.
                    if (_imports.ContainsKey(moduleID))
                    {
                        //An import already exists, so we'll add to it.
                        links   = _imports[moduleID];
                        impData = tempImports[moduleID];
                    }
                    else
                    {
                        //An import does not exist, so it must be made.
                        _imports.Add(moduleID, links = new List <RELLink>());

                        //Create new temporary import data
                        tempImports.Add(moduleID, impData = new ImportData()
                        {
                            _newSection = true, _lastOffset = 0
                        });
                    }

                    //This is true when a new section is being evaluated.
                    if (impData._newSection)
                    {
                        links.Add(new RELLink()
                        {
                            _type = RELLinkType.Section, _section = (byte)s.Index
                        });
                        impData._newSection = false;
                    }

                    //Get the offset of the command within the section.
                    offset = (uint)index * 4 + (command.IsHalf ? 2u : 0);

                    //Get the offset to this address relative to the last written link offset.
                    uint diff = offset - impData._lastOffset;

                    //If the difference is greater than ushort allows,
                    //add increment links until the difference works
                    while (diff > 0xFFFF)
                    {
                        impData._lastOffset += 0xFFFF;
                        diff = offset - impData._lastOffset;

                        links.Add(new RELLink()
                        {
                            _type = RELLinkType.IncrementOffset, _section = 0, _value = 0, _prevOffset = 0xFFFF
                        });
                    }

                    //Gather the link information
                    byte        targetSection = (byte)command._targetSectionId;
                    RELLinkType type          = (RELLinkType)command._command;
                    uint        val           = command._addend;

                    //Write command link
                    links.Add(new RELLink()
                    {
                        _type = type, _section = targetSection, _value = val, _prevOffset = (ushort)diff
                    });

                    //Don't bother adding the difference,
                    //just set the exact offset as the last offset
                    impData._lastOffset = offset;
                }
            }

            foreach (List <RELLink> cmds in _imports.Values)
            {
                cmds.Add(new RELLink()
                {
                    _type = RELLinkType.End
                });
            }
        }