mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-20 10:37:27 +08:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
@@ -103,11 +103,24 @@ public class ElfSymbol implements ByteArrayConverter {
|
||||
|
||||
private String nameAsString;
|
||||
|
||||
/**
|
||||
* create an ElfSymbol()
|
||||
* Warning! the routine initSymbolName() must be called on the symbol later
|
||||
* to initialize the string name. This is a performance enhancement.
|
||||
*
|
||||
* @param reader to read symbol from
|
||||
* @param symbolIndex index of the symbol to read
|
||||
* @param symbolTable symbol table to associate the symbol to
|
||||
* @param stringTable string table to read symbols from
|
||||
* @param header else header
|
||||
* @return newly created ElfSymbol
|
||||
*
|
||||
* @throws IOException if an issue with reading occurs
|
||||
*/
|
||||
public static ElfSymbol createElfSymbol(FactoryBundledWithBinaryReader reader, int symbolIndex,
|
||||
ElfSymbolTable symbolTable, ElfStringTable stringTable, ElfHeader header)
|
||||
throws IOException {
|
||||
ElfSymbolTable symbolTable, ElfHeader header) throws IOException {
|
||||
ElfSymbol elfSymbol = (ElfSymbol) reader.getFactory().create(ElfSymbol.class);
|
||||
elfSymbol.initElfSymbol(reader, symbolIndex, symbolTable, stringTable, header);
|
||||
elfSymbol.initElfSymbol(reader, symbolIndex, symbolTable, header);
|
||||
return elfSymbol;
|
||||
}
|
||||
|
||||
@@ -117,49 +130,6 @@ public class ElfSymbol implements ByteArrayConverter {
|
||||
public ElfSymbol() {
|
||||
}
|
||||
|
||||
private void initElfSymbol(FactoryBundledWithBinaryReader reader, int symbolIndex,
|
||||
ElfSymbolTable symbolTable, ElfStringTable stringTable, ElfHeader header)
|
||||
throws IOException {
|
||||
this.header = header;
|
||||
this.symbolTable = symbolTable;
|
||||
this.symbolTableIndex = symbolIndex;
|
||||
|
||||
if (header.is32Bit()) {
|
||||
st_name = reader.readNextInt();
|
||||
st_value = reader.readNextInt() & Conv.INT_MASK;
|
||||
st_size = reader.readNextInt() & Conv.INT_MASK;
|
||||
st_info = reader.readNextByte();
|
||||
st_other = reader.readNextByte();
|
||||
st_shndx = reader.readNextShort();
|
||||
}
|
||||
else {
|
||||
st_name = reader.readNextInt();
|
||||
st_info = reader.readNextByte();
|
||||
st_other = reader.readNextByte();
|
||||
st_shndx = reader.readNextShort();
|
||||
st_value = reader.readNextLong();
|
||||
st_size = reader.readNextLong();
|
||||
}
|
||||
|
||||
if (st_name == 0) {
|
||||
if (getType() == STT_SECTION) {
|
||||
ElfSectionHeader[] sections = header.getSections();
|
||||
if (st_shndx < 0 || st_shndx >= sections.length) {
|
||||
//invalid section reference...
|
||||
//this is a bug in objcopy, whereby sections are removed
|
||||
//but the corresponding section symbols are left behind.
|
||||
}
|
||||
else {
|
||||
ElfSectionHeader section = sections[st_shndx];
|
||||
nameAsString = section.getNameAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
nameAsString = stringTable.readString(reader, st_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new section symbol.
|
||||
* @param header the corresponding ELF header
|
||||
@@ -209,6 +179,69 @@ public class ElfSymbol implements ByteArrayConverter {
|
||||
this.symbolTableIndex = symbolIndex;
|
||||
}
|
||||
|
||||
private void initElfSymbol(FactoryBundledWithBinaryReader reader, int symbolIndex,
|
||||
ElfSymbolTable symbolTable, ElfHeader header) throws IOException {
|
||||
this.header = header;
|
||||
this.symbolTable = symbolTable;
|
||||
this.symbolTableIndex = symbolIndex;
|
||||
|
||||
if (header.is32Bit()) {
|
||||
st_name = reader.readNextInt();
|
||||
st_value = reader.readNextInt() & Conv.INT_MASK;
|
||||
st_size = reader.readNextInt() & Conv.INT_MASK;
|
||||
st_info = reader.readNextByte();
|
||||
st_other = reader.readNextByte();
|
||||
st_shndx = reader.readNextShort();
|
||||
}
|
||||
else {
|
||||
st_name = reader.readNextInt();
|
||||
st_info = reader.readNextByte();
|
||||
st_other = reader.readNextByte();
|
||||
st_shndx = reader.readNextShort();
|
||||
st_value = reader.readNextLong();
|
||||
st_size = reader.readNextLong();
|
||||
}
|
||||
|
||||
if (st_name == 0) {
|
||||
if (getType() == STT_SECTION) {
|
||||
ElfSectionHeader[] sections = header.getSections();
|
||||
if (st_shndx < 0 || st_shndx >= sections.length) {
|
||||
//invalid section reference...
|
||||
//this is a bug in objcopy, whereby sections are removed
|
||||
//but the corresponding section symbols are left behind.
|
||||
}
|
||||
else {
|
||||
ElfSectionHeader section = sections[st_shndx];
|
||||
nameAsString = section.getNameAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The string name will be initialized later
|
||||
// in a call to initSymbolName()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the string name of the symbol.
|
||||
*
|
||||
* NOTE: This routine MUST be called for each
|
||||
* ELFSymbol after the elf symbols have been created.
|
||||
*
|
||||
* This is done separately from the initial symbol entry read because
|
||||
* the string names are in a separate location. If they are read
|
||||
* at the same time the reading buffer will jump around and significantly
|
||||
* degrade reading performance.
|
||||
*
|
||||
* @param reader to read from
|
||||
* @param stringTable stringTable to initialize symbol name
|
||||
*/
|
||||
public void initSymbolName(FactoryBundledWithBinaryReader reader, ElfStringTable stringTable) {
|
||||
if (nameAsString == null) {
|
||||
nameAsString = stringTable.readString(reader, st_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the symbol table containing this symbol
|
||||
* @return symbol table
|
||||
@@ -249,27 +282,37 @@ public class ElfSymbol implements ByteArrayConverter {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (obj == null)
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ElfSymbol other = (ElfSymbol) obj;
|
||||
if (st_info != other.st_info)
|
||||
if (st_info != other.st_info) {
|
||||
return false;
|
||||
if (st_name != other.st_name)
|
||||
}
|
||||
if (st_name != other.st_name) {
|
||||
return false;
|
||||
if (st_other != other.st_other)
|
||||
}
|
||||
if (st_other != other.st_other) {
|
||||
return false;
|
||||
if (st_shndx != other.st_shndx)
|
||||
}
|
||||
if (st_shndx != other.st_shndx) {
|
||||
return false;
|
||||
if (st_size != other.st_size)
|
||||
}
|
||||
if (st_size != other.st_size) {
|
||||
return false;
|
||||
if (st_value != other.st_value)
|
||||
}
|
||||
if (st_value != other.st_value) {
|
||||
return false;
|
||||
if (symbolTableIndex != other.symbolTableIndex)
|
||||
}
|
||||
if (symbolTableIndex != other.symbolTableIndex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+23
-11
@@ -18,6 +18,7 @@ package ghidra.app.util.bin.format.elf;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ghidra.app.util.bin.ByteArrayConverter;
|
||||
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
|
||||
@@ -96,15 +97,26 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
|
||||
|
||||
long entryPos = reader.getPointerIndex();
|
||||
|
||||
// load the all the symbol entries first, don't initialize the string name
|
||||
// that will be done later to help localize memory access
|
||||
for (int i = 0; i < symbolCount; i++) {
|
||||
// Reposition reader to start of symbol element since ElfSymbol object
|
||||
// may not consume all symbol element data
|
||||
reader.setPointerIndex(entryPos);
|
||||
ElfSymbol sym = ElfSymbol.createElfSymbol(reader, i, this, stringTable, header);
|
||||
ElfSymbol sym = ElfSymbol.createElfSymbol(reader, i, this, header);
|
||||
symbolList.add(sym);
|
||||
entryPos += entrySize;
|
||||
}
|
||||
|
||||
// sort the entries by the index in the string table, so don't jump around reading
|
||||
List<ElfSymbol> sortedList = symbolList.stream().sorted(
|
||||
(o1, o2) -> Integer.compare(o1.getName(), o2.getName())).collect(Collectors.toList());
|
||||
|
||||
// initialize the Symbol string names from string table
|
||||
for (ElfSymbol sym : sortedList) {
|
||||
sym.initSymbolName(reader, stringTable);
|
||||
}
|
||||
|
||||
reader.setPointerIndex(ptr);
|
||||
|
||||
symbols = new ElfSymbol[symbolList.size()];
|
||||
@@ -163,9 +175,9 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
|
||||
* @return the symbol at the specified address
|
||||
*/
|
||||
public ElfSymbol getSymbolAt(long addr) {
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
if (symbols[i].getValue() == addr) {
|
||||
return symbols[i];
|
||||
for (ElfSymbol symbol : symbols) {
|
||||
if (symbol.getValue() == addr) {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -177,9 +189,9 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
|
||||
*/
|
||||
public ElfSymbol[] getGlobalSymbols() {
|
||||
List<ElfSymbol> list = new ArrayList<>();
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
if (symbols[i].getBind() == ElfSymbol.STB_GLOBAL) {
|
||||
list.add(symbols[i]);
|
||||
for (ElfSymbol symbol : symbols) {
|
||||
if (symbol.getBind() == ElfSymbol.STB_GLOBAL) {
|
||||
list.add(symbol);
|
||||
}
|
||||
}
|
||||
ElfSymbol[] array = new ElfSymbol[list.size()];
|
||||
@@ -193,11 +205,11 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
|
||||
*/
|
||||
public String[] getSourceFiles() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (int j = 0; j < symbols.length; j++) {
|
||||
if (symbols[j].getType() == ElfSymbol.STT_FILE) {
|
||||
String name = symbols[j].getNameAsString();
|
||||
for (ElfSymbol symbol : symbols) {
|
||||
if (symbol.getType() == ElfSymbol.STT_FILE) {
|
||||
String name = symbol.getNameAsString();
|
||||
if (name != null) {
|
||||
list.add(symbols[j].getNameAsString());
|
||||
list.add(symbol.getNameAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,9 +15,18 @@
|
||||
*/
|
||||
package ghidra.app.util.xml;
|
||||
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressFormatException;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.listing.Bookmark;
|
||||
import ghidra.program.model.listing.BookmarkManager;
|
||||
import ghidra.program.model.listing.BookmarkType;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.XmlProgramUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -27,8 +35,6 @@ import ghidra.util.xml.XmlWriter;
|
||||
import ghidra.xml.XmlElement;
|
||||
import ghidra.xml.XmlPullParser;
|
||||
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
class BookmarksXmlMgr {
|
||||
private BookmarkManager bookmarkMgr;
|
||||
private AddressFactory factory;
|
||||
@@ -97,13 +103,13 @@ class BookmarksXmlMgr {
|
||||
}
|
||||
|
||||
try {
|
||||
if (!overwrite) {
|
||||
if (bookmarkMgr.getBookmark(addr, type, category) != null) {
|
||||
log.appendMsg("Conflicting '" + type + "' BOOKMARK ignored at: " + addr);
|
||||
return;
|
||||
}
|
||||
boolean hasExistingBookmark = bookmarkMgr.getBookmark(addr, type, category) != null;
|
||||
if (overwrite || !hasExistingBookmark) {
|
||||
bookmarkMgr.setBookmark(addr, type, category, comment);
|
||||
}
|
||||
if (!overwrite && hasExistingBookmark) {
|
||||
log.appendMsg("Conflicting '" + type + "' BOOKMARK ignored at: " + addr);
|
||||
}
|
||||
bookmarkMgr.setBookmark(addr, type, category, comment);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.appendException(e);
|
||||
|
||||
Reference in New Issue
Block a user