public void LinkStatic(uint baseAddress, Dictionary <string, uint> externalSymbols) { _baseAddress = new Word(WordType.AbsoluteAddr, Mapper.Remap(baseAddress)); DoLink(externalSymbols); }
public void LinkDynamic(Dictionary <String, uint> externalSymbols) { _baseAddress = new Word(WordType.RelativeAddr, 0); DoLink(externalSymbols); }
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()); }
private void WriteUInt32(Word addr, uint value) { Util.InjectUInt32(_memory, addr - _baseAddress, value); }
private void WriteUInt16(Word addr, ushort value) { Util.InjectUInt16(_memory, addr - _baseAddress, value); }
private uint ReadUInt32(Word addr) { return(Util.ExtractUInt32(_memory, addr - _baseAddress)); }
private ushort ReadUInt16(Word addr) { return(Util.ExtractUInt16(_memory, addr - _baseAddress)); }