GP-3793 revised ELF symbol handling so as not to preclude use of UTF8

This commit is contained in:
ghidra1
2023-08-28 18:11:44 -04:00
parent ae31a25490
commit de43ed0656
2 changed files with 23 additions and 40 deletions
@@ -94,8 +94,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
private ElfCompressedSectionHeader compressedHeader; private ElfCompressedSectionHeader compressedHeader;
public ElfSectionHeader(BinaryReader reader, ElfHeader header) public ElfSectionHeader(BinaryReader reader, ElfHeader header) throws IOException {
throws IOException {
this.reader = reader; this.reader = reader;
this.header = header; this.header = header;
@@ -237,9 +236,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
* @return the section address alignment constraints * @return the section address alignment constraints
*/ */
public long getAddressAlignment() { public long getAddressAlignment() {
return compressedHeader == null return compressedHeader == null ? sh_addralign : compressedHeader.getCh_addralign();
? sh_addralign
: compressedHeader.getCh_addralign();
} }
/** /**
@@ -297,7 +294,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
} }
private boolean isSupportedCompressionType(int compressionType) { private boolean isSupportedCompressionType(int compressionType) {
return switch ( compressionType ) { return switch (compressionType) {
case ElfCompressedSectionHeader.ELFCOMPRESS_ZLIB -> true; case ElfCompressedSectionHeader.ELFCOMPRESS_ZLIB -> true;
default -> false; default -> false;
}; };
@@ -367,7 +364,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
long stringTableOffset = sections[e_shstrndx].getOffset(); long stringTableOffset = sections[e_shstrndx].getOffset();
long offset = stringTableOffset + sh_name; long offset = stringTableOffset + sh_name;
if (offset < reader.length()) { if (offset < reader.length()) {
name = reader.readAsciiString(stringTableOffset + sh_name); name = reader.readUtf8String(stringTableOffset + sh_name);
if ("".equals(name)) { if ("".equals(name)) {
name = null; name = null;
} }
@@ -447,9 +444,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
* @return logical size of this section, see {@link #getSize()} * @return logical size of this section, see {@link #getSize()}
*/ */
public long getLogicalSize() { public long getLogicalSize() {
return compressedHeader == null return compressedHeader == null ? sh_size : compressedHeader.getCh_size();
? sh_size
: compressedHeader.getCh_size();
} }
@Override @Override
@@ -461,8 +456,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
@Override @Override
public InputStream getFilteredLoadInputStream(ElfLoadHelper elfLoadHelper, Address start, public InputStream getFilteredLoadInputStream(ElfLoadHelper elfLoadHelper, Address start,
long dataLength, BiConsumer<String, Throwable> errorConsumer) throws IOException { long dataLength, BiConsumer<String, Throwable> errorConsumer) throws IOException {
InputStream is = isCompressed() InputStream is = isCompressed() ? getDecompressedDataStream(dataLength, errorConsumer)
? getDecompressedDataStream(dataLength, errorConsumer)
: getRawInputStream(); : getRawInputStream();
return header.getLoadAdapter() return header.getLoadAdapter()
.getFilteredLoadInputStream(elfLoadHelper, this, start, dataLength, is); .getFilteredLoadInputStream(elfLoadHelper, this, start, dataLength, is);
@@ -573,7 +567,7 @@ public class ElfSectionHeader implements StructConverter, MemoryLoadable {
} }
this.sh_addr = header.unadjustAddressForPrelink(addr); this.sh_addr = header.unadjustAddressForPrelink(addr);
} }
/** /**
* @see ghidra.app.util.bin.StructConverter#toDataType() * @see ghidra.app.util.bin.StructConverter#toDataType()
*/ */
@@ -995,7 +995,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
int symbolIndex = reloc.getSymbolIndex(); int symbolIndex = reloc.getSymbolIndex();
String symbolName = symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : ""; String symbolName = symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : "";
if (symbolName != null && isUnsupportedASCIISymbolName(symbolName)) { if (symbolName != null && SymbolUtilities.containsInvalidChars(symbolName)) {
symbolName = getEscapedSymbolName(symbolName); symbolName = getEscapedSymbolName(symbolName);
} }
@@ -2094,9 +2094,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
isPrimary = (existingSym == null); isPrimary = (existingSym == null);
} }
if (name != null && isUnsupportedASCIISymbolName(name)) { if (SymbolUtilities.containsInvalidChars(name)) {
String escapedName = getEscapedSymbolName(name); String escapedName = getEscapedSymbolName(name);
log("Unsupported ASCII symbol name has been escaped: \"" + escapedName + "\""); log("Unsupported symbol name has been escaped: \"" + escapedName + "\"");
name = escapedName; name = escapedName;
} }
@@ -2134,36 +2134,25 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
} }
} }
private boolean isUnsupportedASCIISymbolName(String name) {
for (char c : name.toCharArray()) {
if (!StringUtilities.isAsciiChar(c) || c == ' ') {
return true;
}
}
return false;
}
private String getEscapedSymbolName(String name) { private String getEscapedSymbolName(String name) {
// Do not preclude use of UTF8 strings
StringBuilder escapedBuf = new StringBuilder(); StringBuilder escapedBuf = new StringBuilder();
for (char c : name.toCharArray()) { name.codePoints().forEach(cp -> {
if (c < 0 || c > 0x7f) { if (cp < 0x20) {
// format non-ASCII as escaped numeric hex value \xNN // Format as ^Control character for consistency with readelf
escapedBuf.append("\\x%02x".formatted((int) c)); cp += 0x40; // get ASCII control character, starts with ^@
}
else if (c < ' ') {
// format as ^Control character for consistency with readelf
c += 64; // get ASCII control character, starts with ^@
escapedBuf.append('^'); escapedBuf.append('^');
escapedBuf.append(c); escapedBuf.appendCodePoint(cp);
} }
else if (c == 0x7f) { else if (cp == 0x7F) {
// format as ^? character for consistency with readelf // Format as ^? character for consistency with readelf
escapedBuf.append("^?"); escapedBuf.append("^?");
} }
else { else {
escapedBuf.append(c); // Assume valid code point
escapedBuf.appendCodePoint(cp);
} }
} });
return escapedBuf.toString(); return escapedBuf.toString();
} }
@@ -2841,8 +2830,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
private int createString(Address address) throws CodeUnitInsertionException { private int createString(Address address) throws CodeUnitInsertionException {
Data d = listing.getDataAt(address); Data d = listing.getDataAt(address);
if (d == null || !TerminatedStringDataType.dataType.isEquivalent(d.getDataType())) { if (d == null || !StringUTF8DataType.dataType.isEquivalent(d.getDataType())) {
d = listing.createData(address, TerminatedStringDataType.dataType, -1); d = listing.createData(address, StringUTF8DataType.dataType, -1);
} }
return d.getLength(); return d.getLength();
} }