Skip to content

Commit

Permalink
General PMD fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ledmington committed Nov 4, 2024
1 parent 98418c8 commit 5b2d16f
Show file tree
Hide file tree
Showing 18 changed files with 493 additions and 335 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ public static NoteSectionEntryType fromCode(final String owner, final int type)
case 3 -> NT_GNU_BUILD_ID;
case 4 -> NT_GNU_GOLD_VERSION;
case 5 -> NT_GNU_PROPERTY_TYPE_0;
default -> throw new IllegalArgumentException(String.format(
"Unknown note section entry type %d (0x%08x) for owner '%s'", type, type, owner));
default -> throw new IllegalArgumentException(
String.format("Unknown note section entry type %d (0x%08x) for owner '%s'", type, type, owner));
};
case "stapsdt" -> switch (type) {
case 3 -> NT_STAPSDT;
default -> throw new IllegalArgumentException(String.format(
"Unknown note section entry type %d (0x%08x) for owner '%s'", type, type, owner));
default -> throw new IllegalArgumentException(
String.format("Unknown note section entry type %d (0x%08x) for owner '%s'", type, type, owner));
};
default -> throw new IllegalArgumentException(
String.format("Unknown note section entry owner '%s'", owner));
Expand Down
3 changes: 1 addition & 2 deletions emu-cli/src/main/java/com/ledmington/emu/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ private static void run(final String filename, final String... commandLineArgume
}

final MemoryController mem = new MemoryController(EmulatorConstants.getMemoryInitializer());
final X86RegisterFile rf = new X86RegisterFile();
final X86Emulator cpu = new X86Cpu(rf, mem);
final X86Emulator cpu = new X86Cpu(mem);

ELFLoader.load(
elf,
Expand Down
407 changes: 192 additions & 215 deletions emu-gui/src/main/java/com/ledmington/view/ELFView.java

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion emu-gui/src/main/java/com/ledmington/view/ELFViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public final class ELFViewer extends Stage {
public ELFViewer(final double width, final double height) {
final BorderPane mainPane = new BorderPane();

this.view = new ELFView(this);
this.view = new ELFView();

final FlowPane topPane = new FlowPane();
final Button load = new Button();
Expand Down
54 changes: 27 additions & 27 deletions emu-gui/src/main/java/com/ledmington/view/EmulatorView.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import javafx.geometry.Insets;
import javafx.scene.Scene;
Expand All @@ -50,9 +51,10 @@
import com.ledmington.elf.ELFReader;
import com.ledmington.emu.ELFLoader;
import com.ledmington.emu.EmulatorConstants;
import com.ledmington.emu.ImmutableRegisterFile;
import com.ledmington.emu.InstructionFetcher;
import com.ledmington.emu.RFlags;
import com.ledmington.emu.X86RegisterFile;
import com.ledmington.emu.RegisterFile;
import com.ledmington.mem.MemoryController;
import com.ledmington.utils.MiniLogger;

Expand All @@ -63,13 +65,8 @@ public final class EmulatorView extends Stage {

// The CPU used to emulate
private X86CpuAdapter cpu;
// The register file of the CPU
private X86RegisterFile regFile;
// The memory controller used by the CPU
private MemoryController mem;
// An external decoder used to decode instructions in the GUI without modifying
// the state of the CPU
private InstructionDecoder decoder;
private final Button stepBtn = new Button();
private final Button runBtn = new Button();
private final TextArea codeArea = new TextArea();
Expand Down Expand Up @@ -133,16 +130,16 @@ public EmulatorView() {
for (final Register64 r : Register64.values()) {
registerPane.add(LabelFactory.getDefaultLabel(r.name()), 0, row);
final Label rl = LabelFactory.getDefaultLabel("0x" + "0".repeat(16));
rl.setTooltip(new Tooltip("Click to see the memory at [" + r.name() + "]"));
rl.setOnMouseClicked(e -> updateMemory(regFile.get(r)
rl.setTooltip(TooltipFactory.getDefaultTooltip("Click to see the memory at [" + r.name() + "]"));
rl.setOnMouseClicked(e -> updateMemory(cpu.getRegisters().get(r)
- ((long) AppConstants.getMaxMemoryLines() * AppConstants.getMemoryBytesPerLine()) / 2L));
registerPane.add(rl, 1, row);
regLabels.put(r, rl);
row++;
}

registerPane.add(LabelFactory.getDefaultLabel("RFLAGS"), 0, row);
this.rflagsLabel = LabelFactory.getDefaultLabel("-".repeat(RFlags.values().length));
this.rflagsLabel = LabelFactory.getDefaultLabel("");
registerPane.add(rflagsLabel, 1, row);
row++;

Expand Down Expand Up @@ -189,7 +186,7 @@ public EmulatorView() {
this.cpu.doExecuteOne();
updateRegisters();
updateCode();
updateMemory(regFile.get(Register64.RIP));
updateMemory(cpu.getRegisters().get(Register64.RIP));
});
this.stepBtn.setTooltip(new Tooltip("Step"));

Expand All @@ -204,7 +201,7 @@ public EmulatorView() {
this.cpu.doExecute();
updateRegisters();
updateCode();
updateMemory(regFile.get(Register64.RIP));
updateMemory(cpu.getRegisters().get(Register64.RIP));
});
this.runBtn.setTooltip(new Tooltip("Run"));

Expand All @@ -231,9 +228,7 @@ private InputStream getResourceStream(final String name) {
private void loadFile(final File file) {
logger.info("Loading file '%s'", file.toString());
this.mem = new MemoryController(EmulatorConstants.getMemoryInitializer(), false);
this.regFile = new X86RegisterFile();
this.cpu = new X86CpuAdapter(regFile, mem);
this.decoder = new InstructionDecoderV1(new InstructionFetcher(mem, regFile));
this.cpu = new X86CpuAdapter(mem);

// TODO: implement this
final String[] commandLineArguments = new String[0];
Expand All @@ -252,49 +247,54 @@ private void loadFile(final File file) {

updateRegisters();
updateCode();
updateMemory(regFile.get(Register64.RIP));
updateMemory(cpu.getRegisters().get(Register64.RIP));
}

private void updateRegisters() {
final ImmutableRegisterFile regFile = this.cpu.getRegisters();

for (final Register64 r : Register64.values()) {
this.regLabels.get(r).setText(String.format("0x%016x", this.regFile.get(r)));
this.regLabels.get(r).setText(String.format("0x%016x", regFile.get(r)));
}

for (final Register16 s : new Register16[] {
Register16.CS, Register16.DS, Register16.SS, Register16.ES, Register16.FS, Register16.GS
}) {
this.segLabels.get(s).setText(String.format("0x%04x", this.regFile.get(s)));
this.segLabels.get(s).setText(String.format("0x%04x", regFile.get(s)));
}

final StringBuilder sb = new StringBuilder();
Arrays.stream(RFlags.values())
.sorted(Comparator.comparingInt(RFlags::bit))
.forEach(f -> sb.append(regFile.isSet(f) ? f.getInitial() : '-'));
this.rflagsLabel.setText(sb.toString());
this.rflagsLabel.setText("|"
+ Arrays.stream(RFlags.values())
.sorted(Comparator.comparingInt(RFlags::bit))
.map(f -> regFile.isSet(f) ? f.getSymbol() : "")
.collect(Collectors.joining("|"))
+ "|");
}

private void updateCode() {
final RegisterFile regFile = (RegisterFile) cpu.getRegisters();
final InstructionDecoder decoder = new InstructionDecoderV1(new InstructionFetcher(this.mem, regFile));
final StringBuilder sb = new StringBuilder();
final int n = AppConstants.getMaxCodeInstructions();
final long originalRIP = this.regFile.get(Register64.RIP);
final long originalRIP = regFile.get(Register64.RIP);
long rip = originalRIP;
for (int i = 0; i < n; i++) {
final long startRIP = rip;
this.regFile.set(Register64.RIP, rip);
regFile.set(Register64.RIP, rip);
sb.append("0x").append(String.format("%0" + (2 * ADDRESS_BYTES) + "x", rip));

String inst;
try {
inst = this.decoder.decode().toIntelSyntax();
rip = this.regFile.get(Register64.RIP);
inst = decoder.decode().toIntelSyntax();
rip = regFile.get(Register64.RIP);
} catch (final UnknownOpcode | ReservedOpcode | IllegalArgumentException e) {
inst = String.format(".byte 0x%02x", this.mem.readCode(rip));
rip = startRIP + 1L;
}
sb.append(" : ").append(inst).append('\n');
}
this.codeArea.setText(sb.toString());
this.regFile.set(Register64.RIP, originalRIP);
regFile.set(Register64.RIP, originalRIP);
}

private void updateMemory(final long baseAddress) {
Expand Down
2 changes: 1 addition & 1 deletion emu-gui/src/main/java/com/ledmington/view/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public static void main(final String[] args) {
case verboseFlag -> MiniLogger.setMinimumLevel(MiniLogger.LoggingLevel.INFO);
case veryVerboseFlag -> MiniLogger.setMinimumLevel(MiniLogger.LoggingLevel.DEBUG);
default -> {
out.printf("Unknown flag '%s'\n", arg);
out.printf("Unknown flag '%s'%n", arg);
out.flush();
Platform.exit();
System.exit(-1);
Expand Down
33 changes: 33 additions & 0 deletions emu-gui/src/main/java/com/ledmington/view/TooltipFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* emu - Processor Emulator
* Copyright (C) 2023-2024 Filippo Barbari <filippo.barbari@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.ledmington.view;

import javafx.scene.control.Tooltip;
import javafx.scene.text.Font;

public final class TooltipFactory {

private TooltipFactory() {}

public static Tooltip getDefaultTooltip(final String text) {
final Tooltip lbl = new Tooltip(text);
lbl.setWrapText(false);
lbl.setFont(new Font(AppConstants.getDefaultMonospaceFont(), AppConstants.getDefaultFontSize()));
return lbl;
}
}
5 changes: 2 additions & 3 deletions emu-gui/src/main/java/com/ledmington/view/X86CpuAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import com.ledmington.cpu.x86.Instruction;
import com.ledmington.emu.X86Cpu;
import com.ledmington.emu.X86RegisterFile;
import com.ledmington.mem.MemoryController;

// TODO: refactor avoiding inheritance (and avoiding two queues)
Expand All @@ -31,8 +30,8 @@ public final class X86CpuAdapter extends X86Cpu {
private final BlockingQueue<Object> execute = new ArrayBlockingQueue<>(1);
private final BlockingQueue<Object> executionCompleted = new ArrayBlockingQueue<>(1);

public X86CpuAdapter(final X86RegisterFile regFile, final MemoryController mem) {
super(regFile, mem);
public X86CpuAdapter(final MemoryController mem) {
super(mem);
}

private void waitToStartExecution() {
Expand Down
41 changes: 35 additions & 6 deletions emu/src/main/java/com/ledmington/emu/ELFLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@
import com.ledmington.elf.PHTEntryType;
import com.ledmington.elf.ProgramHeaderTable;
import com.ledmington.elf.SectionTable;
import com.ledmington.elf.section.BasicProgBitsSection;
import com.ledmington.elf.section.ConstructorsSection;
import com.ledmington.elf.section.LoadableSection;
import com.ledmington.elf.section.NoBitsSection;
import com.ledmington.elf.section.Section;
import com.ledmington.elf.section.SectionHeaderFlags;
import com.ledmington.elf.section.StringTableSection;
import com.ledmington.elf.section.sym.SymbolTableEntry;
import com.ledmington.elf.section.sym.SymbolTableEntryType;
import com.ledmington.elf.section.sym.SymbolTableSection;
import com.ledmington.mem.MemoryController;
import com.ledmington.utils.BitUtils;
Expand All @@ -59,6 +62,7 @@ private ELFLoader() {}
* Loads the given ELF file in the emulated memory.
*
* @param elf The file to be loaded.
* @param cpu The CPU to be used to execute some instructions, if needed.
* @param mem The emulated memory where to load the file.
* @param commandLineArguments The arguments to pass to the program.
* @param baseAddress The address where to start loading the file.
Expand All @@ -78,8 +82,9 @@ public static void load(
// We make RSP point at the last 8 bytes of allocated memory
final long stackPointer = highestAddress + stackSize - 8L;

// This is a fake instruction
// These are fake instructions to setup the stack
cpu.executeOne(new Instruction(Opcode.MOV, Register64.RSP, new Immediate(stackPointer)));
cpu.executeOne(new Instruction(Opcode.PUSH, new Immediate(0L)));

loadCommandLineArgumentsAndEnvironmentVariables(
mem, highestAddress, elf.getFileHeader().is32Bit(), commandLineArguments);
Expand All @@ -96,7 +101,12 @@ public static void load(
(StringTableSection) elf.getSectionByName(".strtab").orElseThrow());
}
if (elf.getSectionByName(".init").isPresent()) {
runInit();
runInit(
(BasicProgBitsSection) elf.getSectionByName(".init").orElseThrow(),
cpu,
baseAddress,
(SymbolTableSection) elf.getSectionByName(".symtab").orElseThrow(),
(StringTableSection) elf.getSectionByName(".strtab").orElseThrow());
}
if (elf.getSectionByName(".ctors").isPresent()) {
runCtors();
Expand All @@ -121,6 +131,11 @@ public static void unload(final ELF elf) {
}
}

private static void runFrom(final X86Emulator cpu, final long startAddress) {
cpu.executeOne(new Instruction(Opcode.MOV, Register64.RIP, new Immediate(startAddress)));
cpu.execute();
}

private static void runPreInitArray() {
notImplemented();
}
Expand All @@ -137,13 +152,27 @@ private static void runInitArray(
final String ctorName =
strtab.getString(symtab.getSymbolWithValue(c).nameOffset());
logger.debug("Running .init_array[%d] = %,d (0x%016x) '%s'", i, c, c, ctorName);
cpu.executeOne(new Instruction(Opcode.MOV, Register64.RIP, new Immediate(entryPointVirtualAddress + c)));
cpu.execute();
runFrom(cpu, entryPointVirtualAddress + c);
}
}

private static void runInit() {
notImplemented();
private static void runInit(
final BasicProgBitsSection init,
final X86Emulator cpu,
final long entryPointVirtualAddress,
final SymbolTableSection symtab,
final StringTableSection strtab) {
for (int i = 0; i < symtab.getSymbolTableLength(); i++) {
final SymbolTableEntry ste = symtab.getSymbolTableEntry(i);
if (ste.info().getType() == SymbolTableEntryType.STT_FUNC
&& ste.value() >= init.getHeader().getFileOffset()
&& ste.value()
< init.getHeader().getFileOffset()
+ init.getHeader().getSectionSize()) {
logger.debug("Running constructor '%s' from .init", strtab.getString(ste.nameOffset()));
runFrom(cpu, entryPointVirtualAddress + ste.value());
}
}
}

private static void runCtors() {
Expand Down
Loading

0 comments on commit 5b2d16f

Please sign in to comment.