Exemple #1
0
        public void Link_MultipleMains_ThrowsException()
        {
            var a = new ObjectFile();

            a.Atoms.Add(new Procedure()
            {
                Name   = "Proc1",
                IsMain = true
            });

            var b = new ObjectFile();

            b.Atoms.Add(new Procedure()
            {
                Name   = "Proc2",
                IsMain = true
            });

            var linker = new AtomLinker();

            var message = "Multiple main procedures.";

            Assert.That(
                () => linker.Link(new[] { a, b }),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message));
        }
Exemple #2
0
        public void Link_UndefinedAtoms_ThrowsException()
        {
            var a = new ObjectFile();

            var b = new ObjectFile();

            b.Atoms.Add(new NullTerminatedString()
            {
                Name = "A"
            });

            var procedure = new Procedure();

            procedure.IsDefined = true;
            procedure.Name      = "Proc";
            procedure.References.Add(new Reference(b.Atoms[0]));
            b.Atoms.Add(procedure);

            var linker = new AtomLinker();

            var message = new StringBuilder();

            message.AppendLine("Undefined atoms:");
            message.AppendLine("\tA");

            Assert.That(
                () => linker.Link(new[] { a, b }, new MemoryStream()),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message.ToString()));
        }
Exemple #3
0
        public void Link_MultipleDefinedAtomsWithTheSameName_ThrowsException()
        {
            var a = new ObjectFile();

            a.Atoms.Add(new Procedure()
            {
                Name      = "Proc",
                IsDefined = true
            });

            var b = new ObjectFile();

            b.Atoms.Add(new Procedure()
            {
                Name      = "Proc",
                IsDefined = true
            });

            var linker = new AtomLinker();

            var message = "There are multiple atoms with called 'Proc'.";

            Assert.That(
                () => linker.Link(new[] { a, b }),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message));
        }
Exemple #4
0
        public void Link_LocalAtomInFile2ReferencedByAtomInFile1_ThrowsException()
        {
            var a = new ObjectFile();

            a.Atoms.Add(new NullTerminatedString()
            {
                Name = "A"
            });

            var procedure = new Procedure();

            procedure.IsDefined = true;
            procedure.Name      = "Proc";
            procedure.References.Add(new Reference(a.Atoms[0]));
            a.Atoms.Add(procedure);

            var b = new ObjectFile();

            b.Atoms.Add(new NullTerminatedString()
            {
                IsDefined = true,
                Content   = "Abc",
                Name      = "A"
            });

            var linker = new AtomLinker();

            var message = "'Proc' is referencing 'A' which is local to another object file.";

            Assert.That(
                () => linker.Link(new[] { a, b }),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message));
        }
Exemple #5
0
        public void Link_2FilesWith1Atom_LinksObjectFiles()
        {
            var a = new ObjectFile();

            a.Atoms.Add(new NullTerminatedString()
            {
                Content   = "Abc",
                IsDefined = true,
                Name      = "A"
            });

            var b = new ObjectFile();

            b.Atoms.Add(new NullTerminatedString()
            {
                Content   = "Def",
                IsDefined = true,
                Name      = "B"
            });

            var linker = new AtomLinker();
            var c      = linker.Link(new[] { a, b });

            Assert.AreEqual(2, c.Atoms.Count);

            Assert.AreEqual("A", ((NullTerminatedString)c.Atoms[0]).Name);
            Assert.AreEqual("Abc", ((NullTerminatedString)c.Atoms[0]).Content);
            Assert.True(((NullTerminatedString)c.Atoms[0]).IsDefined);

            Assert.AreEqual("B", ((NullTerminatedString)c.Atoms[1]).Name);
            Assert.AreEqual("Def", ((NullTerminatedString)c.Atoms[1]).Content);
            Assert.True(((NullTerminatedString)c.Atoms[1]).IsDefined);
        }
Exemple #6
0
        public void Link_NoMainProcedure_ThrowsException()
        {
            var a      = new ObjectFile();
            var linker = new AtomLinker();

            var message = "There is no main procedure.";

            Assert.That(
                () => linker.Link(new[] { a }, new MemoryStream()),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message));
        }
Exemple #7
0
        public void Link_InconsistentOrigin_ThrowsException()
        {
            var a = new ObjectFile();

            a.IsOriginSet = true;
            a.Origin      = 0x10;

            var b = new ObjectFile();

            b.IsOriginSet = true;

            var linker = new AtomLinker();

            var message = "Inconsistent origin.";

            Assert.That(
                () => linker.Link(new[] { a, b }),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message));
        }
Exemple #8
0
        public void Link_ProcedureReferencingProcedure_LinksToBinary()
        {
            var file = new ObjectFile();

            var sub = new Procedure();

            file.Atoms.Add(sub);

            sub.IsDefined = true;
            sub.Name      = "Sub";
            sub.Code.Add(0xAA);
            sub.Code.Add(0x55);

            var main = new Procedure();

            file.Atoms.Add(main);

            main.IsMain    = true;
            main.IsDefined = true;
            main.Name      = "Proc";
            main.Code.Add(0x00);
            main.Code.Add(0x00);

            main.References.Add(new Reference(sub)
            {
                IsAddressInLittleEndian = true,
                SizeOfAddress           = 2
            });

            var binary = new byte[]
            {
                0x02, 0x00, // Main procedure.
                0xAA, 0x55, // Sub procedure.
            };

            using (var stream = new MemoryStream())
            {
                var linker = new AtomLinker();
                linker.Link(new[] { file }, stream);

                CollectionAssert.AreEqual(binary, stream.ToArray());
            }
        }
Exemple #9
0
        public void Link_ProcedureReferencingData_LinksToBinary()
        {
            var file = new ObjectFile();

            var data = new Data();

            file.Atoms.Add(data);

            data.IsDefined = true;
            data.Name      = "Data";
            data.Content.Add(0xAA);
            data.Content.Add(0x55);

            var procedure = new Procedure();

            file.Atoms.Add(procedure);

            procedure.IsMain    = true;
            procedure.IsDefined = true;
            procedure.Name      = "Proc";
            procedure.Code.Add(0x00);
            procedure.Code.Add(0x00);

            procedure.References.Add(new Reference(data)
            {
                IsAddressInLittleEndian = true,
                SizeOfAddress           = 2
            });

            var binary = new byte[]
            {
                0x02, 0x00, // Procedure code.
                0xAA, 0x55, // The data chunk.
            };

            using (var stream = new MemoryStream())
            {
                var linker = new AtomLinker();
                linker.Link(new[] { file }, stream);

                CollectionAssert.AreEqual(binary, stream.ToArray());
            }
        }
Exemple #10
0
        public void Link_ProcedureReferencingNullTerminatedString_LinksToBinary()
        {
            var file = new ObjectFile();

            file.Atoms.Add(new NullTerminatedString()
            {
                IsDefined = true,
                Content   = "Abc",
                Name      = "A"
            });

            var procedure = new Procedure();

            file.Atoms.Add(procedure);

            procedure.IsMain    = true;
            procedure.IsDefined = true;
            procedure.Name      = "Proc";
            procedure.Code.Add(0x00);
            procedure.Code.Add(0x00);

            procedure.References.Add(new Reference(file.Atoms[0])
            {
                IsAddressInLittleEndian = true,
                SizeOfAddress           = 2
            });

            var binary = new byte[]
            {
                0x02, 0x00,             // Procedure code.
                0x41, 0x62, 0x63, 0x00  // The string 'Abc'.
            };

            using (var stream = new MemoryStream())
            {
                var linker = new AtomLinker();
                linker.Link(new[] { file }, stream);

                CollectionAssert.AreEqual(binary, stream.ToArray());
            }
        }
Exemple #11
0
        public void Link_GlobalAtomInFile1ReferencedByAtomInFile2_LinksObjectFiles()
        {
            var a = new ObjectFile();

            a.Atoms.Add(new NullTerminatedString()
            {
                IsDefined = true,
                IsGlobal  = true,
                Content   = "Abc",
                Name      = "A"
            });

            var b = new ObjectFile();

            b.Atoms.Add(new NullTerminatedString()
            {
                Name = "A"
            });

            var procedure = new Procedure();

            procedure.IsDefined = true;
            procedure.Name      = "Proc";
            procedure.References.Add(new Reference(b.Atoms[0]));
            b.Atoms.Add(procedure);

            var linker = new AtomLinker();
            var c      = linker.Link(new[] { a, b });

            Assert.AreEqual(2, c.Atoms.Count);

            Assert.AreEqual("A", ((NullTerminatedString)c.Atoms[0]).Name);
            Assert.AreEqual("Abc", ((NullTerminatedString)c.Atoms[0]).Content);
            Assert.True(((NullTerminatedString)c.Atoms[0]).IsDefined);

            Assert.AreEqual("Proc", ((Procedure)c.Atoms[1]).Name);
            Assert.AreSame(((Procedure)c.Atoms[1]).References[0].Atom, c.Atoms[0]);
            Assert.True(((Procedure)c.Atoms[1]).IsDefined);
        }
Exemple #12
0
        public void Link_MultipleUndefinedDifferentlyTypedAtomsWithTheSameName_ThrowsException()
        {
            var a = new ObjectFile();

            a.Atoms.Add(new Procedure()
            {
                Name = "Proc"
            });

            var b = new ObjectFile();

            b.Atoms.Add(new Data()
            {
                Name = "Proc"
            });

            var linker = new AtomLinker();

            var message = "'Proc' and 'Proc' is not of the same type.";

            Assert.That(
                () => linker.Link(new[] { a, b }),
                Throws.TypeOf <InvalidObjectFileException>().With.Message.EqualTo(message));
        }
Exemple #13
0
        public void Link_ObjectFileWithMainAndUnreferencedAtoms_OnlyMainIsLinked()
        {
            var file = new ObjectFile();

            var sub = new Procedure();

            file.Atoms.Add(sub);

            sub.IsDefined = true;
            sub.Name      = "Sub";
            sub.Code.Add(0xAA);
            sub.Code.Add(0x55);

            var main = new Procedure();

            file.Atoms.Add(main);

            main.IsMain    = true;
            main.IsDefined = true;
            main.Name      = "Proc";
            main.Code.Add(0x00);
            main.Code.Add(0x00);

            var binary = new byte[]
            {
                0x00, 0x00, // Main procedure.
            };

            using (var stream = new MemoryStream())
            {
                var linker = new AtomLinker();
                linker.Link(new[] { file }, stream);

                CollectionAssert.AreEqual(binary, stream.ToArray());
            }
        }