Skip to content

Commit

Permalink
Added alignment to some section's parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Ledmington committed May 23, 2024
1 parent 9e9f2fa commit e624d8e
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 93 deletions.
8 changes: 0 additions & 8 deletions elf/src/main/java/com/ledmington/elf/ELFParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,6 @@ private static PHTEntry parseProgramHeaderEntry(final boolean is32Bit) {
"Invalid value for alignment: expected 0x%016x %% %,d to be equal to 0x%016x %% %,d but wasn't",
segmentVirtualAddress, alignment, segmentOffset, alignment));
}
if (alignment != 1) {
throw new Error(String.format(
"Don't know what to do when alignment is not 1: it was %,d (0x%016x)", alignment, alignment));
}

return new PHTEntry(
PHTEntryType.fromCode(segmentType),
Expand Down Expand Up @@ -250,10 +246,6 @@ private static SectionHeader parseSectionHeaderEntry(final boolean is32Bit) {
"Invalid value for alignment: expected a power of two but was %,d (0x%016x)",
alignment, alignment));
}
if (alignment != 1) {
throw new Error(String.format(
"Don't know what to do when alignment is not 1: it was %,d (0x%016x)", alignment, alignment));
}

final long entrySize = is32Bit ? BitUtils.asLong(b.read4()) : b.read8();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public GnuPropertySection(final SectionHeader sectionHeader, final ReadOnlyByteB
}

b.setPosition(sectionHeader.getFileOffset());
b.setAlignment(sectionHeader.getAlignment());
this.entries = NoteSection.loadNoteSectionEntries(is32Bit, b, sectionHeader.getSectionSize());

if (entries.length != 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public InterpreterPathSection(final SectionHeader sectionHeader, final ReadOnlyB
this.header = Objects.requireNonNull(sectionHeader);

b.setPosition(sectionHeader.getFileOffset());
if (sectionHeader.getAlignment() != 1L) {
throw new IllegalArgumentException(String.format(
"Invalid alignment for .interp section: expected 1 but was %,d", sectionHeader.getAlignment()));
}
b.setAlignment(1L);

final StringBuilder sb = new StringBuilder();
char c = (char) b.read1();
Expand Down
3 changes: 0 additions & 3 deletions elf/src/main/java/com/ledmington/elf/section/NoteSection.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@ static NoteSectionEntry[] loadNoteSectionEntries(

while (b.getPosition() - start < length) {
final long namesz = is32Bit ? BitUtils.asLong(b.read4()) : b.read8();
System.out.printf("namesz : 0x%016x\n", namesz);
final long descsz = is32Bit ? BitUtils.asLong(b.read4()) : b.read8();
System.out.printf("descsz : 0x%016x\n", descsz);
final long type = is32Bit ? BitUtils.asLong(b.read4()) : b.read8();
System.out.printf("type : 0x%016x\n", type);

final byte[] nameBytes = new byte[BitUtils.asInt(namesz)];
for (int i = 0; i < namesz; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public long getVirtualAddress() {
return virtualAddress;
}

public long getAlignment() {
return alignment;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder(1_000);
Expand Down
189 changes: 114 additions & 75 deletions readelf/src/main/java/com/ledmington/readelf/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,45 @@ public static void main(final String[] args) {
case "-h", "--file-header":
displayHeader = true;
break;
case "-a", "--all":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "-l", "--program-headers", "--segments":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "-S", "--section-headers", "--sections":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "-g", "--section-groups":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "-t", "--section-details":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "-e", "--headers":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "-s", "--syms", "--symbols":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "--dyn-syms":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;
case "--lto-syms":
System.out.println("This flag is not implemented yet");
System.exit(-1);
break;

// TODO: add the other CLI flags

default:
if (arg.startsWith("-")) {
out.printf("readelf: Error: Invalid option '%s'\n", arg);
Expand Down Expand Up @@ -169,80 +208,80 @@ public static void main(final String[] args) {
private static void printHelp() {
out.println(
"""
Usage: readelf <option(s)> elf-file(s)
Display information about the contents of ELF format files
Options are:
-a --all Equivalent to: -h -l -S -s -r -d -V -A -I
-h --file-header Display the ELF file header
-l --program-headers Display the program headers
--segments An alias for --program-headers
-S --section-headers Display the sections' header
--sections An alias for --section-headers
-g --section-groups Display the section groups
-t --section-details Display the section details
-e --headers Equivalent to: -h -l -S
-s --syms Display the symbol table
--symbols An alias for --syms
--dyn-syms Display the dynamic symbol table
--lto-syms Display LTO symbol tables
--sym-base=[0|8|10|16]
Force base for symbol sizes. The options are
mixed (the default), octal, decimal, hexadecimal.
-C --demangle[=STYLE] Decode mangled/processed symbol names
STYLE can be "none", "auto", "gnu-v3", "java",
"gnat", "dlang", "rust"
--no-demangle Do not demangle low-level symbol names. (default)
--recurse-limit Enable a demangling recursion limit. (default)
--no-recurse-limit Disable a demangling recursion limit
-U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]
Display unicode characters as determined by the current locale
(default), escape sequences, "<hex sequences>", highlighted
escape sequences, or treat them as invalid and display as
"{hex sequences}"
-n --notes Display the core notes (if present)
-r --relocs Display the relocations (if present)
-u --unwind Display the unwind info (if present)
-d --dynamic Display the dynamic section (if present)
-V --version-info Display the version sections (if present)
-A --arch-specific Display architecture specific information (if any)
-c --archive-index Display the symbol/file index in an archive
-D --use-dynamic Use the dynamic section info when displaying symbols
-L --lint|--enable-checks
Display warning messages for possible problems
-x --hex-dump=<number|name>
Dump the contents of section <number|name> as bytes
-p --string-dump=<number|name>
Dump the contents of section <number|name> as strings
-R --relocated-dump=<number|name>
Dump the relocated contents of section <number|name>
-z --decompress Decompress section before dumping it
-w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,
f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,
m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,
s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,
U/=trace_info]
Display the contents of DWARF debug sections
-wk --debug-dump=links Display the contents of sections that link to separate
debuginfo files
-P --process-links Display the contents of non-debug sections in separate
debuginfo files. (Implies -wK)
-wK --debug-dump=follow-links
Follow links to separate debug info files (default)
-wN --debug-dump=no-follow-links
Do not follow links to separate debug info files
--dwarf-depth=N Do not display DIEs at depth N or greater
--dwarf-start=N Display DIEs starting at offset N
--ctf=<number|name> Display CTF info from section <number|name>
--ctf-parent=<name> Use CTF archive member <name> as the CTF parent
--ctf-symbols=<number|name>
Use section <number|name> as the CTF external symtab
--ctf-strings=<number|name>
Use section <number|name> as the CTF external strtab
-I --histogram Display histogram of bucket list lengths
-W --wide Allow output width to exceed 80 characters
-T --silent-truncation If a symbol name is truncated, do not add [...] suffix
@<file> Read options from <file>
-H --help Display this information
-v --version Display the version number of readelf""");
Usage: readelf <option(s)> elf-file(s)
Display information about the contents of ELF format files
Options are:
-a --all Equivalent to: -h -l -S -s -r -d -V -A -I
-h --file-header Display the ELF file header
-l --program-headers Display the program headers
--segments An alias for --program-headers
-S --section-headers Display the sections' header
--sections An alias for --section-headers
-g --section-groups Display the section groups
-t --section-details Display the section details
-e --headers Equivalent to: -h -l -S
-s --syms Display the symbol table
--symbols An alias for --syms
--dyn-syms Display the dynamic symbol table
--lto-syms Display LTO symbol tables
--sym-base=[0|8|10|16]
Force base for symbol sizes. The options are
mixed (the default), octal, decimal, hexadecimal.
-C --demangle[=STYLE] Decode mangled/processed symbol names
STYLE can be "none", "auto", "gnu-v3", "java",
"gnat", "dlang", "rust"
--no-demangle Do not demangle low-level symbol names. (default)
--recurse-limit Enable a demangling recursion limit. (default)
--no-recurse-limit Disable a demangling recursion limit
-U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]
Display unicode characters as determined by the current locale
(default), escape sequences, "<hex sequences>", highlighted
escape sequences, or treat them as invalid and display as
"{hex sequences}"
-n --notes Display the core notes (if present)
-r --relocs Display the relocations (if present)
-u --unwind Display the unwind info (if present)
-d --dynamic Display the dynamic section (if present)
-V --version-info Display the version sections (if present)
-A --arch-specific Display architecture specific information (if any)
-c --archive-index Display the symbol/file index in an archive
-D --use-dynamic Use the dynamic section info when displaying symbols
-L --lint|--enable-checks
Display warning messages for possible problems
-x --hex-dump=<number|name>
Dump the contents of section <number|name> as bytes
-p --string-dump=<number|name>
Dump the contents of section <number|name> as strings
-R --relocated-dump=<number|name>
Dump the relocated contents of section <number|name>
-z --decompress Decompress section before dumping it
-w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,
f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,
m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,
s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,
U/=trace_info]
Display the contents of DWARF debug sections
-wk --debug-dump=links Display the contents of sections that link to separate
debuginfo files
-P --process-links Display the contents of non-debug sections in separate
debuginfo files. (Implies -wK)
-wK --debug-dump=follow-links
Follow links to separate debug info files (default)
-wN --debug-dump=no-follow-links
Do not follow links to separate debug info files
--dwarf-depth=N Do not display DIEs at depth N or greater
--dwarf-start=N Display DIEs starting at offset N
--ctf=<number|name> Display CTF info from section <number|name>
--ctf-parent=<name> Use CTF archive member <name> as the CTF parent
--ctf-symbols=<number|name>
Use section <number|name> as the CTF external symtab
--ctf-strings=<number|name>
Use section <number|name> as the CTF external strtab
-I --histogram Display histogram of bucket list lengths
-W --wide Allow output width to exceed 80 characters
-T --silent-truncation If a symbol name is truncated, do not add [...] suffix
@<file> Read options from <file>
-H --help Display this information
-v --version Display the version number of readelf""");
}
}
20 changes: 13 additions & 7 deletions utils/src/main/java/com/ledmington/utils/ReadOnlyByteBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,7 @@ public abstract class ReadOnlyByteBuffer {
protected ReadOnlyByteBuffer(final boolean isLittleEndian, final long alignment) {
this.isLE = isLittleEndian;

if (alignment < 1) {
throw new IllegalArgumentException(String.format("Invalid alignment: must be >=1 but was %,d", alignment));
}
if (Long.bitCount(alignment) != 1) {
throw new IllegalArgumentException(
String.format("Invalid alignment: must be a power of two but was %,d", alignment));
}
checkAlignment(alignment);
this.alignment = alignment;
}

Expand All @@ -65,6 +59,18 @@ public final void setEndianness(final boolean isLittleEndian) {
this.isLE = isLittleEndian;
}

private void checkAlignment(final long alignment) {
if (alignment <= 0 || Long.bitCount(alignment) != 1) {
throw new IllegalArgumentException(
String.format("Invalid alignment: expected a power of two >0 but was %,d", alignment));
}
}

public void setAlignment(final long newAlignment) {
checkAlignment(newAlignment);
this.alignment = newAlignment;
}

/**
* Changes the position in the buffer.
*
Expand Down

0 comments on commit e624d8e

Please sign in to comment.