size_t Assembler::relocCode(void* dst, Ptr baseAddress) const { if (baseAddress == kNoBaseAddress) baseAddress = hasBaseAddress() ? getBaseAddress() : static_cast<Ptr>((uintptr_t)dst); else if (getBaseAddress() != baseAddress) return 0; return _relocCode(dst, baseAddress); }
bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) { if (_stackReserve < _stackCommit) { diagnostics << "Invalid stack size: reserve size must be equal to or " << "greater than commit size, but got " << _stackCommit << " and " << _stackReserve << ".\n"; return false; } if (_heapReserve < _heapCommit) { diagnostics << "Invalid heap size: reserve size must be equal to or " << "greater than commit size, but got " << _heapCommit << " and " << _heapReserve << ".\n"; return false; } // It's an error if the base address is not multiple of 64K. if (getBaseAddress() & 0xffff) { diagnostics << "Base address have to be multiple of 64K, but got " << getBaseAddress() << "\n"; return false; } // Specifing /noentry without /dll is an error. if (!hasEntry() && !isDll()) { diagnostics << "/noentry must be specified with /dll\n"; return false; } // Check for duplicate export ordinals. std::set<int> exports; for (const PECOFFLinkingContext::ExportDesc &desc : getDllExports()) { if (desc.ordinal == -1) continue; if (exports.count(desc.ordinal) == 1) { diagnostics << "Duplicate export ordinals: " << desc.ordinal << "\n"; return false; } exports.insert(desc.ordinal); } // Check for /align. std::bitset<64> alignment(_sectionDefaultAlignment); if (alignment.count() != 1) { diagnostics << "Section alignment must be a power of 2, but got " << _sectionDefaultAlignment << "\n"; return false; } _writer = createWriterPECOFF(*this); return true; }
void DataReference::print(){ uint16_t sidx = 0; if (rawSection){ sidx = rawSection->getSectionIndex(); } PRINT_INFOR("DATAREF %#llx: Offset %#llx in section %d -- %#llx", getBaseAddress(), sectionOffset, sidx, data); }
void Symbolizer::symbolize(const uintptr_t* addresses, SymbolizedFrame* frames, size_t addrCount) { size_t remaining = 0; for (size_t i = 0; i < addrCount; ++i) { auto& frame = frames[i]; if (!frame.found) { ++remaining; frame.clear(); } } if (remaining == 0) { // we're done return; } if (_r_debug.r_version != 1) { return; } char selfPath[PATH_MAX + 8]; ssize_t selfSize; if ((selfSize = readlink("/proc/self/exe", selfPath, PATH_MAX + 1)) == -1) { // Something has gone terribly wrong. return; } selfPath[selfSize] = '\0'; for (auto lmap = _r_debug.r_map; lmap != nullptr && remaining != 0; lmap = lmap->l_next) { // The empty string is used in place of the filename for the link_map // corresponding to the running executable. Additionally, the `l_addr' is // 0 and the link_map appears to be first in the list---but none of this // behavior appears to be documented, so checking for the empty string is // as good as anything. auto const objPath = lmap->l_name[0] != '\0' ? lmap->l_name : selfPath; auto const elfFile = cache_->getFile(objPath); if (!elfFile) { continue; } // Get the address at which the object is loaded. We have to use the ELF // header for the running executable, since its `l_addr' is zero, but we // should use `l_addr' for everything else---in particular, if the object // is position-independent, getBaseAddress() (which is p_vaddr) will be 0. auto const base = lmap->l_addr != 0 ? lmap->l_addr : elfFile->getBaseAddress(); for (size_t i = 0; i < addrCount && remaining != 0; ++i) { auto& frame = frames[i]; if (frame.found) { continue; } auto const addr = addresses[i]; // Get the unrelocated, ELF-relative address. auto const adjusted = addr - base; if (elfFile->getSectionContainingAddress(adjusted)) { frame.set(elfFile, adjusted, mode_); --remaining; } } } }
Util::Util(Core * coar) { core = coar; BaseAddress = getBaseAddress(); getHwnd(); }
void UART::transaction(Axi4TransactionType *payload) { uint64_t mask = (length_.to_uint64() - 1); uint64_t off = ((payload->addr - getBaseAddress()) & mask) / 4; char wrdata; if (payload->rw) { for (uint64_t i = 0; i < payload->xsize/4; i++) { if ((payload->wstrb & (0xf << 4*i)) == 0) { continue; } switch (off + i) { case 0: wrdata = static_cast<char>(payload->wpayload[i]); RISCV_info("Set data = %s", ®s_.data); for (unsigned n = 0; n < listeners_.size(); n++) { IRawListener *lstn = static_cast<IRawListener *>( listeners_[n].to_iface()); lstn->updateData(&wrdata, 1); } break; case 1: regs_.status = payload->wpayload[i]; RISCV_info("Set status = %08x", regs_.status); break; case 2: regs_.scaler = payload->wpayload[i]; RISCV_info("Set scaler = %d", regs_.scaler); break; default:; } } } else { for (uint64_t i = 0; i < payload->xsize/4; i++) { switch (off + i) { case 0: if (rx_total_ == 0) { payload->rpayload[i] = 0; } else { payload->rpayload[i] = *p_rx_rd_; rx_total_--; if ((++p_rx_rd_) >= (rxfifo_ + RX_FIFO_SIZE)) { p_rx_rd_ = rxfifo_; } } RISCV_debug("Get data = %02x", (payload->rpayload[i] & 0xFF)); break; case 1: regs_.status = UART_STATUS_TX_EMPTY; if (rx_total_ == 0) { regs_.status |= UART_STATUS_RX_EMPTY; } payload->rpayload[i] = regs_.status; RISCV_info("Get status = %08x", regs_.status); break; case 2: payload->rpayload[i] = regs_.scaler; RISCV_info("Get scaler = %d", regs_.scaler); break; default: payload->rpayload[i] = ~0; } } } }