示例#1
0
        /// <summary>
        /// Remove a specific address
        /// </summary>
        /// <param name="address">Address to remove</param>
        /// <returns>True if removed with success, else false</returns>
        public bool DeleteRelocation(uint address)
        {
            List <Reloc> relocs;

            // search if 4K address exists
            if (!pages.TryGetValue((address & 0xFFFFF000) - imageBase, out relocs))
            {
                return(false);
            }

            ushort offset = (ushort)(address & 0x0FFF);

            // search if offset exists
            foreach (Reloc reloc in relocs)
            {
                if (reloc.offset == offset && reloc.type != BASE_RELOCATION_TYPE.ABSOLUTE)
                {
                    relocs.Remove(reloc);
                    virtualSize -= 2;

                    if (relocs.Count % 2 != 0) // align in 32bits
                    {
                        bool isAlignDeleted = false;

                        foreach (Reloc item in relocs) // search if align already exists
                        {
                            if (item.offset == 0 && item.type == BASE_RELOCATION_TYPE.ABSOLUTE)
                            {
                                relocs.Remove(item);
                                isAlignDeleted = true;
                                virtualSize   -= 2;
                                break;
                            }
                        }

                        if (!isAlignDeleted) // if no align reloc found, add it
                        {
                            Reloc item = new Reloc();
                            item.offset = 0;
                            item.type   = BASE_RELOCATION_TYPE.ABSOLUTE;

                            relocs.Add(item);
                            virtualSize += 2;
                        }
                    }

                    if (relocs.Count == 0) // remove page if nothing offset
                    {
                        pages.Remove((address & 0xFFFFF000) - imageBase);
                        virtualSize -= 8;
                    }

                    IsNotSaved = true;
                    return(true);
                }
            }

            return(false);
        }
示例#2
0
            public RelocationWord(Section secId, Reloc r, int offset)
            {
                var secL = Shift.GetRight(0xC0000000);
                var relL = Shift.GetRight(0x3F000000);

                Word   = ((int)secId << secL) | ((int)r << relL) | offset;
                Parent = null;
            }
示例#3
0
        /// <summary>Creates a <see cref="TargetMachine"/> for the target and specified parameters</summary>
        /// <param name="context">Context to use for LLVM objects created by this machine</param>
        /// <param name="triple">Target triple for this machine (e.g. -mtriple)</param>
        /// <param name="cpu">CPU for this machine (e.g. -mcpu)</param>
        /// <param name="features">Features for this machine (e.g. -mattr...)</param>
        /// <param name="optLevel">Optimization level</param>
        /// <param name="relocationMode">Relocation mode for generated code</param>
        /// <param name="codeModel"><see cref="CodeModel"/> to use for generated code</param>
        /// <returns><see cref="TargetMachine"/> based on the specified parameters</returns>
        public TargetMachine CreateTargetMachine(Context context
                                                 , string triple
                                                 , string cpu           = null
                                                 , string features      = null
                                                 , CodeGenOpt optLevel  = CodeGenOpt.Default
                                                 , Reloc relocationMode = Reloc.Default
                                                 , CodeModel codeModel  = CodeModel.Default
                                                 )
        {
            var targetMachineHandle = NativeMethods.CreateTargetMachine(TargetHandle
                                                                        , triple
                                                                        , cpu ?? string.Empty
                                                                        , features ?? string.Empty
                                                                        , ( LLVMCodeGenOptLevel )optLevel
                                                                        , ( LLVMRelocMode )relocationMode
                                                                        , ( LLVMCodeModel )codeModel
                                                                        );

            return(new TargetMachine(context, targetMachineHandle));
        }
示例#4
0
文件: Target.cs 项目: nbsn2/Llvm.NET
        /// <summary>Creates a <see cref="TargetMachine"/> for the target and specified parameters</summary>
        /// <param name="triple">Target triple for this machine (e.g. -mtriple)</param>
        /// <param name="cpu">CPU for this machine (e.g. -mcpu)</param>
        /// <param name="features">Features for this machine (e.g. -mattr...)</param>
        /// <param name="optLevel">Optimization level</param>
        /// <param name="relocationMode">Relocation mode for generated code</param>
        /// <param name="codeModel"><see cref="CodeModel"/> to use for generated code</param>
        /// <returns><see cref="TargetMachine"/> based on the specified parameters</returns>
        public TargetMachine CreateTargetMachine(string triple
                                                 , string cpu           = null
                                                 , string features      = null
                                                 , CodeGenOpt optLevel  = CodeGenOpt.Default
                                                 , Reloc relocationMode = Reloc.Default
                                                 , CodeModel codeModel  = CodeModel.Default
                                                 )
        {
            triple.ValidateNotNullOrWhiteSpace(nameof(triple));
            optLevel.ValidateDefined(nameof(optLevel));
            relocationMode.ValidateDefined(nameof(relocationMode));
            codeModel.ValidateDefined(nameof(codeModel));

            var targetMachineHandle = LLVMCreateTargetMachine(TargetHandle
                                                              , triple
                                                              , cpu ?? string.Empty
                                                              , features ?? string.Empty
                                                              , ( LLVMCodeGenOptLevel )optLevel
                                                              , ( LLVMRelocMode )relocationMode
                                                              , ( LLVMCodeModel )codeModel
                                                              );

            return(new TargetMachine(targetMachineHandle));
        }
示例#5
0
        /// <summary>
        /// Open the file specified into the <paramref name="path"/>, read the relocation section
        /// and load it.
        /// </summary>
        /// <param name="path"></param>
        public Relocations(string path)
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException();
            }

            this.path       = path;
            this.IsNotSaved = false;

            BinaryReader br = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read));

            if (br.ReadInt16() != 0x5A4D) // MZ signature
            {
                br.Close();
                throw new InvalidOperationException("MZ");
            }

            br.BaseStream.Seek(0x3C, SeekOrigin.Begin);           // go to ptr to COFF File Header
            br.BaseStream.Seek(br.ReadInt32(), SeekOrigin.Begin); // go to COFF File Header

            if (br.ReadInt32() != 0x00004550)                     // PE\0\0
            {
                br.Close();
                throw new InvalidOperationException("PE");
            }

            br.ReadUInt16(); // machine ID. Ignored
            uint numbersOfSections = br.ReadUInt16();

            br.BaseStream.Seek(20 - 4, SeekOrigin.Current); // go to magic number (PE or PE+ = x86 or x64)

            if (br.ReadInt16() != 0x010B)
            {
                br.Close();
                throw new InvalidOperationException("X86");
            }

            br.BaseStream.Seek(26, SeekOrigin.Current);      // go to ImageBase
            imageBase = br.ReadUInt32();
            br.BaseStream.Seek(64 + 40, SeekOrigin.Current); // go to Data Directories -> Base Relocation Table

            virtualAddress     = br.ReadUInt32();
            addressVirtualSize = br.BaseStream.Position;
            virtualSize        = br.ReadUInt32();

            br.BaseStream.Seek(80, SeekOrigin.Current); // jump to Section Table

            // find the RAW address/size
            RawAddress = 0;
            RawSize    = 0;

            for (int i = 0; i < numbersOfSections; i++)
            {
                br.BaseStream.Seek(12, SeekOrigin.Current);

                if (br.ReadUInt32() == virtualAddress)
                {
                    RawSize    = br.ReadUInt32();
                    RawAddress = br.ReadUInt32();
                    break;
                }

                br.BaseStream.Seek(24, SeekOrigin.Current); // place the pointer to the next section
            }

            if (RawAddress == 0x00 || RawSize == 0x00)
            {
                br.Close();
                throw new InvalidOperationException("RAW");
            }

            // reading relocation section
            br.BaseStream.Seek(RawAddress, SeekOrigin.Begin);

            pages = new SortedDictionary <uint, List <Reloc> >();

            while (br.BaseStream.Position < RawAddress + virtualSize) // 4K block loop
            {
                uint address = br.ReadUInt32();
                uint size    = br.ReadUInt32();
                uint count   = (size - 8) / 2;

                List <Reloc> relocs = new List <Reloc>();

                for (int i = 0; i < count; i++) // offsets loop
                {
                    ushort data = br.ReadUInt16();
                    BASE_RELOCATION_TYPE type = (BASE_RELOCATION_TYPE)((data & 0xF000) >> 12);
                    ushort offset             = (ushort)(data & 0x0FFF);

                    Reloc reloc = new Reloc();
                    reloc.offset = offset;
                    reloc.type   = type;

                    relocs.Add(reloc);
                }

                pages.Add(address, relocs);
            }

            br.Close();
        }
示例#6
0
        /// <summary>
        /// Add a relocation address
        /// </summary>
        /// <param name="address">Address to add</param>
        /// <param name="type">Type of relocation</param>
        /// <returns>-1 if duplicated, 0 if not added, 1 if added a page and 2 if added only in reloc of page</returns>
        public int AddRelocation(uint address, BASE_RELOCATION_TYPE type)
        {
            if (address < imageBase)
            {
                return(0);
            }

            uint   page   = (address & 0xFFFFF000) - imageBase;
            ushort offset = (ushort)(address & 0x00000FFF);

            if (!pages.ContainsKey(page)) // create a new page if doesn't exists
            {
                if (RawSize - virtualSize < 12)
                {
                    return(0);
                }

                List <Reloc> relocs = new List <Reloc>();

                Reloc reloc = new Reloc();
                reloc.offset = offset;
                reloc.type   = type;
                relocs.Add(reloc);

                reloc        = new Reloc();
                reloc.offset = 0;
                reloc.type   = BASE_RELOCATION_TYPE.ABSOLUTE;
                relocs.Add(reloc);

                pages.Add(page, relocs);

                virtualSize += 12;

                IsNotSaved = true;
                return(1);
            }
            else // just added the offset
            {
                List <Reloc> relocs;

                if (!pages.TryGetValue(page, out relocs))
                {
                    return(0);
                }

                foreach (Reloc item in relocs) // search if address already present
                {
                    if (item.offset == offset && item.type != BASE_RELOCATION_TYPE.ABSOLUTE)
                    {
                        return(-1);
                    }
                }

                if (relocs.Count % 2 == 0) // align in 32bits
                {
                    bool isAlignDeleted = false;

                    foreach (Reloc item in relocs) // search if align already exists
                    {
                        if (item.offset == 0 && item.type == BASE_RELOCATION_TYPE.ABSOLUTE)
                        {
                            relocs.Remove(item);
                            isAlignDeleted = true;
                            virtualSize   -= 2;
                            break;
                        }
                    }

                    if (!isAlignDeleted) // if no align reloc found, add it
                    {
                        if (RawSize - virtualSize < 4)
                        {
                            return(0);
                        }

                        Reloc item = new Reloc();
                        item.offset = 0;
                        item.type   = BASE_RELOCATION_TYPE.ABSOLUTE;

                        relocs.Add(item);
                        virtualSize += 2;
                    }
                }

                Reloc reloc = new Reloc();
                reloc.offset = offset;
                reloc.type   = type;

                relocs.Add(reloc);

                virtualSize += 2;

                IsNotSaved = true;
                return(2);
            }
        }
        /// <summary>
        /// Open the file specified into the <paramref name="path"/>, read the relocation section
        /// and load it.
        /// </summary>
        /// <param name="path"></param>
        public Relocations(string path)
        {
            if (!File.Exists(path))
                throw new FileNotFoundException();

            this.path = path;
            this.IsNotSaved = false;

            BinaryReader br = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read));

            if (br.ReadInt16() != 0x5A4D) // MZ signature
            {
                br.Close();
                throw new InvalidOperationException("MZ");
            }

            br.BaseStream.Seek(0x3C, SeekOrigin.Begin); // go to ptr to COFF File Header
            br.BaseStream.Seek(br.ReadInt32(), SeekOrigin.Begin); // go to COFF File Header

            if (br.ReadInt32() != 0x00004550) // PE\0\0
            {
                br.Close();
                throw new InvalidOperationException("PE");
            }

            br.ReadUInt16(); // machine ID. Ignored
            uint numbersOfSections = br.ReadUInt16();

            br.BaseStream.Seek(20 - 4, SeekOrigin.Current); // go to magic number (PE or PE+ = x86 or x64)

            if (br.ReadInt16() != 0x010B)
            {
                br.Close();
                throw new InvalidOperationException("X86");
            }

            br.BaseStream.Seek(26, SeekOrigin.Current); // go to ImageBase
            imageBase = br.ReadUInt32();
            br.BaseStream.Seek(64 + 40, SeekOrigin.Current); // go to Data Directories -> Base Relocation Table

            virtualAddress = br.ReadUInt32();
            addressVirtualSize = br.BaseStream.Position;
            virtualSize = br.ReadUInt32();

            br.BaseStream.Seek(80, SeekOrigin.Current); // jump to Section Table

            // find the RAW address/size
            RawAddress = 0;
            RawSize = 0;

            for (int i = 0; i < numbersOfSections; i++)
            {
                br.BaseStream.Seek(12, SeekOrigin.Current);

                if (br.ReadUInt32() == virtualAddress)
                {
                    RawSize = br.ReadUInt32();
                    RawAddress = br.ReadUInt32();
                    break;
                }

                br.BaseStream.Seek(24, SeekOrigin.Current); // place the pointer to the next section
            }

            if (RawAddress == 0x00 || RawSize == 0x00)
            {
                br.Close();
                throw new InvalidOperationException("RAW");
            }

            // reading relocation section
            br.BaseStream.Seek(RawAddress, SeekOrigin.Begin);

            pages = new SortedDictionary<uint, List<Reloc>>();

            while (br.BaseStream.Position < RawAddress + virtualSize) // 4K block loop
            {
                uint address = br.ReadUInt32();
                uint size = br.ReadUInt32();
                uint count = (size - 8) / 2;

                List<Reloc> relocs = new List<Reloc>();

                for (int i = 0; i < count; i++) // offsets loop
                {
                    ushort data = br.ReadUInt16();
                    BASE_RELOCATION_TYPE type = (BASE_RELOCATION_TYPE)((data & 0xF000) >> 12);
                    ushort offset = (ushort)(data & 0x0FFF);

                    Reloc reloc = new Reloc();
                    reloc.offset = offset;
                    reloc.type = type;

                    relocs.Add(reloc);
                }

                pages.Add(address, relocs);
            }

            br.Close();
        }
        /// <summary>
        /// Remove a specific address
        /// </summary>
        /// <param name="address">Address to remove</param>
        /// <returns>True if removed with success, else false</returns>
        public bool DeleteRelocation(uint address)
        {
            List<Reloc> relocs;

            // search if 4K address exists
            if (!pages.TryGetValue((address & 0xFFFFF000) - imageBase, out relocs))
                return false;

            ushort offset = (ushort)(address & 0x0FFF);

            // search if offset exists
            foreach (Reloc reloc in relocs)
            {
                if (reloc.offset == offset && reloc.type != BASE_RELOCATION_TYPE.ABSOLUTE)
                {
                    relocs.Remove(reloc);
                    virtualSize -= 2;

                    if (relocs.Count % 2 != 0) // align in 32bits
                    {
                        bool isAlignDeleted = false;

                        foreach (Reloc item in relocs) // search if align already exists
                        {
                            if (item.offset == 0 && item.type == BASE_RELOCATION_TYPE.ABSOLUTE)
                            {
                                relocs.Remove(item);
                                isAlignDeleted = true;
                                virtualSize -= 2;
                                break;
                            }
                        }

                        if (!isAlignDeleted) // if no align reloc found, add it
                        {
                            Reloc item = new Reloc();
                            item.offset = 0;
                            item.type = BASE_RELOCATION_TYPE.ABSOLUTE;

                            relocs.Add(item);
                            virtualSize += 2;
                        }
                    }

                    if (relocs.Count == 0) // remove page if nothing offset
                    {
                        pages.Remove((address & 0xFFFFF000) - imageBase);
                        virtualSize -= 8;
                    }

                    IsNotSaved = true;
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Add a relocation address
        /// </summary>
        /// <param name="address">Address to add</param>
        /// <param name="type">Type of relocation</param>
        /// <returns>-1 if duplicated, 0 if not added, 1 if added a page and 2 if added only in reloc of page</returns>
        public int AddRelocation(uint address, BASE_RELOCATION_TYPE type)
        {
            if (address < imageBase)
                return 0;

            uint page = (address & 0xFFFFF000) - imageBase;
            ushort offset = (ushort)(address & 0x00000FFF);

            if (!pages.ContainsKey(page)) // create a new page if doesn't exists
            {
                if (RawSize - virtualSize < 12)
                    return 0;

                List<Reloc> relocs = new List<Reloc>();

                Reloc reloc = new Reloc();
                reloc.offset = offset;
                reloc.type = type;
                relocs.Add(reloc);

                reloc = new Reloc();
                reloc.offset = 0;
                reloc.type = BASE_RELOCATION_TYPE.ABSOLUTE;
                relocs.Add(reloc);

                pages.Add(page, relocs);

                virtualSize += 12;

                IsNotSaved = true;
                return 1;
            }
            else // just added the offset
            {
                List<Reloc> relocs;

                if (!pages.TryGetValue(page, out relocs))
                    return 0;

                foreach (Reloc item in relocs) // search if address already present
                {
                    if (item.offset == offset && item.type != BASE_RELOCATION_TYPE.ABSOLUTE)
                        return -1;
                }

                if (relocs.Count % 2 == 0) // align in 32bits
                {
                    bool isAlignDeleted = false;

                    foreach (Reloc item in relocs) // search if align already exists
                    {
                        if (item.offset == 0 && item.type == BASE_RELOCATION_TYPE.ABSOLUTE)
                        {
                            relocs.Remove(item);
                            isAlignDeleted = true;
                            virtualSize -= 2;
                            break;
                        }
                    }

                    if (!isAlignDeleted) // if no align reloc found, add it
                    {
                        if (RawSize - virtualSize < 4)
                            return 0;

                        Reloc item = new Reloc();
                        item.offset = 0;
                        item.type = BASE_RELOCATION_TYPE.ABSOLUTE;

                        relocs.Add(item);
                        virtualSize += 2;
                    }
                }

                Reloc reloc = new Reloc();
                reloc.offset = offset;
                reloc.type = type;

                relocs.Add(reloc);

                virtualSize += 2;

                IsNotSaved = true;
                return 2;
            }
        }