Exemple #1
0
        public void AddModule(Elf elf)
        {
            if (_linked)
                throw new InvalidOperationException("This linker has already been linked");
            if (_modules.Contains(elf))
                throw new InvalidOperationException("This module is already part of this linker");

            _modules.Add(elf);
        }
Exemple #2
0
        private void ProcessRelaSection(Elf elf, Elf.ElfSection relocs, Elf.ElfSection section, Elf.ElfSection symtab)
        {
            if (relocs.sh_entsize != 12)
            {
                throw new InvalidDataException("Invalid relocs format (sh_entsize != 12)");
            }
            if (symtab.sh_type != Elf.ElfSection.Type.SHT_SYMTAB)
            {
                throw new InvalidDataException("Symbol table does not have type SHT_SYMTAB");
            }

            var reader = new BinaryReader(new MemoryStream(relocs.data));
            int count  = relocs.data.Length / 12;

            for (int i = 0; i < count; i++)
            {
                uint r_offset = reader.ReadBigUInt32();
                uint r_info   = reader.ReadBigUInt32();
                int  r_addend = reader.ReadBigInt32();

                Elf.Reloc reloc    = (Elf.Reloc)(r_info & 0xFF);
                int       symIndex = (int)(r_info >> 8);

                if (symIndex == 0)
                {
                    throw new InvalidDataException("linking to undefined symbol");
                }
                if (!_sectionBases.ContainsKey(section))
                {
                    continue; // we don't care about this
                }
                string symName = _symbolTableContents[symtab][symIndex];
                //Console.WriteLine("{0,-30} {1}", symName, reloc);

                Word source = _sectionBases[section] + r_offset;
                Word dest   = ResolveSymbol(elf, symName).address + r_addend;

                //Console.WriteLine("Linking from {0} to {1}", source, dest);

                if (!KamekUseReloc(reloc, source, dest))
                {
                    _fixups.Add(new Fixup {
                        type = reloc, source = source, dest = dest
                    });
                }
            }
        }
Exemple #3
0
        Symbol ResolveSymbol(Elf elf, string name)
        {
            var locals = _localSymbols[elf];

            if (locals.ContainsKey(name))
            {
                return(locals[name]);
            }
            if (_globalSymbols.ContainsKey(name))
            {
                return(_globalSymbols[name]);
            }
            if (_externalSymbols.ContainsKey(name))
            {
                return new Symbol {
                           address = new Word(WordType.AbsoluteAddr, _externalSymbols[name])
                }
            }
            ;

            throw new InvalidDataException("undefined symbol " + name);
        }
Exemple #4
0
        Symbol ResolveSymbol(Elf elf, string name)
        {
            var locals = _localSymbols[elf];

            if (locals.ContainsKey(name))
            {
                return(locals[name]);
            }
            if (_globalSymbols.ContainsKey(name))
            {
                return(_globalSymbols[name]);
            }
            if (_externalSymbols.ContainsKey(name))
            {
                return new Symbol {
                           address = new Word(WordType.AbsoluteAddr, _externalSymbols[name])
                }
            }
            ;
            if (name.StartsWith("__kAutoMap_"))
            {
                var addr = name.Substring(11);

                if (addr.StartsWith("0x") || addr.StartsWith("0X"))
                {
                    addr = addr.Substring(2);
                }
                var parsedAddr = uint.Parse(addr, System.Globalization.NumberStyles.AllowHexSpecifier);
                var mappedAddr = Mapper.Remap(parsedAddr);
                return(new Symbol {
                    address = new Word(WordType.AbsoluteAddr, mappedAddr)
                });
            }

            throw new InvalidDataException("undefined symbol " + name);
        }
Exemple #5
0
        Symbol ResolveSymbol(Elf elf, string name)
        {
            var locals = _localSymbols[elf];
            if (locals.ContainsKey(name))
                return locals[name];
            if (_globalSymbols.ContainsKey(name))
                return _globalSymbols[name];
            if (_externalSymbols.ContainsKey(name))
                return new Symbol { address = new Word(WordType.AbsoluteAddr, _externalSymbols[name]) };

            throw new InvalidDataException("undefined symbol " + name);
        }
Exemple #6
0
        private void ProcessRelaSection(Elf elf, Elf.ElfSection relocs, Elf.ElfSection section, Elf.ElfSection symtab)
        {
            if (relocs.sh_entsize != 12)
                throw new InvalidDataException("Invalid relocs format (sh_entsize != 12)");
            if (symtab.sh_type != Elf.ElfSection.Type.SHT_SYMTAB)
                throw new InvalidDataException("Symbol table does not have type SHT_SYMTAB");

            var reader = new BinaryReader(new MemoryStream(relocs.data));
            int count = relocs.data.Length / 12;

            for (int i = 0; i < count; i++)
            {
                uint r_offset = reader.ReadBigUInt32();
                uint r_info = reader.ReadBigUInt32();
                int r_addend = reader.ReadBigInt32();

                Elf.Reloc reloc = (Elf.Reloc)(r_info & 0xFF);
                int symIndex = (int)(r_info >> 8);

                if (symIndex == 0)
                    throw new InvalidDataException("linking to undefined symbol");
                if (!_sectionBases.ContainsKey(section))
                    continue; // we don't care about this

                string symName = _symbolTableContents[symtab][symIndex];
                //Console.WriteLine("{0,-30} {1}", symName, reloc);

                Word source = _sectionBases[section] + r_offset;
                Word dest = ResolveSymbol(elf, symName).address + r_addend;

                //Console.WriteLine("Linking from {0} to {1}", source, dest);

                if (!KamekUseReloc(reloc, source, dest))
                    _fixups.Add(new Fixup { type = reloc, source = source, dest = dest });
            }
        }
Exemple #7
0
        private string[] ParseSymbolTable(Elf elf, Elf.ElfSection symtab, Elf.ElfSection strtab, Dictionary<string, Symbol> locals)
        {
            if (symtab.sh_entsize != 16)
                throw new InvalidDataException("Invalid symbol table format (sh_entsize != 16)");
            if (strtab.sh_type != Elf.ElfSection.Type.SHT_STRTAB)
                throw new InvalidDataException("String table does not have type SHT_STRTAB");

            var symbolNames = new List<string>();
            var reader = new BinaryReader(new MemoryStream(symtab.data));
            int count = symtab.data.Length / 16;

            // always ignore the first symbol
            symbolNames.Add(null);
            reader.BaseStream.Seek(16, SeekOrigin.Begin);

            for (int i = 1; i < count; i++)
            {
                // Read info from the ELF
                uint st_name = reader.ReadBigUInt32();
                uint st_value = reader.ReadBigUInt32();
                uint st_size = reader.ReadBigUInt32();
                byte st_info = reader.ReadByte();
                byte st_other = reader.ReadByte();
                ushort st_shndx = reader.ReadBigUInt16();

                Elf.SymBind bind = (Elf.SymBind)(st_info >> 4);
                Elf.SymType type = (Elf.SymType)(st_info & 0xF);

                string name = Util.ExtractNullTerminatedString(strtab.data, (int)st_name);

                symbolNames.Add(name);
                if (name.Length == 0 || st_shndx == 0)
                    continue;

                // What location is this referencing?
                Elf.ElfSection refSection;
                if (st_shndx < 0xFF00)
                    refSection = elf.Sections[st_shndx];
                else if (st_shndx == 0xFFF1) // absolute symbol
                    refSection = null;
                else
                    throw new InvalidDataException("unknown section index found in symbol table");

                Word addr;
                if (st_shndx == 0xFFF1)
                {
                    // Absolute symbol
                    addr = new Word(WordType.AbsoluteAddr, st_value);
                }
                else if (st_shndx < 0xFF00)
                {
                    // Part of a section
                    var section = elf.Sections[st_shndx];
                    if (!_sectionBases.ContainsKey(section))
                        continue; // skips past symbols we don't care about, like DWARF junk
                    addr = _sectionBases[section] + st_value;
                }
                else
                    throw new NotImplementedException("unknown section index found in symbol table");

                switch (bind)
                {
                    case Elf.SymBind.STB_LOCAL:
                        if (locals.ContainsKey(name))
                            throw new InvalidDataException("redefinition of local symbol " + name);
                        locals[name] = new Symbol { address = addr, size = st_size };
                        break;

                    case Elf.SymBind.STB_GLOBAL:
                        if (_globalSymbols.ContainsKey(name) && !_globalSymbols[name].isWeak)
                            throw new InvalidDataException("redefinition of global symbol " + name);
                        _globalSymbols[name] = new Symbol { address = addr, size = st_size };
                        break;

                    case Elf.SymBind.STB_WEAK:
                        if (!_globalSymbols.ContainsKey(name))
                            _globalSymbols[name] = new Symbol { address = addr, size = st_size, isWeak = true };
                        break;
                }
            }

            return symbolNames.ToArray();
        }
Exemple #8
0
        private bool KamekUseReloc(Elf.Reloc type, Word source, Word dest)
        {
            if (source < _kamekStart || source >= _kamekEnd)
                return false;
            if (type != Elf.Reloc.R_PPC_ADDR32)
                return false;

            _kamekRelocations[source] = dest;
            return true;
        }
Exemple #9
0
        private string[] ParseSymbolTable(Elf elf, Elf.ElfSection symtab, Elf.ElfSection strtab, Dictionary <string, Symbol> locals)
        {
            if (symtab.sh_entsize != 16)
            {
                throw new InvalidDataException("Invalid symbol table format (sh_entsize != 16)");
            }
            if (strtab.sh_type != Elf.ElfSection.Type.SHT_STRTAB)
            {
                throw new InvalidDataException("String table does not have type SHT_STRTAB");
            }

            var symbolNames = new List <string>();
            var reader      = new BinaryReader(new MemoryStream(symtab.data));
            int count       = symtab.data.Length / 16;

            // always ignore the first symbol
            symbolNames.Add(null);
            reader.BaseStream.Seek(16, SeekOrigin.Begin);

            for (int i = 1; i < count; i++)
            {
                // Read info from the ELF
                uint   st_name  = reader.ReadBigUInt32();
                uint   st_value = reader.ReadBigUInt32();
                uint   st_size  = reader.ReadBigUInt32();
                byte   st_info  = reader.ReadByte();
                byte   st_other = reader.ReadByte();
                ushort st_shndx = reader.ReadBigUInt16();

                Elf.SymBind bind = (Elf.SymBind)(st_info >> 4);
                Elf.SymType type = (Elf.SymType)(st_info & 0xF);

                string name = Util.ExtractNullTerminatedString(strtab.data, (int)st_name);

                symbolNames.Add(name);
                if (name.Length == 0 || st_shndx == 0)
                {
                    continue;
                }

                // What location is this referencing?
                Elf.ElfSection refSection;
                if (st_shndx < 0xFF00)
                {
                    refSection = elf.Sections[st_shndx];
                }
                else if (st_shndx == 0xFFF1) // absolute symbol
                {
                    refSection = null;
                }
                else
                {
                    throw new InvalidDataException("unknown section index found in symbol table");
                }

                Word addr;
                if (st_shndx == 0xFFF1)
                {
                    // Absolute symbol
                    addr = new Word(WordType.AbsoluteAddr, st_value);
                }
                else if (st_shndx < 0xFF00)
                {
                    // Part of a section
                    var section = elf.Sections[st_shndx];
                    if (!_sectionBases.ContainsKey(section))
                    {
                        continue; // skips past symbols we don't care about, like DWARF junk
                    }
                    addr = _sectionBases[section] + st_value;
                }
                else
                {
                    throw new NotImplementedException("unknown section index found in symbol table");
                }


                switch (bind)
                {
                case Elf.SymBind.STB_LOCAL:
                    if (locals.ContainsKey(name))
                    {
                        throw new InvalidDataException("redefinition of local symbol " + name);
                    }
                    locals[name] = new Symbol {
                        address = addr, size = st_size
                    };
                    _symbolSizes[addr] = st_size;
                    break;

                case Elf.SymBind.STB_GLOBAL:
                    if (_globalSymbols.ContainsKey(name) && !_globalSymbols[name].isWeak)
                    {
                        throw new InvalidDataException("redefinition of global symbol " + name);
                    }
                    _globalSymbols[name] = new Symbol {
                        address = addr, size = st_size
                    };
                    _symbolSizes[addr] = st_size;
                    break;

                case Elf.SymBind.STB_WEAK:
                    if (!_globalSymbols.ContainsKey(name))
                    {
                        _globalSymbols[name] = new Symbol {
                            address = addr, size = st_size, isWeak = true
                        };
                        _symbolSizes[addr] = st_size;
                    }
                    break;
                }
            }

            return(symbolNames.ToArray());
        }