Exemple #1
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 #2
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());
        }