diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f7ffab2
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,145 @@
+# EditorConfig is awesome:http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# All Files
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = false
+trim_trailing_whitespace = true
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_prefer_braces = true:silent
+csharp_style_namespace_declarations = block_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_style_throw_expression = true:suggestion
+csharp_style_prefer_null_check_over_type_check = true:suggestion
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_prefer_local_over_anonymous_function = true:suggestion
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
+csharp_style_prefer_tuple_swap = true:suggestion
+csharp_style_prefer_utf8_string_literals = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_indent_labels = one_less_than_current
+csharp_style_deconstructed_variable_declaration = true:suggestion
+dotnet_diagnostic.NUnit2006.severity = silent
+dotnet_diagnostic.NUnit2005.severity = silent
+dotnet_diagnostic.NUnit2004.severity = silent
+dotnet_diagnostic.NUnit2003.severity = silent
+dotnet_diagnostic.NUnit2002.severity = silent
+dotnet_diagnostic.NUnit2001.severity = silent
+
+# Solution Files
+[*.sln]
+indent_style = tab
+
+# XML Project Files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# Configuration Files
+[*.{json,xml,yml,config,props,targets,nuspec,resx,ruleset}]
+indent_size = 2
+
+# Txt/Markdown Files
+[*.{md,txt}]
+trim_trailing_whitespace = false
+
+# Web Files
+[*.{htm,html,js,ts,css,scss,less}]
+indent_size = 2
+insert_final_newline = true
+
+# Bash Files
+[*.sh]
+end_of_line = lf
+
+[*.{cs,vb}]
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+dotnet_style_namespace_match_folder = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+
+
+# Verify settings
+[*.{received,verified}.{txt,xml,json}]
+charset = "utf-8-bom"
+end_of_line = lf
+indent_size = unset
+indent_style = unset
+insert_final_newline = false
+tab_width = unset
+trim_trailing_whitespace = false
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..811523a
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
+*.sh text eol=lf
+*.verified.txt text eol=lf working-tree-encoding=UTF-8
+*.verified.xml text eol=lf working-tree-encoding=UTF-8
+*.verified.json text eol=lf working-tree-encoding=UTF-8
\ No newline at end of file
diff --git a/doc/PE.png b/doc/PE.png
new file mode 100644
index 0000000..02a8b24
Binary files /dev/null and b/doc/PE.png differ
diff --git a/doc/readme.md b/doc/readme.md
index 9a2240a..d638bc4 100644
--- a/doc/readme.md
+++ b/doc/readme.md
@@ -240,3 +240,304 @@ symbolTable.Symbols.Add(new ArSymbol("my_symbol", elf));
### Links
- [Archive ar file format (Wikipedia)](https://en.wikipedia.org/wiki/Ar_(Unix))
+
+## PE Object File Format
+
+### Overview
+
+The main entry-point for reading/writing PE file is the [`PEFile`](https://github.com/xoofx/LibObjectFile/blob/master/src/LibObjectFile/PE/PEFile.cs) class.
+
+
+
+#### Sections and Directories
+
+In `LibObjectFile` all the section data `PESectionData` - e.g code, data but also including PE directories - are part of either:
+
+- a `PESection`
+- some raw data before the first section via `PEFile.ExtraDataBeforeSections`
+- raw data after the last section via `PEFile.ExtraDataAfterSections`
+
+Most of the conventional data is stored in sections, including PE directories.
+
+A PE Directory itself can contain also a collection of `PESectionData`.
+
+If the size of a section data is modified (e.g adding elements to a directory table or modifying a stream in a `PEStreamSectionData`), it is important to call `PEFile.UpdateLayout` to update the layout of the PE file.
+
+#### VA, RVA, RVO
+
+In the PE file format, there are different types of addresses:
+
+- `VA` (Virtual Address) is the address of a section in memory including the base address of the image `PEFile.OptionalHeader.ImageBase`
+- `RVA` (Relative Virtual Address) is the address of a section relative to the base address of the image
+ - A `RVA` can be converted to a `VA` by adding the `PEFile.OptionalHeader.ImageBase`.
+- `RVO` (Relative Virtual Offset) is an offset relative to an RVA provided by section data or a section.
+ - A `RVO` can be converted to a `RVA` by adding the RVA of the section data or the section.
+
+In `LibObjectFile` links to RVA between section and section datas are done through a `IPELink` that is combining a reference to a `PEObjectBase` and a `RVO`. It means that RVA are always up to date and linked to the right section data.
+
+### Reading a PE File
+
+The PE API allows to read from a `System.IO.Stream` via the method `PEFile.Read`:
+
+```csharp
+PEFile pe = PEFile.Read(inputStream);
+foreach(var section in pe.Sections)
+{
+ Console.WriteLine($"{section}");
+}
+```
+
+### Writing a PE File
+
+The PE API allows to write to a `System.IO.Stream` via the method `PEFile.Write`:
+
+```csharp
+PEFile pe = PEFile.Read(inputStream);
+// Modify the PE file
+// ....
+pe.Write(stream);
+```
+
+### Printing a PE File
+
+You can print a PE file to a textual by using the extension method `PEFile.Print(TextWriter)`:
+
+```csharp
+PEFile pe = PEFile.Read(inputStream);
+pe.Print(Console.Out);
+```
+
+It will generate an output like this:
+
+```
+DOS Header
+ Magic = DOS
+ ByteCountOnLastPage = 0x90
+ PageCount = 0x3
+ RelocationCount = 0x0
+ SizeOfParagraphsHeader = 0x4
+ MinExtraParagraphs = 0x0
+ MaxExtraParagraphs = 0xFFFF
+ InitialSSValue = 0x0
+ InitialSPValue = 0xB8
+ Checksum = 0x0
+ InitialIPValue = 0x0
+ InitialCSValue = 0x0
+ FileAddressRelocationTable = 0x40
+ OverlayNumber = 0x0
+ Reserved = 0x0, 0x0, 0x0, 0x0
+ OEMIdentifier = 0x0
+ OEMInformation = 0x0
+ Reserved2 = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+ FileAddressPEHeader = 0xC8
+
+DOS Stub
+ DosStub = 64 bytes
+
+COFF Header
+ Machine = Amd64
+ NumberOfSections = 3
+ TimeDateStamp = 1727726362
+ PointerToSymbolTable = 0x0
+ NumberOfSymbols = 0
+ SizeOfOptionalHeader = 240
+ Characteristics = ExecutableImage, LargeAddressAware
+
+Optional Header
+ Magic = PE32Plus
+ MajorLinkerVersion = 14
+ MinorLinkerVersion = 41
+ SizeOfCode = 0x200
+ SizeOfInitializedData = 0x400
+ SizeOfUninitializedData = 0x0
+ AddressOfEntryPoint = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x0
+ BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x200, Content[1] }
+ BaseOfData = 0x0x0
+ ImageBase = 0x140000000
+ SectionAlignment = 0x1000
+ FileAlignment = 0x200
+ MajorOperatingSystemVersion = 6
+ MinorOperatingSystemVersion = 0
+ MajorImageVersion = 0
+ MinorImageVersion = 0
+ MajorSubsystemVersion = 6
+ MinorSubsystemVersion = 0
+ Win32VersionValue = 0x0
+ SizeOfImage = 0x4000
+ SizeOfHeaders = 0x400
+ CheckSum = 0x0
+ Subsystem = WindowsCui
+ DllCharacteristics = HighEntropyVirtualAddressSpace, DynamicBase, TerminalServerAware
+ SizeOfStackReserve = 0x100000
+ SizeOfStackCommit = 0x1000
+ SizeOfHeapReserve = 0x100000
+ SizeOfHeapCommit = 0x1000
+ LoaderFlags = 0x0
+ NumberOfRvaAndSizes = 0x10
+
+Data Directories
+ [00] = null
+ [01] = PEImportDirectory Position = 0x00000744, Size = 0x00000028, RVA = 0x00002144, VirtualSize = 0x00000028
+ [02] = null
+ [03] = PEExceptionDirectory Position = 0x00000800, Size = 0x0000000C, RVA = 0x00003000, VirtualSize = 0x0000000C
+ [04] = null
+ [05] = null
+ [06] = PEDebugDirectory Position = 0x00000610, Size = 0x00000038, RVA = 0x00002010, VirtualSize = 0x00000038
+ [07] = null
+ [08] = null
+ [09] = null
+ [10] = null
+ [11] = null
+ [12] = PEImportAddressTableDirectory Position = 0x00000600, Size = 0x00000010, RVA = 0x00002000, VirtualSize = 0x00000010
+ [13] = null
+ [14] = null
+ [15] = null
+
+Section Headers
+ [00] .text PESection Position = 0x00000400, Size = 0x00000200, RVA = 0x00001000, VirtualSize = 0x00000010, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+ [01] .rdata PESection Position = 0x00000600, Size = 0x00000200, RVA = 0x00002000, VirtualSize = 0x0000019C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [02] .pdata PESection Position = 0x00000800, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x0000000C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+Sections
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [00] .text PESection Position = 0x00000400, Size = 0x00000200, RVA = 0x00001000, VirtualSize = 0x00000010, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+
+ [00] PEStreamSectionData Position = 0x00000400, Size = 0x00000010, RVA = 0x00001000, VirtualSize = 0x00000010
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [01] .rdata PESection Position = 0x00000600, Size = 0x00000200, RVA = 0x00002000, VirtualSize = 0x0000019C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEImportAddressTableDirectory Position = 0x00000600, Size = 0x00000010, RVA = 0x00002000, VirtualSize = 0x00000010
+ [00] PEImportAddressTable Position = 0x00000600, Size = 0x00000010, RVA = 0x00002000, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 376, Name = ExitProcess } (RVA = 0x2180, PEStreamSectionData { RVA = 0x2180, VirtualSize = 0x1C, Position = 0x780, Size = 0x1C }, Offset = 0x0)
+
+
+ [01] PEDebugDirectory Position = 0x00000610, Size = 0x00000038, RVA = 0x00002010, VirtualSize = 0x00000038
+ [0] Type = POGO, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FB031A, Data = RVA = 0x00002060 (PEDebugStreamSectionData[3] -> .rdata)
+ [1] Type = ILTCG, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FB031A, Data = null
+
+ [02] PEStreamSectionData Position = 0x00000648, Size = 0x00000018, RVA = 0x00002048, VirtualSize = 0x00000018
+
+ [03] PEDebugStreamSectionData Position = 0x00000660, Size = 0x000000DC, RVA = 0x00002060, VirtualSize = 0x000000DC
+
+ [04] PEStreamSectionData Position = 0x0000073C, Size = 0x00000008, RVA = 0x0000213C, VirtualSize = 0x00000008
+
+ [05] PEImportDirectory Position = 0x00000744, Size = 0x00000028, RVA = 0x00002144, VirtualSize = 0x00000028
+ [0] ImportDllNameLink = KERNEL32.dll (RVA = 0x218E, PEStreamSectionData { RVA = 0x2180, VirtualSize = 0x1C, Position = 0x780, Size = 0x1C }, Offset = 0xE)
+ [0] ImportAddressTable = RVA = 0x00002000 (PEImportAddressTable[0] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [0] ImportLookupTable = RVA = 0x00002170 (PEImportLookupTable[7] -> .rdata)
+
+
+ [06] PEStreamSectionData Position = 0x0000076C, Size = 0x00000004, RVA = 0x0000216C, VirtualSize = 0x00000004
+
+ [07] PEImportLookupTable Position = 0x00000770, Size = 0x00000010, RVA = 0x00002170, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 376, Name = ExitProcess } (RVA = 0x2180, PEStreamSectionData { RVA = 0x2180, VirtualSize = 0x1C, Position = 0x780, Size = 0x1C }, Offset = 0x0)
+
+ [08] PEStreamSectionData Position = 0x00000780, Size = 0x0000001C, RVA = 0x00002180, VirtualSize = 0x0000001C
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [02] .pdata PESection Position = 0x00000800, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x0000000C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEExceptionDirectory Position = 0x00000800, Size = 0x0000000C, RVA = 0x00003000, VirtualSize = 0x0000000C
+ [0] Begin = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x0
+ [0] End = RVA = 0x1010, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x10
+ [0] UnwindInfoAddress = RVA = 0x213C, PEStreamSectionData { RVA = 0x213C, VirtualSize = 0x8, Position = 0x73C, Size = 0x8 }, Offset = 0x0
+```
+
+### Creating a PE File
+
+The PE format is complex and requires a lot of information to be created.
+
+While LibObjectFile provides a way to create a PE file from scratch, it is not easy to create a working exe/dll file. If you are trying to create a file from scratch, use the `PEFile.Print` on existing exe/dll files to understand the structure and how to create a similar file.
+
+The following example is a complete example that creates a PE file with a code section that calls `ExitProcess` from `KERNEL32.DLL` with the value `156`:
+
+```csharp
+var pe = new PEFile();
+
+// ***************************************************************************
+// Code section
+// ***************************************************************************
+var codeSection = pe.AddSection(PESectionName.Text, 0x1000);
+var streamCode = new PEStreamSectionData();
+
+streamCode.Stream.Write([
+ // SUB RSP, 0x28
+ 0x48, 0x83, 0xEC, 0x28,
+ // MOV ECX, 0x9C
+ 0xB9, 0x9C, 0x00, 0x00, 0x00,
+ // CALL ExitProcess (CALL [RIP + 0xFF1])
+ 0xFF, 0x15, 0xF1, 0x0F, 0x00, 0x00,
+ // INT3
+ 0xCC
+]);
+
+codeSection.Content.Add(streamCode);
+
+// ***************************************************************************
+// Data section
+// ***************************************************************************
+var dataSection = pe.AddSection(PESectionName.RData, 0x2000);
+
+var streamData = new PEStreamSectionData();
+var kernelName = streamData.WriteAsciiString("KERNEL32.DLL");
+var exitProcessFunction = streamData.WriteHintName(new(0x178, "ExitProcess"));
+
+// PEImportAddressTableDirectory comes first, it is referenced by the RIP + 0xFF1, first address being ExitProcess
+var peImportAddressTable = new PEImportAddressTable()
+{
+ exitProcessFunction
+};
+var iatDirectory = new PEImportAddressTableDirectory()
+{
+ peImportAddressTable
+};
+
+var peImportLookupTable = new PEImportLookupTable()
+{
+ exitProcessFunction
+};
+
+var importDirectory = new PEImportDirectory()
+{
+ Entries =
+ {
+ new PEImportDirectoryEntry(kernelName, peImportAddressTable, peImportLookupTable)
+ }
+};
+
+// Layout of the data section
+dataSection.Content.Add(iatDirectory);
+dataSection.Content.Add(peImportLookupTable);
+dataSection.Content.Add(importDirectory);
+dataSection.Content.Add(streamData);
+
+// ***************************************************************************
+// Optional Header
+// ***************************************************************************
+pe.OptionalHeader.AddressOfEntryPoint = new(streamCode, 0);
+pe.OptionalHeader.BaseOfCode = codeSection;
+
+// ***************************************************************************
+// Write the PE to a file
+// ***************************************************************************
+var output = new MemoryStream();
+pe.Write(output, new() { EnableStackTrace = true });
+output.Position = 0;
+
+var sourceFile = Path.Combine(AppContext.BaseDirectory, "PE", "RawNativeConsoleWin64_Generated.exe");
+File.WriteAllBytes(sourceFile, output.ToArray());
+
+// Check the generated exe
+var process = Process.Start(sourceFile);
+process.WaitForExit();
+Assert.AreEqual(156, process.ExitCode);
+```
+
+> Notice that the code above doesn't have to setup the `PEFile.Directories` explicitly.
+>
+> In fact when writing a PE file, the `PEFile.Write` method will automatically populate the directories based on the content of the sections.
+
+### Links
+
+- [PE and COFF Specification](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format)
diff --git a/img/banner.png b/img/banner.png
new file mode 100644
index 0000000..843f16f
Binary files /dev/null and b/img/banner.png differ
diff --git a/img/libobjectfile.pdn b/img/libobjectfile.pdn
new file mode 100644
index 0000000..a7abbd3
Binary files /dev/null and b/img/libobjectfile.pdn differ
diff --git a/img/libobjectfile.png b/img/libobjectfile.png
index 13a891a..e95b684 100644
Binary files a/img/libobjectfile.png and b/img/libobjectfile.png differ
diff --git a/readme.md b/readme.md
index 591ecd3..1e503fc 100644
--- a/readme.md
+++ b/readme.md
@@ -2,10 +2,11 @@
-LibObjectFile is a .NET library to read, manipulate and write linker and executable object files (e.g ELF, ar, DWARF, COFF...)
+LibObjectFile is a .NET library to read, manipulate and write linker and executable object files (e.g ELF, ar, DWARF, PE...)
-> NOTE: Currently LibObjectFile supports only the following file format:
+> NOTE: Currently LibObjectFile supports the following file format:
>
+> - **PE** image file format (Portable Executable / DLL)
> - **ELF** object-file format
> - **DWARF** debugging format (version 4)
> - **Archive `ar`** file format (Common, GNU and BSD variants)
@@ -31,8 +32,12 @@ elf.Write(outStream);
```
## Features
-- Full support of Archive `ar` file format including Common, GNU and BSD variants.
-- Good support for the ELF file format:
+- Full support of **Archive `ar` file format** including Common, GNU and BSD variants.
+- Full support for the **PE file format**
+ - Read and write from/to a `System.IO.Stream`
+ - All PE Directories are supported
+ - `PEFile.Print` to print the content of a PE file to a textual representation
+- - Good support for the **ELF file format**:
- Read and write from/to a `System.IO.Stream`
- Handling of LSB/MSB
- Support the following sections:
@@ -43,7 +48,7 @@ elf.Write(outStream);
- Other sections fallback to `ElfCustomSection`
- Program headers with or without sections
- Print with `readelf` similar output
-- Support for DWARF debugging format:
+- Support for **DWARF debugging format**:
- Partial support of Version 4 (currently still the default for GCC)
- Support for the sections: `.debug_info`, `.debug_line`, `.debug_aranges`, `.debug_abbrev` and `.debug_str`
- Support for Dwarf expressions
@@ -58,33 +63,6 @@ elf.Write(outStream);
The [doc/readme.md](doc/readme.md) explains how the library is designed and can be used.
-## Known Issues
-
-PR Welcome if you are willing to contribute to one of these issues:
-
-- [ ] Add more unit tests
-
-### ELF
-There are still a few missing implementation of `ElfSection` for completeness:
-
-- [ ] Dynamic Linking Table (`SHT_DYNAMIC`)
-- [ ] Version Symbol Table (`SHT_VERSYM`)
-- [ ] Version Needs Table (`SHT_VERNEED`)
-
-These sections are currently loaded as `ElfCustomSection` but should have their own ElfXXXTable (e.g `ElfDynamicLinkingTable`, `ElfVersionSymbolTable`...)
-
-### DWARF
-
-- [ ] Version 4: support for `.debug_types`, `.debug_frame`, `.debug_loc`, `.debug_ranges`, `.debug_pubnames`, `.debug_pubtypes`, `.debug_macinfo` section
-- [ ] Version 5
-
-### Other file formats
-In a future version I would like to implement the following file format:
-
-- [ ] COFF
-- [ ] Mach-O
-- [ ] Portable in Memory file format to easily convert between ELF/COFF/Mach-O file formats.
-
## Download
LibObjectFile is available as a NuGet package: [](https://www.nuget.org/packages/LibObjectFile/)
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
new file mode 100644
index 0000000..0dfc2d1
--- /dev/null
+++ b/src/Directory.Packages.props
@@ -0,0 +1,17 @@
+
+
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/LibObjectFile.CodeGen/LibObjectFile.CodeGen.csproj b/src/LibObjectFile.CodeGen/LibObjectFile.CodeGen.csproj
index 77c6fbd..f5e76dc 100644
--- a/src/LibObjectFile.CodeGen/LibObjectFile.CodeGen.csproj
+++ b/src/LibObjectFile.CodeGen/LibObjectFile.CodeGen.csproj
@@ -1,4 +1,4 @@
-
+
net8.0
Exe
@@ -12,7 +12,7 @@
-
+
PreserveNewest
diff --git a/src/LibObjectFile.CodeGen/Program.Dwarf.cs b/src/LibObjectFile.CodeGen/Program.Dwarf.cs
index 28fe2c0..1bfe71c 100644
--- a/src/LibObjectFile.CodeGen/Program.Dwarf.cs
+++ b/src/LibObjectFile.CodeGen/Program.Dwarf.cs
@@ -1,6 +1,7 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -9,780 +10,781 @@
using System.Text.RegularExpressions;
using CppAst.CodeGen.CSharp;
-namespace LibObjectFile.CodeGen
+namespace LibObjectFile.CodeGen;
+
+partial class Program
{
- partial class Program
+ private static void GenerateDwarf()
{
- private static void GenerateDwarf()
+ var cppOptions = new CSharpConverterOptions()
{
- var cppOptions = new CSharpConverterOptions()
+ DefaultClassLib = "DwarfNative",
+ DefaultNamespace = "LibObjectFile.Dwarf",
+ DefaultOutputFilePath = "/LibObjectFile.Dwarf.generated.cs",
+ DefaultDllImportNameAndArguments = "NotUsed",
+ MappingRules =
{
- DefaultClassLib = "DwarfNative",
- DefaultNamespace = "LibObjectFile.Dwarf",
- DefaultOutputFilePath = "/LibObjectFile.Dwarf.generated.cs",
- DefaultDllImportNameAndArguments = "NotUsed",
- MappingRules =
- {
- map => map.MapMacroToConst("^DW_TAG_.*", "unsigned short"),
- map => map.MapMacroToConst("^DW_FORM_.*", "unsigned short"),
- map => map.MapMacroToConst("^DW_AT_.*", "unsigned short"),
- map => map.MapMacroToConst("^DW_LN[ES]_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_IDX_.*", "unsigned short"),
- map => map.MapMacroToConst("^DW_LANG_.*", "unsigned short"),
- map => map.MapMacroToConst("^DW_ID_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_CC_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_ISA_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_CHILDREN_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_OP_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_ACCESS_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_VIS_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_VIRTUALITY_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_INL_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_ORD_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_DSC_.*", "unsigned char"),
- map => map.MapMacroToConst("^DW_UT_.*", "unsigned char"),
- }
- };
+ map => map.MapMacroToConst("^DW_TAG_.*", "unsigned short"),
+ map => map.MapMacroToConst("^DW_FORM_.*", "unsigned short"),
+ map => map.MapMacroToConst("^DW_AT_.*", "unsigned short"),
+ map => map.MapMacroToConst("^DW_LN[ES]_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_IDX_.*", "unsigned short"),
+ map => map.MapMacroToConst("^DW_LANG_.*", "unsigned short"),
+ map => map.MapMacroToConst("^DW_ID_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_CC_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_ISA_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_CHILDREN_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_OP_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_ACCESS_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_VIS_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_VIRTUALITY_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_INL_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_ORD_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_DSC_.*", "unsigned char"),
+ map => map.MapMacroToConst("^DW_UT_.*", "unsigned char"),
+ }
+ };
- cppOptions.GenerateEnumItemAsFields = false;
- cppOptions.IncludeFolders.Add(Environment.CurrentDirectory);
+ cppOptions.GenerateEnumItemAsFields = false;
+ cppOptions.IncludeFolders.Add(Environment.CurrentDirectory);
- var csCompilation = CSharpConverter.Convert(@"#include ""dwarf.h""", cppOptions);
+ var csCompilation = CSharpConverter.Convert(@"#include ""dwarf.h""", cppOptions);
- AssertCompilation(csCompilation);
+ AssertCompilation(csCompilation);
- // Add pragma
- var csFile = csCompilation.Members.OfType().First();
- var ns = csFile.Members.OfType().First();
- csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#pragma warning disable 1591") );
+ // Add pragma
+ var csFile = csCompilation.Members.OfType().First();
+ var ns = csFile.Members.OfType().First();
+ csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#pragma warning disable 1591") );
+ csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#pragma warning disable CS8765"));
+ csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#nullable enable"));
- ProcessEnum(cppOptions, csCompilation, "DW_AT_", "DwarfAttributeKind");
- ProcessEnum(cppOptions, csCompilation, "DW_FORM_", "DwarfAttributeForm");
- ProcessEnum(cppOptions, csCompilation, "DW_TAG_", "DwarfTag");
- ProcessEnum(cppOptions, csCompilation, "DW_OP_", "DwarfOperationKind");
- ProcessEnum(cppOptions, csCompilation, "DW_LANG_", "DwarfLanguageKind");
- ProcessEnum(cppOptions, csCompilation, "DW_CC_", "DwarfCallingConvention");
- ProcessEnum(cppOptions, csCompilation, "DW_UT_", "DwarfUnitKind");
+ ProcessEnum(cppOptions, csCompilation, "DW_AT_", "DwarfAttributeKind");
+ ProcessEnum(cppOptions, csCompilation, "DW_FORM_", "DwarfAttributeForm");
+ ProcessEnum(cppOptions, csCompilation, "DW_TAG_", "DwarfTag");
+ ProcessEnum(cppOptions, csCompilation, "DW_OP_", "DwarfOperationKind");
+ ProcessEnum(cppOptions, csCompilation, "DW_LANG_", "DwarfLanguageKind");
+ ProcessEnum(cppOptions, csCompilation, "DW_CC_", "DwarfCallingConvention");
+ ProcessEnum(cppOptions, csCompilation, "DW_UT_", "DwarfUnitKind");
- GenerateDwarfAttributes(ns);
- GenerateDwarfDIE(ns);
+ GenerateDwarfAttributes(ns);
+ GenerateDwarfDIE(ns);
- csCompilation.DumpTo(GetCodeWriter(Path.Combine("LibObjectFile", "generated")));
- }
+ csCompilation.DumpTo(GetCodeWriter(Path.Combine("LibObjectFile", "generated")));
+ }
- private static Dictionary MapAttributeCompactNameToType = new Dictionary();
+ private static Dictionary MapAttributeCompactNameToType = new Dictionary();
- private static void GenerateDwarfAttributes(CSharpNamespace ns)
- {
- var alreadyDone = new HashSet();
+ private static void GenerateDwarfAttributes(CSharpNamespace ns)
+ {
+ var alreadyDone = new HashSet();
- var csHelper = new CSharpClass("DwarfHelper")
- {
- Modifiers = CSharpModifiers.Static | CSharpModifiers.Partial,
- Visibility = CSharpVisibility.Public
- };
- ns.Members.Add(csHelper);
+ var csHelper = new CSharpClass("DwarfHelper")
+ {
+ Modifiers = CSharpModifiers.Static | CSharpModifiers.Partial,
+ Visibility = CSharpVisibility.Public
+ };
+ ns.Members.Add(csHelper);
- var csField = new CSharpField("AttributeToEncoding")
- {
- Modifiers = CSharpModifiers.Static | CSharpModifiers.ReadOnly,
- Visibility = CSharpVisibility.Private,
- FieldType = new CSharpArrayType(new CSharpFreeType("DwarfAttributeEncoding"))
- };
- csHelper.Members.Add(csField);
+ var csField = new CSharpField("AttributeToEncoding")
+ {
+ Modifiers = CSharpModifiers.Static | CSharpModifiers.ReadOnly,
+ Visibility = CSharpVisibility.Private,
+ FieldType = new CSharpArrayType(new CSharpFreeType("DwarfAttributeEncoding"))
+ };
+ csHelper.Members.Add(csField);
- var fieldArrayBuilder = new StringBuilder();
- fieldArrayBuilder.AppendLine("new DwarfAttributeEncoding[] {");
+ var fieldArrayBuilder = new StringBuilder();
+ fieldArrayBuilder.AppendLine("new DwarfAttributeEncoding[] {");
- int currentAttributeIndex = 0;
+ int currentAttributeIndex = 0;
- foreach (var attrEncoding in MapAttributeToEncoding)
- {
- var attrEncodingParts = attrEncoding.Split(' ', StringSplitOptions.RemoveEmptyEntries);
- var attributeName = attrEncodingParts[0];
- var attributeIndex = int.Parse(attrEncodingParts[1].Substring(2), System.Globalization.NumberStyles.HexNumber);
- var rawName = attributeName.Substring("DW_AT_".Length);
- //var csharpName = CSharpifyName(rawName);
+ foreach (var attrEncoding in MapAttributeToEncoding)
+ {
+ var attrEncodingParts = attrEncoding.Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ var attributeName = attrEncodingParts[0];
+ var attributeIndex = int.Parse(attrEncodingParts[1].Substring(2), System.Globalization.NumberStyles.HexNumber);
+ var rawName = attributeName.Substring("DW_AT_".Length);
+ //var csharpName = CSharpifyName(rawName);
- string attrType = "object";
- var kind = AttributeKind.Managed;
+ string attrType = "object";
+ var kind = AttributeKind.Managed;
- if (attributeName == "DW_AT_accessibility")
- {
- attrType = "DwarfAccessibility";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_visibility")
- {
- attrType = "DwarfVisibility";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_virtuality")
- {
- attrType = "DwarfVirtuality";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_language")
- {
- attrType = "DwarfLanguageKind";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_identifier_case")
- {
- attrType = "DwarfIdentifierCaseKind";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_calling_convention")
- {
- attrType = "DwarfCallingConvention";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_inline")
- {
- attrType = "DwarfInlineKind";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_ordering")
- {
- attrType = "DwarfArrayOrderingKind";
- kind = AttributeKind.ValueType;
- }
- else if (attributeName == "DW_AT_discr_list")
- {
- attrType = "DwarfDiscriminantListKind";
- kind = AttributeKind.ValueType;
- }
- else if (attrEncodingParts.Length == 3)
+ if (attributeName == "DW_AT_accessibility")
+ {
+ attrType = "DwarfAccessibility";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_visibility")
+ {
+ attrType = "DwarfVisibility";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_virtuality")
+ {
+ attrType = "DwarfVirtuality";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_language")
+ {
+ attrType = "DwarfLanguageKind";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_identifier_case")
+ {
+ attrType = "DwarfIdentifierCaseKind";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_calling_convention")
+ {
+ attrType = "DwarfCallingConvention";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_inline")
+ {
+ attrType = "DwarfInlineKind";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_ordering")
+ {
+ attrType = "DwarfArrayOrderingKind";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attributeName == "DW_AT_discr_list")
+ {
+ attrType = "DwarfDiscriminantListKind";
+ kind = AttributeKind.ValueType;
+ }
+ else if (attrEncodingParts.Length == 3)
+ {
+ switch (attrEncodingParts[2])
{
- switch (attrEncodingParts[2])
- {
- case "string":
- attrType = "string";
- break;
+ case "string":
+ attrType = "string";
+ break;
- case "flag":
- attrType = "bool";
- kind = AttributeKind.ValueType;
- break;
+ case "flag":
+ attrType = "bool";
+ kind = AttributeKind.ValueType;
+ break;
- case "reference":
- attrType = "DwarfDIE";
- break;
+ case "reference":
+ attrType = "DwarfDIE";
+ break;
- case "address":
- attrType = "ulong";
- kind = AttributeKind.ValueType;
- break;
+ case "address":
+ attrType = "ulong";
+ kind = AttributeKind.ValueType;
+ break;
- case "constant":
- attrType = "DwarfConstant";
- kind = AttributeKind.ValueType;
- break;
+ case "constant":
+ attrType = "DwarfConstant";
+ kind = AttributeKind.ValueType;
+ break;
- case "lineptr":
- attrType = "DwarfLineProgramTable";
- break;
+ case "lineptr":
+ attrType = "DwarfLineProgramTable";
+ break;
- case "exprloc":
- attrType = "DwarfExpression";
- break;
-
- case "loclist":
- case "loclistptr":
- attrType = "DwarfLocation";
- break;
-
- case "addrptr":
- case "macptr":
- case "rnglist":
- case "rangelistptr":
- case "rnglistsptr":
- case "stroffsetsptr":
- attrType = "ulong";
- kind = AttributeKind.ValueType;
- break;
- }
- }
- else if (attrEncodingParts.Length > 3)
- {
- var key = string.Join(" ", attrEncodingParts.Skip(2).ToArray());
- alreadyDone.Add(key);
-
- Console.WriteLine(attrEncoding);
-
- bool hasConstant = false;
- for (int i = 2; i < attrEncodingParts.Length; i++)
- {
- switch (attrEncodingParts[i])
- {
- case "loclist":
- case "loclistptr":
- attrType = "DwarfLocation";
- kind = AttributeKind.ValueType;
- goto next;
- case "constant":
- hasConstant = true;
- break;
- }
- }
-
- if (hasConstant)
- {
- attrType = "DwarfConstant";
+ case "exprloc":
+ attrType = "DwarfExpression";
+ break;
+
+ case "loclist":
+ case "loclistptr":
+ attrType = "DwarfLocation";
+ break;
+
+ case "addrptr":
+ case "macptr":
+ case "rnglist":
+ case "rangelistptr":
+ case "rnglistsptr":
+ case "stroffsetsptr":
+ attrType = "ulong";
kind = AttributeKind.ValueType;
- }
+ break;
}
+ }
+ else if (attrEncodingParts.Length > 3)
+ {
+ var key = string.Join(" ", attrEncodingParts.Skip(2).ToArray());
+ alreadyDone.Add(key);
- next:
-
- MapAttributeCompactNameToType.Add(attributeName.Replace("_", string.Empty), new AttributeMapping(rawName, attrType, kind));
-
- const int PaddingEncodingName = 50;
-
- for (; currentAttributeIndex < attributeIndex; currentAttributeIndex++)
- {
- fieldArrayBuilder.AppendLine($" {"DwarfAttributeEncoding.None",-PaddingEncodingName}, // 0x{currentAttributeIndex:x2} (undefined)");
- }
+ Console.WriteLine(attrEncoding);
+ bool hasConstant = false;
for (int i = 2; i < attrEncodingParts.Length; i++)
{
- string name;
switch (attrEncodingParts[i])
{
- case "string":
- name = "String";
- break;
-
- case "flag":
- name = "Flag";
- break;
-
- case "block":
- name = "Block";
- break;
-
- case "reference":
- name = "Reference";
- break;
-
- case "address":
- name = "Address";
- break;
-
- case "constant":
- name = "Constant";
- break;
-
- case "lineptr":
- name = "LinePointer";
- break;
-
- case "exprloc":
- name = "ExpressionLocation";
- break;
-
case "loclist":
- name = "LocationList";
- break;
-
case "loclistptr":
- name = "LocationListPointer";
- break;
-
- case "loclistsptr":
- name = "LocationListsPointer";
- break;
-
- case "addrptr":
- name = "AddressPointer";
+ attrType = "DwarfLocation";
+ kind = AttributeKind.ValueType;
+ goto next;
+ case "constant":
+ hasConstant = true;
break;
+ }
+ }
- case "macptr":
- name = "MacroPointer";
- break;
+ if (hasConstant)
+ {
+ attrType = "DwarfConstant";
+ kind = AttributeKind.ValueType;
+ }
+ }
- case "rnglist":
- name = "RangeList";
- break;
+ next:
- case "rangelistptr":
- name = "RangeListPointer";
- break;
+ MapAttributeCompactNameToType.Add(attributeName.Replace("_", string.Empty), new AttributeMapping(rawName, attrType, kind));
- case "rnglistsptr":
- name = "RangeListsPointer";
- break;
+ const int PaddingEncodingName = 50;
- case "stroffsetsptr":
- name = "StringOffsetPointer";
- break;
- default:
- throw new InvalidOperationException($"Unknown encoding {attrEncodingParts[i]}");
- }
+ for (; currentAttributeIndex < attributeIndex; currentAttributeIndex++)
+ {
+ fieldArrayBuilder.AppendLine($" {"DwarfAttributeEncoding.None",-PaddingEncodingName}, // 0x{currentAttributeIndex:x2} (undefined)");
+ }
- bool isLast = i + 1 == attrEncodingParts.Length;
+ for (int i = 2; i < attrEncodingParts.Length; i++)
+ {
+ string name;
+ switch (attrEncodingParts[i])
+ {
+ case "string":
+ name = "String";
+ break;
+
+ case "flag":
+ name = "Flag";
+ break;
+
+ case "block":
+ name = "Block";
+ break;
+
+ case "reference":
+ name = "Reference";
+ break;
+
+ case "address":
+ name = "Address";
+ break;
+
+ case "constant":
+ name = "Constant";
+ break;
+
+ case "lineptr":
+ name = "LinePointer";
+ break;
+
+ case "exprloc":
+ name = "ExpressionLocation";
+ break;
+
+ case "loclist":
+ name = "LocationList";
+ break;
+
+ case "loclistptr":
+ name = "LocationListPointer";
+ break;
+
+ case "loclistsptr":
+ name = "LocationListsPointer";
+ break;
+
+ case "addrptr":
+ name = "AddressPointer";
+ break;
+
+ case "macptr":
+ name = "MacroPointer";
+ break;
+
+ case "rnglist":
+ name = "RangeList";
+ break;
+
+ case "rangelistptr":
+ name = "RangeListPointer";
+ break;
+
+ case "rnglistsptr":
+ name = "RangeListsPointer";
+ break;
+
+ case "stroffsetsptr":
+ name = "StringOffsetPointer";
+ break;
+ default:
+ throw new InvalidOperationException($"Unknown encoding {attrEncodingParts[i]}");
+ }
- fieldArrayBuilder.Append($" {"DwarfAttributeEncoding." + name + (isLast ? "" : " | "),-PaddingEncodingName}");
+ bool isLast = i + 1 == attrEncodingParts.Length;
- if (isLast)
- {
- fieldArrayBuilder.Append($", // 0x{currentAttributeIndex:x2} {attributeName} ");
- }
- fieldArrayBuilder.AppendLine();
+ fieldArrayBuilder.Append($" {"DwarfAttributeEncoding." + name + (isLast ? "" : " | "),-PaddingEncodingName}");
+ if (isLast)
+ {
+ fieldArrayBuilder.Append($", // 0x{currentAttributeIndex:x2} {attributeName} ");
}
+ fieldArrayBuilder.AppendLine();
- currentAttributeIndex++;
}
- fieldArrayBuilder.Append(" }");
- csField.InitValue = fieldArrayBuilder.ToString();
+ currentAttributeIndex++;
+ }
- Console.WriteLine();
- foreach (var key in alreadyDone.ToArray().OrderBy(x => x))
- {
- Console.WriteLine(key);
- }
+ fieldArrayBuilder.Append(" }");
+ csField.InitValue = fieldArrayBuilder.ToString();
+
+ Console.WriteLine();
+ foreach (var key in alreadyDone.ToArray().OrderBy(x => x))
+ {
+ Console.WriteLine(key);
}
+ }
- struct AttributeMapping
+ struct AttributeMapping
+ {
+ public AttributeMapping(string rawName, string attributeType, AttributeKind kind)
{
- public AttributeMapping(string rawName, string attributeType, AttributeKind kind)
- {
- RawName = rawName;
- AttributeType = attributeType;
- Kind = kind;
- }
+ RawName = rawName;
+ AttributeType = attributeType;
+ Kind = kind;
+ }
- public string RawName { get; set; }
+ public string RawName { get; set; }
- public string AttributeType { get; set; }
+ public string AttributeType { get; set; }
- public AttributeKind Kind { get; set; }
+ public AttributeKind Kind { get; set; }
- public override string ToString()
- {
- return $"{nameof(RawName)}: {RawName}, {nameof(AttributeType)}: {AttributeType}, {nameof(Kind)}: {Kind}";
- }
+ public override string ToString()
+ {
+ return $"{nameof(RawName)}: {RawName}, {nameof(AttributeType)}: {AttributeType}, {nameof(Kind)}: {Kind}";
}
+ }
- enum AttributeKind
- {
- Managed,
+ enum AttributeKind
+ {
+ Managed,
- ValueType,
+ ValueType,
- Link,
- }
+ Link,
+ }
- private static void GenerateDwarfDIE(CSharpNamespace ns)
- {
- var file = File.ReadAllLines(@"C:\code\LibObjectFile\ext\dwarf-specs\attributesbytag.tex");
+ private static void GenerateDwarfDIE(CSharpNamespace ns)
+ {
+ var file = File.ReadAllLines(@"C:\code\LibObjectFile\ext\dwarf-specs\attributesbytag.tex");
- var regexDWTag = new Regex(@"^\\(DWTAG\w+)");
- var regexDWAT = new Regex(@"^&\\(DWAT\w+)");
+ var regexDWTag = new Regex(@"^\\(DWTAG\w+)");
+ var regexDWAT = new Regex(@"^&\\(DWAT\w+)");
- int state = 0;
+ int state = 0;
- string currentCompactTagName = null;
- CSharpClass currentDIE = null;
+ string currentCompactTagName = null;
+ CSharpClass currentDIE = null;
- var dieClasses = new List();
- var dieTags = new List();
+ var dieClasses = new List();
+ var dieTags = new List();
- foreach (var line in file)
+ foreach (var line in file)
+ {
+ if (state == 0)
{
- if (state == 0)
+ if (line.StartsWith(@"\begin{longtable}"))
{
- if (line.StartsWith(@"\begin{longtable}"))
- {
- continue;
- }
- else
- {
- state = 1;
- }
+ continue;
}
- var match = regexDWTag.Match(line);
- if (match.Success)
+ else
{
- var compactTagName = match.Groups[1].Value;
- if (compactTagName == currentCompactTagName)
- {
- continue;
- }
- currentCompactTagName = compactTagName;
- var fullTagName = MapTagCompactNameToFullName[compactTagName];
- dieTags.Add(fullTagName);
- var csDIEName = fullTagName.Substring("DW_TAG_".Length);
- csDIEName = CSharpifyName(csDIEName);
- currentDIE = new CSharpClass($"DwarfDIE{csDIEName}");
- currentDIE.BaseTypes.Add(new CSharpFreeType("DwarfDIE"));
- ns.Members.Add(currentDIE);
-
- var csConstructor = new CSharpMethod(string.Empty)
- {
- Kind = CSharpMethodKind.Constructor,
- Body = (writer, element) => writer.WriteLine($"this.Tag = (DwarfTag)DwarfNative.{fullTagName};")
- };
- currentDIE.Members.Add(csConstructor);
-
- dieClasses.Add(currentDIE);
+ state = 1;
}
- else
+ }
+ var match = regexDWTag.Match(line);
+ if (match.Success)
+ {
+ var compactTagName = match.Groups[1].Value;
+ if (compactTagName == currentCompactTagName)
+ {
+ continue;
+ }
+ currentCompactTagName = compactTagName;
+ var fullTagName = MapTagCompactNameToFullName[compactTagName];
+ dieTags.Add(fullTagName);
+ var csDIEName = fullTagName.Substring("DW_TAG_".Length);
+ csDIEName = CSharpifyName(csDIEName);
+ currentDIE = new CSharpClass($"DwarfDIE{csDIEName}");
+ currentDIE.BaseTypes.Add(new CSharpFreeType("DwarfDIE"));
+ ns.Members.Add(currentDIE);
+
+ var csConstructor = new CSharpMethod(string.Empty)
{
- match = regexDWAT.Match(line);
- if (match.Success)
+ Kind = CSharpMethodKind.Constructor,
+ Body = (writer, element) => writer.WriteLine($"this.Tag = (DwarfTag)DwarfNative.{fullTagName};")
+ };
+ currentDIE.Members.Add(csConstructor);
+
+ dieClasses.Add(currentDIE);
+ }
+ else
+ {
+ match = regexDWAT.Match(line);
+ if (match.Success)
+ {
+ var compactAttrName = match.Groups[1].Value;
+ var csProperty = CreatePropertyFromDwarfAttributeName(compactAttrName);
+ currentDIE.Members.Add(csProperty);
+
+ // The DW_AT_description attribute can be used on any debugging information
+ // entry that may have a DW_AT_name attribute. For simplicity, this attribute is
+ // not explicitly shown.
+ if (compactAttrName == "DWATname")
{
- var compactAttrName = match.Groups[1].Value;
- var csProperty = CreatePropertyFromDwarfAttributeName(compactAttrName);
+ csProperty = CreatePropertyFromDwarfAttributeName("DWATdescription");
currentDIE.Members.Add(csProperty);
-
- // The DW_AT_description attribute can be used on any debugging information
- // entry that may have a DW_AT_name attribute. For simplicity, this attribute is
- // not explicitly shown.
- if (compactAttrName == "DWATname")
- {
- csProperty = CreatePropertyFromDwarfAttributeName("DWATdescription");
- currentDIE.Members.Add(csProperty);
- }
+ }
- }
- else if (currentDIE != null && line.Contains("{DECL}"))
- {
- currentDIE.BaseTypes[0] = new CSharpFreeType("DwarfDIEDeclaration");
- }
+ }
+ else if (currentDIE != null && line.Contains("{DECL}"))
+ {
+ currentDIE.BaseTypes[0] = new CSharpFreeType("DwarfDIEDeclaration");
}
}
+ }
- // Generate the DIEHelper class
- var dieHelperClass = new CSharpClass("DIEHelper")
- {
- Modifiers = CSharpModifiers.Partial | CSharpModifiers.Static,
- Visibility = CSharpVisibility.Internal
- };
- ns.Members.Add(dieHelperClass);
- var dieHelperMethod = new CSharpMethod("ConvertTagToDwarfDIE")
- {
- Modifiers = CSharpModifiers.Static,
- Visibility = CSharpVisibility.Public
- };
- dieHelperClass.Members.Add(dieHelperMethod);
+ // Generate the DIEHelper class
+ var dieHelperClass = new CSharpClass("DIEHelper")
+ {
+ Modifiers = CSharpModifiers.Partial | CSharpModifiers.Static,
+ Visibility = CSharpVisibility.Internal
+ };
+ ns.Members.Add(dieHelperClass);
+ var dieHelperMethod = new CSharpMethod("ConvertTagToDwarfDIE")
+ {
+ Modifiers = CSharpModifiers.Static,
+ Visibility = CSharpVisibility.Public
+ };
+ dieHelperClass.Members.Add(dieHelperMethod);
- dieHelperMethod.Parameters.Add(new CSharpParameter("tag") { ParameterType = CSharpPrimitiveType.UShort() });
- dieHelperMethod.ReturnType = new CSharpFreeType("DwarfDIE");
+ dieHelperMethod.Parameters.Add(new CSharpParameter("tag") { ParameterType = CSharpPrimitiveType.UShort() });
+ dieHelperMethod.ReturnType = new CSharpFreeType("DwarfDIE");
- dieHelperMethod.Body = (writer, element) => {
+ dieHelperMethod.Body = (writer, element) => {
- writer.WriteLine("switch (tag)");
- writer.OpenBraceBlock();
-
- for (var i = 0; i < dieClasses.Count; i++)
- {
- var dieCls = dieClasses[i];
- var dieTag = dieTags[i];
- writer.WriteLine($"case DwarfNative.{dieTag}:");
- writer.Indent();
- writer.WriteLine($"return new {dieCls.Name}();");
- writer.UnIndent();
- }
-
- writer.CloseBraceBlock();
- writer.WriteLine("return new DwarfDIE();");
- };
- }
+ writer.WriteLine("switch (tag)");
+ writer.OpenBraceBlock();
- private static CSharpProperty CreatePropertyFromDwarfAttributeName(string compactAttrName)
- {
- if (compactAttrName == "DWATuseUTFeight")
+ for (var i = 0; i < dieClasses.Count; i++)
{
- compactAttrName = "DWATuseUTF8";
+ var dieCls = dieClasses[i];
+ var dieTag = dieTags[i];
+ writer.WriteLine($"case DwarfNative.{dieTag}:");
+ writer.Indent();
+ writer.WriteLine($"return new {dieCls.Name}();");
+ writer.UnIndent();
}
- var map = MapAttributeCompactNameToType[compactAttrName];
- var rawAttrName = map.RawName;
- var attrType = map.AttributeType;
+ writer.CloseBraceBlock();
+ writer.WriteLine("return new DwarfDIE();");
+ };
+ }
- var propertyName = CSharpifyName(map.RawName);
+ private static CSharpProperty CreatePropertyFromDwarfAttributeName(string compactAttrName)
+ {
+ if (compactAttrName == "DWATuseUTFeight")
+ {
+ compactAttrName = "DWATuseUTF8";
+ }
- var csProperty = new CSharpProperty(propertyName)
- {
- Visibility = CSharpVisibility.Public,
- ReturnType = new CSharpFreeType(map.Kind == AttributeKind.Managed ? attrType : $"{attrType}?"),
- };
+ var map = MapAttributeCompactNameToType[compactAttrName];
+ var rawAttrName = map.RawName;
+ var attrType = map.AttributeType;
- var attrName = CSharpifyName(rawAttrName);
+ var propertyName = CSharpifyName(map.RawName);
- switch (map.Kind)
- {
- case AttributeKind.Managed:
- csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeValue<{attrType}>(DwarfAttributeKind.{attrName});");
- csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeValue<{attrType}>(DwarfAttributeKind.{attrName}, value);");
- break;
- case AttributeKind.ValueType:
- if (map.AttributeType == "DwarfConstant")
- {
- csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeConstantOpt(DwarfAttributeKind.{attrName});");
- csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeConstantOpt(DwarfAttributeKind.{attrName}, value);");
- }
- else if (map.AttributeType == "DwarfLocation")
- {
- csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeLocationOpt(DwarfAttributeKind.{attrName});");
- csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeLocationOpt(DwarfAttributeKind.{attrName}, value);");
- }
- else
- {
- csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeValueOpt<{attrType}>(DwarfAttributeKind.{attrName});");
- csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeValueOpt<{attrType}>(DwarfAttributeKind.{attrName}, value);");
- }
- break;
- case AttributeKind.Link:
- csProperty.GetBody = (writer, element) =>
- {
- writer.WriteLine($"var attr = FindAttributeByKey(DwarfAttributeKind.{attrName});");
- writer.WriteLine($"return attr == null ? null : new {attrType}(attr.ValueAsU64, attr.ValueAsObject);");
- };
- csProperty.SetBody = (writer, element) => { writer.WriteLine($"SetAttributeLinkValue(DwarfAttributeKind.{attrName}, value);"); };
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
+ var csProperty = new CSharpProperty(propertyName)
+ {
+ Visibility = CSharpVisibility.Public,
+ ReturnType = new CSharpNullableType(new CSharpFreeType(attrType)),
+ };
- return csProperty;
- }
+ var attrName = CSharpifyName(rawAttrName);
- private static string CSharpifyName(string rawName)
+ switch (map.Kind)
{
- if (rawName.EndsWith("_pc"))
- {
- rawName = rawName.Replace("_pc", "_PC");
- }
-
- var newName = new StringBuilder();
- bool upperCase = true;
- for (var i = 0; i < rawName.Length; i++)
- {
- var c = rawName[i];
- if (c == '_')
+ case AttributeKind.Managed:
+ csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeValue<{attrType}>(DwarfAttributeKind.{attrName});");
+ csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeValue<{attrType}>(DwarfAttributeKind.{attrName}, value);");
+ break;
+ case AttributeKind.ValueType:
+ if (map.AttributeType == "DwarfConstant")
{
- upperCase = true;
- continue;
+ csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeConstantOpt(DwarfAttributeKind.{attrName});");
+ csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeConstantOpt(DwarfAttributeKind.{attrName}, value);");
}
-
- if (upperCase)
+ else if (map.AttributeType == "DwarfLocation")
{
- newName.Append(char.ToUpperInvariant(c));
- upperCase = false;
+ csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeLocationOpt(DwarfAttributeKind.{attrName});");
+ csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeLocationOpt(DwarfAttributeKind.{attrName}, value);");
}
else
{
- newName.Append(c);
+ csProperty.GetBody = (writer, element) => writer.WriteLine($"return GetAttributeValueOpt<{attrType}>(DwarfAttributeKind.{attrName});");
+ csProperty.SetBody = (writer, element) => writer.WriteLine($"SetAttributeValueOpt<{attrType}>(DwarfAttributeKind.{attrName}, value);");
}
- }
- return newName.ToString();
+ break;
+ case AttributeKind.Link:
+ csProperty.GetBody = (writer, element) =>
+ {
+ writer.WriteLine($"var attr = FindAttributeByKey(DwarfAttributeKind.{attrName});");
+ writer.WriteLine($"return attr == null ? null : new {attrType}(attr.ValueAsU64, attr.ValueAsObject);");
+ };
+ csProperty.SetBody = (writer, element) => { writer.WriteLine($"SetAttributeLinkValue(DwarfAttributeKind.{attrName}, value);"); };
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
}
+ return csProperty;
+ }
- private static Dictionary MapTagCompactNameToFullName = new Dictionary()
+ private static string CSharpifyName(string rawName)
+ {
+ if (rawName.EndsWith("_pc"))
{
- {"DWTAGaccessdeclaration", "DW_TAG_access_declaration"},
- {"DWTAGarraytype", "DW_TAG_array_type"},
- {"DWTAGatomictype", "DW_TAG_atomic_type"},
- {"DWTAGbasetype", "DW_TAG_base_type"},
- {"DWTAGcallsite", "DW_TAG_call_site"},
- {"DWTAGcallsiteparameter", "DW_TAG_call_site_parameter"},
- {"DWTAGcatchblock", "DW_TAG_catch_block"},
- {"DWTAGclasstype", "DW_TAG_class_type"},
- {"DWTAGcoarraytype", "DW_TAG_coarray_type"},
- {"DWTAGcommonblock", "DW_TAG_common_block"},
- {"DWTAGcommoninclusion", "DW_TAG_common_inclusion"},
- {"DWTAGcompileunit", "DW_TAG_compile_unit"},
- {"DWTAGcondition", "DW_TAG_condition"},
- {"DWTAGconsttype", "DW_TAG_const_type"},
- {"DWTAGconstant", "DW_TAG_constant"},
- {"DWTAGdescriptortype", "DW_TAG_descriptor_type"},
- {"DWTAGdwarfprocedure", "DW_TAG_dwarf_procedure"},
- {"DWTAGdynamictype", "DW_TAG_dynamic_type"},
- {"DWTAGentrypoint", "DW_TAG_entry_point"},
- {"DWTAGenumerationtype", "DW_TAG_enumeration_type"},
- {"DWTAGenumerator", "DW_TAG_enumerator"},
- {"DWTAGfiletype", "DW_TAG_file_type"},
- {"DWTAGformalparameter", "DW_TAG_formal_parameter"},
- {"DWTAGfriend", "DW_TAG_friend"},
- {"DWTAGgenericsubrange", "DW_TAG_generic_subrange"},
- {"DWTAGhiuser", "DW_TAG_hi_user"},
- {"DWTAGimmutabletype", "DW_TAG_immutable_type"},
- {"DWTAGimporteddeclaration", "DW_TAG_imported_declaration"},
- {"DWTAGimportedmodule", "DW_TAG_imported_module"},
- {"DWTAGimportedunit", "DW_TAG_imported_unit"},
- {"DWTAGinheritance", "DW_TAG_inheritance"},
- {"DWTAGinlinedsubroutine", "DW_TAG_inlined_subroutine"},
- {"DWTAGinterfacetype", "DW_TAG_interface_type"},
- {"DWTAGlabel", "DW_TAG_label"},
- {"DWTAGlexicalblock", "DW_TAG_lexical_block"},
- {"DWTAGlouser", "DW_TAG_lo_user"},
- {"DWTAGmember", "DW_TAG_member"},
- {"DWTAGmodule", "DW_TAG_module"},
- {"DWTAGnamelist", "DW_TAG_namelist"},
- {"DWTAGnamelistitem", "DW_TAG_namelist_item"},
- {"DWTAGnamespace", "DW_TAG_namespace"},
- {"DWTAGpackedtype", "DW_TAG_packed_type"},
- {"DWTAGpartialunit", "DW_TAG_partial_unit"},
- {"DWTAGpointertype", "DW_TAG_pointer_type"},
- {"DWTAGptrtomembertype", "DW_TAG_ptr_to_member_type"},
- {"DWTAGreferencetype", "DW_TAG_reference_type"},
- {"DWTAGrestricttype", "DW_TAG_restrict_type"},
- {"DWTAGrvaluereferencetype", "DW_TAG_rvalue_reference_type"},
- {"DWTAGsettype", "DW_TAG_set_type"},
- {"DWTAGsharedtype", "DW_TAG_shared_type"},
- {"DWTAGskeletonunit", "DW_TAG_skeleton_unit"},
- {"DWTAGstringtype", "DW_TAG_string_type"},
- {"DWTAGstructuretype", "DW_TAG_structure_type"},
- {"DWTAGsubprogram", "DW_TAG_subprogram"},
- {"DWTAGsubrangetype", "DW_TAG_subrange_type"},
- {"DWTAGsubroutinetype", "DW_TAG_subroutine_type"},
- {"DWTAGtemplatealias", "DW_TAG_template_alias"},
- {"DWTAGtemplatetypeparameter", "DW_TAG_template_type_parameter"},
- {"DWTAGtemplatevalueparameter", "DW_TAG_template_value_parameter"},
- {"DWTAGthrowntype", "DW_TAG_thrown_type"},
- {"DWTAGtryblock", "DW_TAG_try_block"},
- {"DWTAGtypedef", "DW_TAG_typedef"},
- {"DWTAGtypeunit", "DW_TAG_type_unit"},
- {"DWTAGuniontype", "DW_TAG_union_type"},
- {"DWTAGunspecifiedparameters", "DW_TAG_unspecified_parameters"},
- {"DWTAGunspecifiedtype", "DW_TAG_unspecified_type"},
- {"DWTAGvariable", "DW_TAG_variable"},
- {"DWTAGvariant", "DW_TAG_variant"},
- {"DWTAGvariantpart", "DW_TAG_variant_part"},
- {"DWTAGvolatiletype", "DW_TAG_volatile_type"},
- {"DWTAGwithstmt", "DW_TAG_with_stmt"},
- };
+ rawName = rawName.Replace("_pc", "_PC");
+ }
- // Extract from Dwarf 5 specs - Figure 20, Attribute encodings
- private static readonly string[] MapAttributeToEncoding = new string[]
+ var newName = new StringBuilder();
+ bool upperCase = true;
+ for (var i = 0; i < rawName.Length; i++)
{
- "DW_AT_sibling 0x01 reference",
- "DW_AT_location 0x02 exprloc loclist",
- "DW_AT_name 0x03 string",
- "DW_AT_ordering 0x09 constant",
- "DW_AT_byte_size 0x0b constant exprloc reference",
- "DW_AT_bit_offset 0x0c constant exprloc reference",
- "DW_AT_bit_size 0x0d constant exprloc reference",
- "DW_AT_stmt_list 0x10 lineptr",
- "DW_AT_low_pc 0x11 address",
- "DW_AT_high_pc 0x12 address constant",
- "DW_AT_language 0x13 constant",
- "DW_AT_discr 0x15 reference",
- "DW_AT_discr_value 0x16 constant",
- "DW_AT_visibility 0x17 constant",
- "DW_AT_import 0x18 reference",
- "DW_AT_string_length 0x19 exprloc loclistptr",
- "DW_AT_common_reference 0x1a reference",
- "DW_AT_comp_dir 0x1b string",
- "DW_AT_const_value 0x1c block constant string ",
- "DW_AT_containing_type 0x1d reference",
- "DW_AT_default_value 0x1e reference",
- "DW_AT_inline 0x20 constant",
- "DW_AT_is_optional 0x21 flag",
- "DW_AT_lower_bound 0x22 constant exprloc reference",
- "DW_AT_producer 0x25 string",
- "DW_AT_prototyped 0x27 flag",
- "DW_AT_return_addr 0x2a exprloc loclistptr",
- "DW_AT_start_scope 0x2c constant rangelistptr",
- "DW_AT_bit_stride 0x2e constant exprloc reference",
- "DW_AT_upper_bound 0x2f constant exprloc reference",
- "DW_AT_abstract_origin 0x31 reference",
- "DW_AT_accessibility 0x32 constant",
- "DW_AT_address_class 0x33 constant",
- "DW_AT_artificial 0x34 flag",
- "DW_AT_base_types 0x35 reference",
- "DW_AT_calling_convention 0x36 constant",
- "DW_AT_count 0x37 constant exprloc reference",
- "DW_AT_data_member_location 0x38 constant exprloc loclistptr",
- "DW_AT_decl_column 0x39 constant",
- "DW_AT_decl_file 0x3a constant",
- "DW_AT_decl_line 0x3b constant",
- "DW_AT_declaration 0x3c flag",
- "DW_AT_discr_list 0x3d block",
- "DW_AT_encoding 0x3e constant",
- "DW_AT_external 0x3f flag",
- "DW_AT_frame_base 0x40 exprloc loclistptr",
- "DW_AT_friend 0x41 reference",
- "DW_AT_identifier_case 0x42 constant",
- "DW_AT_macro_info 0x43 macptr",
- "DW_AT_namelist_item 0x44 reference",
- "DW_AT_priority 0x45 reference",
- "DW_AT_segment 0x46 exprloc loclistptr",
- "DW_AT_specification 0x47 reference",
- "DW_AT_static_link 0x48 exprloc loclistptr",
- "DW_AT_type 0x49 reference",
- "DW_AT_use_location 0x4a exprloc loclistptr",
- "DW_AT_variable_parameter 0x4b flag",
- "DW_AT_virtuality 0x4c constant",
- "DW_AT_vtable_elem_location 0x4d exprloc loclistptr ",
- "DW_AT_allocated 0x4e constant exprloc reference",
- "DW_AT_associated 0x4f constant exprloc reference",
- "DW_AT_data_location 0x50 exprloc",
- "DW_AT_byte_stride 0x51 constant exprloc reference",
- "DW_AT_entry_pc 0x52 address",
- "DW_AT_use_UTF8 0x53 flag",
- "DW_AT_extension 0x54 reference",
- "DW_AT_ranges 0x55 rangelistptr",
- "DW_AT_trampoline 0x56 address flag reference string",
- "DW_AT_call_column 0x57 constant",
- "DW_AT_call_file 0x58 constant",
- "DW_AT_call_line 0x59 constant",
- "DW_AT_description 0x5a string",
- "DW_AT_binary_scale 0x5b constant",
- "DW_AT_decimal_scale 0x5c constant",
- "DW_AT_small 0x5d reference",
- "DW_AT_decimal_sign 0x5e constant",
- "DW_AT_digit_count 0x5f constant",
- "DW_AT_picture_string 0x60 string",
- "DW_AT_mutable 0x61 flag ",
- "DW_AT_threads_scaled 0x62 flag",
- "DW_AT_explicit 0x63 flag",
- "DW_AT_object_pointer 0x64 reference",
- "DW_AT_endianity 0x65 constant",
- "DW_AT_elemental 0x66 flag",
- "DW_AT_pure 0x67 flag",
- "DW_AT_recursive 0x68 flag",
- "DW_AT_signature 0x69 reference",
- "DW_AT_main_subprogram 0x6a flag",
- "DW_AT_data_bit_offset 0x6b constant",
- "DW_AT_const_expr 0x6c flag",
- "DW_AT_enum_class 0x6d flag",
- "DW_AT_linkage_name 0x6e string ",
- "DW_AT_string_length_bit_size 0x6f constant",
- "DW_AT_string_length_byte_size 0x70 constant",
- "DW_AT_rank 0x71 constant exprloc",
- "DW_AT_str_offsets_base 0x72 stroffsetsptr",
- "DW_AT_addr_base 0x73 addrptr",
- "DW_AT_rnglists_base 0x74 rnglistsptr",
- "DW_AT_dwo_name 0x76 string",
- "DW_AT_reference 0x77 flag",
- "DW_AT_rvalue_reference 0x78 flag",
- "DW_AT_macros 0x79 macptr",
- "DW_AT_call_all_calls 0x7a flag",
- "DW_AT_call_all_source_calls 0x7b flag",
- "DW_AT_call_all_tail_calls 0x7c flag",
- "DW_AT_call_return_pc 0x7d address",
- "DW_AT_call_value 0x7e exprloc",
- "DW_AT_call_origin 0x7f exprloc",
- "DW_AT_call_parameter 0x80 reference",
- "DW_AT_call_pc 0x81 address",
- "DW_AT_call_tail_call 0x82 flag",
- "DW_AT_call_target 0x83 exprloc",
- "DW_AT_call_target_clobbered 0x84 exprloc",
- "DW_AT_call_data_location 0x85 exprloc",
- "DW_AT_call_data_value 0x86 exprloc",
- "DW_AT_noreturn 0x87 flag",
- "DW_AT_alignment 0x88 constant",
- "DW_AT_export_symbols 0x89 flag",
- "DW_AT_deleted 0x8a flag",
- "DW_AT_defaulted 0x8b constant",
- "DW_AT_loclists_base 0x8c loclistsptr",
- };
+ var c = rawName[i];
+ if (c == '_')
+ {
+ upperCase = true;
+ continue;
+ }
+
+ if (upperCase)
+ {
+ newName.Append(char.ToUpperInvariant(c));
+ upperCase = false;
+ }
+ else
+ {
+ newName.Append(c);
+ }
+ }
+ return newName.ToString();
}
+
+
+ private static Dictionary MapTagCompactNameToFullName = new Dictionary()
+ {
+ {"DWTAGaccessdeclaration", "DW_TAG_access_declaration"},
+ {"DWTAGarraytype", "DW_TAG_array_type"},
+ {"DWTAGatomictype", "DW_TAG_atomic_type"},
+ {"DWTAGbasetype", "DW_TAG_base_type"},
+ {"DWTAGcallsite", "DW_TAG_call_site"},
+ {"DWTAGcallsiteparameter", "DW_TAG_call_site_parameter"},
+ {"DWTAGcatchblock", "DW_TAG_catch_block"},
+ {"DWTAGclasstype", "DW_TAG_class_type"},
+ {"DWTAGcoarraytype", "DW_TAG_coarray_type"},
+ {"DWTAGcommonblock", "DW_TAG_common_block"},
+ {"DWTAGcommoninclusion", "DW_TAG_common_inclusion"},
+ {"DWTAGcompileunit", "DW_TAG_compile_unit"},
+ {"DWTAGcondition", "DW_TAG_condition"},
+ {"DWTAGconsttype", "DW_TAG_const_type"},
+ {"DWTAGconstant", "DW_TAG_constant"},
+ {"DWTAGdescriptortype", "DW_TAG_descriptor_type"},
+ {"DWTAGdwarfprocedure", "DW_TAG_dwarf_procedure"},
+ {"DWTAGdynamictype", "DW_TAG_dynamic_type"},
+ {"DWTAGentrypoint", "DW_TAG_entry_point"},
+ {"DWTAGenumerationtype", "DW_TAG_enumeration_type"},
+ {"DWTAGenumerator", "DW_TAG_enumerator"},
+ {"DWTAGfiletype", "DW_TAG_file_type"},
+ {"DWTAGformalparameter", "DW_TAG_formal_parameter"},
+ {"DWTAGfriend", "DW_TAG_friend"},
+ {"DWTAGgenericsubrange", "DW_TAG_generic_subrange"},
+ {"DWTAGhiuser", "DW_TAG_hi_user"},
+ {"DWTAGimmutabletype", "DW_TAG_immutable_type"},
+ {"DWTAGimporteddeclaration", "DW_TAG_imported_declaration"},
+ {"DWTAGimportedmodule", "DW_TAG_imported_module"},
+ {"DWTAGimportedunit", "DW_TAG_imported_unit"},
+ {"DWTAGinheritance", "DW_TAG_inheritance"},
+ {"DWTAGinlinedsubroutine", "DW_TAG_inlined_subroutine"},
+ {"DWTAGinterfacetype", "DW_TAG_interface_type"},
+ {"DWTAGlabel", "DW_TAG_label"},
+ {"DWTAGlexicalblock", "DW_TAG_lexical_block"},
+ {"DWTAGlouser", "DW_TAG_lo_user"},
+ {"DWTAGmember", "DW_TAG_member"},
+ {"DWTAGmodule", "DW_TAG_module"},
+ {"DWTAGnamelist", "DW_TAG_namelist"},
+ {"DWTAGnamelistitem", "DW_TAG_namelist_item"},
+ {"DWTAGnamespace", "DW_TAG_namespace"},
+ {"DWTAGpackedtype", "DW_TAG_packed_type"},
+ {"DWTAGpartialunit", "DW_TAG_partial_unit"},
+ {"DWTAGpointertype", "DW_TAG_pointer_type"},
+ {"DWTAGptrtomembertype", "DW_TAG_ptr_to_member_type"},
+ {"DWTAGreferencetype", "DW_TAG_reference_type"},
+ {"DWTAGrestricttype", "DW_TAG_restrict_type"},
+ {"DWTAGrvaluereferencetype", "DW_TAG_rvalue_reference_type"},
+ {"DWTAGsettype", "DW_TAG_set_type"},
+ {"DWTAGsharedtype", "DW_TAG_shared_type"},
+ {"DWTAGskeletonunit", "DW_TAG_skeleton_unit"},
+ {"DWTAGstringtype", "DW_TAG_string_type"},
+ {"DWTAGstructuretype", "DW_TAG_structure_type"},
+ {"DWTAGsubprogram", "DW_TAG_subprogram"},
+ {"DWTAGsubrangetype", "DW_TAG_subrange_type"},
+ {"DWTAGsubroutinetype", "DW_TAG_subroutine_type"},
+ {"DWTAGtemplatealias", "DW_TAG_template_alias"},
+ {"DWTAGtemplatetypeparameter", "DW_TAG_template_type_parameter"},
+ {"DWTAGtemplatevalueparameter", "DW_TAG_template_value_parameter"},
+ {"DWTAGthrowntype", "DW_TAG_thrown_type"},
+ {"DWTAGtryblock", "DW_TAG_try_block"},
+ {"DWTAGtypedef", "DW_TAG_typedef"},
+ {"DWTAGtypeunit", "DW_TAG_type_unit"},
+ {"DWTAGuniontype", "DW_TAG_union_type"},
+ {"DWTAGunspecifiedparameters", "DW_TAG_unspecified_parameters"},
+ {"DWTAGunspecifiedtype", "DW_TAG_unspecified_type"},
+ {"DWTAGvariable", "DW_TAG_variable"},
+ {"DWTAGvariant", "DW_TAG_variant"},
+ {"DWTAGvariantpart", "DW_TAG_variant_part"},
+ {"DWTAGvolatiletype", "DW_TAG_volatile_type"},
+ {"DWTAGwithstmt", "DW_TAG_with_stmt"},
+ };
+
+ // Extract from Dwarf 5 specs - Figure 20, Attribute encodings
+ private static readonly string[] MapAttributeToEncoding = new string[]
+ {
+ "DW_AT_sibling 0x01 reference",
+ "DW_AT_location 0x02 exprloc loclist",
+ "DW_AT_name 0x03 string",
+ "DW_AT_ordering 0x09 constant",
+ "DW_AT_byte_size 0x0b constant exprloc reference",
+ "DW_AT_bit_offset 0x0c constant exprloc reference",
+ "DW_AT_bit_size 0x0d constant exprloc reference",
+ "DW_AT_stmt_list 0x10 lineptr",
+ "DW_AT_low_pc 0x11 address",
+ "DW_AT_high_pc 0x12 address constant",
+ "DW_AT_language 0x13 constant",
+ "DW_AT_discr 0x15 reference",
+ "DW_AT_discr_value 0x16 constant",
+ "DW_AT_visibility 0x17 constant",
+ "DW_AT_import 0x18 reference",
+ "DW_AT_string_length 0x19 exprloc loclistptr",
+ "DW_AT_common_reference 0x1a reference",
+ "DW_AT_comp_dir 0x1b string",
+ "DW_AT_const_value 0x1c block constant string ",
+ "DW_AT_containing_type 0x1d reference",
+ "DW_AT_default_value 0x1e reference",
+ "DW_AT_inline 0x20 constant",
+ "DW_AT_is_optional 0x21 flag",
+ "DW_AT_lower_bound 0x22 constant exprloc reference",
+ "DW_AT_producer 0x25 string",
+ "DW_AT_prototyped 0x27 flag",
+ "DW_AT_return_addr 0x2a exprloc loclistptr",
+ "DW_AT_start_scope 0x2c constant rangelistptr",
+ "DW_AT_bit_stride 0x2e constant exprloc reference",
+ "DW_AT_upper_bound 0x2f constant exprloc reference",
+ "DW_AT_abstract_origin 0x31 reference",
+ "DW_AT_accessibility 0x32 constant",
+ "DW_AT_address_class 0x33 constant",
+ "DW_AT_artificial 0x34 flag",
+ "DW_AT_base_types 0x35 reference",
+ "DW_AT_calling_convention 0x36 constant",
+ "DW_AT_count 0x37 constant exprloc reference",
+ "DW_AT_data_member_location 0x38 constant exprloc loclistptr",
+ "DW_AT_decl_column 0x39 constant",
+ "DW_AT_decl_file 0x3a constant",
+ "DW_AT_decl_line 0x3b constant",
+ "DW_AT_declaration 0x3c flag",
+ "DW_AT_discr_list 0x3d block",
+ "DW_AT_encoding 0x3e constant",
+ "DW_AT_external 0x3f flag",
+ "DW_AT_frame_base 0x40 exprloc loclistptr",
+ "DW_AT_friend 0x41 reference",
+ "DW_AT_identifier_case 0x42 constant",
+ "DW_AT_macro_info 0x43 macptr",
+ "DW_AT_namelist_item 0x44 reference",
+ "DW_AT_priority 0x45 reference",
+ "DW_AT_segment 0x46 exprloc loclistptr",
+ "DW_AT_specification 0x47 reference",
+ "DW_AT_static_link 0x48 exprloc loclistptr",
+ "DW_AT_type 0x49 reference",
+ "DW_AT_use_location 0x4a exprloc loclistptr",
+ "DW_AT_variable_parameter 0x4b flag",
+ "DW_AT_virtuality 0x4c constant",
+ "DW_AT_vtable_elem_location 0x4d exprloc loclistptr ",
+ "DW_AT_allocated 0x4e constant exprloc reference",
+ "DW_AT_associated 0x4f constant exprloc reference",
+ "DW_AT_data_location 0x50 exprloc",
+ "DW_AT_byte_stride 0x51 constant exprloc reference",
+ "DW_AT_entry_pc 0x52 address",
+ "DW_AT_use_UTF8 0x53 flag",
+ "DW_AT_extension 0x54 reference",
+ "DW_AT_ranges 0x55 rangelistptr",
+ "DW_AT_trampoline 0x56 address flag reference string",
+ "DW_AT_call_column 0x57 constant",
+ "DW_AT_call_file 0x58 constant",
+ "DW_AT_call_line 0x59 constant",
+ "DW_AT_description 0x5a string",
+ "DW_AT_binary_scale 0x5b constant",
+ "DW_AT_decimal_scale 0x5c constant",
+ "DW_AT_small 0x5d reference",
+ "DW_AT_decimal_sign 0x5e constant",
+ "DW_AT_digit_count 0x5f constant",
+ "DW_AT_picture_string 0x60 string",
+ "DW_AT_mutable 0x61 flag ",
+ "DW_AT_threads_scaled 0x62 flag",
+ "DW_AT_explicit 0x63 flag",
+ "DW_AT_object_pointer 0x64 reference",
+ "DW_AT_endianity 0x65 constant",
+ "DW_AT_elemental 0x66 flag",
+ "DW_AT_pure 0x67 flag",
+ "DW_AT_recursive 0x68 flag",
+ "DW_AT_signature 0x69 reference",
+ "DW_AT_main_subprogram 0x6a flag",
+ "DW_AT_data_bit_offset 0x6b constant",
+ "DW_AT_const_expr 0x6c flag",
+ "DW_AT_enum_class 0x6d flag",
+ "DW_AT_linkage_name 0x6e string ",
+ "DW_AT_string_length_bit_size 0x6f constant",
+ "DW_AT_string_length_byte_size 0x70 constant",
+ "DW_AT_rank 0x71 constant exprloc",
+ "DW_AT_str_offsets_base 0x72 stroffsetsptr",
+ "DW_AT_addr_base 0x73 addrptr",
+ "DW_AT_rnglists_base 0x74 rnglistsptr",
+ "DW_AT_dwo_name 0x76 string",
+ "DW_AT_reference 0x77 flag",
+ "DW_AT_rvalue_reference 0x78 flag",
+ "DW_AT_macros 0x79 macptr",
+ "DW_AT_call_all_calls 0x7a flag",
+ "DW_AT_call_all_source_calls 0x7b flag",
+ "DW_AT_call_all_tail_calls 0x7c flag",
+ "DW_AT_call_return_pc 0x7d address",
+ "DW_AT_call_value 0x7e exprloc",
+ "DW_AT_call_origin 0x7f exprloc",
+ "DW_AT_call_parameter 0x80 reference",
+ "DW_AT_call_pc 0x81 address",
+ "DW_AT_call_tail_call 0x82 flag",
+ "DW_AT_call_target 0x83 exprloc",
+ "DW_AT_call_target_clobbered 0x84 exprloc",
+ "DW_AT_call_data_location 0x85 exprloc",
+ "DW_AT_call_data_value 0x86 exprloc",
+ "DW_AT_noreturn 0x87 flag",
+ "DW_AT_alignment 0x88 constant",
+ "DW_AT_export_symbols 0x89 flag",
+ "DW_AT_deleted 0x8a flag",
+ "DW_AT_defaulted 0x8b constant",
+ "DW_AT_loclists_base 0x8c loclistsptr",
+ };
}
\ No newline at end of file
diff --git a/src/LibObjectFile.CodeGen/Program.cs b/src/LibObjectFile.CodeGen/Program.cs
index 3ff2e74..0e4182a 100644
--- a/src/LibObjectFile.CodeGen/Program.cs
+++ b/src/LibObjectFile.CodeGen/Program.cs
@@ -1,6 +1,7 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -10,317 +11,318 @@
using CppAst.CodeGen.CSharp;
using Zio.FileSystems;
-namespace LibObjectFile.CodeGen
+namespace LibObjectFile.CodeGen;
+
+partial class Program
{
- partial class Program
- {
- private const string SrcFolderRelative = @"..\..\..\..\..";
+ private const string SrcFolderRelative = @"..\..\..\..\..";
- static void Main(string[] args)
- {
- GenerateElf();
- GenerateDwarf();
- }
+ static void Main(string[] args)
+ {
+ GenerateElf();
+ GenerateDwarf();
+ }
- private static CodeWriter GetCodeWriter(string subPath)
- {
- var fs = new PhysicalFileSystem();
- var destFolder = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, SrcFolderRelative, subPath));
- var subfs = new SubFileSystem(fs, fs.ConvertPathFromInternal(destFolder));
- var codeWriter = new CodeWriter(new CodeWriterOptions(subfs));
- return codeWriter;
- }
+ private static CodeWriter GetCodeWriter(string subPath)
+ {
+ var fs = new PhysicalFileSystem();
+ var destFolder = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, SrcFolderRelative, subPath));
+ var subfs = new SubFileSystem(fs, fs.ConvertPathFromInternal(destFolder));
+ var codeWriter = new CodeWriter(new CodeWriterOptions(subfs));
+ return codeWriter;
+ }
- private static void AssertCompilation(CSharpCompilation csCompilation)
+ private static void AssertCompilation(CSharpCompilation csCompilation)
+ {
+ if (csCompilation.HasErrors)
{
- if (csCompilation.HasErrors)
+ foreach (var message in csCompilation.Diagnostics.Messages)
{
- foreach (var message in csCompilation.Diagnostics.Messages)
- {
- Console.Error.WriteLine(message);
- }
- Console.Error.WriteLine("Unexpected parsing errors");
- Environment.Exit(1);
+ Console.Error.WriteLine(message);
}
+ Console.Error.WriteLine("Unexpected parsing errors");
+ Environment.Exit(1);
}
+ }
- private static void GenerateElf()
+ private static void GenerateElf()
+ {
+ var cppOptions = new CSharpConverterOptions()
{
- var cppOptions = new CSharpConverterOptions()
+ DefaultClassLib = "ElfNative",
+ DefaultNamespace = "LibObjectFile.Elf",
+ DefaultOutputFilePath = "/LibObjectFile.Elf.generated.cs",
+ DefaultDllImportNameAndArguments = "NotUsed",
+ MappingRules =
{
- DefaultClassLib = "ElfNative",
- DefaultNamespace = "LibObjectFile.Elf",
- DefaultOutputFilePath = "/LibObjectFile.Elf.generated.cs",
- DefaultDllImportNameAndArguments = "NotUsed",
- MappingRules =
- {
- map => map.MapMacroToConst("^EI.*", "uint8_t"),
- map => map.MapMacroToConst("^ELFMAG\\d", "uint8_t"),
- map => map.MapMacroToConst("^ELFCLASS.*", "uint8_t"),
- map => map.MapMacroToConst("^ELFDATA.*", "uint8_t"),
- map => map.MapMacroToConst("^ELFOSABI.*", "uint8_t"),
- map => map.MapMacroToConst("^ET_.*", "uint16_t"),
- map => map.MapMacroToConst("^EM_.*", "uint16_t"),
- map => map.MapMacroToConst("^EV_.*", "uint8_t"),
- map => map.MapMacroToConst("^SHN_.*", "uint32_t"),
- map => map.MapMacroToConst("^SHT_.*", "uint32_t"),
- map => map.MapMacroToConst("^SHF_.*", "uint32_t"),
- map => map.MapMacroToConst("^EF_.*", "uint32_t"),
- map => map.MapMacroToConst("^PT_.*", "uint32_t"),
- map => map.MapMacroToConst("^PF_.*", "uint32_t"),
- map => map.MapMacroToConst("^NT_.*", "uint32_t"),
- map => map.MapMacroToConst("^DT_.*", "int32_t"),
- map => map.MapMacroToConst("^DF_.*", "uint32_t"),
- map => map.MapMacroToConst("^DTF_.*", "uint32_t"),
- map => map.MapMacroToConst("^VER_DEF_.*", "uint16_t"),
- map => map.MapMacroToConst("^VER_FLG_.*", "uint16_t"),
- map => map.MapMacroToConst("^VER_NDX_.*", "uint16_t"),
- map => map.MapMacroToConst("^VER_NEED_.*", "uint16_t"),
- map => map.MapMacroToConst("^ELFCOMPRESS_.*", "int32_t"),
- map => map.MapMacroToConst("^SYMINFO_.*", "uint16_t"),
- map => map.MapMacroToConst("^STB_.*", "uint8_t"),
- map => map.MapMacroToConst("^STT_.*", "uint8_t"),
- map => map.MapMacroToConst("^STN_.*", "uint8_t"),
- map => map.MapMacroToConst("^STV_.*", "uint8_t"),
- map => map.MapMacroToConst("^R_.*", "uint32_t"),
- map => map.MapMacroToConst("ELF_NOTE_OS_.*", "uint32_t"),
- }
- };
+ map => map.MapMacroToConst("^EI.*", "uint8_t"),
+ map => map.MapMacroToConst("^ELFMAG\\d", "uint8_t"),
+ map => map.MapMacroToConst("^ELFCLASS.*", "uint8_t"),
+ map => map.MapMacroToConst("^ELFDATA.*", "uint8_t"),
+ map => map.MapMacroToConst("^ELFOSABI.*", "uint8_t"),
+ map => map.MapMacroToConst("^ET_.*", "uint16_t"),
+ map => map.MapMacroToConst("^EM_.*", "uint16_t"),
+ map => map.MapMacroToConst("^EV_.*", "uint8_t"),
+ map => map.MapMacroToConst("^SHN_.*", "uint32_t"),
+ map => map.MapMacroToConst("^SHT_.*", "uint32_t"),
+ map => map.MapMacroToConst("^SHF_.*", "uint32_t"),
+ map => map.MapMacroToConst("^EF_.*", "uint32_t"),
+ map => map.MapMacroToConst("^PT_.*", "uint32_t"),
+ map => map.MapMacroToConst("^PF_.*", "uint32_t"),
+ map => map.MapMacroToConst("^NT_.*", "uint32_t"),
+ map => map.MapMacroToConst("^DT_.*", "int32_t"),
+ map => map.MapMacroToConst("^DF_.*", "uint32_t"),
+ map => map.MapMacroToConst("^DTF_.*", "uint32_t"),
+ map => map.MapMacroToConst("^VER_DEF_.*", "uint16_t"),
+ map => map.MapMacroToConst("^VER_FLG_.*", "uint16_t"),
+ map => map.MapMacroToConst("^VER_NDX_.*", "uint16_t"),
+ map => map.MapMacroToConst("^VER_NEED_.*", "uint16_t"),
+ map => map.MapMacroToConst("^ELFCOMPRESS_.*", "int32_t"),
+ map => map.MapMacroToConst("^SYMINFO_.*", "uint16_t"),
+ map => map.MapMacroToConst("^STB_.*", "uint8_t"),
+ map => map.MapMacroToConst("^STT_.*", "uint8_t"),
+ map => map.MapMacroToConst("^STN_.*", "uint8_t"),
+ map => map.MapMacroToConst("^STV_.*", "uint8_t"),
+ map => map.MapMacroToConst("^R_.*", "uint32_t"),
+ map => map.MapMacroToConst("ELF_NOTE_OS_.*", "uint32_t"),
+ }
+ };
- cppOptions.ConfigureForWindowsMsvc(CppTargetCpu.X86_64);
- cppOptions.Defines.Add("_AMD64_");
- cppOptions.Defines.Add("_TARGET_AMD64_");
- cppOptions.Defines.Add("STARK_NO_ENUM_FLAG");
- cppOptions.GenerateEnumItemAsFields = false;
- cppOptions.IncludeFolders.Add(Environment.CurrentDirectory);
+ cppOptions.ConfigureForWindowsMsvc(CppTargetCpu.X86_64);
+ cppOptions.Defines.Add("_AMD64_");
+ cppOptions.Defines.Add("_TARGET_AMD64_");
+ cppOptions.Defines.Add("STARK_NO_ENUM_FLAG");
+ cppOptions.GenerateEnumItemAsFields = false;
+ cppOptions.IncludeFolders.Add(Environment.CurrentDirectory);
- var csCompilation = CSharpConverter.Convert(@"#include ""elf.h""", cppOptions);
+ var csCompilation = CSharpConverter.Convert(@"#include ""elf.h""", cppOptions);
- AssertCompilation(csCompilation);
+ AssertCompilation(csCompilation);
- // Add pragma
- var csFile = csCompilation.Members.OfType().First();
- var ns = csFile.Members.OfType().First();
- csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#pragma warning disable 1591") );
+ // Add pragma
+ var csFile = csCompilation.Members.OfType().First();
+ var ns = csFile.Members.OfType().First();
+ csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#pragma warning disable 1591") );
+ csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#pragma warning disable CS8765"));
+ csFile.Members.Insert(csFile.Members.IndexOf(ns), new CSharpLineElement("#nullable enable"));
- ProcessEnum(cppOptions, csCompilation, "EM_", "ElfArch");
- ProcessEnum(cppOptions, csCompilation, "ELFOSABI_", "ElfOSABI");
- ProcessEnum(cppOptions, csCompilation, "R_", "ElfRelocationType");
- ProcessEnum(cppOptions, csCompilation, "NT_", "ElfNoteType");
+ ProcessEnum(cppOptions, csCompilation, "EM_", "ElfArch");
+ ProcessEnum(cppOptions, csCompilation, "ELFOSABI_", "ElfOSABI");
+ ProcessEnum(cppOptions, csCompilation, "R_", "ElfRelocationType");
+ ProcessEnum(cppOptions, csCompilation, "NT_", "ElfNoteType");
- csCompilation.DumpTo(GetCodeWriter(Path.Combine("LibObjectFile", "generated")));
- }
+ csCompilation.DumpTo(GetCodeWriter(Path.Combine("LibObjectFile", "generated")));
+ }
- private static readonly Dictionary MapRelocMachineToArch = new Dictionary()
- {
- {"R_386_", "I386"},
- {"R_X86_64_", "X86_64"},
- {"R_ARM_", "ARM"},
- {"R_AARCH64_", "AARCH64"},
- };
+ private static readonly Dictionary MapRelocMachineToArch = new Dictionary()
+ {
+ {"R_386_", "I386"},
+ {"R_X86_64_", "X86_64"},
+ {"R_ARM_", "ARM"},
+ {"R_AARCH64_", "AARCH64"},
+ };
- private static readonly Dictionary MapRelocMachineToMachine = new Dictionary()
- {
- {"R_386_", "EM_386"},
- {"R_X86_64_", "EM_X86_64"},
- {"R_ARM_", "EM_ARM"},
- {"R_AARCH64_", "EM_AARCH64"},
- };
+ private static readonly Dictionary MapRelocMachineToMachine = new Dictionary()
+ {
+ {"R_386_", "EM_386"},
+ {"R_X86_64_", "EM_X86_64"},
+ {"R_ARM_", "EM_ARM"},
+ {"R_AARCH64_", "EM_AARCH64"},
+ };
- private static void ProcessEnum(CSharpConverterOptions cppOptions, CSharpCompilation csCompilation, string enumPrefix, string enumClassName)
- {
- var ns = csCompilation.Members.OfType().First().Members.OfType().First();
+ private static void ProcessEnum(CSharpConverterOptions cppOptions, CSharpCompilation csCompilation, string enumPrefix, string enumClassName)
+ {
+ var ns = csCompilation.Members.OfType().First().Members.OfType().First();
- var rawElfClass = ns.Members.OfType().First();
+ var rawElfClass = ns.Members.OfType().First();
- var enumRawFields = rawElfClass.Members.OfType().Where(x => (x.Modifiers & CSharpModifiers.Const) != 0 && x.Name.StartsWith(enumPrefix)).ToList();
+ var enumRawFields = rawElfClass.Members.OfType().Where(x => (x.Modifiers & CSharpModifiers.Const) != 0 && x.Name.StartsWith(enumPrefix)).ToList();
- var enumClass = new CSharpStruct(enumClassName)
- {
- Modifiers = CSharpModifiers.Partial | CSharpModifiers.ReadOnly
- };
- ns.Members.Add(enumClass);
+ var enumClass = new CSharpStruct(enumClassName)
+ {
+ Modifiers = CSharpModifiers.Partial | CSharpModifiers.ReadOnly
+ };
+ ns.Members.Add(enumClass);
- CSharpEnum stdEnum = null;
+ CSharpEnum stdEnum = null;
- var enumItemType = enumRawFields[0].FieldType;
+ var enumItemType = enumRawFields[0].FieldType;
- bool isReloc = enumPrefix == "R_";
+ bool isReloc = enumPrefix == "R_";
- if (!isReloc)
+ if (!isReloc)
+ {
+ enumClass.Name = enumClass.Name + "Ex";
+ stdEnum = new CSharpEnum(enumClassName)
{
- enumClass.Name = enumClass.Name + "Ex";
- stdEnum = new CSharpEnum(enumClassName)
- {
- Visibility = CSharpVisibility.Public
- };
- ns.Members.Add(stdEnum);
- stdEnum.BaseTypes.Add(enumItemType);
- }
+ Visibility = CSharpVisibility.Public
+ };
+ ns.Members.Add(stdEnum);
+ stdEnum.BaseTypes.Add(enumItemType);
+ }
- var filteredFields = new List();
+ var filteredFields = new List();
- foreach (var enumRawField in enumRawFields)
- {
- var rawName = enumRawField.Name;
+ foreach (var enumRawField in enumRawFields)
+ {
+ var rawName = enumRawField.Name;
- string relocArch = null;
+ string relocArch = null;
- if (isReloc)
+ if (isReloc)
+ {
+ foreach (var mapReloc in MapRelocMachineToArch)
{
- foreach (var mapReloc in MapRelocMachineToArch)
- {
- if (rawName.StartsWith(mapReloc.Key))
- {
- relocArch = mapReloc.Value;
- break;
- }
- }
-
- if (relocArch == null)
+ if (rawName.StartsWith(mapReloc.Key))
{
- continue;
+ relocArch = mapReloc.Value;
+ break;
}
}
- // skip lo/hi user
- if (rawName.StartsWith("DW_") && (rawName.Contains("_lo_") || rawName.Contains("_hi_")))
+ if (relocArch == null)
{
continue;
}
+ }
- // NUM fields
- if (rawName.EndsWith("_NUM")) continue;
-
- filteredFields.Add(enumRawField);
-
- var csFieldName = isReloc ? rawName : rawName.Substring(enumPrefix.Length); // discard EM_
- if (csFieldName.StartsWith("386"))
- {
- csFieldName = $"I{csFieldName}";
- }
- else
- {
- switch (csFieldName)
- {
- case "88K":
- csFieldName = "M88K";
- break;
- case "860":
- csFieldName = "I860";
- break;
- case "960":
- csFieldName = "I960";
- break;
- default:
- // assume Motorola
- if (csFieldName.StartsWith("68"))
- {
- csFieldName = $"M{csFieldName}";
- }
+ // skip lo/hi user
+ if (rawName.StartsWith("DW_") && (rawName.Contains("_lo_") || rawName.Contains("_hi_")))
+ {
+ continue;
+ }
- break;
- }
- }
+ // NUM fields
+ if (rawName.EndsWith("_NUM")) continue;
+
+ filteredFields.Add(enumRawField);
- if (char.IsDigit(csFieldName[0]))
+ var csFieldName = isReloc ? rawName : rawName.Substring(enumPrefix.Length); // discard EM_
+ if (csFieldName.StartsWith("386"))
+ {
+ csFieldName = $"I{csFieldName}";
+ }
+ else
+ {
+ switch (csFieldName)
{
- throw new InvalidOperationException($"The enum name `{rawName}` starts with a number and needs to be modified");
- }
+ case "88K":
+ csFieldName = "M88K";
+ break;
+ case "860":
+ csFieldName = "I860";
+ break;
+ case "960":
+ csFieldName = "I960";
+ break;
+ default:
+ // assume Motorola
+ if (csFieldName.StartsWith("68"))
+ {
+ csFieldName = $"M{csFieldName}";
+ }
- if (rawName.StartsWith("DW_"))
- {
- csFieldName = CSharpifyName(csFieldName);
+ break;
}
+ }
- csFieldName = CSharpHelper.EscapeName(csFieldName);
+ if (char.IsDigit(csFieldName[0]))
+ {
+ throw new InvalidOperationException($"The enum name `{rawName}` starts with a number and needs to be modified");
+ }
- var enumField = new CSharpField(csFieldName)
- {
- Modifiers = CSharpModifiers.Static | CSharpModifiers.ReadOnly,
- FieldType = enumClass,
- Visibility = CSharpVisibility.Public,
- Comment = enumRawField.Comment,
- InitValue = relocArch != null ?
- $"new {enumClass.Name}(ElfArch.{relocArch}, {cppOptions.DefaultClassLib}.{rawName})" :
- $"new {enumClass.Name}({cppOptions.DefaultClassLib}.{rawName})"
- };
-
- enumClass.Members.Add(enumField);
-
- if (!isReloc)
- {
- var stdEnumField = new CSharpEnumItem(csFieldName, $"{cppOptions.DefaultClassLib}.{rawName}");
- stdEnum.Members.Add(stdEnumField);
- }
+ if (rawName.StartsWith("DW_"))
+ {
+ csFieldName = CSharpifyName(csFieldName);
}
- var toStringInternal = new CSharpMethod("ToStringInternal")
+ csFieldName = CSharpHelper.EscapeName(csFieldName);
+
+ var enumField = new CSharpField(csFieldName)
{
- Visibility = CSharpVisibility.Private,
- ReturnType = CSharpPrimitiveType.String()
+ Modifiers = CSharpModifiers.Static | CSharpModifiers.ReadOnly,
+ FieldType = enumClass,
+ Visibility = CSharpVisibility.Public,
+ Comment = enumRawField.Comment,
+ InitValue = relocArch != null ?
+ $"new {enumClass.Name}(ElfArch.{relocArch}, {cppOptions.DefaultClassLib}.{rawName})" :
+ $"new {enumClass.Name}({cppOptions.DefaultClassLib}.{rawName})"
};
- enumClass.Members.Add(toStringInternal);
- toStringInternal.Body = (writer, element) =>
+ enumClass.Members.Add(enumField);
+
+ if (!isReloc)
+ {
+ var stdEnumField = new CSharpEnumItem(csFieldName, $"{cppOptions.DefaultClassLib}.{rawName}");
+ stdEnum.Members.Add(stdEnumField);
+ }
+ }
+
+ var toStringInternal = new CSharpMethod("ToStringInternal")
+ {
+ Visibility = CSharpVisibility.Private,
+ ReturnType = new CSharpNullableType(CSharpPrimitiveType.String())
+ };
+ enumClass.Members.Add(toStringInternal);
+
+ toStringInternal.Body = (writer, element) =>
+ {
+ var values = new HashSet
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/LibObjectFile.Tests/LinuxUtil.cs b/src/LibObjectFile.Tests/LinuxUtil.cs
index 06205fc..2df9acb 100644
--- a/src/LibObjectFile.Tests/LinuxUtil.cs
+++ b/src/LibObjectFile.Tests/LinuxUtil.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
@@ -8,94 +8,93 @@
using System.Runtime.InteropServices;
using System.Text;
-namespace LibObjectFile.Tests
+namespace LibObjectFile.Tests;
+
+public static class LinuxUtil
{
- public static class LinuxUtil
+ public static string ReadElf(string file, string arguments = "-W -a")
+ {
+ return RunLinuxExe("readelf", $"{file} {arguments}");
+ }
+
+ public static string RunLinuxExe(string exe, string arguments, string distribution = "Ubuntu")
{
- public static string ReadElf(string file, string arguments = "-W -a")
+ if (exe == null) throw new ArgumentNullException(nameof(exe));
+ if (arguments == null) throw new ArgumentNullException(nameof(arguments));
+ if (distribution == null) throw new ArgumentNullException(nameof(distribution));
+
+ // redirect to a file the output as there is a bug reading back stdout with WSL
+ var wslOut = $"wsl_stdout_{Guid.NewGuid()}.txt";
+
+ bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+ if (isWindows)
{
- return RunLinuxExe("readelf", $"{file} {arguments}");
+ arguments = $"-d {distribution} {exe} {arguments} > {wslOut}";
+ exe = "wsl.exe";
}
- public static string RunLinuxExe(string exe, string arguments, string distribution = "Ubuntu")
+ StringBuilder? errorBuilder = null;
+ StringBuilder outputBuilder = new StringBuilder();
+
+ using (var process = new Process()
+ {
+ StartInfo = new ProcessStartInfo(exe, arguments)
+ {
+ UseShellExecute = false,
+ RedirectStandardOutput = !isWindows,
+ CreateNoWindow = true,
+ RedirectStandardError = true,
+ },
+ })
{
- if (exe == null) throw new ArgumentNullException(nameof(exe));
- if (arguments == null) throw new ArgumentNullException(nameof(arguments));
- if (distribution == null) throw new ArgumentNullException(nameof(distribution));
- // redirect to a file the output as there is a bug reading back stdout with WSL
- var wslOut = $"wsl_stdout_{Guid.NewGuid()}.txt";
-
- bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
- if (isWindows)
+ process.ErrorDataReceived += (sender, args) =>
{
- arguments = $"-d {distribution} {exe} {arguments} > {wslOut}";
- exe = "wsl.exe";
- }
+ if (errorBuilder == null)
+ {
+ errorBuilder = new StringBuilder();
+ }
- StringBuilder errorBuilder = null;
- StringBuilder outputBuilder = new StringBuilder();
+ errorBuilder.Append(args.Data).Append('\n');
+ };
- using (var process = new Process()
- {
- StartInfo = new ProcessStartInfo(exe, arguments)
- {
- UseShellExecute = false,
- RedirectStandardOutput = !isWindows,
- CreateNoWindow = true,
- RedirectStandardError = true,
- },
- })
+ if (!isWindows)
{
+ process.OutputDataReceived += (sender, args) => { outputBuilder.Append(args.Data).Append('\n'); };
+ }
- process.ErrorDataReceived += (sender, args) =>
- {
- if (errorBuilder == null)
- {
- errorBuilder = new StringBuilder();
- }
+ process.Start();
+ process.BeginErrorReadLine();
- errorBuilder.Append(args.Data).Append('\n');
- };
+ if (!isWindows)
+ {
+ process.BeginOutputReadLine();
+ }
- if (!isWindows)
- {
- process.OutputDataReceived += (sender, args) => { outputBuilder.Append(args.Data).Append('\n'); };
- }
+ process.WaitForExit();
- process.Start();
- process.BeginErrorReadLine();
+ if (process.ExitCode != 0)
+ {
+ throw new InvalidOperationException($"Error while running command `{exe} {arguments}`: {errorBuilder}");
+ }
- if (!isWindows)
+ if (isWindows)
+ {
+ var generated = Path.Combine(Environment.CurrentDirectory, wslOut);
+ var result = File.ReadAllText(generated);
+ try
{
- process.BeginOutputReadLine();
+ File.Delete(generated);
}
-
- process.WaitForExit();
-
- if (process.ExitCode != 0)
+ catch
{
- throw new InvalidOperationException($"Error while running command `{exe} {arguments}`: {errorBuilder}");
+ // ignore
}
- if (isWindows)
- {
- var generated = Path.Combine(Environment.CurrentDirectory, wslOut);
- var result = File.ReadAllText(generated);
- try
- {
- File.Delete(generated);
- }
- catch
- {
- // ignore
- }
-
- return result;
- }
+ return result;
}
-
- return outputBuilder.ToString();
}
+
+ return outputBuilder.ToString();
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile.Tests/PE/NativeConsole2Win64.exe b/src/LibObjectFile.Tests/PE/NativeConsole2Win64.exe
new file mode 100644
index 0000000..b412967
Binary files /dev/null and b/src/LibObjectFile.Tests/PE/NativeConsole2Win64.exe differ
diff --git a/src/LibObjectFile.Tests/PE/NativeConsoleWin64.exe b/src/LibObjectFile.Tests/PE/NativeConsoleWin64.exe
new file mode 100644
index 0000000..8179ecd
Binary files /dev/null and b/src/LibObjectFile.Tests/PE/NativeConsoleWin64.exe differ
diff --git a/src/LibObjectFile.Tests/PE/NativeLibraryWin64.dll b/src/LibObjectFile.Tests/PE/NativeLibraryWin64.dll
new file mode 100644
index 0000000..1185985
Binary files /dev/null and b/src/LibObjectFile.Tests/PE/NativeLibraryWin64.dll differ
diff --git a/src/LibObjectFile.Tests/PE/PEReaderTests.cs b/src/LibObjectFile.Tests/PE/PEReaderTests.cs
new file mode 100644
index 0000000..8f8d822
--- /dev/null
+++ b/src/LibObjectFile.Tests/PE/PEReaderTests.cs
@@ -0,0 +1,283 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using LibObjectFile.Diagnostics;
+using LibObjectFile.PE;
+using VerifyMSTest;
+
+namespace LibObjectFile.Tests.PE;
+
+[TestClass]
+[UsesVerify]
+public partial class PEReaderTests
+{
+ [DataTestMethod]
+ [DataRow("NativeConsoleWin64.exe")]
+ [DataRow("NativeConsole2Win64.exe")]
+ [DataRow("NativeLibraryWin64.dll")]
+ [DataRow("RawNativeConsoleWin64.exe")]
+
+ public async Task TestPrinter(string name)
+ {
+ var sourceFile = Path.Combine(AppContext.BaseDirectory, "PE", name);
+ await using var stream = File.OpenRead(sourceFile);
+ var peImage = PEFile.Read(stream, new() { EnableStackTrace = true });
+ var afterReadWriter = new StringWriter();
+ peImage.Print(afterReadWriter);
+
+ var afterReadText = afterReadWriter.ToString();
+
+ await Verifier.Verify(afterReadText).UseParameters(name);
+
+ // Update the layout
+ var diagnostics = new DiagnosticBag() { EnableStackTrace = true };
+ peImage.UpdateLayout(diagnostics);
+
+ var afterUpdateWriter = new StringWriter();
+ peImage.Print(afterUpdateWriter);
+ var afterUpdateText = afterUpdateWriter.ToString();
+
+ if (!string.Equals(afterReadText, afterUpdateText, StringComparison.Ordinal))
+ {
+ TestContext.WriteLine("Error while verifying UpdateLayout");
+ await Verifier.Verify(afterUpdateText).UseParameters(name).DisableRequireUniquePrefix();
+ }
+
+ // Read in input as raw bytes
+ stream.Position = 0;
+ var inputBuffer = new byte[stream.Length];
+ stream.ReadExactly(inputBuffer);
+
+ // Write the PE back to a byte buffer
+ var output = new MemoryStream();
+ peImage.Write(output, new PEImageWriterOptions()
+ {
+ EnableStackTrace = true,
+ EnableChecksum = peImage.OptionalHeader.CheckSum != 0 // Recalculate the checksum if it was present
+ });
+ output.Position = 0;
+ byte[] outputBuffer = output.ToArray();
+
+ // Fake an error
+ //outputBuffer[250] = 0x44;
+
+ //await Verifier.Verify(outputBuffer, sourceFile sourceFile).
+ await File.WriteAllBytesAsync($"{sourceFile}.bak", outputBuffer);
+
+ // Compare the input and output buffer
+ ByteArrayAssert.AreEqual(inputBuffer, outputBuffer, $"Invalid roundtrip for `{name}`");
+ }
+
+ [TestMethod]
+ public void TestCreatePE()
+ {
+ var pe = new PEFile();
+
+ // ***************************************************************************
+ // Code section
+ // ***************************************************************************
+ var codeSection = pe.AddSection(PESectionName.Text, 0x1000);
+ var streamCode = new PEStreamSectionData();
+
+ streamCode.Stream.Write([
+ // SUB RSP, 0x28
+ 0x48, 0x83, 0xEC, 0x28,
+ // MOV ECX, 0x9C
+ 0xB9, 0x9C, 0x00, 0x00, 0x00,
+ // CALL ExitProcess (CALL [RIP + 0xFF1])
+ 0xFF, 0x15, 0xF1, 0x0F, 0x00, 0x00,
+ // INT3
+ 0xCC
+ ]);
+
+ codeSection.Content.Add(streamCode);
+
+ // ***************************************************************************
+ // Data section
+ // ***************************************************************************
+ var dataSection = pe.AddSection(PESectionName.RData, 0x2000);
+
+ var streamData = new PEStreamSectionData();
+ var kernelName = streamData.WriteAsciiString("KERNEL32.DLL");
+ var exitProcessFunction = streamData.WriteHintName(new(0x178, "ExitProcess"));
+
+ // PEImportAddressTableDirectory comes first, it is referenced by the RIP + 0xFF1, first address being ExitProcess
+ var peImportAddressTable = new PEImportAddressTable()
+ {
+ exitProcessFunction
+ };
+ var iatDirectory = new PEImportAddressTableDirectory()
+ {
+ peImportAddressTable
+ };
+
+ var peImportLookupTable = new PEImportLookupTable()
+ {
+ exitProcessFunction
+ };
+
+ var importDirectory = new PEImportDirectory()
+ {
+ Entries =
+ {
+ new PEImportDirectoryEntry(kernelName, peImportAddressTable, peImportLookupTable)
+ }
+ };
+
+ // Layout of the data section
+ dataSection.Content.Add(iatDirectory);
+ dataSection.Content.Add(peImportLookupTable);
+ dataSection.Content.Add(importDirectory);
+ dataSection.Content.Add(streamData);
+
+ // ***************************************************************************
+ // Optional Header
+ // ***************************************************************************
+ pe.OptionalHeader.AddressOfEntryPoint = new(streamCode, 0);
+ pe.OptionalHeader.BaseOfCode = codeSection;
+
+ // ***************************************************************************
+ // Write the PE to a file
+ // ***************************************************************************
+ var output = new MemoryStream();
+ pe.Write(output, new() { EnableStackTrace = true });
+ output.Position = 0;
+
+ var sourceFile = Path.Combine(AppContext.BaseDirectory, "PE", "RawNativeConsoleWin64_Generated.exe");
+ File.WriteAllBytes(sourceFile, output.ToArray());
+
+ // Only try to run the generated exe on Windows x64
+ if (OperatingSystem.IsWindows() && RuntimeInformation.OSArchitecture == Architecture.X64)
+ {
+ // Check the generated exe
+ var process = Process.Start(sourceFile);
+ process.WaitForExit();
+ Assert.AreEqual(156, process.ExitCode);
+ }
+ }
+
+ [DataTestMethod]
+ [DynamicData(nameof(GetWindowsExeAndDlls), DynamicDataSourceType.Method)]
+ public async Task TestWindows(string sourceFile)
+ {
+ if (!OperatingSystem.IsWindows())
+ {
+ Assert.Inconclusive("This test can only run on Windows");
+ return;
+ }
+
+ TestContext.WriteLine($"Testing {sourceFile}");
+ await using var stream = File.OpenRead(sourceFile);
+ var peImage = PEFile.Read(stream, new() { EnableStackTrace = true });
+
+ if (peImage.CoffHeader.PointerToSymbolTable != 0)
+ {
+ Assert.Inconclusive($"The file {sourceFile} contains a non supported symbol table");
+ return;
+ }
+
+ var sizeOfInitializedData = peImage.OptionalHeader.SizeOfInitializedData;
+
+ // Read in input as raw bytes
+ stream.Position = 0;
+ var inputBuffer = new byte[stream.Length];
+ stream.ReadExactly(inputBuffer);
+
+ peImage.UpdateLayout(new DiagnosticBag()
+ {
+ EnableStackTrace = true
+ });
+
+ var newSizeOfInitializedData = peImage.OptionalHeader.SizeOfInitializedData;
+
+ if (newSizeOfInitializedData != sizeOfInitializedData)
+ {
+ TestContext.WriteLine($"SizeOfInitializedData changed from {sizeOfInitializedData} to {newSizeOfInitializedData}. Trying to reuse old size");
+ peImage.ForceSizeOfInitializedData = sizeOfInitializedData;
+ }
+
+ // Write the PE back to a byte buffer
+ var output = new MemoryStream();
+ peImage.Write(output, new PEImageWriterOptions()
+ {
+ EnableStackTrace = true,
+ //EnableChecksum = peImage.OptionalHeader.CheckSum != 0 // Recalculate the checksum if it was present, we cannot enable it because some DLLs have an invalid checksum
+ });
+ output.Position = 0;
+ var outputBuffer = output.ToArray();
+
+ if (!inputBuffer.AsSpan().SequenceEqual(outputBuffer))
+ {
+ // Uncomment the following code to save the output file to compare it with the original file
+ //{
+ // var dir = Path.Combine(AppContext.BaseDirectory, "Errors");
+ // Directory.CreateDirectory(dir);
+
+ // var sourceFileName = Path.GetFileName(sourceFile);
+ // var outputFileName = Path.Combine(dir, $"{sourceFileName}.new");
+
+ // await File.WriteAllBytesAsync(outputFileName, outputBuffer);
+ //}
+
+ ByteArrayAssert.AreEqual(inputBuffer, outputBuffer, $"Invalid roundtrip for `{sourceFile}`");
+ }
+ }
+
+ public static IEnumerable GetWindowsExeAndDlls()
+ {
+ if (!OperatingSystem.IsWindows())
+ {
+ yield return [""];
+ }
+ else
+ {
+
+ foreach (var file in Directory.EnumerateFiles(Environment.SystemDirectory, "*.exe", SearchOption.TopDirectoryOnly))
+ {
+ yield return [file];
+ }
+
+ foreach (var file in Directory.EnumerateFiles(Environment.SystemDirectory, "*.dll", SearchOption.TopDirectoryOnly))
+ {
+ yield return [file];
+ }
+ }
+ }
+
+ [TestMethod]
+ [Ignore("PEFile does not support PE files that are folding the PE header into the DosHeader")]
+ public async Task TestTinyExe97Bytes()
+ {
+ // http://www.phreedom.org/research/tinype/
+ // TinyPE: The smallest possible PE file
+ // 97 bytes
+ byte[] data =
+ [
+ 0x4D, 0x5A, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4C, 0x01, 0x01, 0x00, 0x6A, 0x2A, 0x58, 0xC3,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x03, 0x01, 0x0B, 0x01, 0x08, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02
+ ];
+
+ var stream = new MemoryStream();
+ stream.Write(data, 0, data.Length);
+ stream.Position = 0;
+
+ var peImage = PEFile.Read(stream);
+ var writer = new StringWriter();
+ peImage.Print(writer);
+ var afterReadText = writer.ToString();
+
+ await Verifier.Verify(afterReadText);
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile.Tests/PE/RawNativeConsoleWin64.exe b/src/LibObjectFile.Tests/PE/RawNativeConsoleWin64.exe
new file mode 100644
index 0000000..f2db2dc
Binary files /dev/null and b/src/LibObjectFile.Tests/PE/RawNativeConsoleWin64.exe differ
diff --git a/src/LibObjectFile.Tests/TestsInitializer.cs b/src/LibObjectFile.Tests/TestsInitializer.cs
new file mode 100644
index 0000000..bb8384b
--- /dev/null
+++ b/src/LibObjectFile.Tests/TestsInitializer.cs
@@ -0,0 +1,20 @@
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using VerifyMSTest;
+using VerifyTests;
+using VerifyTests.DiffPlex;
+
+namespace LibObjectFile.Tests;
+
+internal static class TestsInitializer
+{
+ [ModuleInitializer]
+ public static void Initialize()
+ {
+ VerifyDiffPlex.Initialize(OutputType.Compact);
+ CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
+ Verifier.UseProjectRelativeDirectory("Verified");
+ DiffEngine.DiffRunner.Disabled = true;
+ VerifierSettings.DontScrubSolutionDirectory();
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile.Tests/Usings.cs b/src/LibObjectFile.Tests/Usings.cs
deleted file mode 100644
index 501a06f..0000000
--- a/src/LibObjectFile.Tests/Usings.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
-// This file is licensed under the BSD-Clause 2 license.
-// See the license.txt file in the project root for more information.
-
-global using NUnit.Framework;
-global using Assert = NUnit.Framework.Legacy.ClassicAssert;
-global using CollectionAssert = NUnit.Framework.Legacy.CollectionAssert;
-global using StringAssert = NUnit.Framework.Legacy.StringAssert;
-global using DirectoryAssert = NUnit.Framework.Legacy.DirectoryAssert;
-global using FileAssert = NUnit.Framework.Legacy.FileAssert;
\ No newline at end of file
diff --git a/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsole2Win64.exe.verified.txt b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsole2Win64.exe.verified.txt
new file mode 100644
index 0000000..ed6b33c
--- /dev/null
+++ b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsole2Win64.exe.verified.txt
@@ -0,0 +1,655 @@
+DOS Header
+ Magic = DOS
+ ByteCountOnLastPage = 0x90
+ PageCount = 0x3
+ RelocationCount = 0x0
+ SizeOfParagraphsHeader = 0x4
+ MinExtraParagraphs = 0x0
+ MaxExtraParagraphs = 0xFFFF
+ InitialSSValue = 0x0
+ InitialSPValue = 0xB8
+ Checksum = 0x0
+ InitialIPValue = 0x0
+ InitialCSValue = 0x0
+ FileAddressRelocationTable = 0x40
+ OverlayNumber = 0x0
+ Reserved = 0x0, 0x0, 0x0, 0x0
+ OEMIdentifier = 0x0
+ OEMInformation = 0x0
+ Reserved2 = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+ FileAddressPEHeader = 0xF8
+
+DOS Stub
+ DosStub = 64 bytes
+
+COFF Header
+ Machine = Amd64
+ NumberOfSections = 6
+ TimeDateStamp = 1727802524
+ PointerToSymbolTable = 0x0
+ NumberOfSymbols = 0
+ SizeOfOptionalHeader = 240
+ Characteristics = ExecutableImage, LargeAddressAware
+
+Optional Header
+ Magic = PE32Plus
+ MajorLinkerVersion = 14
+ MinorLinkerVersion = 41
+ SizeOfCode = 0x1A00
+ SizeOfInitializedData = 0x2A00
+ SizeOfUninitializedData = 0x0
+ AddressOfEntryPoint = RVA = 0x15E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x5E0
+ BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x1A00, Content[1] }
+ BaseOfData = 0x0x0
+ ImageBase = 0x140000000
+ SectionAlignment = 0x1000
+ FileAlignment = 0x200
+ MajorOperatingSystemVersion = 6
+ MinorOperatingSystemVersion = 0
+ MajorImageVersion = 0
+ MinorImageVersion = 0
+ MajorSubsystemVersion = 6
+ MinorSubsystemVersion = 0
+ Win32VersionValue = 0x0
+ SizeOfImage = 0x9000
+ SizeOfHeaders = 0x400
+ CheckSum = 0x7C57
+ Subsystem = WindowsCui
+ DllCharacteristics = HighEntropyVirtualAddressSpace, DynamicBase, NxCompatible, TerminalServerAware
+ SizeOfStackReserve = 0x100000
+ SizeOfStackCommit = 0x1000
+ SizeOfHeapReserve = 0x100000
+ SizeOfHeapCommit = 0x1000
+ LoaderFlags = 0x0
+ NumberOfRvaAndSizes = 0x10
+
+Data Directories
+ [00] = null
+ [01] = PEImportDirectory Position = 0x00002B3C, Size = 0x000000C8, RVA = 0x00003D3C, VirtualSize = 0x000000C8
+ [02] = PEResourceDirectory Position = 0x00003E00, Size = 0x000001E0, RVA = 0x00007000, VirtualSize = 0x000001E0
+ [03] = PEExceptionDirectory Position = 0x00003A00, Size = 0x00000210, RVA = 0x00006000, VirtualSize = 0x00000210
+ [04] = null
+ [05] = PEBaseRelocationDirectory Position = 0x00004000, Size = 0x0000003C, RVA = 0x00008000, VirtualSize = 0x0000003C
+ [06] = PEDebugDirectory Position = 0x000022E0, Size = 0x00000070, RVA = 0x000034E0, VirtualSize = 0x00000070
+ [07] = null
+ [08] = null
+ [09] = null
+ [10] = PELoadConfigDirectory64 Position = 0x00002190, Size = 0x00000140, RVA = 0x00003390, VirtualSize = 0x00000140
+ [11] = null
+ [12] = PEImportAddressTableDirectory Position = 0x00001E00, Size = 0x00000250, RVA = 0x00003000, VirtualSize = 0x00000250
+ [13] = PEDelayImportDirectory Position = 0x000029A8, Size = 0x00000040, RVA = 0x00003BA8, VirtualSize = 0x00000040
+ [14] = null
+ [15] = null
+
+Section Headers
+ [00] .text PESection Position = 0x00000400, Size = 0x00001A00, RVA = 0x00001000, VirtualSize = 0x000019E9, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+ [01] .rdata PESection Position = 0x00001E00, Size = 0x00001A00, RVA = 0x00003000, VirtualSize = 0x0000183C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [02] .data PESection Position = 0x00003800, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x000006D0, Characteristics = 0xC0000040 (ContainsInitializedData, MemRead, MemWrite)
+ [03] .pdata PESection Position = 0x00003A00, Size = 0x00000400, RVA = 0x00006000, VirtualSize = 0x00000210, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [04] .rsrc PESection Position = 0x00003E00, Size = 0x00000200, RVA = 0x00007000, VirtualSize = 0x000001E0, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [05] .reloc PESection Position = 0x00004000, Size = 0x00000200, RVA = 0x00008000, VirtualSize = 0x0000003C, Characteristics = 0x42000040 (ContainsInitializedData, MemDiscardable, MemRead)
+
+Sections
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [00] .text PESection Position = 0x00000400, Size = 0x00001A00, RVA = 0x00001000, VirtualSize = 0x000019E9, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+
+ [00] PEStreamSectionData Position = 0x00000400, Size = 0x000019E9, RVA = 0x00001000, VirtualSize = 0x000019E9
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [01] .rdata PESection Position = 0x00001E00, Size = 0x00001A00, RVA = 0x00003000, VirtualSize = 0x0000183C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEImportAddressTableDirectory Position = 0x00001E00, Size = 0x00000250, RVA = 0x00003000, VirtualSize = 0x00000250
+ [00] PEImportAddressTable Position = 0x00001E00, Size = 0x000000C0, RVA = 0x00003000, VirtualSize = 0x000000C0
+ [0] PEImportHintName { Hint = 997, Name = LoadLibraryExA } (RVA = 0x482A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7D2)
+ [1] PEImportHintName { Hint = 1277, Name = RtlLookupFunctionEntry } (RVA = 0x4654, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5FC)
+ [2] PEImportHintName { Hint = 1284, Name = RtlVirtualUnwind } (RVA = 0x466E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x616)
+ [3] PEImportHintName { Hint = 1510, Name = UnhandledExceptionFilter } (RVA = 0x4682, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x62A)
+ [4] PEImportHintName { Hint = 1444, Name = SetUnhandledExceptionFilter } (RVA = 0x469E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x646)
+ [5] PEImportHintName { Hint = 562, Name = GetCurrentProcess } (RVA = 0x46BC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x664)
+ [6] PEImportHintName { Hint = 1476, Name = TerminateProcess } (RVA = 0x46D0, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x678)
+ [7] PEImportHintName { Hint = 936, Name = IsProcessorFeaturePresent } (RVA = 0x46E4, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x68C)
+ [8] PEImportHintName { Hint = 1136, Name = QueryPerformanceCounter } (RVA = 0x4700, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6A8)
+ [9] PEImportHintName { Hint = 563, Name = GetCurrentProcessId } (RVA = 0x471A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6C2)
+ [10] PEImportHintName { Hint = 567, Name = GetCurrentThreadId } (RVA = 0x4730, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6D8)
+ [11] PEImportHintName { Hint = 778, Name = GetSystemTimeAsFileTime } (RVA = 0x4746, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6EE)
+ [12] PEImportHintName { Hint = 906, Name = InitializeSListHead } (RVA = 0x4760, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x708)
+ [13] PEImportHintName { Hint = 928, Name = IsDebuggerPresent } (RVA = 0x4776, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x71E)
+ [14] PEImportHintName { Hint = 661, Name = GetModuleHandleW } (RVA = 0x478A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x732)
+ [15] PEImportHintName { Hint = 1159, Name = RaiseException } (RVA = 0x47B6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x75E)
+ [16] PEImportHintName { Hint = 637, Name = GetLastError } (RVA = 0x47C8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x770)
+ [17] PEImportHintName { Hint = 717, Name = GetProcAddress } (RVA = 0x4818, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7C0)
+ [18] PEImportHintName { Hint = 453, Name = FreeLibrary } (RVA = 0x480A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7B2)
+ [19] PEImportHintName { Hint = 1543, Name = VirtualQuery } (RVA = 0x47FA, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7A2)
+ [20] PEImportHintName { Hint = 1541, Name = VirtualProtect } (RVA = 0x47E8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x790)
+ [21] PEImportHintName { Hint = 772, Name = GetSystemInfo } (RVA = 0x47D8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x780)
+ [22] PEImportHintName { Hint = 1269, Name = RtlCaptureContext } (RVA = 0x4640, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5E8)
+
+ [01] PEImportAddressTable Position = 0x00001EC0, Size = 0x00000068, RVA = 0x000030C0, VirtualSize = 0x00000068
+ [0] PEImportHintName { Hint = 255, Name = ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@H@Z } (RVA = 0x42D6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x27E)
+ [1] PEImportHintName { Hint = 262, Name = ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z } (RVA = 0x4282, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x22A)
+ [2] PEImportHintName { Hint = 1221, Name = ?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QEAAXH_N@Z } (RVA = 0x4242, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x1EA)
+ [3] PEImportHintName { Hint = 872, Name = ?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@XZ } (RVA = 0x41FE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x1A6)
+ [4] PEImportHintName { Hint = 580, Name = ?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAXXZ } (RVA = 0x41C0, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x168)
+ [5] PEImportHintName { Hint = 1246, Name = ?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAHD@Z } (RVA = 0x417E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x126)
+ [6] PEImportHintName { Hint = 1121, Name = ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@D@Z } (RVA = 0x413A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0xE2)
+ [7] PEImportHintName { Hint = 1332, Name = ?widen@?$basic_ios@DU?$char_traits@D@std@@@std@@QEBADD@Z } (RVA = 0x40FE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0xA6)
+ [8] PEImportHintName { Hint = 1249, Name = ?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAA_JPEBD_J@Z } (RVA = 0x40B6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5E)
+ [9] PEImportHintName { Hint = 1310, Name = ?uncaught_exception@std@@YA_NXZ } (RVA = 0x4094, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3C)
+ [10] PEImportHintName { Hint = 965, Name = ?good@ios_base@std@@QEBA_NXZ } (RVA = 0x4318, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x2C0)
+ [11] PEImportHintName { Hint = 692, Name = ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A } (RVA = 0x4058, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x0)
+
+ [02] PEImportAddressTable Position = 0x00001F28, Size = 0x00000038, RVA = 0x00003128, VirtualSize = 0x00000038
+ [0] PEImportHintName { Hint = 60, Name = memcpy } (RVA = 0x47AC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x754)
+ [1] PEImportHintName { Hint = 28, Name = __current_exception_context } (RVA = 0x439C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x344)
+ [2] PEImportHintName { Hint = 62, Name = memset } (RVA = 0x43BA, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x362)
+ [3] PEImportHintName { Hint = 8, Name = __C_specific_handler } (RVA = 0x436E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x316)
+ [4] PEImportHintName { Hint = 27, Name = __current_exception } (RVA = 0x4386, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x32E)
+ [5] PEImportHintName { Hint = 35, Name = __std_terminate } (RVA = 0x435C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x304)
+
+ [03] PEImportAddressTable Position = 0x00001F60, Size = 0x00000010, RVA = 0x00003160, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 0, Name = __CxxFrameHandler4 } (RVA = 0x4346, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x2EE)
+
+ [04] PEImportAddressTable Position = 0x00001F70, Size = 0x00000010, RVA = 0x00003170, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 22, Name = _set_new_mode } (RVA = 0x452A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4D2)
+
+ [05] PEImportAddressTable Position = 0x00001F80, Size = 0x00000010, RVA = 0x00003180, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 8, Name = _configthreadlocale } (RVA = 0x4514, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4BC)
+
+ [06] PEImportAddressTable Position = 0x00001F90, Size = 0x00000010, RVA = 0x00003190, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 9, Name = __setusermatherr } (RVA = 0x440C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3B4)
+
+ [07] PEImportAddressTable Position = 0x00001FA0, Size = 0x00000098, RVA = 0x000031A0, VirtualSize = 0x00000098
+ [0] PEImportHintName { Hint = 5, Name = __p___argv } (RVA = 0x44C4, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x46C)
+ [1] PEImportHintName { Hint = 60, Name = _register_onexit_function } (RVA = 0x4566, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x50E)
+ [2] PEImportHintName { Hint = 52, Name = _initialize_onexit_table } (RVA = 0x454A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4F2)
+ [3] PEImportHintName { Hint = 35, Name = _exit } (RVA = 0x44A0, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x448)
+ [4] PEImportHintName { Hint = 55, Name = _initterm_e } (RVA = 0x448A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x432)
+ [5] PEImportHintName { Hint = 54, Name = _initterm } (RVA = 0x447E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x426)
+ [6] PEImportHintName { Hint = 40, Name = _get_initial_narrow_environment } (RVA = 0x445C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x404)
+ [7] PEImportHintName { Hint = 51, Name = _initialize_narrow_environment } (RVA = 0x443A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3E2)
+ [8] PEImportHintName { Hint = 24, Name = _configure_narrow_argv } (RVA = 0x4420, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3C8)
+ [9] PEImportHintName { Hint = 22, Name = _cexit } (RVA = 0x44D2, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x47A)
+ [10] PEImportHintName { Hint = 66, Name = _set_app_type } (RVA = 0x43FC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3A4)
+ [11] PEImportHintName { Hint = 64, Name = _seh_filter_exe } (RVA = 0x43EA, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x392)
+ [12] PEImportHintName { Hint = 103, Name = terminate } (RVA = 0x4590, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x538)
+ [13] PEImportHintName { Hint = 85, Name = exit } (RVA = 0x4498, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x440)
+ [14] PEImportHintName { Hint = 30, Name = _crt_atexit } (RVA = 0x4582, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x52A)
+ [15] PEImportHintName { Hint = 4, Name = __p___argc } (RVA = 0x44B6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x45E)
+ [16] PEImportHintName { Hint = 61, Name = _register_thread_local_exe_atexit_callback } (RVA = 0x44E6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x48E)
+ [17] PEImportHintName { Hint = 21, Name = _c_exit } (RVA = 0x44DC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x484)
+
+ [08] PEImportAddressTable Position = 0x00002038, Size = 0x00000018, RVA = 0x00003238, VirtualSize = 0x00000018
+ [0] PEImportHintName { Hint = 1, Name = __p__commode } (RVA = 0x453A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4E2)
+ [1] PEImportHintName { Hint = 84, Name = _set_fmode } (RVA = 0x44A8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x450)
+
+
+ [01] PEStreamSectionData Position = 0x00002050, Size = 0x00000140, RVA = 0x00003250, VirtualSize = 0x00000140
+
+ [02] PELoadConfigDirectory64 Position = 0x00002190, Size = 0x00000140, RVA = 0x00003390, VirtualSize = 0x00000140
+ Size = 0x140
+ TimeDateStamp = 0x0
+ MajorVersion = 0
+ MinorVersion = 0
+ GlobalFlagsClear = 0x0
+ GlobalFlagsSet = 0x0
+ CriticalSectionDefaultTimeout = 0x0
+ DeCommitFreeBlockThreshold = 0x0
+ DeCommitTotalFreeThreshold = 0x0
+ LockPrefixTable = 0x0x0
+ MaximumAllocationSize = 0x0
+ VirtualMemoryThreshold = 0x0
+ ProcessAffinityMask = 0x0
+ ProcessHeapFlags = 0x0
+ CSDVersion = 0
+ DependentLoadFlags = 0x0
+ EditList = 0x0
+ SecurityCookie = 0x140005000
+ SEHandlerTable = 0x0
+ SEHandlerCount = 0x0
+ GuardCFCheckFunctionPointer = 0x140003250
+ GuardCFDispatchFunctionPointer = 0x140003260
+ GuardCFFunctionTable = 0x0
+ GuardCFFunctionCount = 0x0
+ GuardFlags = Instrumented
+ TableSizeShift = 0x0
+ CodeIntegrity.Flags = 0x0
+ CodeIntegrity.Catalog = 0x0
+ CodeIntegrity.CatalogOffset = 0x0
+ CodeIntegrity.Reserved = 0x0
+ GuardAddressTakenIatEntryTable = 0x0
+ GuardAddressTakenIatEntryCount = 0x0
+ GuardLongJumpTargetTable = 0x0
+ GuardLongJumpTargetCount = 0x0
+ DynamicValueRelocTable = 0x0
+ CHPEMetadataPointer = 0x0
+ GuardRFFailureRoutine = 0x0
+ GuardRFFailureRoutineFunctionPointer = 0x0
+ DynamicValueRelocTableOffset = 0x0
+ DynamicValueRelocTableSection = 0
+ Reserved2 = 0
+ GuardRFVerifyStackPointerFunctionPointer = 0x0
+ HotPatchTableOffset = 0x0
+ Reserved3 = 0x0
+ EnclaveConfigurationPointer = 0x0
+ VolatileMetadataPointer = 0x140003580
+ GuardEHContinuationTable = 0x0
+ GuardEHContinuationCount = 0x0
+ GuardXFGCheckFunctionPointer = 0x140003258
+ GuardXFGDispatchFunctionPointer = 0x140003268
+ GuardXFGTableDispatchFunctionPointer = 0x140003270
+ CastGuardOsDeterminedFailureMode = 0x140003278
+ GuardMemcpyFunctionPointer = 0x140003280
+
+ [03] PEStreamSectionData Position = 0x000022D0, Size = 0x00000010, RVA = 0x000034D0, VirtualSize = 0x00000010
+
+ [04] PEDebugDirectory Position = 0x000022E0, Size = 0x00000070, RVA = 0x000034E0, VirtualSize = 0x00000070
+ [0] Type = CodeView, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FC2C9C, Data = RVA = 0x00003618 (PEDebugSectionDataRSDS[6] -> .rdata)
+ [1] Type = VCFeature, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FC2C9C, Data = RVA = 0x0000368C (PEDebugStreamSectionData[8] -> .rdata)
+ [2] Type = POGO, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FC2C9C, Data = RVA = 0x000036A0 (PEDebugStreamSectionData[9] -> .rdata)
+ [3] Type = ILTCG, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FC2C9C, Data = null
+
+ [05] PEStreamSectionData Position = 0x00002350, Size = 0x000000C8, RVA = 0x00003550, VirtualSize = 0x000000C8
+
+ [06] PEDebugSectionDataRSDS Position = 0x00002418, Size = 0x00000072, RVA = 0x00003618, VirtualSize = 0x00000072
+ Debug Section Data (RSDS)
+ Guid = ffed6f99-5708-452c-a889-ff343b6ce898
+ Age = 7
+ PdbPath = C:\code\LibObjectFile\src\native\Win64\NativeProjects\x64\Release\NativeConsole2Win64.pdb
+
+ [07] PEStreamSectionData Position = 0x0000248A, Size = 0x00000002, RVA = 0x0000368A, VirtualSize = 0x00000002
+
+ [08] PEDebugStreamSectionData Position = 0x0000248C, Size = 0x00000014, RVA = 0x0000368C, VirtualSize = 0x00000014
+
+ [09] PEDebugStreamSectionData Position = 0x000024A0, Size = 0x000002FC, RVA = 0x000036A0, VirtualSize = 0x000002FC
+
+ [10] PEStreamSectionData Position = 0x0000279C, Size = 0x0000020C, RVA = 0x0000399C, VirtualSize = 0x0000020C
+
+ [11] PEDelayImportDirectory Position = 0x000029A8, Size = 0x00000040, RVA = 0x00003BA8, VirtualSize = 0x00000040
+ [0] DllName = NativeLibraryWin64.dll, RVA = 0x32E0
+ [0] Attributes = 1
+ [0] DelayImportAddressTable RVA = 0x00005078 (PEBoundImportAddressTable64[1] -> .data)
+ [0] DelayImportNameTable RVA = 0x00003BE8 (PEImportLookupTable[12] -> .rdata)
+ [0] BoundImportAddressTable RVA = 0x3C20, PEStreamSectionData { RVA = 0x3C00, VirtualSize = 0x13C, Position = 0x2A00, Size = 0x13C }, Offset = 0x20
+ [0] UnloadDelayInformationTable
+
+
+ [12] PEImportLookupTable Position = 0x000029E8, Size = 0x00000018, RVA = 0x00003BE8, VirtualSize = 0x00000018
+ [0] PEImportHintName { Hint = 0, Name = AnotherFunction } (RVA = 0x3C0E, PEStreamSectionData { RVA = 0x3C00, VirtualSize = 0x13C, Position = 0x2A00, Size = 0x13C }, Offset = 0xE)
+ [1] PEImportHintName { Hint = 1, Name = HelloWorld } (RVA = 0x3C00, PEStreamSectionData { RVA = 0x3C00, VirtualSize = 0x13C, Position = 0x2A00, Size = 0x13C }, Offset = 0x0)
+
+ [13] PEStreamSectionData Position = 0x00002A00, Size = 0x0000013C, RVA = 0x00003C00, VirtualSize = 0x0000013C
+
+ [14] PEImportDirectory Position = 0x00002B3C, Size = 0x000000C8, RVA = 0x00003D3C, VirtualSize = 0x000000C8
+ [0] ImportDllNameLink = MSVCP140.dll (RVA = 0x4338, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x2E0)
+ [0] ImportAddressTable = RVA = 0x000030C0 (PEImportAddressTable[1] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [0] ImportLookupTable = RVA = 0x00003EC8 (PEImportLookupTable[17] -> .rdata)
+
+ [1] ImportDllNameLink = VCRUNTIME140_1.dll (RVA = 0x43C4, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x36C)
+ [1] ImportAddressTable = RVA = 0x00003160 (PEImportAddressTable[3] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [1] ImportLookupTable = RVA = 0x00003F68 (PEImportLookupTable[19] -> .rdata)
+
+ [2] ImportDllNameLink = VCRUNTIME140.dll (RVA = 0x43D8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x380)
+ [2] ImportAddressTable = RVA = 0x00003128 (PEImportAddressTable[2] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [2] ImportLookupTable = RVA = 0x00003F30 (PEImportLookupTable[18] -> .rdata)
+
+ [3] ImportDllNameLink = api-ms-win-crt-runtime-l1-1-0.dll (RVA = 0x459C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x544)
+ [3] ImportAddressTable = RVA = 0x000031A0 (PEImportAddressTable[7] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [3] ImportLookupTable = RVA = 0x00003FA8 (PEImportLookupTable[23] -> .rdata)
+
+ [4] ImportDllNameLink = api-ms-win-crt-math-l1-1-0.dll (RVA = 0x45BE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x566)
+ [4] ImportAddressTable = RVA = 0x00003190 (PEImportAddressTable[6] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [4] ImportLookupTable = RVA = 0x00003F98 (PEImportLookupTable[22] -> .rdata)
+
+ [5] ImportDllNameLink = api-ms-win-crt-stdio-l1-1-0.dll (RVA = 0x45DE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x586)
+ [5] ImportAddressTable = RVA = 0x00003238 (PEImportAddressTable[8] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [5] ImportLookupTable = RVA = 0x00004040 (PEImportLookupTable[24] -> .rdata)
+
+ [6] ImportDllNameLink = api-ms-win-crt-locale-l1-1-0.dll (RVA = 0x45FE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5A6)
+ [6] ImportAddressTable = RVA = 0x00003180 (PEImportAddressTable[5] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [6] ImportLookupTable = RVA = 0x00003F88 (PEImportLookupTable[21] -> .rdata)
+
+ [7] ImportDllNameLink = api-ms-win-crt-heap-l1-1-0.dll (RVA = 0x4620, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5C8)
+ [7] ImportAddressTable = RVA = 0x00003170 (PEImportAddressTable[4] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [7] ImportLookupTable = RVA = 0x00003F78 (PEImportLookupTable[20] -> .rdata)
+
+ [8] ImportDllNameLink = KERNEL32.dll (RVA = 0x479E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x746)
+ [8] ImportAddressTable = RVA = 0x00003000 (PEImportAddressTable[0] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [8] ImportLookupTable = RVA = 0x00003E08 (PEImportLookupTable[16] -> .rdata)
+
+
+ [15] PEStreamSectionData Position = 0x00002C04, Size = 0x00000004, RVA = 0x00003E04, VirtualSize = 0x00000004
+
+ [16] PEImportLookupTable Position = 0x00002C08, Size = 0x000000C0, RVA = 0x00003E08, VirtualSize = 0x000000C0
+ [0] PEImportHintName { Hint = 997, Name = LoadLibraryExA } (RVA = 0x482A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7D2)
+ [1] PEImportHintName { Hint = 1277, Name = RtlLookupFunctionEntry } (RVA = 0x4654, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5FC)
+ [2] PEImportHintName { Hint = 1284, Name = RtlVirtualUnwind } (RVA = 0x466E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x616)
+ [3] PEImportHintName { Hint = 1510, Name = UnhandledExceptionFilter } (RVA = 0x4682, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x62A)
+ [4] PEImportHintName { Hint = 1444, Name = SetUnhandledExceptionFilter } (RVA = 0x469E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x646)
+ [5] PEImportHintName { Hint = 562, Name = GetCurrentProcess } (RVA = 0x46BC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x664)
+ [6] PEImportHintName { Hint = 1476, Name = TerminateProcess } (RVA = 0x46D0, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x678)
+ [7] PEImportHintName { Hint = 936, Name = IsProcessorFeaturePresent } (RVA = 0x46E4, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x68C)
+ [8] PEImportHintName { Hint = 1136, Name = QueryPerformanceCounter } (RVA = 0x4700, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6A8)
+ [9] PEImportHintName { Hint = 563, Name = GetCurrentProcessId } (RVA = 0x471A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6C2)
+ [10] PEImportHintName { Hint = 567, Name = GetCurrentThreadId } (RVA = 0x4730, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6D8)
+ [11] PEImportHintName { Hint = 778, Name = GetSystemTimeAsFileTime } (RVA = 0x4746, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x6EE)
+ [12] PEImportHintName { Hint = 906, Name = InitializeSListHead } (RVA = 0x4760, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x708)
+ [13] PEImportHintName { Hint = 928, Name = IsDebuggerPresent } (RVA = 0x4776, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x71E)
+ [14] PEImportHintName { Hint = 661, Name = GetModuleHandleW } (RVA = 0x478A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x732)
+ [15] PEImportHintName { Hint = 1159, Name = RaiseException } (RVA = 0x47B6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x75E)
+ [16] PEImportHintName { Hint = 637, Name = GetLastError } (RVA = 0x47C8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x770)
+ [17] PEImportHintName { Hint = 717, Name = GetProcAddress } (RVA = 0x4818, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7C0)
+ [18] PEImportHintName { Hint = 453, Name = FreeLibrary } (RVA = 0x480A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7B2)
+ [19] PEImportHintName { Hint = 1543, Name = VirtualQuery } (RVA = 0x47FA, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x7A2)
+ [20] PEImportHintName { Hint = 1541, Name = VirtualProtect } (RVA = 0x47E8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x790)
+ [21] PEImportHintName { Hint = 772, Name = GetSystemInfo } (RVA = 0x47D8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x780)
+ [22] PEImportHintName { Hint = 1269, Name = RtlCaptureContext } (RVA = 0x4640, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5E8)
+
+ [17] PEImportLookupTable Position = 0x00002CC8, Size = 0x00000068, RVA = 0x00003EC8, VirtualSize = 0x00000068
+ [0] PEImportHintName { Hint = 255, Name = ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@H@Z } (RVA = 0x42D6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x27E)
+ [1] PEImportHintName { Hint = 262, Name = ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z } (RVA = 0x4282, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x22A)
+ [2] PEImportHintName { Hint = 1221, Name = ?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QEAAXH_N@Z } (RVA = 0x4242, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x1EA)
+ [3] PEImportHintName { Hint = 872, Name = ?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@XZ } (RVA = 0x41FE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x1A6)
+ [4] PEImportHintName { Hint = 580, Name = ?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAXXZ } (RVA = 0x41C0, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x168)
+ [5] PEImportHintName { Hint = 1246, Name = ?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAHD@Z } (RVA = 0x417E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x126)
+ [6] PEImportHintName { Hint = 1121, Name = ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@D@Z } (RVA = 0x413A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0xE2)
+ [7] PEImportHintName { Hint = 1332, Name = ?widen@?$basic_ios@DU?$char_traits@D@std@@@std@@QEBADD@Z } (RVA = 0x40FE, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0xA6)
+ [8] PEImportHintName { Hint = 1249, Name = ?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAA_JPEBD_J@Z } (RVA = 0x40B6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x5E)
+ [9] PEImportHintName { Hint = 1310, Name = ?uncaught_exception@std@@YA_NXZ } (RVA = 0x4094, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3C)
+ [10] PEImportHintName { Hint = 965, Name = ?good@ios_base@std@@QEBA_NXZ } (RVA = 0x4318, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x2C0)
+ [11] PEImportHintName { Hint = 692, Name = ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A } (RVA = 0x4058, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x0)
+
+ [18] PEImportLookupTable Position = 0x00002D30, Size = 0x00000038, RVA = 0x00003F30, VirtualSize = 0x00000038
+ [0] PEImportHintName { Hint = 60, Name = memcpy } (RVA = 0x47AC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x754)
+ [1] PEImportHintName { Hint = 28, Name = __current_exception_context } (RVA = 0x439C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x344)
+ [2] PEImportHintName { Hint = 62, Name = memset } (RVA = 0x43BA, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x362)
+ [3] PEImportHintName { Hint = 8, Name = __C_specific_handler } (RVA = 0x436E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x316)
+ [4] PEImportHintName { Hint = 27, Name = __current_exception } (RVA = 0x4386, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x32E)
+ [5] PEImportHintName { Hint = 35, Name = __std_terminate } (RVA = 0x435C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x304)
+
+ [19] PEImportLookupTable Position = 0x00002D68, Size = 0x00000010, RVA = 0x00003F68, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 0, Name = __CxxFrameHandler4 } (RVA = 0x4346, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x2EE)
+
+ [20] PEImportLookupTable Position = 0x00002D78, Size = 0x00000010, RVA = 0x00003F78, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 22, Name = _set_new_mode } (RVA = 0x452A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4D2)
+
+ [21] PEImportLookupTable Position = 0x00002D88, Size = 0x00000010, RVA = 0x00003F88, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 8, Name = _configthreadlocale } (RVA = 0x4514, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4BC)
+
+ [22] PEImportLookupTable Position = 0x00002D98, Size = 0x00000010, RVA = 0x00003F98, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 9, Name = __setusermatherr } (RVA = 0x440C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3B4)
+
+ [23] PEImportLookupTable Position = 0x00002DA8, Size = 0x00000098, RVA = 0x00003FA8, VirtualSize = 0x00000098
+ [0] PEImportHintName { Hint = 5, Name = __p___argv } (RVA = 0x44C4, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x46C)
+ [1] PEImportHintName { Hint = 60, Name = _register_onexit_function } (RVA = 0x4566, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x50E)
+ [2] PEImportHintName { Hint = 52, Name = _initialize_onexit_table } (RVA = 0x454A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4F2)
+ [3] PEImportHintName { Hint = 35, Name = _exit } (RVA = 0x44A0, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x448)
+ [4] PEImportHintName { Hint = 55, Name = _initterm_e } (RVA = 0x448A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x432)
+ [5] PEImportHintName { Hint = 54, Name = _initterm } (RVA = 0x447E, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x426)
+ [6] PEImportHintName { Hint = 40, Name = _get_initial_narrow_environment } (RVA = 0x445C, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x404)
+ [7] PEImportHintName { Hint = 51, Name = _initialize_narrow_environment } (RVA = 0x443A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3E2)
+ [8] PEImportHintName { Hint = 24, Name = _configure_narrow_argv } (RVA = 0x4420, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3C8)
+ [9] PEImportHintName { Hint = 22, Name = _cexit } (RVA = 0x44D2, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x47A)
+ [10] PEImportHintName { Hint = 66, Name = _set_app_type } (RVA = 0x43FC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x3A4)
+ [11] PEImportHintName { Hint = 64, Name = _seh_filter_exe } (RVA = 0x43EA, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x392)
+ [12] PEImportHintName { Hint = 103, Name = terminate } (RVA = 0x4590, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x538)
+ [13] PEImportHintName { Hint = 85, Name = exit } (RVA = 0x4498, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x440)
+ [14] PEImportHintName { Hint = 30, Name = _crt_atexit } (RVA = 0x4582, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x52A)
+ [15] PEImportHintName { Hint = 4, Name = __p___argc } (RVA = 0x44B6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x45E)
+ [16] PEImportHintName { Hint = 61, Name = _register_thread_local_exe_atexit_callback } (RVA = 0x44E6, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x48E)
+ [17] PEImportHintName { Hint = 21, Name = _c_exit } (RVA = 0x44DC, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x484)
+
+ [24] PEImportLookupTable Position = 0x00002E40, Size = 0x00000018, RVA = 0x00004040, VirtualSize = 0x00000018
+ [0] PEImportHintName { Hint = 1, Name = __p__commode } (RVA = 0x453A, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x4E2)
+ [1] PEImportHintName { Hint = 84, Name = _set_fmode } (RVA = 0x44A8, PEStreamSectionData { RVA = 0x4058, VirtualSize = 0x7E4, Position = 0x2E58, Size = 0x7E4 }, Offset = 0x450)
+
+ [25] PEStreamSectionData Position = 0x00002E58, Size = 0x000007E4, RVA = 0x00004058, VirtualSize = 0x000007E4
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [02] .data PESection Position = 0x00003800, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x000006D0, Characteristics = 0xC0000040 (ContainsInitializedData, MemRead, MemWrite)
+
+ [00] PEStreamSectionData Position = 0x00003800, Size = 0x00000078, RVA = 0x00005000, VirtualSize = 0x00000078
+
+ [01] PEBoundImportAddressTable64 Position = 0x00003878, Size = 0x00000018, RVA = 0x00005078, VirtualSize = 0x00000018
+ [0] VA = 0x14000133E
+ [1] VA = 0x140001332
+
+ [02] PEStreamSectionData Position = 0x00003890, Size = 0x00000170, RVA = 0x00005090, VirtualSize = 0x00000170
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [03] .pdata PESection Position = 0x00003A00, Size = 0x00000400, RVA = 0x00006000, VirtualSize = 0x00000210, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEExceptionDirectory Position = 0x00003A00, Size = 0x00000210, RVA = 0x00006000, VirtualSize = 0x00000210
+ [0] Begin = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x0
+ [0] End = RVA = 0x104B, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x4B
+ [0] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [1] Begin = RVA = 0x1050, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x50
+ [1] End = RVA = 0x108E, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x8E
+ [1] UnwindInfoAddress = RVA = 0x39C8, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x2C
+
+ [2] Begin = RVA = 0x1090, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x90
+ [2] End = RVA = 0x10B4, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xB4
+ [2] UnwindInfoAddress = RVA = 0x39EC, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x50
+
+ [3] Begin = RVA = 0x10C0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xC0
+ [3] End = RVA = 0x1272, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x272
+ [3] UnwindInfoAddress = RVA = 0x3A04, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x68
+
+ [4] Begin = RVA = 0x1280, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x280
+ [4] End = RVA = 0x12B9, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x2B9
+ [4] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [5] Begin = RVA = 0x12B9, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x2B9
+ [5] End = RVA = 0x1330, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x330
+ [5] UnwindInfoAddress = RVA = 0x3A64, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xC8
+
+ [6] Begin = RVA = 0x1360, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x360
+ [6] End = RVA = 0x137E, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x37E
+ [6] UnwindInfoAddress = RVA = 0x3A70, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD4
+
+ [7] Begin = RVA = 0x1380, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x380
+ [7] End = RVA = 0x1436, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x436
+ [7] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [8] Begin = RVA = 0x1438, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x438
+ [8] End = RVA = 0x1448, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x448
+ [8] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [9] Begin = RVA = 0x1448, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x448
+ [9] End = RVA = 0x1461, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x461
+ [9] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [10] Begin = RVA = 0x1464, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x464
+ [10] End = RVA = 0x15E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x5E0
+ [10] UnwindInfoAddress = RVA = 0x3A7C, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xE0
+
+ [11] Begin = RVA = 0x15E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x5E0
+ [11] End = RVA = 0x15F2, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x5F2
+ [11] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [12] Begin = RVA = 0x15F4, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x5F4
+ [12] End = RVA = 0x1628, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x628
+ [12] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [13] Begin = RVA = 0x1628, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x628
+ [13] End = RVA = 0x16FB, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x6FB
+ [13] UnwindInfoAddress = RVA = 0x3ABC, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x120
+
+ [14] Begin = RVA = 0x16FC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x6FC
+ [14] End = RVA = 0x176D, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x76D
+ [14] UnwindInfoAddress = RVA = 0x3AC4, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x128
+
+ [15] Begin = RVA = 0x1770, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x770
+ [15] End = RVA = 0x17A9, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x7A9
+ [15] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [16] Begin = RVA = 0x17AC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x7AC
+ [16] End = RVA = 0x17E6, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x7E6
+ [16] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [17] Begin = RVA = 0x17E8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x7E8
+ [17] End = RVA = 0x1873, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x873
+ [17] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [18] Begin = RVA = 0x1874, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x874
+ [18] End = RVA = 0x190C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x90C
+ [18] UnwindInfoAddress = RVA = 0x3AD0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x134
+
+ [19] Begin = RVA = 0x190C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x90C
+ [19] End = RVA = 0x1930, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x930
+ [19] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [20] Begin = RVA = 0x1930, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x930
+ [20] End = RVA = 0x1959, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x959
+ [20] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [21] Begin = RVA = 0x195C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x95C
+ [21] End = RVA = 0x1996, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x996
+ [21] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [22] Begin = RVA = 0x1998, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x998
+ [22] End = RVA = 0x19AF, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x9AF
+ [22] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [23] Begin = RVA = 0x19B0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x9B0
+ [23] End = RVA = 0x1A5C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xA5C
+ [23] UnwindInfoAddress = RVA = 0x3AF8, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x15C
+
+ [24] Begin = RVA = 0x1A98, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xA98
+ [24] End = RVA = 0x1AB3, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xAB3
+ [24] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [25] Begin = RVA = 0x1AD8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xAD8
+ [25] End = RVA = 0x1C20, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xC20
+ [25] UnwindInfoAddress = RVA = 0x3B04, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x168
+
+ [26] Begin = RVA = 0x1C28, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xC28
+ [26] End = RVA = 0x1C79, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xC79
+ [26] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [27] Begin = RVA = 0x1C8C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xC8C
+ [27] End = RVA = 0x1CE7, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xCE7
+ [27] UnwindInfoAddress = RVA = 0x3B14, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x178
+
+ [28] Begin = RVA = 0x1CE8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xCE8
+ [28] End = RVA = 0x1D24, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xD24
+ [28] UnwindInfoAddress = RVA = 0x3B14, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x178
+
+ [29] Begin = RVA = 0x1D24, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xD24
+ [29] End = RVA = 0x1D60, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xD60
+ [29] UnwindInfoAddress = RVA = 0x3B14, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x178
+
+ [30] Begin = RVA = 0x1D60, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0xD60
+ [30] End = RVA = 0x202A, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x102A
+ [30] UnwindInfoAddress = RVA = 0x3B20, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x184
+
+ [31] Begin = RVA = 0x20F0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x10F0
+ [31] End = RVA = 0x21DB, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x11DB
+ [31] UnwindInfoAddress = RVA = 0x3B94, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x1F8
+
+ [32] Begin = RVA = 0x21DC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x11DC
+ [32] End = RVA = 0x2296, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1296
+ [32] UnwindInfoAddress = RVA = 0x39C0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x24
+
+ [33] Begin = RVA = 0x2298, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1298
+ [33] End = RVA = 0x2336, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1336
+ [33] UnwindInfoAddress = RVA = 0x3B14, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x178
+
+ [34] Begin = RVA = 0x2338, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1338
+ [34] End = RVA = 0x23D0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x13D0
+ [34] UnwindInfoAddress = RVA = 0x3B54, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x1B8
+
+ [35] Begin = RVA = 0x23D0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x13D0
+ [35] End = RVA = 0x246A, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x146A
+ [35] UnwindInfoAddress = RVA = 0x3B44, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x1A8
+
+ [36] Begin = RVA = 0x246C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x146C
+ [36] End = RVA = 0x2563, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1563
+ [36] UnwindInfoAddress = RVA = 0x3B60, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x1C4
+
+ [37] Begin = RVA = 0x2564, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1564
+ [37] End = RVA = 0x260D, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x160D
+ [37] UnwindInfoAddress = RVA = 0x3A74, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xD8
+
+ [38] Begin = RVA = 0x2610, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1610
+ [38] End = RVA = 0x290C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x190C
+ [38] UnwindInfoAddress = RVA = 0x3B78, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x1DC
+
+ [39] Begin = RVA = 0x2930, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1930
+ [39] End = RVA = 0x2932, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1932
+ [39] UnwindInfoAddress = RVA = 0x3B38, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x19C
+
+ [40] Begin = RVA = 0x2950, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1950
+ [40] End = RVA = 0x2956, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1956
+ [40] UnwindInfoAddress = RVA = 0x3B40, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x1A4
+
+ [41] Begin = RVA = 0x2978, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x1978
+ [41] End = RVA = 0x29B3, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x19B3
+ [41] UnwindInfoAddress = RVA = 0x3A5C, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0xC0
+
+ [42] Begin = RVA = 0x29B3, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x19B3
+ [42] End = RVA = 0x29D1, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x19D1
+ [42] UnwindInfoAddress = RVA = 0x3AB4, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x118
+
+ [43] Begin = RVA = 0x29D1, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x19D1
+ [43] End = RVA = 0x29E9, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x19E9
+ [43] UnwindInfoAddress = RVA = 0x3AF0, PEStreamSectionData { RVA = 0x399C, VirtualSize = 0x20C, Position = 0x279C, Size = 0x20C }, Offset = 0x154
+
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [04] .rsrc PESection Position = 0x00003E00, Size = 0x00000200, RVA = 0x00007000, VirtualSize = 0x000001E0, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEResourceDirectory Position = 0x00003E00, Size = 0x000001E0, RVA = 0x00007000, VirtualSize = 0x000001E0
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x18, Entry = PEResourceDirectoryEntry { RVA = 0x7018, VirtualSize = 0x18, Position = 0x3E18, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
+ [00] PEResourceDirectoryEntry Position = 0x00003E18, Size = 0x00000018, RVA = 0x00007018, VirtualSize = 0x00000018
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x1, Entry = PEResourceDirectoryEntry { RVA = 0x7030, VirtualSize = 0x18, Position = 0x3E30, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
+
+ [01] PEResourceDirectoryEntry Position = 0x00003E30, Size = 0x00000018, RVA = 0x00007030, VirtualSize = 0x00000018
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x409, Entry = PEResourceDataEntry { RVA = 0x7048, VirtualSize = 0x10, Position = 0x3E48, Size = 0x10, CodePage = , Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x3E60, Size = 0x17D } }
+
+ [02] PEResourceDataEntry Position = 0x00003E48, Size = 0x00000010, RVA = 0x00007048, VirtualSize = 0x00000010
+ > CodePage = null, Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x3E60, Size = 0x17D }
+
+ [03] PEStreamSectionData Position = 0x00003E58, Size = 0x00000008, RVA = 0x00007058, VirtualSize = 0x00000008
+
+ [04] PEResourceData Position = 0x00003E60, Size = 0x0000017D, RVA = 0x00007060, VirtualSize = 0x0000017D
+
+ [05] PEStreamSectionData Position = 0x00003FDD, Size = 0x00000003, RVA = 0x000071DD, VirtualSize = 0x00000003
+
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [05] .reloc PESection Position = 0x00004000, Size = 0x00000200, RVA = 0x00008000, VirtualSize = 0x0000003C, Characteristics = 0x42000040 (ContainsInitializedData, MemDiscardable, MemRead)
+
+ [00] PEBaseRelocationDirectory Position = 0x00004000, Size = 0x0000003C, RVA = 0x00008000, VirtualSize = 0x0000003C
+ [00] PEBaseRelocationBlock Position = 0x00004000, Size = 0x00000030, RVA = 0x00008000, VirtualSize = 0x00000030
+ Block 0x3000 Relocations[20]
+ [000] Dir64 Offset = 0x0250, RVA = 0x3250 (0x0000000140001A84), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [001] Dir64 Offset = 0x0258, RVA = 0x3258 (0x0000000140001A84), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [002] Dir64 Offset = 0x0260, RVA = 0x3260 (0x0000000140002930), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [003] Dir64 Offset = 0x0268, RVA = 0x3268 (0x0000000140002950), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [004] Dir64 Offset = 0x0270, RVA = 0x3270 (0x0000000140002950), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [005] Dir64 Offset = 0x0280, RVA = 0x3280 (0x000000014000290C), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [006] Dir64 Offset = 0x0290, RVA = 0x3290 (0x0000000140001448), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [007] Dir64 Offset = 0x02A8, RVA = 0x32A8 (0x0000000140001380), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [008] Dir64 Offset = 0x02B0, RVA = 0x32B0 (0x0000000140001438), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [009] Dir64 Offset = 0x02F8, RVA = 0x32F8 (0x00000001400050A0), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [010] Dir64 Offset = 0x0300, RVA = 0x3300 (0x0000000140005140), SectionData = { RVA = 0x00003250 (PEStreamSectionData[1] -> .rdata) }
+ [011] Dir64 Offset = 0x03E8, RVA = 0x33E8 (0x0000000140005000), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [012] Dir64 Offset = 0x0400, RVA = 0x3400 (0x0000000140003250), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [013] Dir64 Offset = 0x0408, RVA = 0x3408 (0x0000000140003260), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [014] Dir64 Offset = 0x0490, RVA = 0x3490 (0x0000000140003580), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [015] Dir64 Offset = 0x04A8, RVA = 0x34A8 (0x0000000140003258), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [016] Dir64 Offset = 0x04B0, RVA = 0x34B0 (0x0000000140003268), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [017] Dir64 Offset = 0x04B8, RVA = 0x34B8 (0x0000000140003270), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [018] Dir64 Offset = 0x04C0, RVA = 0x34C0 (0x0000000140003278), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+ [019] Dir64 Offset = 0x04C8, RVA = 0x34C8 (0x0000000140003280), SectionData = { RVA = 0x00003390 (PELoadConfigDirectory64[2] -> .rdata) }
+
+ [01] PEBaseRelocationBlock Position = 0x00004030, Size = 0x0000000C, RVA = 0x00008030, VirtualSize = 0x0000000C
+ Block 0x5000 Relocations[2]
+ [000] Dir64 Offset = 0x0078, RVA = 0x5078 (0x000000014000133E), SectionData = { RVA = 0x00005078 (PEBoundImportAddressTable64[1] -> .data) }
+ [001] Dir64 Offset = 0x0080, RVA = 0x5080 (0x0000000140001332), SectionData = { RVA = 0x00005078 (PEBoundImportAddressTable64[1] -> .data) }
+
+
diff --git a/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsoleWin64.exe.verified.txt b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsoleWin64.exe.verified.txt
new file mode 100644
index 0000000..e4a0e93
--- /dev/null
+++ b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsoleWin64.exe.verified.txt
@@ -0,0 +1,563 @@
+DOS Header
+ Magic = DOS
+ ByteCountOnLastPage = 0x90
+ PageCount = 0x3
+ RelocationCount = 0x0
+ SizeOfParagraphsHeader = 0x4
+ MinExtraParagraphs = 0x0
+ MaxExtraParagraphs = 0xFFFF
+ InitialSSValue = 0x0
+ InitialSPValue = 0xB8
+ Checksum = 0x0
+ InitialIPValue = 0x0
+ InitialCSValue = 0x0
+ FileAddressRelocationTable = 0x40
+ OverlayNumber = 0x0
+ Reserved = 0x0, 0x0, 0x0, 0x0
+ OEMIdentifier = 0x0
+ OEMInformation = 0x0
+ Reserved2 = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+ FileAddressPEHeader = 0xF8
+
+DOS Stub
+ DosStub = 64 bytes
+
+COFF Header
+ Machine = Amd64
+ NumberOfSections = 6
+ TimeDateStamp = 1727077439
+ PointerToSymbolTable = 0x0
+ NumberOfSymbols = 0
+ SizeOfOptionalHeader = 240
+ Characteristics = ExecutableImage, LargeAddressAware
+
+Optional Header
+ Magic = PE32Plus
+ MajorLinkerVersion = 14
+ MinorLinkerVersion = 41
+ SizeOfCode = 0x1200
+ SizeOfInitializedData = 0x2200
+ SizeOfUninitializedData = 0x0
+ AddressOfEntryPoint = RVA = 0x14E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x4E0
+ BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x1200, Content[1] }
+ BaseOfData = 0x0x0
+ ImageBase = 0x140000000
+ SectionAlignment = 0x1000
+ FileAlignment = 0x200
+ MajorOperatingSystemVersion = 6
+ MinorOperatingSystemVersion = 0
+ MajorImageVersion = 0
+ MinorImageVersion = 0
+ MajorSubsystemVersion = 6
+ MinorSubsystemVersion = 0
+ Win32VersionValue = 0x0
+ SizeOfImage = 0x9000
+ SizeOfHeaders = 0x400
+ CheckSum = 0x0
+ Subsystem = WindowsCui
+ DllCharacteristics = HighEntropyVirtualAddressSpace, DynamicBase, NxCompatible, TerminalServerAware
+ SizeOfStackReserve = 0x100000
+ SizeOfStackCommit = 0x1000
+ SizeOfHeapReserve = 0x100000
+ SizeOfHeapCommit = 0x1000
+ LoaderFlags = 0x0
+ NumberOfRvaAndSizes = 0x10
+
+Data Directories
+ [00] = null
+ [01] = PEImportDirectory Position = 0x00001F84, Size = 0x000000C8, RVA = 0x00003984, VirtualSize = 0x000000C8
+ [02] = PEResourceDirectory Position = 0x00002E00, Size = 0x000001E0, RVA = 0x00007000, VirtualSize = 0x000001E0
+ [03] = PEExceptionDirectory Position = 0x00002C00, Size = 0x00000198, RVA = 0x00006000, VirtualSize = 0x00000198
+ [04] = null
+ [05] = PEBaseRelocationDirectory Position = 0x00003000, Size = 0x00000030, RVA = 0x00008000, VirtualSize = 0x00000030
+ [06] = PEDebugDirectory Position = 0x000019F0, Size = 0x00000070, RVA = 0x000033F0, VirtualSize = 0x00000070
+ [07] = null
+ [08] = null
+ [09] = null
+ [10] = PELoadConfigDirectory64 Position = 0x000018B0, Size = 0x00000140, RVA = 0x000032B0, VirtualSize = 0x00000140
+ [11] = null
+ [12] = PEImportAddressTableDirectory Position = 0x00001600, Size = 0x000001F0, RVA = 0x00003000, VirtualSize = 0x000001F0
+ [13] = null
+ [14] = null
+ [15] = null
+
+Section Headers
+ [00] .text PESection Position = 0x00000400, Size = 0x00001200, RVA = 0x00001000, VirtualSize = 0x000010C9, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+ [01] .rdata PESection Position = 0x00001600, Size = 0x00001400, RVA = 0x00003000, VirtualSize = 0x00001288, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [02] .data PESection Position = 0x00002A00, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x00000680, Characteristics = 0xC0000040 (ContainsInitializedData, MemRead, MemWrite)
+ [03] .pdata PESection Position = 0x00002C00, Size = 0x00000200, RVA = 0x00006000, VirtualSize = 0x00000198, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [04] .rsrc PESection Position = 0x00002E00, Size = 0x00000200, RVA = 0x00007000, VirtualSize = 0x000001E0, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [05] .reloc PESection Position = 0x00003000, Size = 0x00000200, RVA = 0x00008000, VirtualSize = 0x00000030, Characteristics = 0x42000040 (ContainsInitializedData, MemDiscardable, MemRead)
+
+Sections
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [00] .text PESection Position = 0x00000400, Size = 0x00001200, RVA = 0x00001000, VirtualSize = 0x000010C9, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+
+ [00] PEStreamSectionData Position = 0x00000400, Size = 0x000010C9, RVA = 0x00001000, VirtualSize = 0x000010C9
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [01] .rdata PESection Position = 0x00001600, Size = 0x00001400, RVA = 0x00003000, VirtualSize = 0x00001288, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEImportAddressTableDirectory Position = 0x00001600, Size = 0x000001F0, RVA = 0x00003000, VirtualSize = 0x000001F0
+ [00] PEImportAddressTable Position = 0x00001600, Size = 0x00000080, RVA = 0x00003000, VirtualSize = 0x00000080
+ [0] PEImportHintName { Hint = 1269, Name = RtlCaptureContext } (RVA = 0x4112, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x4D2)
+ [1] PEImportHintName { Hint = 1136, Name = QueryPerformanceCounter } (RVA = 0x41D2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x592)
+ [2] PEImportHintName { Hint = 563, Name = GetCurrentProcessId } (RVA = 0x41EC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5AC)
+ [3] PEImportHintName { Hint = 567, Name = GetCurrentThreadId } (RVA = 0x4202, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5C2)
+ [4] PEImportHintName { Hint = 778, Name = GetSystemTimeAsFileTime } (RVA = 0x4218, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5D8)
+ [5] PEImportHintName { Hint = 906, Name = InitializeSListHead } (RVA = 0x4232, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5F2)
+ [6] PEImportHintName { Hint = 928, Name = IsDebuggerPresent } (RVA = 0x4248, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x608)
+ [7] PEImportHintName { Hint = 661, Name = GetModuleHandleW } (RVA = 0x425C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x61C)
+ [8] PEImportHintName { Hint = 1476, Name = TerminateProcess } (RVA = 0x41A2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x562)
+ [9] PEImportHintName { Hint = 562, Name = GetCurrentProcess } (RVA = 0x418E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x54E)
+ [10] PEImportHintName { Hint = 1444, Name = SetUnhandledExceptionFilter } (RVA = 0x4170, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x530)
+ [11] PEImportHintName { Hint = 1510, Name = UnhandledExceptionFilter } (RVA = 0x4154, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x514)
+ [12] PEImportHintName { Hint = 1284, Name = RtlVirtualUnwind } (RVA = 0x4140, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x500)
+ [13] PEImportHintName { Hint = 1277, Name = RtlLookupFunctionEntry } (RVA = 0x4126, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x4E6)
+ [14] PEImportHintName { Hint = 936, Name = IsProcessorFeaturePresent } (RVA = 0x41B6, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x576)
+
+ [01] PEImportAddressTable Position = 0x00001680, Size = 0x00000048, RVA = 0x00003080, VirtualSize = 0x00000048
+ [0] PEImportHintName { Hint = 692, Name = ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A } (RVA = 0x3C40, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x0)
+ [1] PEImportHintName { Hint = 1246, Name = ?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAHD@Z } (RVA = 0x3DA8, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x168)
+ [2] PEImportHintName { Hint = 1221, Name = ?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QEAAXH_N@Z } (RVA = 0x3D68, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x128)
+ [3] PEImportHintName { Hint = 1249, Name = ?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAA_JPEBD_J@Z } (RVA = 0x3D20, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0xE0)
+ [4] PEImportHintName { Hint = 872, Name = ?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@XZ } (RVA = 0x3CDC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x9C)
+ [5] PEImportHintName { Hint = 580, Name = ?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAXXZ } (RVA = 0x3C9E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5E)
+ [6] PEImportHintName { Hint = 1310, Name = ?uncaught_exception@std@@YA_NXZ } (RVA = 0x3C7C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3C)
+ [7] PEImportHintName { Hint = 965, Name = ?good@ios_base@std@@QEBA_NXZ } (RVA = 0x3DEA, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1AA)
+
+ [02] PEImportAddressTable Position = 0x000016C8, Size = 0x00000038, RVA = 0x000030C8, VirtualSize = 0x00000038
+ [0] PEImportHintName { Hint = 8, Name = __C_specific_handler } (RVA = 0x3E40, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x200)
+ [1] PEImportHintName { Hint = 35, Name = __std_terminate } (RVA = 0x3E2E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1EE)
+ [2] PEImportHintName { Hint = 60, Name = memcpy } (RVA = 0x427E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x63E)
+ [3] PEImportHintName { Hint = 28, Name = __current_exception_context } (RVA = 0x3E6E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x22E)
+ [4] PEImportHintName { Hint = 27, Name = __current_exception } (RVA = 0x3E58, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x218)
+ [5] PEImportHintName { Hint = 62, Name = memset } (RVA = 0x3E8C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x24C)
+
+ [03] PEImportAddressTable Position = 0x00001700, Size = 0x00000010, RVA = 0x00003100, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 0, Name = __CxxFrameHandler4 } (RVA = 0x3E18, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1D8)
+
+ [04] PEImportAddressTable Position = 0x00001710, Size = 0x00000010, RVA = 0x00003110, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 22, Name = _set_new_mode } (RVA = 0x3FFC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3BC)
+
+ [05] PEImportAddressTable Position = 0x00001720, Size = 0x00000010, RVA = 0x00003120, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 8, Name = _configthreadlocale } (RVA = 0x3FE6, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3A6)
+
+ [06] PEImportAddressTable Position = 0x00001730, Size = 0x00000010, RVA = 0x00003130, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 9, Name = __setusermatherr } (RVA = 0x3EDE, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x29E)
+
+ [07] PEImportAddressTable Position = 0x00001740, Size = 0x00000098, RVA = 0x00003140, VirtualSize = 0x00000098
+ [0] PEImportHintName { Hint = 103, Name = terminate } (RVA = 0x4062, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x422)
+ [1] PEImportHintName { Hint = 30, Name = _crt_atexit } (RVA = 0x4054, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x414)
+ [2] PEImportHintName { Hint = 60, Name = _register_onexit_function } (RVA = 0x4038, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3F8)
+ [3] PEImportHintName { Hint = 52, Name = _initialize_onexit_table } (RVA = 0x401C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3DC)
+ [4] PEImportHintName { Hint = 21, Name = _c_exit } (RVA = 0x3FAE, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x36E)
+ [5] PEImportHintName { Hint = 22, Name = _cexit } (RVA = 0x3FA4, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x364)
+ [6] PEImportHintName { Hint = 4, Name = __p___argc } (RVA = 0x3F88, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x348)
+ [7] PEImportHintName { Hint = 64, Name = _seh_filter_exe } (RVA = 0x3EBC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x27C)
+ [8] PEImportHintName { Hint = 35, Name = _exit } (RVA = 0x3F72, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x332)
+ [9] PEImportHintName { Hint = 85, Name = exit } (RVA = 0x3F6A, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x32A)
+ [10] PEImportHintName { Hint = 55, Name = _initterm_e } (RVA = 0x3F5C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x31C)
+ [11] PEImportHintName { Hint = 54, Name = _initterm } (RVA = 0x3F50, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x310)
+ [12] PEImportHintName { Hint = 40, Name = _get_initial_narrow_environment } (RVA = 0x3F2E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x2EE)
+ [13] PEImportHintName { Hint = 51, Name = _initialize_narrow_environment } (RVA = 0x3F0C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x2CC)
+ [14] PEImportHintName { Hint = 24, Name = _configure_narrow_argv } (RVA = 0x3EF2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x2B2)
+ [15] PEImportHintName { Hint = 61, Name = _register_thread_local_exe_atexit_callback } (RVA = 0x3FB8, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x378)
+ [16] PEImportHintName { Hint = 66, Name = _set_app_type } (RVA = 0x3ECE, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x28E)
+ [17] PEImportHintName { Hint = 5, Name = __p___argv } (RVA = 0x3F96, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x356)
+
+ [08] PEImportAddressTable Position = 0x000017D8, Size = 0x00000018, RVA = 0x000031D8, VirtualSize = 0x00000018
+ [0] PEImportHintName { Hint = 1, Name = __p__commode } (RVA = 0x400C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3CC)
+ [1] PEImportHintName { Hint = 84, Name = _set_fmode } (RVA = 0x3F7A, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x33A)
+
+
+ [01] PEStreamSectionData Position = 0x000017F0, Size = 0x000000C0, RVA = 0x000031F0, VirtualSize = 0x000000C0
+
+ [02] PELoadConfigDirectory64 Position = 0x000018B0, Size = 0x00000140, RVA = 0x000032B0, VirtualSize = 0x00000140
+ Size = 0x140
+ TimeDateStamp = 0x0
+ MajorVersion = 0
+ MinorVersion = 0
+ GlobalFlagsClear = 0x0
+ GlobalFlagsSet = 0x0
+ CriticalSectionDefaultTimeout = 0x0
+ DeCommitFreeBlockThreshold = 0x0
+ DeCommitTotalFreeThreshold = 0x0
+ LockPrefixTable = 0x0x0
+ MaximumAllocationSize = 0x0
+ VirtualMemoryThreshold = 0x0
+ ProcessAffinityMask = 0x0
+ ProcessHeapFlags = 0x0
+ CSDVersion = 0
+ DependentLoadFlags = 0x0
+ EditList = 0x0
+ SecurityCookie = 0x140005000
+ SEHandlerTable = 0x0
+ SEHandlerCount = 0x0
+ GuardCFCheckFunctionPointer = 0x1400031F0
+ GuardCFDispatchFunctionPointer = 0x140003200
+ GuardCFFunctionTable = 0x0
+ GuardCFFunctionCount = 0x0
+ GuardFlags = Instrumented
+ TableSizeShift = 0x0
+ CodeIntegrity.Flags = 0x0
+ CodeIntegrity.Catalog = 0x0
+ CodeIntegrity.CatalogOffset = 0x0
+ CodeIntegrity.Reserved = 0x0
+ GuardAddressTakenIatEntryTable = 0x0
+ GuardAddressTakenIatEntryCount = 0x0
+ GuardLongJumpTargetTable = 0x0
+ GuardLongJumpTargetCount = 0x0
+ DynamicValueRelocTable = 0x0
+ CHPEMetadataPointer = 0x0
+ GuardRFFailureRoutine = 0x0
+ GuardRFFailureRoutineFunctionPointer = 0x0
+ DynamicValueRelocTableOffset = 0x0
+ DynamicValueRelocTableSection = 0
+ Reserved2 = 0
+ GuardRFVerifyStackPointerFunctionPointer = 0x0
+ HotPatchTableOffset = 0x0
+ Reserved3 = 0x0
+ EnclaveConfigurationPointer = 0x0
+ VolatileMetadataPointer = 0x140003480
+ GuardEHContinuationTable = 0x0
+ GuardEHContinuationCount = 0x0
+ GuardXFGCheckFunctionPointer = 0x1400031F8
+ GuardXFGDispatchFunctionPointer = 0x140003208
+ GuardXFGTableDispatchFunctionPointer = 0x140003210
+ CastGuardOsDeterminedFailureMode = 0x140003218
+ GuardMemcpyFunctionPointer = 0x140003220
+
+ [03] PEDebugDirectory Position = 0x000019F0, Size = 0x00000070, RVA = 0x000033F0, VirtualSize = 0x00000070
+ [0] Type = CodeView, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F11C3F, Data = RVA = 0x000034DC (PEDebugSectionDataRSDS[5] -> .rdata)
+ [1] Type = VCFeature, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F11C3F, Data = RVA = 0x00003550 (PEDebugStreamSectionData[7] -> .rdata)
+ [2] Type = POGO, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F11C3F, Data = RVA = 0x00003564 (PEDebugStreamSectionData[8] -> .rdata)
+ [3] Type = ILTCG, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F11C3F, Data = null
+
+ [04] PEStreamSectionData Position = 0x00001A60, Size = 0x0000007C, RVA = 0x00003460, VirtualSize = 0x0000007C
+
+ [05] PEDebugSectionDataRSDS Position = 0x00001ADC, Size = 0x00000071, RVA = 0x000034DC, VirtualSize = 0x00000071
+ Debug Section Data (RSDS)
+ Guid = a28d7ba2-048a-4315-9bbe-0edbca526f59
+ Age = 2
+ PdbPath = C:\code\LibObjectFile\src\native\Win64\NativeProjects\x64\Release\NativeConsoleWin64.pdb
+
+ [06] PEStreamSectionData Position = 0x00001B4D, Size = 0x00000003, RVA = 0x0000354D, VirtualSize = 0x00000003
+
+ [07] PEDebugStreamSectionData Position = 0x00001B50, Size = 0x00000014, RVA = 0x00003550, VirtualSize = 0x00000014
+
+ [08] PEDebugStreamSectionData Position = 0x00001B64, Size = 0x00000284, RVA = 0x00003564, VirtualSize = 0x00000284
+
+ [09] PEStreamSectionData Position = 0x00001DE8, Size = 0x0000019C, RVA = 0x000037E8, VirtualSize = 0x0000019C
+
+ [10] PEImportDirectory Position = 0x00001F84, Size = 0x000000C8, RVA = 0x00003984, VirtualSize = 0x000000C8
+ [0] ImportDllNameLink = MSVCP140.dll (RVA = 0x3E0A, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1CA)
+ [0] ImportAddressTable = RVA = 0x00003080 (PEImportAddressTable[1] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [0] ImportLookupTable = RVA = 0x00003AD0 (PEImportLookupTable[13] -> .rdata)
+
+ [1] ImportDllNameLink = VCRUNTIME140_1.dll (RVA = 0x3E96, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x256)
+ [1] ImportAddressTable = RVA = 0x00003100 (PEImportAddressTable[3] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [1] ImportLookupTable = RVA = 0x00003B50 (PEImportLookupTable[15] -> .rdata)
+
+ [2] ImportDllNameLink = VCRUNTIME140.dll (RVA = 0x3EAA, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x26A)
+ [2] ImportAddressTable = RVA = 0x000030C8 (PEImportAddressTable[2] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [2] ImportLookupTable = RVA = 0x00003B18 (PEImportLookupTable[14] -> .rdata)
+
+ [3] ImportDllNameLink = api-ms-win-crt-runtime-l1-1-0.dll (RVA = 0x406E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x42E)
+ [3] ImportAddressTable = RVA = 0x00003140 (PEImportAddressTable[7] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [3] ImportLookupTable = RVA = 0x00003B90 (PEImportLookupTable[19] -> .rdata)
+
+ [4] ImportDllNameLink = api-ms-win-crt-math-l1-1-0.dll (RVA = 0x4090, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x450)
+ [4] ImportAddressTable = RVA = 0x00003130 (PEImportAddressTable[6] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [4] ImportLookupTable = RVA = 0x00003B80 (PEImportLookupTable[18] -> .rdata)
+
+ [5] ImportDllNameLink = api-ms-win-crt-stdio-l1-1-0.dll (RVA = 0x40B0, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x470)
+ [5] ImportAddressTable = RVA = 0x000031D8 (PEImportAddressTable[8] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [5] ImportLookupTable = RVA = 0x00003C28 (PEImportLookupTable[20] -> .rdata)
+
+ [6] ImportDllNameLink = api-ms-win-crt-locale-l1-1-0.dll (RVA = 0x40D0, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x490)
+ [6] ImportAddressTable = RVA = 0x00003120 (PEImportAddressTable[5] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [6] ImportLookupTable = RVA = 0x00003B70 (PEImportLookupTable[17] -> .rdata)
+
+ [7] ImportDllNameLink = api-ms-win-crt-heap-l1-1-0.dll (RVA = 0x40F2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x4B2)
+ [7] ImportAddressTable = RVA = 0x00003110 (PEImportAddressTable[4] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [7] ImportLookupTable = RVA = 0x00003B60 (PEImportLookupTable[16] -> .rdata)
+
+ [8] ImportDllNameLink = KERNEL32.dll (RVA = 0x4270, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x630)
+ [8] ImportAddressTable = RVA = 0x00003000 (PEImportAddressTable[0] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [8] ImportLookupTable = RVA = 0x00003A50 (PEImportLookupTable[12] -> .rdata)
+
+
+ [11] PEStreamSectionData Position = 0x0000204C, Size = 0x00000004, RVA = 0x00003A4C, VirtualSize = 0x00000004
+
+ [12] PEImportLookupTable Position = 0x00002050, Size = 0x00000080, RVA = 0x00003A50, VirtualSize = 0x00000080
+ [0] PEImportHintName { Hint = 1269, Name = RtlCaptureContext } (RVA = 0x4112, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x4D2)
+ [1] PEImportHintName { Hint = 1136, Name = QueryPerformanceCounter } (RVA = 0x41D2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x592)
+ [2] PEImportHintName { Hint = 563, Name = GetCurrentProcessId } (RVA = 0x41EC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5AC)
+ [3] PEImportHintName { Hint = 567, Name = GetCurrentThreadId } (RVA = 0x4202, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5C2)
+ [4] PEImportHintName { Hint = 778, Name = GetSystemTimeAsFileTime } (RVA = 0x4218, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5D8)
+ [5] PEImportHintName { Hint = 906, Name = InitializeSListHead } (RVA = 0x4232, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5F2)
+ [6] PEImportHintName { Hint = 928, Name = IsDebuggerPresent } (RVA = 0x4248, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x608)
+ [7] PEImportHintName { Hint = 661, Name = GetModuleHandleW } (RVA = 0x425C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x61C)
+ [8] PEImportHintName { Hint = 1476, Name = TerminateProcess } (RVA = 0x41A2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x562)
+ [9] PEImportHintName { Hint = 562, Name = GetCurrentProcess } (RVA = 0x418E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x54E)
+ [10] PEImportHintName { Hint = 1444, Name = SetUnhandledExceptionFilter } (RVA = 0x4170, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x530)
+ [11] PEImportHintName { Hint = 1510, Name = UnhandledExceptionFilter } (RVA = 0x4154, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x514)
+ [12] PEImportHintName { Hint = 1284, Name = RtlVirtualUnwind } (RVA = 0x4140, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x500)
+ [13] PEImportHintName { Hint = 1277, Name = RtlLookupFunctionEntry } (RVA = 0x4126, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x4E6)
+ [14] PEImportHintName { Hint = 936, Name = IsProcessorFeaturePresent } (RVA = 0x41B6, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x576)
+
+ [13] PEImportLookupTable Position = 0x000020D0, Size = 0x00000048, RVA = 0x00003AD0, VirtualSize = 0x00000048
+ [0] PEImportHintName { Hint = 692, Name = ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A } (RVA = 0x3C40, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x0)
+ [1] PEImportHintName { Hint = 1246, Name = ?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAHD@Z } (RVA = 0x3DA8, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x168)
+ [2] PEImportHintName { Hint = 1221, Name = ?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QEAAXH_N@Z } (RVA = 0x3D68, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x128)
+ [3] PEImportHintName { Hint = 1249, Name = ?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAA_JPEBD_J@Z } (RVA = 0x3D20, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0xE0)
+ [4] PEImportHintName { Hint = 872, Name = ?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@XZ } (RVA = 0x3CDC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x9C)
+ [5] PEImportHintName { Hint = 580, Name = ?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAXXZ } (RVA = 0x3C9E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x5E)
+ [6] PEImportHintName { Hint = 1310, Name = ?uncaught_exception@std@@YA_NXZ } (RVA = 0x3C7C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3C)
+ [7] PEImportHintName { Hint = 965, Name = ?good@ios_base@std@@QEBA_NXZ } (RVA = 0x3DEA, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1AA)
+
+ [14] PEImportLookupTable Position = 0x00002118, Size = 0x00000038, RVA = 0x00003B18, VirtualSize = 0x00000038
+ [0] PEImportHintName { Hint = 8, Name = __C_specific_handler } (RVA = 0x3E40, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x200)
+ [1] PEImportHintName { Hint = 35, Name = __std_terminate } (RVA = 0x3E2E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1EE)
+ [2] PEImportHintName { Hint = 60, Name = memcpy } (RVA = 0x427E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x63E)
+ [3] PEImportHintName { Hint = 28, Name = __current_exception_context } (RVA = 0x3E6E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x22E)
+ [4] PEImportHintName { Hint = 27, Name = __current_exception } (RVA = 0x3E58, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x218)
+ [5] PEImportHintName { Hint = 62, Name = memset } (RVA = 0x3E8C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x24C)
+
+ [15] PEImportLookupTable Position = 0x00002150, Size = 0x00000010, RVA = 0x00003B50, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 0, Name = __CxxFrameHandler4 } (RVA = 0x3E18, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x1D8)
+
+ [16] PEImportLookupTable Position = 0x00002160, Size = 0x00000010, RVA = 0x00003B60, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 22, Name = _set_new_mode } (RVA = 0x3FFC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3BC)
+
+ [17] PEImportLookupTable Position = 0x00002170, Size = 0x00000010, RVA = 0x00003B70, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 8, Name = _configthreadlocale } (RVA = 0x3FE6, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3A6)
+
+ [18] PEImportLookupTable Position = 0x00002180, Size = 0x00000010, RVA = 0x00003B80, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 9, Name = __setusermatherr } (RVA = 0x3EDE, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x29E)
+
+ [19] PEImportLookupTable Position = 0x00002190, Size = 0x00000098, RVA = 0x00003B90, VirtualSize = 0x00000098
+ [0] PEImportHintName { Hint = 103, Name = terminate } (RVA = 0x4062, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x422)
+ [1] PEImportHintName { Hint = 30, Name = _crt_atexit } (RVA = 0x4054, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x414)
+ [2] PEImportHintName { Hint = 60, Name = _register_onexit_function } (RVA = 0x4038, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3F8)
+ [3] PEImportHintName { Hint = 52, Name = _initialize_onexit_table } (RVA = 0x401C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3DC)
+ [4] PEImportHintName { Hint = 21, Name = _c_exit } (RVA = 0x3FAE, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x36E)
+ [5] PEImportHintName { Hint = 22, Name = _cexit } (RVA = 0x3FA4, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x364)
+ [6] PEImportHintName { Hint = 4, Name = __p___argc } (RVA = 0x3F88, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x348)
+ [7] PEImportHintName { Hint = 64, Name = _seh_filter_exe } (RVA = 0x3EBC, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x27C)
+ [8] PEImportHintName { Hint = 35, Name = _exit } (RVA = 0x3F72, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x332)
+ [9] PEImportHintName { Hint = 85, Name = exit } (RVA = 0x3F6A, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x32A)
+ [10] PEImportHintName { Hint = 55, Name = _initterm_e } (RVA = 0x3F5C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x31C)
+ [11] PEImportHintName { Hint = 54, Name = _initterm } (RVA = 0x3F50, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x310)
+ [12] PEImportHintName { Hint = 40, Name = _get_initial_narrow_environment } (RVA = 0x3F2E, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x2EE)
+ [13] PEImportHintName { Hint = 51, Name = _initialize_narrow_environment } (RVA = 0x3F0C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x2CC)
+ [14] PEImportHintName { Hint = 24, Name = _configure_narrow_argv } (RVA = 0x3EF2, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x2B2)
+ [15] PEImportHintName { Hint = 61, Name = _register_thread_local_exe_atexit_callback } (RVA = 0x3FB8, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x378)
+ [16] PEImportHintName { Hint = 66, Name = _set_app_type } (RVA = 0x3ECE, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x28E)
+ [17] PEImportHintName { Hint = 5, Name = __p___argv } (RVA = 0x3F96, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x356)
+
+ [20] PEImportLookupTable Position = 0x00002228, Size = 0x00000018, RVA = 0x00003C28, VirtualSize = 0x00000018
+ [0] PEImportHintName { Hint = 1, Name = __p__commode } (RVA = 0x400C, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x3CC)
+ [1] PEImportHintName { Hint = 84, Name = _set_fmode } (RVA = 0x3F7A, PEStreamSectionData { RVA = 0x3C40, VirtualSize = 0x648, Position = 0x2240, Size = 0x648 }, Offset = 0x33A)
+
+ [21] PEStreamSectionData Position = 0x00002240, Size = 0x00000648, RVA = 0x00003C40, VirtualSize = 0x00000648
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [02] .data PESection Position = 0x00002A00, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x00000680, Characteristics = 0xC0000040 (ContainsInitializedData, MemRead, MemWrite)
+
+ [00] PEStreamSectionData Position = 0x00002A00, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x00000200
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [03] .pdata PESection Position = 0x00002C00, Size = 0x00000200, RVA = 0x00006000, VirtualSize = 0x00000198, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEExceptionDirectory Position = 0x00002C00, Size = 0x00000198, RVA = 0x00006000, VirtualSize = 0x00000198
+ [0] Begin = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x0
+ [0] End = RVA = 0x1017, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x17
+ [0] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [1] Begin = RVA = 0x1020, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x20
+ [1] End = RVA = 0x11D2, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1D2
+ [1] UnwindInfoAddress = RVA = 0x3810, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x28
+
+ [2] Begin = RVA = 0x11E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1E0
+ [2] End = RVA = 0x121E, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x21E
+ [2] UnwindInfoAddress = RVA = 0x3870, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x88
+
+ [3] Begin = RVA = 0x1220, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x220
+ [3] End = RVA = 0x1244, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x244
+ [3] UnwindInfoAddress = RVA = 0x3894, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xAC
+
+ [4] Begin = RVA = 0x1260, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x260
+ [4] End = RVA = 0x127E, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x27E
+ [4] UnwindInfoAddress = RVA = 0x38B0, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xC8
+
+ [5] Begin = RVA = 0x1280, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x280
+ [5] End = RVA = 0x1336, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x336
+ [5] UnwindInfoAddress = RVA = 0x38B4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xCC
+
+ [6] Begin = RVA = 0x1338, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x338
+ [6] End = RVA = 0x1348, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x348
+ [6] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [7] Begin = RVA = 0x1348, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x348
+ [7] End = RVA = 0x1361, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x361
+ [7] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [8] Begin = RVA = 0x1364, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x364
+ [8] End = RVA = 0x14E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x4E0
+ [8] UnwindInfoAddress = RVA = 0x38BC, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xD4
+
+ [9] Begin = RVA = 0x14E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x4E0
+ [9] End = RVA = 0x14F2, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x4F2
+ [9] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [10] Begin = RVA = 0x14F4, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x4F4
+ [10] End = RVA = 0x1528, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x528
+ [10] UnwindInfoAddress = RVA = 0x38B4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xCC
+
+ [11] Begin = RVA = 0x1528, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x528
+ [11] End = RVA = 0x15FB, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x5FB
+ [11] UnwindInfoAddress = RVA = 0x38FC, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x114
+
+ [12] Begin = RVA = 0x15FC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x5FC
+ [12] End = RVA = 0x166D, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x66D
+ [12] UnwindInfoAddress = RVA = 0x3904, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x11C
+
+ [13] Begin = RVA = 0x1670, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x670
+ [13] End = RVA = 0x16A9, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x6A9
+ [13] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [14] Begin = RVA = 0x16AC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x6AC
+ [14] End = RVA = 0x16E6, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x6E6
+ [14] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [15] Begin = RVA = 0x16E8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x6E8
+ [15] End = RVA = 0x1773, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x773
+ [15] UnwindInfoAddress = RVA = 0x38B4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xCC
+
+ [16] Begin = RVA = 0x1774, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x774
+ [16] End = RVA = 0x180C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x80C
+ [16] UnwindInfoAddress = RVA = 0x3910, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x128
+
+ [17] Begin = RVA = 0x180C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x80C
+ [17] End = RVA = 0x1830, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x830
+ [17] UnwindInfoAddress = RVA = 0x38B4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xCC
+
+ [18] Begin = RVA = 0x1830, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x830
+ [18] End = RVA = 0x1859, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x859
+ [18] UnwindInfoAddress = RVA = 0x38B4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xCC
+
+ [19] Begin = RVA = 0x185C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x85C
+ [19] End = RVA = 0x1896, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x896
+ [19] UnwindInfoAddress = RVA = 0x38B4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0xCC
+
+ [20] Begin = RVA = 0x1898, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x898
+ [20] End = RVA = 0x18AF, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x8AF
+ [20] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [21] Begin = RVA = 0x18B0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x8B0
+ [21] End = RVA = 0x195C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x95C
+ [21] UnwindInfoAddress = RVA = 0x3938, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x150
+
+ [22] Begin = RVA = 0x1998, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x998
+ [22] End = RVA = 0x19B3, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x9B3
+ [22] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [23] Begin = RVA = 0x19D8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x9D8
+ [23] End = RVA = 0x1B20, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xB20
+ [23] UnwindInfoAddress = RVA = 0x3944, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x15C
+
+ [24] Begin = RVA = 0x1B28, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xB28
+ [24] End = RVA = 0x1B79, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xB79
+ [24] UnwindInfoAddress = RVA = 0x3808, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x20
+
+ [25] Begin = RVA = 0x1B8C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xB8C
+ [25] End = RVA = 0x1BE7, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xBE7
+ [25] UnwindInfoAddress = RVA = 0x3954, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x16C
+
+ [26] Begin = RVA = 0x1BE8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xBE8
+ [26] End = RVA = 0x1C24, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xC24
+ [26] UnwindInfoAddress = RVA = 0x3954, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x16C
+
+ [27] Begin = RVA = 0x1C24, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xC24
+ [27] End = RVA = 0x1C60, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xC60
+ [27] UnwindInfoAddress = RVA = 0x3954, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x16C
+
+ [28] Begin = RVA = 0x1C60, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xC60
+ [28] End = RVA = 0x1F2A, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0xF2A
+ [28] UnwindInfoAddress = RVA = 0x3960, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x178
+
+ [29] Begin = RVA = 0x2010, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1010
+ [29] End = RVA = 0x2012, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1012
+ [29] UnwindInfoAddress = RVA = 0x3978, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x190
+
+ [30] Begin = RVA = 0x2030, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1030
+ [30] End = RVA = 0x2036, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1036
+ [30] UnwindInfoAddress = RVA = 0x3980, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x198
+
+ [31] Begin = RVA = 0x2058, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1058
+ [31] End = RVA = 0x2093, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1093
+ [31] UnwindInfoAddress = RVA = 0x3868, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x80
+
+ [32] Begin = RVA = 0x2093, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x1093
+ [32] End = RVA = 0x20B1, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x10B1
+ [32] UnwindInfoAddress = RVA = 0x38F4, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x10C
+
+ [33] Begin = RVA = 0x20B1, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x10B1
+ [33] End = RVA = 0x20C9, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x10C9
+ [33] UnwindInfoAddress = RVA = 0x3930, PEStreamSectionData { RVA = 0x37E8, VirtualSize = 0x19C, Position = 0x1DE8, Size = 0x19C }, Offset = 0x148
+
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [04] .rsrc PESection Position = 0x00002E00, Size = 0x00000200, RVA = 0x00007000, VirtualSize = 0x000001E0, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEResourceDirectory Position = 0x00002E00, Size = 0x000001E0, RVA = 0x00007000, VirtualSize = 0x000001E0
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x18, Entry = PEResourceDirectoryEntry { RVA = 0x7018, VirtualSize = 0x18, Position = 0x2E18, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
+ [00] PEResourceDirectoryEntry Position = 0x00002E18, Size = 0x00000018, RVA = 0x00007018, VirtualSize = 0x00000018
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x1, Entry = PEResourceDirectoryEntry { RVA = 0x7030, VirtualSize = 0x18, Position = 0x2E30, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
+
+ [01] PEResourceDirectoryEntry Position = 0x00002E30, Size = 0x00000018, RVA = 0x00007030, VirtualSize = 0x00000018
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x409, Entry = PEResourceDataEntry { RVA = 0x7048, VirtualSize = 0x10, Position = 0x2E48, Size = 0x10, CodePage = , Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x2E60, Size = 0x17D } }
+
+ [02] PEResourceDataEntry Position = 0x00002E48, Size = 0x00000010, RVA = 0x00007048, VirtualSize = 0x00000010
+ > CodePage = null, Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x2E60, Size = 0x17D }
+
+ [03] PEStreamSectionData Position = 0x00002E58, Size = 0x00000008, RVA = 0x00007058, VirtualSize = 0x00000008
+
+ [04] PEResourceData Position = 0x00002E60, Size = 0x0000017D, RVA = 0x00007060, VirtualSize = 0x0000017D
+
+ [05] PEStreamSectionData Position = 0x00002FDD, Size = 0x00000003, RVA = 0x000071DD, VirtualSize = 0x00000003
+
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [05] .reloc PESection Position = 0x00003000, Size = 0x00000200, RVA = 0x00008000, VirtualSize = 0x00000030, Characteristics = 0x42000040 (ContainsInitializedData, MemDiscardable, MemRead)
+
+ [00] PEBaseRelocationDirectory Position = 0x00003000, Size = 0x00000030, RVA = 0x00008000, VirtualSize = 0x00000030
+ [00] PEBaseRelocationBlock Position = 0x00003000, Size = 0x00000030, RVA = 0x00008000, VirtualSize = 0x00000030
+ Block 0x3000 Relocations[20]
+ [000] Dir64 Offset = 0x01F0, RVA = 0x31F0 (0x0000000140001984), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [001] Dir64 Offset = 0x01F8, RVA = 0x31F8 (0x0000000140001984), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [002] Dir64 Offset = 0x0200, RVA = 0x3200 (0x0000000140002010), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [003] Dir64 Offset = 0x0208, RVA = 0x3208 (0x0000000140002030), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [004] Dir64 Offset = 0x0210, RVA = 0x3210 (0x0000000140002030), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [005] Dir64 Offset = 0x0220, RVA = 0x3220 (0x0000000140001FEE), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [006] Dir64 Offset = 0x0230, RVA = 0x3230 (0x0000000140001348), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [007] Dir64 Offset = 0x0248, RVA = 0x3248 (0x0000000140001280), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [008] Dir64 Offset = 0x0250, RVA = 0x3250 (0x0000000140001338), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [009] Dir64 Offset = 0x0280, RVA = 0x3280 (0x0000000140005080), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [010] Dir64 Offset = 0x0288, RVA = 0x3288 (0x0000000140005120), SectionData = { RVA = 0x000031F0 (PEStreamSectionData[1] -> .rdata) }
+ [011] Dir64 Offset = 0x0308, RVA = 0x3308 (0x0000000140005000), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [012] Dir64 Offset = 0x0320, RVA = 0x3320 (0x00000001400031F0), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [013] Dir64 Offset = 0x0328, RVA = 0x3328 (0x0000000140003200), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [014] Dir64 Offset = 0x03B0, RVA = 0x33B0 (0x0000000140003480), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [015] Dir64 Offset = 0x03C8, RVA = 0x33C8 (0x00000001400031F8), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [016] Dir64 Offset = 0x03D0, RVA = 0x33D0 (0x0000000140003208), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [017] Dir64 Offset = 0x03D8, RVA = 0x33D8 (0x0000000140003210), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [018] Dir64 Offset = 0x03E0, RVA = 0x33E0 (0x0000000140003218), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+ [019] Dir64 Offset = 0x03E8, RVA = 0x33E8 (0x0000000140003220), SectionData = { RVA = 0x000032B0 (PELoadConfigDirectory64[2] -> .rdata) }
+
+
diff --git a/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeLibraryWin64.dll.verified.txt b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeLibraryWin64.dll.verified.txt
new file mode 100644
index 0000000..e908aec
--- /dev/null
+++ b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeLibraryWin64.dll.verified.txt
@@ -0,0 +1,485 @@
+DOS Header
+ Magic = DOS
+ ByteCountOnLastPage = 0x90
+ PageCount = 0x3
+ RelocationCount = 0x0
+ SizeOfParagraphsHeader = 0x4
+ MinExtraParagraphs = 0x0
+ MaxExtraParagraphs = 0xFFFF
+ InitialSSValue = 0x0
+ InitialSPValue = 0xB8
+ Checksum = 0x0
+ InitialIPValue = 0x0
+ InitialCSValue = 0x0
+ FileAddressRelocationTable = 0x40
+ OverlayNumber = 0x0
+ Reserved = 0x0, 0x0, 0x0, 0x0
+ OEMIdentifier = 0x0
+ OEMInformation = 0x0
+ Reserved2 = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+ FileAddressPEHeader = 0xF8
+
+DOS Stub
+ DosStub = 64 bytes
+
+COFF Header
+ Machine = Amd64
+ NumberOfSections = 6
+ TimeDateStamp = 1727110446
+ PointerToSymbolTable = 0x0
+ NumberOfSymbols = 0
+ SizeOfOptionalHeader = 240
+ Characteristics = ExecutableImage, LargeAddressAware, Dll
+
+Optional Header
+ Magic = PE32Plus
+ MajorLinkerVersion = 14
+ MinorLinkerVersion = 41
+ SizeOfCode = 0x1000
+ SizeOfInitializedData = 0x1C00
+ SizeOfUninitializedData = 0x0
+ AddressOfEntryPoint = RVA = 0x1370, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x370
+ BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0x1000, Content[1] }
+ BaseOfData = 0x0x0
+ ImageBase = 0x180000000
+ SectionAlignment = 0x1000
+ FileAlignment = 0x200
+ MajorOperatingSystemVersion = 6
+ MinorOperatingSystemVersion = 0
+ MajorImageVersion = 0
+ MinorImageVersion = 0
+ MajorSubsystemVersion = 6
+ MinorSubsystemVersion = 0
+ Win32VersionValue = 0x0
+ SizeOfImage = 0x7000
+ SizeOfHeaders = 0x400
+ CheckSum = 0x0
+ Subsystem = WindowsGui
+ DllCharacteristics = HighEntropyVirtualAddressSpace, DynamicBase, NxCompatible
+ SizeOfStackReserve = 0x100000
+ SizeOfStackCommit = 0x1000
+ SizeOfHeapReserve = 0x100000
+ SizeOfHeapCommit = 0x1000
+ LoaderFlags = 0x0
+ NumberOfRvaAndSizes = 0x10
+
+Data Directories
+ [00] = PEExportDirectory Position = 0x00001C70, Size = 0x00000070, RVA = 0x00002870, VirtualSize = 0x00000070
+ [01] = PEImportDirectory Position = 0x00001CE0, Size = 0x00000050, RVA = 0x000028E0, VirtualSize = 0x00000050
+ [02] = PEResourceDirectory Position = 0x00002600, Size = 0x000000F8, RVA = 0x00005000, VirtualSize = 0x000000F8
+ [03] = PEExceptionDirectory Position = 0x00002400, Size = 0x000001A4, RVA = 0x00004000, VirtualSize = 0x000001A4
+ [04] = null
+ [05] = PEBaseRelocationDirectory Position = 0x00002800, Size = 0x0000002C, RVA = 0x00006000, VirtualSize = 0x0000002C
+ [06] = PEDebugDirectory Position = 0x000016D0, Size = 0x00000070, RVA = 0x000022D0, VirtualSize = 0x00000070
+ [07] = null
+ [08] = null
+ [09] = null
+ [10] = PELoadConfigDirectory64 Position = 0x00001590, Size = 0x00000140, RVA = 0x00002190, VirtualSize = 0x00000140
+ [11] = null
+ [12] = PEImportAddressTableDirectory Position = 0x00001400, Size = 0x000000E8, RVA = 0x00002000, VirtualSize = 0x000000E8
+ [13] = null
+ [14] = null
+ [15] = null
+
+Section Headers
+ [00] .text PESection Position = 0x00000400, Size = 0x00001000, RVA = 0x00001000, VirtualSize = 0x00000F18, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+ [01] .rdata PESection Position = 0x00001400, Size = 0x00000E00, RVA = 0x00002000, VirtualSize = 0x00000C96, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [02] .data PESection Position = 0x00002200, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x00000680, Characteristics = 0xC0000040 (ContainsInitializedData, MemRead, MemWrite)
+ [03] .pdata PESection Position = 0x00002400, Size = 0x00000200, RVA = 0x00004000, VirtualSize = 0x000001A4, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [04] .rsrc PESection Position = 0x00002600, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x000000F8, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [05] .reloc PESection Position = 0x00002800, Size = 0x00000200, RVA = 0x00006000, VirtualSize = 0x0000002C, Characteristics = 0x42000040 (ContainsInitializedData, MemDiscardable, MemRead)
+
+Sections
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [00] .text PESection Position = 0x00000400, Size = 0x00001000, RVA = 0x00001000, VirtualSize = 0x00000F18, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+
+ [00] PEStreamSectionData Position = 0x00000400, Size = 0x00000F18, RVA = 0x00001000, VirtualSize = 0x00000F18
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [01] .rdata PESection Position = 0x00001400, Size = 0x00000E00, RVA = 0x00002000, VirtualSize = 0x00000C96, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEImportAddressTableDirectory Position = 0x00001400, Size = 0x000000E8, RVA = 0x00002000, VirtualSize = 0x000000E8
+ [00] PEImportAddressTable Position = 0x00001400, Size = 0x00000078, RVA = 0x00002000, VirtualSize = 0x00000078
+ [0] PEImportHintName { Hint = 567, Name = GetCurrentThreadId } (RVA = 0x2C24, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x20C)
+ [1] PEImportHintName { Hint = 1284, Name = RtlVirtualUnwind } (RVA = 0x2B62, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x14A)
+ [2] PEImportHintName { Hint = 1277, Name = RtlLookupFunctionEntry } (RVA = 0x2B48, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x130)
+ [3] PEImportHintName { Hint = 1269, Name = RtlCaptureContext } (RVA = 0x2B34, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x11C)
+ [4] PEImportHintName { Hint = 1444, Name = SetUnhandledExceptionFilter } (RVA = 0x2B92, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x17A)
+ [5] PEImportHintName { Hint = 562, Name = GetCurrentProcess } (RVA = 0x2BB0, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x198)
+ [6] PEImportHintName { Hint = 928, Name = IsDebuggerPresent } (RVA = 0x2C6A, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x252)
+ [7] PEImportHintName { Hint = 906, Name = InitializeSListHead } (RVA = 0x2C54, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x23C)
+ [8] PEImportHintName { Hint = 778, Name = GetSystemTimeAsFileTime } (RVA = 0x2C3A, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x222)
+ [9] PEImportHintName { Hint = 1510, Name = UnhandledExceptionFilter } (RVA = 0x2B76, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x15E)
+ [10] PEImportHintName { Hint = 563, Name = GetCurrentProcessId } (RVA = 0x2C0E, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1F6)
+ [11] PEImportHintName { Hint = 1136, Name = QueryPerformanceCounter } (RVA = 0x2BF4, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1DC)
+ [12] PEImportHintName { Hint = 936, Name = IsProcessorFeaturePresent } (RVA = 0x2BD8, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1C0)
+ [13] PEImportHintName { Hint = 1476, Name = TerminateProcess } (RVA = 0x2BC4, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1AC)
+
+ [01] PEImportAddressTable Position = 0x00001478, Size = 0x00000028, RVA = 0x00002078, VirtualSize = 0x00000028
+ [0] PEImportHintName { Hint = 60, Name = memcpy } (RVA = 0x2C8C, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x274)
+ [1] PEImportHintName { Hint = 37, Name = __std_type_info_destroy_list } (RVA = 0x2A30, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x18)
+ [2] PEImportHintName { Hint = 8, Name = __C_specific_handler } (RVA = 0x2A18, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x0)
+ [3] PEImportHintName { Hint = 62, Name = memset } (RVA = 0x2A50, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x38)
+
+ [02] PEImportAddressTable Position = 0x000014A0, Size = 0x00000048, RVA = 0x000020A0, VirtualSize = 0x00000048
+ [0] PEImportHintName { Hint = 22, Name = _cexit } (RVA = 0x2B08, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xF0)
+ [1] PEImportHintName { Hint = 34, Name = _execute_onexit_table } (RVA = 0x2AF0, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xD8)
+ [2] PEImportHintName { Hint = 52, Name = _initialize_onexit_table } (RVA = 0x2AD4, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xBC)
+ [3] PEImportHintName { Hint = 51, Name = _initialize_narrow_environment } (RVA = 0x2AB2, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x9A)
+ [4] PEImportHintName { Hint = 24, Name = _configure_narrow_argv } (RVA = 0x2A98, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x80)
+ [5] PEImportHintName { Hint = 63, Name = _seh_filter_dll } (RVA = 0x2A86, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x6E)
+ [6] PEImportHintName { Hint = 55, Name = _initterm_e } (RVA = 0x2A78, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x60)
+ [7] PEImportHintName { Hint = 54, Name = _initterm } (RVA = 0x2A6C, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x54)
+
+
+ [01] PEStreamSectionData Position = 0x000014E8, Size = 0x000000A8, RVA = 0x000020E8, VirtualSize = 0x000000A8
+
+ [02] PELoadConfigDirectory64 Position = 0x00001590, Size = 0x00000140, RVA = 0x00002190, VirtualSize = 0x00000140
+ Size = 0x140
+ TimeDateStamp = 0x0
+ MajorVersion = 0
+ MinorVersion = 0
+ GlobalFlagsClear = 0x0
+ GlobalFlagsSet = 0x0
+ CriticalSectionDefaultTimeout = 0x0
+ DeCommitFreeBlockThreshold = 0x0
+ DeCommitTotalFreeThreshold = 0x0
+ LockPrefixTable = 0x0x0
+ MaximumAllocationSize = 0x0
+ VirtualMemoryThreshold = 0x0
+ ProcessAffinityMask = 0x0
+ ProcessHeapFlags = 0x0
+ CSDVersion = 0
+ DependentLoadFlags = 0x0
+ EditList = 0x0
+ SecurityCookie = 0x180003000
+ SEHandlerTable = 0x0
+ SEHandlerCount = 0x0
+ GuardCFCheckFunctionPointer = 0x1800020E8
+ GuardCFDispatchFunctionPointer = 0x1800020F8
+ GuardCFFunctionTable = 0x0
+ GuardCFFunctionCount = 0x0
+ GuardFlags = Instrumented
+ TableSizeShift = 0x0
+ CodeIntegrity.Flags = 0x0
+ CodeIntegrity.Catalog = 0x0
+ CodeIntegrity.CatalogOffset = 0x0
+ CodeIntegrity.Reserved = 0x0
+ GuardAddressTakenIatEntryTable = 0x0
+ GuardAddressTakenIatEntryCount = 0x0
+ GuardLongJumpTargetTable = 0x0
+ GuardLongJumpTargetCount = 0x0
+ DynamicValueRelocTable = 0x0
+ CHPEMetadataPointer = 0x0
+ GuardRFFailureRoutine = 0x0
+ GuardRFFailureRoutineFunctionPointer = 0x0
+ DynamicValueRelocTableOffset = 0x0
+ DynamicValueRelocTableSection = 0
+ Reserved2 = 0
+ GuardRFVerifyStackPointerFunctionPointer = 0x0
+ HotPatchTableOffset = 0x0
+ Reserved3 = 0x0
+ EnclaveConfigurationPointer = 0x0
+ VolatileMetadataPointer = 0x180002380
+ GuardEHContinuationTable = 0x0
+ GuardEHContinuationCount = 0x0
+ GuardXFGCheckFunctionPointer = 0x1800020F0
+ GuardXFGDispatchFunctionPointer = 0x180002100
+ GuardXFGTableDispatchFunctionPointer = 0x180002108
+ CastGuardOsDeterminedFailureMode = 0x180002110
+ GuardMemcpyFunctionPointer = 0x180002118
+
+ [03] PEDebugDirectory Position = 0x000016D0, Size = 0x00000070, RVA = 0x000022D0, VirtualSize = 0x00000070
+ [0] Type = CodeView, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F19D2E, Data = RVA = 0x000023E4 (PEDebugSectionDataRSDS[5] -> .rdata)
+ [1] Type = VCFeature, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F19D2E, Data = RVA = 0x00002458 (PEDebugStreamSectionData[7] -> .rdata)
+ [2] Type = POGO, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F19D2E, Data = RVA = 0x0000246C (PEDebugStreamSectionData[8] -> .rdata)
+ [3] Type = ILTCG, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66F19D2E, Data = null
+
+ [04] PEStreamSectionData Position = 0x00001740, Size = 0x000000A4, RVA = 0x00002340, VirtualSize = 0x000000A4
+
+ [05] PEDebugSectionDataRSDS Position = 0x000017E4, Size = 0x00000071, RVA = 0x000023E4, VirtualSize = 0x00000071
+ Debug Section Data (RSDS)
+ Guid = 9e24e83e-5203-490d-b4fe-ac81f739897a
+ Age = 2
+ PdbPath = C:\code\LibObjectFile\src\native\Win64\NativeProjects\x64\Release\NativeLibraryWin64.pdb
+
+ [06] PEStreamSectionData Position = 0x00001855, Size = 0x00000003, RVA = 0x00002455, VirtualSize = 0x00000003
+
+ [07] PEDebugStreamSectionData Position = 0x00001858, Size = 0x00000014, RVA = 0x00002458, VirtualSize = 0x00000014
+
+ [08] PEDebugStreamSectionData Position = 0x0000186C, Size = 0x00000258, RVA = 0x0000246C, VirtualSize = 0x00000258
+
+ [09] PEStreamSectionData Position = 0x00001AC4, Size = 0x000001AC, RVA = 0x000026C4, VirtualSize = 0x000001AC
+
+ [10] PEExportDirectory Position = 0x00001C70, Size = 0x00000070, RVA = 0x00002870, VirtualSize = 0x00000070
+ TimeStamp = 02/07/2106 06:28:15
+ MajorVersion = 0
+ MinorVersion = 0
+ OrdinalBase = 0x1
+ NameLink = NativeLibraryWin64.dll (RVA = 0x28AC, PEStreamSectionData { RVA = 0x28AC, VirtualSize = 0x34, Position = 0x1CAC, Size = 0x34 }, Offset = 0x0)
+ ExportFunctionAddressTable = RVA = 0x00002898 (PEExportAddressTable[0] -> PEExportDirectory[10] -> .rdata)
+ ExportNameTable = RVA = 0x000028A0 (PEExportNameTable[1] -> PEExportDirectory[10] -> .rdata)
+ ExportOrdinalTable = RVA = 0x000028A8 (PEExportOrdinalTable[2] -> PEExportDirectory[10] -> .rdata)
+ [00] PEExportAddressTable Position = 0x00001C98, Size = 0x00000008, RVA = 0x00002898, VirtualSize = 0x00000008
+ [0] Exported RVA = 0x1020 (RVA = 0x00001000 (PEStreamSectionData[0] -> .text))
+ [1] Exported RVA = 0x1010 (RVA = 0x00001000 (PEStreamSectionData[0] -> .text))
+
+ [01] PEExportNameTable Position = 0x00001CA0, Size = 0x00000008, RVA = 0x000028A0, VirtualSize = 0x00000008
+ [0] AnotherFunction (RVA = 0x28C3, PEStreamSectionData { RVA = 0x28AC, VirtualSize = 0x34, Position = 0x1CAC, Size = 0x34 }, Offset = 0x17)
+ [1] HelloWorld (RVA = 0x28D3, PEStreamSectionData { RVA = 0x28AC, VirtualSize = 0x34, Position = 0x1CAC, Size = 0x34 }, Offset = 0x27)
+
+ [02] PEExportOrdinalTable Position = 0x00001CA8, Size = 0x00000004, RVA = 0x000028A8, VirtualSize = 0x00000004
+ [0] Ordinal = 0
+ [1] Ordinal = 1
+
+ [03] PEStreamSectionData Position = 0x00001CAC, Size = 0x00000034, RVA = 0x000028AC, VirtualSize = 0x00000034
+
+
+ [11] PEImportDirectory Position = 0x00001CE0, Size = 0x00000050, RVA = 0x000028E0, VirtualSize = 0x00000050
+ [0] ImportDllNameLink = VCRUNTIME140.dll (RVA = 0x2A5A, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x42)
+ [0] ImportAddressTable = RVA = 0x00002078 (PEImportAddressTable[1] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [0] ImportLookupTable = RVA = 0x000029A8 (PEImportLookupTable[13] -> .rdata)
+
+ [1] ImportDllNameLink = api-ms-win-crt-runtime-l1-1-0.dll (RVA = 0x2B12, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xFA)
+ [1] ImportAddressTable = RVA = 0x000020A0 (PEImportAddressTable[2] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [1] ImportLookupTable = RVA = 0x000029D0 (PEImportLookupTable[14] -> .rdata)
+
+ [2] ImportDllNameLink = KERNEL32.dll (RVA = 0x2C7E, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x266)
+ [2] ImportAddressTable = RVA = 0x00002000 (PEImportAddressTable[0] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [2] ImportLookupTable = RVA = 0x00002930 (PEImportLookupTable[12] -> .rdata)
+
+
+ [12] PEImportLookupTable Position = 0x00001D30, Size = 0x00000078, RVA = 0x00002930, VirtualSize = 0x00000078
+ [0] PEImportHintName { Hint = 567, Name = GetCurrentThreadId } (RVA = 0x2C24, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x20C)
+ [1] PEImportHintName { Hint = 1284, Name = RtlVirtualUnwind } (RVA = 0x2B62, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x14A)
+ [2] PEImportHintName { Hint = 1277, Name = RtlLookupFunctionEntry } (RVA = 0x2B48, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x130)
+ [3] PEImportHintName { Hint = 1269, Name = RtlCaptureContext } (RVA = 0x2B34, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x11C)
+ [4] PEImportHintName { Hint = 1444, Name = SetUnhandledExceptionFilter } (RVA = 0x2B92, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x17A)
+ [5] PEImportHintName { Hint = 562, Name = GetCurrentProcess } (RVA = 0x2BB0, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x198)
+ [6] PEImportHintName { Hint = 928, Name = IsDebuggerPresent } (RVA = 0x2C6A, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x252)
+ [7] PEImportHintName { Hint = 906, Name = InitializeSListHead } (RVA = 0x2C54, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x23C)
+ [8] PEImportHintName { Hint = 778, Name = GetSystemTimeAsFileTime } (RVA = 0x2C3A, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x222)
+ [9] PEImportHintName { Hint = 1510, Name = UnhandledExceptionFilter } (RVA = 0x2B76, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x15E)
+ [10] PEImportHintName { Hint = 563, Name = GetCurrentProcessId } (RVA = 0x2C0E, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1F6)
+ [11] PEImportHintName { Hint = 1136, Name = QueryPerformanceCounter } (RVA = 0x2BF4, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1DC)
+ [12] PEImportHintName { Hint = 936, Name = IsProcessorFeaturePresent } (RVA = 0x2BD8, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1C0)
+ [13] PEImportHintName { Hint = 1476, Name = TerminateProcess } (RVA = 0x2BC4, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x1AC)
+
+ [13] PEImportLookupTable Position = 0x00001DA8, Size = 0x00000028, RVA = 0x000029A8, VirtualSize = 0x00000028
+ [0] PEImportHintName { Hint = 60, Name = memcpy } (RVA = 0x2C8C, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x274)
+ [1] PEImportHintName { Hint = 37, Name = __std_type_info_destroy_list } (RVA = 0x2A30, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x18)
+ [2] PEImportHintName { Hint = 8, Name = __C_specific_handler } (RVA = 0x2A18, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x0)
+ [3] PEImportHintName { Hint = 62, Name = memset } (RVA = 0x2A50, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x38)
+
+ [14] PEImportLookupTable Position = 0x00001DD0, Size = 0x00000048, RVA = 0x000029D0, VirtualSize = 0x00000048
+ [0] PEImportHintName { Hint = 22, Name = _cexit } (RVA = 0x2B08, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xF0)
+ [1] PEImportHintName { Hint = 34, Name = _execute_onexit_table } (RVA = 0x2AF0, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xD8)
+ [2] PEImportHintName { Hint = 52, Name = _initialize_onexit_table } (RVA = 0x2AD4, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0xBC)
+ [3] PEImportHintName { Hint = 51, Name = _initialize_narrow_environment } (RVA = 0x2AB2, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x9A)
+ [4] PEImportHintName { Hint = 24, Name = _configure_narrow_argv } (RVA = 0x2A98, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x80)
+ [5] PEImportHintName { Hint = 63, Name = _seh_filter_dll } (RVA = 0x2A86, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x6E)
+ [6] PEImportHintName { Hint = 55, Name = _initterm_e } (RVA = 0x2A78, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x60)
+ [7] PEImportHintName { Hint = 54, Name = _initterm } (RVA = 0x2A6C, PEStreamSectionData { RVA = 0x2A18, VirtualSize = 0x27E, Position = 0x1E18, Size = 0x27E }, Offset = 0x54)
+
+ [15] PEStreamSectionData Position = 0x00001E18, Size = 0x0000027E, RVA = 0x00002A18, VirtualSize = 0x0000027E
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [02] .data PESection Position = 0x00002200, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x00000680, Characteristics = 0xC0000040 (ContainsInitializedData, MemRead, MemWrite)
+
+ [00] PEStreamSectionData Position = 0x00002200, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x00000200
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [03] .pdata PESection Position = 0x00002400, Size = 0x00000200, RVA = 0x00004000, VirtualSize = 0x000001A4, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEExceptionDirectory Position = 0x00002400, Size = 0x000001A4, RVA = 0x00004000, VirtualSize = 0x000001A4
+ [0] Begin = RVA = 0x1040, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x40
+ [0] End = RVA = 0x105E, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x5E
+ [0] UnwindInfoAddress = RVA = 0x26E8, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x24
+
+ [1] Begin = RVA = 0x1060, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x60
+ [1] End = RVA = 0x10B0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xB0
+ [1] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [2] Begin = RVA = 0x10B0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xB0
+ [2] End = RVA = 0x11C6, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x1C6
+ [2] UnwindInfoAddress = RVA = 0x26EC, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x28
+
+ [3] Begin = RVA = 0x11C8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x1C8
+ [3] End = RVA = 0x1248, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x248
+ [3] UnwindInfoAddress = RVA = 0x2730, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x6C
+
+ [4] Begin = RVA = 0x1248, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x248
+ [4] End = RVA = 0x1370, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x370
+ [4] UnwindInfoAddress = RVA = 0x278C, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC8
+
+ [5] Begin = RVA = 0x1370, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x370
+ [5] End = RVA = 0x13AD, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x3AD
+ [5] UnwindInfoAddress = RVA = 0x27BC, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xF8
+
+ [6] Begin = RVA = 0x13B0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x3B0
+ [6] End = RVA = 0x13E4, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x3E4
+ [6] UnwindInfoAddress = RVA = 0x27E0, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x11C
+
+ [7] Begin = RVA = 0x13E4, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x3E4
+ [7] End = RVA = 0x14B7, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x4B7
+ [7] UnwindInfoAddress = RVA = 0x27CC, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x108
+
+ [8] Begin = RVA = 0x14B8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x4B8
+ [8] End = RVA = 0x1529, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x529
+ [8] UnwindInfoAddress = RVA = 0x27D4, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x110
+
+ [9] Begin = RVA = 0x152C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x52C
+ [9] End = RVA = 0x15D8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x5D8
+ [9] UnwindInfoAddress = RVA = 0x27E8, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x124
+
+ [10] Begin = RVA = 0x1604, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x604
+ [10] End = RVA = 0x161F, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x61F
+ [10] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [11] Begin = RVA = 0x1620, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x620
+ [11] End = RVA = 0x1659, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x659
+ [11] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [12] Begin = RVA = 0x165C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x65C
+ [12] End = RVA = 0x1690, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x690
+ [12] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [13] Begin = RVA = 0x1690, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x690
+ [13] End = RVA = 0x16A5, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x6A5
+ [13] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [14] Begin = RVA = 0x16A8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x6A8
+ [14] End = RVA = 0x16D0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x6D0
+ [14] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [15] Begin = RVA = 0x16D0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x6D0
+ [15] End = RVA = 0x16E5, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x6E5
+ [15] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [16] Begin = RVA = 0x16E8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x6E8
+ [16] End = RVA = 0x1748, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x748
+ [16] UnwindInfoAddress = RVA = 0x281C, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x158
+
+ [17] Begin = RVA = 0x1748, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x748
+ [17] End = RVA = 0x1778, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x778
+ [17] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [18] Begin = RVA = 0x1778, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x778
+ [18] End = RVA = 0x178C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x78C
+ [18] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [19] Begin = RVA = 0x178C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x78C
+ [19] End = RVA = 0x17C6, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x7C6
+ [19] UnwindInfoAddress = RVA = 0x2784, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xC0
+
+ [20] Begin = RVA = 0x17C8, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x7C8
+ [20] End = RVA = 0x1853, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x853
+ [20] UnwindInfoAddress = RVA = 0x27E0, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x11C
+
+ [21] Begin = RVA = 0x1854, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x854
+ [21] End = RVA = 0x18EC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x8EC
+ [21] UnwindInfoAddress = RVA = 0x27F4, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x130
+
+ [22] Begin = RVA = 0x18EC, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x8EC
+ [22] End = RVA = 0x1910, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x910
+ [22] UnwindInfoAddress = RVA = 0x27E0, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x11C
+
+ [23] Begin = RVA = 0x1910, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x910
+ [23] End = RVA = 0x1939, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x939
+ [23] UnwindInfoAddress = RVA = 0x27E0, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x11C
+
+ [24] Begin = RVA = 0x194C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x94C
+ [24] End = RVA = 0x1A94, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xA94
+ [24] UnwindInfoAddress = RVA = 0x2830, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x16C
+
+ [25] Begin = RVA = 0x1A94, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xA94
+ [25] End = RVA = 0x1AD0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xAD0
+ [25] UnwindInfoAddress = RVA = 0x2840, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x17C
+
+ [26] Begin = RVA = 0x1AD0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xAD0
+ [26] End = RVA = 0x1B0C, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xB0C
+ [26] UnwindInfoAddress = RVA = 0x2840, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x17C
+
+ [27] Begin = RVA = 0x1B10, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xB10
+ [27] End = RVA = 0x1DDA, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xDDA
+ [27] UnwindInfoAddress = RVA = 0x284C, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x188
+
+ [28] Begin = RVA = 0x1E60, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE60
+ [28] End = RVA = 0x1E62, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE62
+ [28] UnwindInfoAddress = RVA = 0x2860, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x19C
+
+ [29] Begin = RVA = 0x1E80, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE80
+ [29] End = RVA = 0x1E86, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE86
+ [29] UnwindInfoAddress = RVA = 0x2868, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x1A4
+
+ [30] Begin = RVA = 0x1E86, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE86
+ [30] End = RVA = 0x1E9D, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE9D
+ [30] UnwindInfoAddress = RVA = 0x2728, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x64
+
+ [31] Begin = RVA = 0x1E9D, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xE9D
+ [31] End = RVA = 0x1EB6, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xEB6
+ [31] UnwindInfoAddress = RVA = 0x2728, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x64
+
+ [32] Begin = RVA = 0x1EB6, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xEB6
+ [32] End = RVA = 0x1ECA, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xECA
+ [32] UnwindInfoAddress = RVA = 0x2728, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x64
+
+ [33] Begin = RVA = 0x1ECA, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xECA
+ [33] End = RVA = 0x1F00, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xF00
+ [33] UnwindInfoAddress = RVA = 0x27B4, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0xF0
+
+ [34] Begin = RVA = 0x1F00, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xF00
+ [34] End = RVA = 0x1F18, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0xF18
+ [34] UnwindInfoAddress = RVA = 0x2814, PEStreamSectionData { RVA = 0x26C4, VirtualSize = 0x1AC, Position = 0x1AC4, Size = 0x1AC }, Offset = 0x150
+
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [04] .rsrc PESection Position = 0x00002600, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x000000F8, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEResourceDirectory Position = 0x00002600, Size = 0x000000F8, RVA = 0x00005000, VirtualSize = 0x000000F8
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x18, Entry = PEResourceDirectoryEntry { RVA = 0x5018, VirtualSize = 0x18, Position = 0x2618, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
+ [00] PEResourceDirectoryEntry Position = 0x00002618, Size = 0x00000018, RVA = 0x00005018, VirtualSize = 0x00000018
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x2, Entry = PEResourceDirectoryEntry { RVA = 0x5030, VirtualSize = 0x18, Position = 0x2630, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
+
+ [01] PEResourceDirectoryEntry Position = 0x00002630, Size = 0x00000018, RVA = 0x00005030, VirtualSize = 0x00000018
+ > ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
+ [0] Id = 0x409, Entry = PEResourceDataEntry { RVA = 0x5048, VirtualSize = 0x10, Position = 0x2648, Size = 0x10, CodePage = , Data = PEResourceData { RVA = 0x5060, VirtualSize = 0x91, Position = 0x2660, Size = 0x91 } }
+
+ [02] PEResourceDataEntry Position = 0x00002648, Size = 0x00000010, RVA = 0x00005048, VirtualSize = 0x00000010
+ > CodePage = null, Data = PEResourceData { RVA = 0x5060, VirtualSize = 0x91, Position = 0x2660, Size = 0x91 }
+
+ [03] PEStreamSectionData Position = 0x00002658, Size = 0x00000008, RVA = 0x00005058, VirtualSize = 0x00000008
+
+ [04] PEResourceData Position = 0x00002660, Size = 0x00000091, RVA = 0x00005060, VirtualSize = 0x00000091
+
+ [05] PEStreamSectionData Position = 0x000026F1, Size = 0x00000007, RVA = 0x000050F1, VirtualSize = 0x00000007
+
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [05] .reloc PESection Position = 0x00002800, Size = 0x00000200, RVA = 0x00006000, VirtualSize = 0x0000002C, Characteristics = 0x42000040 (ContainsInitializedData, MemDiscardable, MemRead)
+
+ [00] PEBaseRelocationDirectory Position = 0x00002800, Size = 0x0000002C, RVA = 0x00006000, VirtualSize = 0x0000002C
+ [00] PEBaseRelocationBlock Position = 0x00002800, Size = 0x0000002C, RVA = 0x00006000, VirtualSize = 0x0000002C
+ Block 0x2000 Relocations[18]
+ [000] Dir64 Offset = 0x00E8, RVA = 0x20E8 (0x0000000180001B0C), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [001] Dir64 Offset = 0x00F0, RVA = 0x20F0 (0x0000000180001B0C), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [002] Dir64 Offset = 0x00F8, RVA = 0x20F8 (0x0000000180001E60), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [003] Dir64 Offset = 0x0100, RVA = 0x2100 (0x0000000180001E80), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [004] Dir64 Offset = 0x0108, RVA = 0x2108 (0x0000000180001E80), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [005] Dir64 Offset = 0x0118, RVA = 0x2118 (0x0000000180001E3B), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [006] Dir64 Offset = 0x0168, RVA = 0x2168 (0x0000000180003090), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [007] Dir64 Offset = 0x0170, RVA = 0x2170 (0x0000000180003130), SectionData = { RVA = 0x000020E8 (PEStreamSectionData[1] -> .rdata) }
+ [008] Dir64 Offset = 0x01E8, RVA = 0x21E8 (0x0000000180003000), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [009] Dir64 Offset = 0x0200, RVA = 0x2200 (0x00000001800020E8), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [010] Dir64 Offset = 0x0208, RVA = 0x2208 (0x00000001800020F8), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [011] Dir64 Offset = 0x0290, RVA = 0x2290 (0x0000000180002380), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [012] Dir64 Offset = 0x02A8, RVA = 0x22A8 (0x00000001800020F0), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [013] Dir64 Offset = 0x02B0, RVA = 0x22B0 (0x0000000180002100), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [014] Dir64 Offset = 0x02B8, RVA = 0x22B8 (0x0000000180002108), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [015] Dir64 Offset = 0x02C0, RVA = 0x22C0 (0x0000000180002110), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [016] Dir64 Offset = 0x02C8, RVA = 0x22C8 (0x0000000180002118), SectionData = { RVA = 0x00002190 (PELoadConfigDirectory64[2] -> .rdata) }
+ [017] Absolute Zero padding
+
+
diff --git a/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=RawNativeConsoleWin64.exe.verified.txt b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=RawNativeConsoleWin64.exe.verified.txt
new file mode 100644
index 0000000..f9ae4eb
--- /dev/null
+++ b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=RawNativeConsoleWin64.exe.verified.txt
@@ -0,0 +1,134 @@
+DOS Header
+ Magic = DOS
+ ByteCountOnLastPage = 0x90
+ PageCount = 0x3
+ RelocationCount = 0x0
+ SizeOfParagraphsHeader = 0x4
+ MinExtraParagraphs = 0x0
+ MaxExtraParagraphs = 0xFFFF
+ InitialSSValue = 0x0
+ InitialSPValue = 0xB8
+ Checksum = 0x0
+ InitialIPValue = 0x0
+ InitialCSValue = 0x0
+ FileAddressRelocationTable = 0x40
+ OverlayNumber = 0x0
+ Reserved = 0x0, 0x0, 0x0, 0x0
+ OEMIdentifier = 0x0
+ OEMInformation = 0x0
+ Reserved2 = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+ FileAddressPEHeader = 0xC8
+
+DOS Stub
+ DosStub = 64 bytes
+
+COFF Header
+ Machine = Amd64
+ NumberOfSections = 3
+ TimeDateStamp = 1727726362
+ PointerToSymbolTable = 0x0
+ NumberOfSymbols = 0
+ SizeOfOptionalHeader = 240
+ Characteristics = ExecutableImage, LargeAddressAware
+
+Optional Header
+ Magic = PE32Plus
+ MajorLinkerVersion = 14
+ MinorLinkerVersion = 41
+ SizeOfCode = 0x200
+ SizeOfInitializedData = 0x400
+ SizeOfUninitializedData = 0x0
+ AddressOfEntryPoint = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x0
+ BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x200, Content[1] }
+ BaseOfData = 0x0x0
+ ImageBase = 0x140000000
+ SectionAlignment = 0x1000
+ FileAlignment = 0x200
+ MajorOperatingSystemVersion = 6
+ MinorOperatingSystemVersion = 0
+ MajorImageVersion = 0
+ MinorImageVersion = 0
+ MajorSubsystemVersion = 6
+ MinorSubsystemVersion = 0
+ Win32VersionValue = 0x0
+ SizeOfImage = 0x4000
+ SizeOfHeaders = 0x400
+ CheckSum = 0x0
+ Subsystem = WindowsCui
+ DllCharacteristics = HighEntropyVirtualAddressSpace, DynamicBase, TerminalServerAware
+ SizeOfStackReserve = 0x100000
+ SizeOfStackCommit = 0x1000
+ SizeOfHeapReserve = 0x100000
+ SizeOfHeapCommit = 0x1000
+ LoaderFlags = 0x0
+ NumberOfRvaAndSizes = 0x10
+
+Data Directories
+ [00] = null
+ [01] = PEImportDirectory Position = 0x00000744, Size = 0x00000028, RVA = 0x00002144, VirtualSize = 0x00000028
+ [02] = null
+ [03] = PEExceptionDirectory Position = 0x00000800, Size = 0x0000000C, RVA = 0x00003000, VirtualSize = 0x0000000C
+ [04] = null
+ [05] = null
+ [06] = PEDebugDirectory Position = 0x00000610, Size = 0x00000038, RVA = 0x00002010, VirtualSize = 0x00000038
+ [07] = null
+ [08] = null
+ [09] = null
+ [10] = null
+ [11] = null
+ [12] = PEImportAddressTableDirectory Position = 0x00000600, Size = 0x00000010, RVA = 0x00002000, VirtualSize = 0x00000010
+ [13] = null
+ [14] = null
+ [15] = null
+
+Section Headers
+ [00] .text PESection Position = 0x00000400, Size = 0x00000200, RVA = 0x00001000, VirtualSize = 0x00000010, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+ [01] .rdata PESection Position = 0x00000600, Size = 0x00000200, RVA = 0x00002000, VirtualSize = 0x0000019C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+ [02] .pdata PESection Position = 0x00000800, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x0000000C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+Sections
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [00] .text PESection Position = 0x00000400, Size = 0x00000200, RVA = 0x00001000, VirtualSize = 0x00000010, Characteristics = 0x60000020 (ContainsCode, MemExecute, MemRead)
+
+ [00] PEStreamSectionData Position = 0x00000400, Size = 0x00000010, RVA = 0x00001000, VirtualSize = 0x00000010
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [01] .rdata PESection Position = 0x00000600, Size = 0x00000200, RVA = 0x00002000, VirtualSize = 0x0000019C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEImportAddressTableDirectory Position = 0x00000600, Size = 0x00000010, RVA = 0x00002000, VirtualSize = 0x00000010
+ [00] PEImportAddressTable Position = 0x00000600, Size = 0x00000010, RVA = 0x00002000, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 376, Name = ExitProcess } (RVA = 0x2180, PEStreamSectionData { RVA = 0x2180, VirtualSize = 0x1C, Position = 0x780, Size = 0x1C }, Offset = 0x0)
+
+
+ [01] PEDebugDirectory Position = 0x00000610, Size = 0x00000038, RVA = 0x00002010, VirtualSize = 0x00000038
+ [0] Type = POGO, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FB031A, Data = RVA = 0x00002060 (PEDebugStreamSectionData[3] -> .rdata)
+ [1] Type = ILTCG, Characteristics = 0x0, Version = 0.0, TimeStamp = 0x66FB031A, Data = null
+
+ [02] PEStreamSectionData Position = 0x00000648, Size = 0x00000018, RVA = 0x00002048, VirtualSize = 0x00000018
+
+ [03] PEDebugStreamSectionData Position = 0x00000660, Size = 0x000000DC, RVA = 0x00002060, VirtualSize = 0x000000DC
+
+ [04] PEStreamSectionData Position = 0x0000073C, Size = 0x00000008, RVA = 0x0000213C, VirtualSize = 0x00000008
+
+ [05] PEImportDirectory Position = 0x00000744, Size = 0x00000028, RVA = 0x00002144, VirtualSize = 0x00000028
+ [0] ImportDllNameLink = KERNEL32.dll (RVA = 0x218E, PEStreamSectionData { RVA = 0x2180, VirtualSize = 0x1C, Position = 0x780, Size = 0x1C }, Offset = 0xE)
+ [0] ImportAddressTable = RVA = 0x00002000 (PEImportAddressTable[0] -> PEImportAddressTableDirectory[0] -> .rdata)
+ [0] ImportLookupTable = RVA = 0x00002170 (PEImportLookupTable[7] -> .rdata)
+
+
+ [06] PEStreamSectionData Position = 0x0000076C, Size = 0x00000004, RVA = 0x0000216C, VirtualSize = 0x00000004
+
+ [07] PEImportLookupTable Position = 0x00000770, Size = 0x00000010, RVA = 0x00002170, VirtualSize = 0x00000010
+ [0] PEImportHintName { Hint = 376, Name = ExitProcess } (RVA = 0x2180, PEStreamSectionData { RVA = 0x2180, VirtualSize = 0x1C, Position = 0x780, Size = 0x1C }, Offset = 0x0)
+
+ [08] PEStreamSectionData Position = 0x00000780, Size = 0x0000001C, RVA = 0x00002180, VirtualSize = 0x0000001C
+
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [02] .pdata PESection Position = 0x00000800, Size = 0x00000200, RVA = 0x00003000, VirtualSize = 0x0000000C, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
+
+ [00] PEExceptionDirectory Position = 0x00000800, Size = 0x0000000C, RVA = 0x00003000, VirtualSize = 0x0000000C
+ [0] Begin = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x0
+ [0] End = RVA = 0x1010, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x10
+ [0] UnwindInfoAddress = RVA = 0x213C, PEStreamSectionData { RVA = 0x213C, VirtualSize = 0x8, Position = 0x73C, Size = 0x8 }, Offset = 0x0
+
+
diff --git a/src/LibObjectFile.Tests/Verified/PEReaderTests.TestTinyExe97Bytes.verified.txt b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestTinyExe97Bytes.verified.txt
new file mode 100644
index 0000000..062ad5d
--- /dev/null
+++ b/src/LibObjectFile.Tests/Verified/PEReaderTests.TestTinyExe97Bytes.verified.txt
@@ -0,0 +1,74 @@
+DOS Header
+ Magic = DOS
+ ByteCountOnLastPage = 0x0
+ PageCount = 0x4550
+ RelocationCount = 0x0
+ SizeOfParagraphsHeader = 0x14C
+ MinExtraParagraphs = 0x1
+ MaxExtraParagraphs = 0x2A6A
+ InitialSSValue = 0xC358
+ InitialSPValue = 0x0
+ Checksum = 0x0
+ InitialIPValue = 0x0
+ InitialCSValue = 0x0
+ FileAddressRelocationTable = 0x4
+ OverlayNumber = 0x103
+ Reserved = 0x10B, 0x8, 0x4, 0x0
+ OEMIdentifier = 0x0
+ OEMInformation = 0x0
+ Reserved2 = 0x4, 0x0, 0xC, 0x0, 0x4, 0x0, 0xC, 0x0, 0x0, 0x40
+ FileAddressPEHeader = 0x4
+
+DOS Stub
+ DosStub = 0 bytes
+
+COFF Header
+ Machine = I386
+ NumberOfSections = 1
+ TimeDateStamp = 3277335146
+ PointerToSymbolTable = 0x0
+ NumberOfSymbols = 0
+ SizeOfOptionalHeader = 4
+ Characteristics = RelocsStripped, ExecutableImage, Bit32Machine
+
+Optional Header
+ Magic = PE32
+ MajorLinkerVersion = 8
+ MinorLinkerVersion = 0
+ SizeOfCode = 0x4
+ SizeOfInitializedData = 0x0
+ SizeOfUninitializedData = 0x4
+ AddressOfEntryPoint = 0xC
+ BaseOfCode = 0x4
+ BaseOfData = 0xC
+ ImageBase = 0x0
+ SectionAlignment = 0x4
+ FileAlignment = 0x4
+ MajorOperatingSystemVersion = 4
+ MinorOperatingSystemVersion = 0
+ MajorImageVersion = 0
+ MinorImageVersion = 0
+ MajorSubsystemVersion = 4
+ MinorSubsystemVersion = 0
+ Win32VersionValue = 0x0
+ SizeOfImage = 0x68
+ SizeOfHeaders = 0x64
+ CheckSum = 0x0
+ Subsystem = WindowsGui
+ DllCharacteristics = 0
+ SizeOfStackReserve = 0x0
+ SizeOfStackCommit = 0x0
+ SizeOfHeapReserve = 0x0
+ SizeOfHeapCommit = 0x0
+ LoaderFlags = 0x0
+ NumberOfRvaAndSizes = 0x0
+
+Section Headers
+ [00] PESection Position = 0x0000000C, Size = 0x00000004, RVA = 0x0000000C, VirtualSize = 0x00000004, Characteristics = 0x00000004 (TypeGroup)
+
+Sections
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [00] PESection Position = 0x0000000C, Size = 0x00000004, RVA = 0x0000000C, VirtualSize = 0x00000004, Characteristics = 0x00000004 (TypeGroup)
+
+ [00] PEStreamSectionData Position = 0x0000000C, Size = 0x00000004, RVA = 0x0000000C, VirtualSize = 0x00000004
+
diff --git a/src/LibObjectFile.sln b/src/LibObjectFile.sln
index b3d04ef..c6de7eb 100644
--- a/src/LibObjectFile.sln
+++ b/src/LibObjectFile.sln
@@ -11,10 +11,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibObjectFile.CodeGen", "Li
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E0D117A3-A530-46EE-A873-4FE18DCA6841}"
ProjectSection(SolutionItems) = preProject
+ ..\.editorconfig = ..\.editorconfig
+ ..\.gitattributes = ..\.gitattributes
..\.gitignore = ..\.gitignore
..\changelog.md = ..\changelog.md
..\.github\workflows\ci.yml = ..\.github\workflows\ci.yml
Directory.Build.props = Directory.Build.props
+ Directory.Packages.props = Directory.Packages.props
dotnet-releaser.toml = dotnet-releaser.toml
global.json = global.json
..\license.txt = ..\license.txt
diff --git a/src/LibObjectFile.sln.DotSettings b/src/LibObjectFile.sln.DotSettings
index a8c814e..8a3b5ef 100644
--- a/src/LibObjectFile.sln.DotSettings
+++ b/src/LibObjectFile.sln.DotSettings
@@ -2,16 +2,25 @@
Copyright (c) Alexandre Mutel. All rights reserved.
This file is licensed under the BSD-Clause 2 license.
See the license.txt file in the project root for more information.
+ ARM
BSD
DIE
GNU
LEB
+ RSDS
+ RVA
+ RVO
+ VA
True
True
True
+ True
True
+ True
True
+ True
True
True
True
+ True
True
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArArchiveFile.cs b/src/LibObjectFile/Ar/ArArchiveFile.cs
index 1564d02..e91f925 100644
--- a/src/LibObjectFile/Ar/ArArchiveFile.cs
+++ b/src/LibObjectFile/Ar/ArArchiveFile.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
@@ -6,13 +6,15 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
+using LibObjectFile.Collections;
+using LibObjectFile.Diagnostics;
namespace LibObjectFile.Ar;
///
/// An 'ar' archive file.
///
-public sealed class ArArchiveFile : ObjectFileNode
+public sealed class ArArchiveFile : ArObjectBase
{
private readonly List _files;
@@ -48,17 +50,17 @@ public ArArchiveFile()
///
/// Gets the associated to this instance. Must be first entry in
///
- public ArSymbolTable SymbolTable { get; private set; }
+ public ArSymbolTable? SymbolTable { get; private set; }
///
/// Internal extended file names used for GNU entries.
///
- internal ArLongNamesTable LongNamesTable { get; set; }
+ internal ArLongNamesTable? LongNamesTable { get; set; }
///
/// Gets the file entries. Use or to manipulate the entries.
///
- public IReadOnlyList Files => _files;
+ public ReadOnlyList Files => _files;
///
/// Adds a file to .
@@ -80,7 +82,7 @@ public void AddFile(ArFile file)
}
file.Parent = this;
- file.Index = (uint)_files.Count;
+ file.Index = _files.Count;
_files.Add(file);
}
@@ -122,7 +124,7 @@ public void InsertFileAt(int index, ArFile file)
}
}
- file.Index = (uint)index;
+ file.Index = index;
_files.Insert(index, file);
file.Parent = this;
@@ -154,7 +156,7 @@ public void RemoveFile(ArFile file)
var i = (int)file.Index;
_files.RemoveAt(i);
- file.Index = 0;
+ file.ResetIndex();
// Update indices for other sections
for (int j = i + 1; j < _files.Count; j++)
@@ -178,9 +180,23 @@ public ArFile RemoveFileAt(int index)
return file;
}
- public override void Verify(DiagnosticBag diagnostics)
+ public DiagnosticBag Verify()
{
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
+ var diagnostics = new DiagnosticBag();
+ Verify(diagnostics);
+ return diagnostics;
+ }
+
+ public void Verify(DiagnosticBag diagnostics)
+ {
+ ArgumentNullException.ThrowIfNull(diagnostics);
+ var context = new ArVisitorContext(this, diagnostics);
+ Verify(context);
+ }
+
+ public override void Verify(ArVisitorContext context)
+ {
+ var diagnostics = context.Diagnostics;
for (var i = 0; i < Files.Count; i++)
{
@@ -198,7 +214,7 @@ public override void Verify(DiagnosticBag diagnostics)
}
}
- item.Verify(diagnostics);
+ item.Verify(context);
}
}
@@ -308,10 +324,17 @@ public void Write(Stream stream)
var writer = new ArArchiveFileWriter(this, stream);
writer.Write();
}
-
- public override void UpdateLayout(DiagnosticBag diagnostics)
+
+ protected override void UpdateLayoutCore(ArVisitorContext context)
+ {
+
+ }
+
+
+ public void UpdateLayout(DiagnosticBag diagnostics)
{
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
+ ArgumentNullException.ThrowIfNull(diagnostics);
+ var layoutContext = new ArVisitorContext(this, diagnostics);
Size = 0;
@@ -352,25 +375,25 @@ public override void UpdateLayout(DiagnosticBag diagnostics)
{
var entry = Files[i];
- entry.UpdateLayout(diagnostics);
+ entry.UpdateLayout(layoutContext);
if (diagnostics.HasErrors) return;
// If we have a GNU headers and they are required, add them to the offset and size
if (LongNamesTable != null && LongNamesTable.Index == i)
{
- LongNamesTable.UpdateLayout(diagnostics);
+ LongNamesTable.UpdateLayout(layoutContext);
if (diagnostics.HasErrors) return;
var headerSize = LongNamesTable.Size;
if (headerSize > 0)
{
- LongNamesTable.Offset = size;
+ LongNamesTable.Position = size;
size += ArFile.FileEntrySizeInBytes + LongNamesTable.Size;
if ((size & 1) != 0) size++;
}
}
- entry.Offset = size;
+ entry.Position = size;
size += ArFile.FileEntrySizeInBytes + entry.Size;
if ((size & 1) != 0) size++;
}
diff --git a/src/LibObjectFile/Ar/ArArchiveFileReader.cs b/src/LibObjectFile/Ar/ArArchiveFileReader.cs
index 557d794..c5259db 100644
--- a/src/LibObjectFile/Ar/ArArchiveFileReader.cs
+++ b/src/LibObjectFile/Ar/ArArchiveFileReader.cs
@@ -5,348 +5,348 @@
using System;
using System.Buffers;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
+using LibObjectFile.Diagnostics;
using LibObjectFile.Elf;
-namespace LibObjectFile.Ar
-{
- ///
- /// Class for reading and building an from a .
- ///
- public class ArArchiveFileReader : ObjectFileReaderWriter
- {
- private ArLongNamesTable _futureHeaders;
+namespace LibObjectFile.Ar;
- internal ArArchiveFileReader(ArArchiveFile arArchiveFile, Stream stream, ArArchiveFileReaderOptions options) : base(stream)
- {
- ArArchiveFile = arArchiveFile;
- Options = options;
- IsReadOnly = options.IsReadOnly;
- }
+///
+/// Class for reading and building an from a .
+///
+public class ArArchiveFileReader : ObjectFileReaderWriter
+{
+ private ArLongNamesTable? _futureHeaders;
- public ArArchiveFileReaderOptions Options { get; }
+ internal ArArchiveFileReader(ArArchiveFile arArchiveFile, Stream stream, ArArchiveFileReaderOptions options) : base(arArchiveFile, stream)
+ {
+ Options = options;
+ KeepOriginalStreamForSubStreams = options.IsReadOnly;
+ }
+
+ public ArArchiveFileReaderOptions Options { get; }
- public override bool IsReadOnly { get; }
+ public override bool KeepOriginalStreamForSubStreams { get; }
- internal ArArchiveFile ArArchiveFile { get; }
+ public ArArchiveFile ArArchiveFile => (ArArchiveFile)base.File;
- internal static bool IsAr(Stream stream, DiagnosticBag diagnostics)
+ internal static bool IsAr(Stream stream, DiagnosticBag? diagnostics)
+ {
+ Span magic = stackalloc byte[ArArchiveFile.Magic.Length];
+ int magicLength = stream.Read(magic);
+ if (magicLength != magic.Length)
{
- Span magic = stackalloc byte[ArArchiveFile.Magic.Length];
- int magicLength = stream.Read(magic);
- if (magicLength != magic.Length)
+ if (diagnostics != null)
{
- if (diagnostics != null)
- {
- diagnostics.Error(DiagnosticId.AR_ERR_InvalidMagicLength, $"Invalid length {magicLength} while trying to read ! from stream while expecting at least {magic.Length} bytes");
- }
- return false;
+ diagnostics.Error(DiagnosticId.AR_ERR_InvalidMagicLength, $"Invalid length {magicLength} while trying to read ! from stream while expecting at least {magic.Length} bytes");
}
+ return false;
+ }
- if (!magic.SequenceEqual(ArArchiveFile.Magic))
+ if (!magic.SequenceEqual(ArArchiveFile.Magic))
+ {
+ if (diagnostics != null)
{
- if (diagnostics != null)
- {
- diagnostics.Error(DiagnosticId.AR_ERR_MagicNotFound, $"Magic !\\n not found");
- }
- return false;
+ diagnostics.Error(DiagnosticId.AR_ERR_MagicNotFound, $"Magic !\\n not found");
}
-
- return true;
+ return false;
}
- internal void Read()
+ return true;
+ }
+
+ internal void Read()
+ {
+ if (!IsAr(Stream, Diagnostics))
{
- if (!IsAr(Stream, Diagnostics))
- {
- return;
- }
+ return;
+ }
- Span entryBuffer = stackalloc byte[ArFile.FileEntrySizeInBytes];
+ Span entryBuffer = stackalloc byte[ArFile.FileEntrySizeInBytes];
- _futureHeaders = null;
+ _futureHeaders = null;
- while (TryReadFileEntry(entryBuffer, out var fileEntry))
+ while (TryReadFileEntry(entryBuffer, out var fileEntry))
+ {
+ if (fileEntry is ArLongNamesTable arGnuFutureHeaders)
{
- if (fileEntry is ArLongNamesTable arGnuFutureHeaders)
- {
- if (_futureHeaders != null)
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidDuplicatedFutureHeadersTable, $"Invalid duplicated future headers table found at offset {fileEntry.Offset} while another table was already found at offset {_futureHeaders.Offset}. This file is invalid.");
- break;
- }
-
- _futureHeaders = arGnuFutureHeaders;
- }
- else
+ if (_futureHeaders != null)
{
- ArArchiveFile.AddFile(fileEntry);
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidDuplicatedFutureHeadersTable, $"Invalid duplicated future headers table found at offset {fileEntry.Position} while another table was already found at offset {_futureHeaders.Position}. This file is invalid.");
+ break;
}
- }
-
- if (Diagnostics.HasErrors) return;
- // Perform a pass after all entries have been read
- foreach (var arFileEntry in ArArchiveFile.Files)
+ _futureHeaders = arGnuFutureHeaders;
+ }
+ else
{
- arFileEntry.AfterReadInternal(this.Diagnostics);
+ ArArchiveFile.AddFile(fileEntry);
}
}
- private bool TryReadFileEntry(Span buffer, out ArFile entry)
+ if (Diagnostics.HasErrors) return;
+
+ // Perform a pass after all entries have been read
+ foreach (var arFileEntry in ArArchiveFile.Files)
{
- entry = null;
+ arFileEntry.AfterReadInternal(this.Diagnostics);
+ }
+ }
- Debug.Assert((Stream.Position & 1) == 0);
+ private bool TryReadFileEntry(Span buffer, [NotNullWhen(true)] out ArFile? entry)
+ {
+ entry = null;
- long entryOffset = Stream.Position;
- int length = Stream.Read(buffer);
- if (length == 0)
- {
- return false;
- }
+ Debug.Assert((Stream.Position & 1) == 0);
- if (length < buffer.Length)
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidFileEntryLength, $"Invalid length {length} while trying to read a file entry from stream at offset {entryOffset}. Expecting {buffer.Length} bytes");
- return false;
- }
- // 0 16 File identifier ASCII
- // discard right padding characters
- int idLength = 16;
- while (idLength > 0)
- {
- if (buffer[idLength - 1] != ' ')
- {
- break;
- }
- idLength--;
- }
-
- string name = null;
- ulong? bsdNameLength = null;
+ long entryOffset = Stream.Position;
+ int length = Stream.Read(buffer);
+ if (length == 0)
+ {
+ return false;
+ }
- if (idLength > 3 && ArArchiveFile.Kind == ArArchiveKind.BSD)
+ if (length < buffer.Length)
+ {
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidFileEntryLength, $"Invalid length {length} while trying to read a file entry from stream at offset {entryOffset}. Expecting {buffer.Length} bytes");
+ return false;
+ }
+ // 0 16 File identifier ASCII
+ // discard right padding characters
+ int idLength = 16;
+ while (idLength > 0)
+ {
+ if (buffer[idLength - 1] != ' ')
{
- if (buffer[0] == '#' && buffer[1] == '1' && buffer[2] == '/')
- {
- // If we have a future header table, we are using it and expecting only numbers
- if (!TryDecodeDecimal(entryOffset, buffer, 3, ArFile.FieldNameLength - 3, $"BSD Name length following #1/ at offset {entryOffset}", out ulong bsdNameLengthDecoded))
- {
- // Don't try to process more entries, the archive might be corrupted
- return false;
- }
-
- bsdNameLength = bsdNameLengthDecoded;
- }
+ break;
}
+ idLength--;
+ }
- // If the last char is `/`
- // Keep file names with / or //
- // But remove trailing `/`for regular file names
- if (!bsdNameLength.HasValue && ArArchiveFile.Kind != ArArchiveKind.Common && idLength > 0 && buffer[idLength - 1] == '/')
- {
- if (!(idLength == 1 || idLength == 2 && buffer[idLength - 2] == '/'))
- {
- idLength--;
- }
- }
+ string? name = null;
+ ulong? bsdNameLength = null;
- if (_futureHeaders != null && buffer[0] == (byte)'/')
+ if (idLength > 3 && ArArchiveFile.Kind == ArArchiveKind.BSD)
+ {
+ if (buffer[0] == '#' && buffer[1] == '1' && buffer[2] == '/')
{
// If we have a future header table, we are using it and expecting only numbers
- if (!TryDecodeDecimal(entryOffset, buffer, 1, ArFile.FieldNameLength - 1, $"Name with offset to Future Headers Table at file offset {entryOffset}", out ulong offsetInFutureHeaders))
+ if (!TryDecodeDecimal(entryOffset, buffer, 3, ArFile.FieldNameLength - 3, $"BSD Name length following #1/ at offset {entryOffset}", out ulong bsdNameLengthDecoded))
{
// Don't try to process more entries, the archive might be corrupted
return false;
}
- // If the number is ok, check that we have actually a string for this offset
- if (!_futureHeaders.FileNames.TryGetValue((int)offsetInFutureHeaders, out name))
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidReferenceToFutureHeadersTable, $"Invalid reference {offsetInFutureHeaders} found at file offset {entryOffset}. This file is invalid.");
- }
+ bsdNameLength = bsdNameLengthDecoded;
}
+ }
- if (!bsdNameLength.HasValue && name == null)
+ // If the last char is `/`
+ // Keep file names with / or //
+ // But remove trailing `/`for regular file names
+ if (!bsdNameLength.HasValue && ArArchiveFile.Kind != ArArchiveKind.Common && idLength > 0 && buffer[idLength - 1] == '/')
+ {
+ if (!(idLength == 1 || idLength == 2 && buffer[idLength - 2] == '/'))
{
- name = idLength == 0 ? string.Empty : Encoding.UTF8.GetString(buffer.Slice(0, idLength));
+ idLength--;
}
-
- // 16 12 File modification timestamp Decimal
- if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldTimestampOffset, ArFile.FieldTimestampLength, "File modification timestamp Decimal", out ulong timestamp))
+ }
+
+ if (_futureHeaders != null && buffer[0] == (byte)'/')
+ {
+ // If we have a future header table, we are using it and expecting only numbers
+ if (!TryDecodeDecimal(entryOffset, buffer, 1, ArFile.FieldNameLength - 1, $"Name with offset to Future Headers Table at file offset {entryOffset}", out ulong offsetInFutureHeaders))
{
+ // Don't try to process more entries, the archive might be corrupted
return false;
}
- // 28 6 Owner ID Decimal
- if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldOwnerIdOffset, ArFile.FieldOwnerIdLength, "Owner ID", out ulong ownerId))
+ // If the number is ok, check that we have actually a string for this offset
+ if (!_futureHeaders.FileNames.TryGetValue((int)offsetInFutureHeaders, out name))
{
- return false;
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidReferenceToFutureHeadersTable, $"Invalid reference {offsetInFutureHeaders} found at file offset {entryOffset}. This file is invalid.");
}
+ }
+
+ if (!bsdNameLength.HasValue && name == null)
+ {
+ name = idLength == 0 ? string.Empty : Encoding.UTF8.GetString(buffer.Slice(0, idLength));
+ }
+
+ // 16 12 File modification timestamp Decimal
+ if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldTimestampOffset, ArFile.FieldTimestampLength, "File modification timestamp Decimal", out ulong timestamp))
+ {
+ return false;
+ }
- // 34 6 Group ID Decimal
- if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldGroupIdOffset, ArFile.FieldGroupIdLength, "Group ID", out ulong groupId))
+ // 28 6 Owner ID Decimal
+ if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldOwnerIdOffset, ArFile.FieldOwnerIdLength, "Owner ID", out ulong ownerId))
+ {
+ return false;
+ }
+
+ // 34 6 Group ID Decimal
+ if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldGroupIdOffset, ArFile.FieldGroupIdLength, "Group ID", out ulong groupId))
+ {
+ return false;
+ }
+
+ // 40 8 File mode Octal
+ if (!TryDecodeOctal(entryOffset, buffer, ArFile.FieldFileModeOffset, ArFile.FieldFileModeLength, "File mode", out uint fileMode))
+ {
+ return false;
+ }
+
+ // 48 10 File size in bytes Decimal
+ if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldFileSizeOffset, ArFile.FieldFileSizeLength, "File size in bytes", out ulong fileSize))
+ {
+ return false;
+ }
+
+ // 58 2 Ending characters 0x60 0x0A
+ if (buffer[ArFile.FieldEndCharactersOffset] != 0x60 || buffer[ArFile.FieldEndCharactersOffset + 1] != '\n')
+ {
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry, $"Invalid ASCII characters found 0x{buffer[ArFile.FieldEndCharactersOffset]:x} 0x{buffer[ArFile.FieldEndCharactersOffset+1]:x} instead of `\\n at the end of file entry at offset {entryOffset + ArFile.FieldEndCharactersOffset}");
+ return false;
+ }
+
+ entry = CreateFileEntryFromName(name);
+ entry.Timestamp = DateTimeOffset.FromUnixTimeSeconds((long)timestamp);
+ entry.OwnerId = (uint)ownerId;
+ entry.GroupId = (uint)groupId;
+ entry.FileMode = fileMode;
+ entry.Position = (ulong)entryOffset;
+ entry.Size = fileSize;
+
+ // Read the BSD name if necessary
+ if (bsdNameLength.HasValue)
+ {
+ var nameLength = (int) bsdNameLength.Value;
+ var bufferForName = ArrayPool.Shared.Rent(nameLength);
+ var streamPosition = Stream.Position;
+ var dataReadCount = Stream.Read(bufferForName, 0, nameLength);
+ if (dataReadCount != nameLength)
{
+ Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected end of file while trying to read the filename from the data section of the file entry at offset of {streamPosition}. Expecting {nameLength} bytes while only {dataReadCount} bytes were read from the stream.");
return false;
}
+ name = Encoding.UTF8.GetString(bufferForName, 0, nameLength);
+ }
- // 40 8 File mode Octal
- if (!TryDecodeOctal(entryOffset, buffer, ArFile.FieldFileModeOffset, ArFile.FieldFileModeLength, "File mode", out uint fileMode))
+ if (!entry.IsSystem)
+ {
+ if (name!.Contains('/'))
{
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterInFileEntryName, $"The character `/` was found in the entry `{name}` while it is invalid.");
return false;
}
+ entry.Name = name;
+ }
- // 48 10 File size in bytes Decimal
- if (!TryDecodeDecimal(entryOffset, buffer, ArFile.FieldFileSizeOffset, ArFile.FieldFileSizeLength, "File size in bytes", out ulong fileSize))
+ entry.ReadInternal(this);
+
+ // The end of an entry is always aligned
+ if ((Stream.Position & 1) != 0)
+ {
+ long padOffset = Stream.Position;
+ int pad = Stream.ReadByte();
+ if (pad < 0)
{
+ Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected end of file while trying to Invalid character 0x{pad:x} found at offset {padOffset} while expecting \\n 0xa");
return false;
}
-
- // 58 2 Ending characters 0x60 0x0A
- if (buffer[ArFile.FieldEndCharactersOffset] != 0x60 || buffer[ArFile.FieldEndCharactersOffset + 1] != '\n')
+ if (pad != '\n')
{
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry, $"Invalid ASCII characters found 0x{buffer[ArFile.FieldEndCharactersOffset]:x} 0x{buffer[ArFile.FieldEndCharactersOffset+1]:x} instead of `\\n at the end of file entry at offset {entryOffset + ArFile.FieldEndCharactersOffset}");
+ Diagnostics.Error(DiagnosticId.AR_ERR_ExpectingNewLineCharacter, $"Invalid character 0x{pad:x} found at offset {padOffset} while expecting \\n 0xa");
return false;
}
+ }
- entry = CreateFileEntryFromName(name);
- entry.Timestamp = DateTimeOffset.FromUnixTimeSeconds((long)timestamp);
- entry.OwnerId = (uint)ownerId;
- entry.GroupId = (uint)groupId;
- entry.FileMode = fileMode;
- entry.Offset = (ulong)entryOffset;
- entry.Size = fileSize;
+ return true;
+ }
- // Read the BSD name if necessary
- if (bsdNameLength.HasValue)
+ private bool TryDecodeDecimal(long entryOffset, Span buffer, int offset, int length, string fieldName, out ulong value)
+ {
+ value = 0;
+ // == 0, expect number or space
+ // == 1, expect space
+ int state = 0;
+ for (int i = 0; i < length; i++)
+ {
+ var c = buffer[offset + i];
+ if (state == 0 && c >= '0' && c <= '9')
{
- var nameLength = (int) bsdNameLength.Value;
- var bufferForName = ArrayPool.Shared.Rent(nameLength);
- var streamPosition = Stream.Position;
- var dataReadCount = Stream.Read(bufferForName, 0, nameLength);
- if (dataReadCount != nameLength)
- {
- Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected end of file while trying to read the filename from the data section of the file entry at offset of {streamPosition}. Expecting {nameLength} bytes while only {dataReadCount} bytes were read from the stream.");
- return false;
- }
- name = Encoding.UTF8.GetString(bufferForName, 0, nameLength);
+ value = value * 10 + (ulong) (c - '0');
}
-
- if (!entry.IsSystem)
+ else if (state >= 0 && c == ' ')
{
- if (name.Contains('/'))
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterInFileEntryName, $"The character `/` was found in the entry `{name}` while it is invalid.");
- return false;
- }
- entry.Name = name;
+ state = 1;
}
-
- entry.ReadInternal(this);
-
- // The end of an entry is always aligned
- if ((Stream.Position & 1) != 0)
+ else
{
- long padOffset = Stream.Position;
- int pad = Stream.ReadByte();
- if (pad < 0)
- {
- Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected end of file while trying to Invalid character 0x{pad:x} found at offset {padOffset} while expecting \\n 0xa");
- return false;
- }
- if (pad != '\n')
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_ExpectingNewLineCharacter, $"Invalid character 0x{pad:x} found at offset {padOffset} while expecting \\n 0xa");
- return false;
- }
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry, $"Invalid ASCII character 0x{c:x} found instead of {state switch { 0 => "' '/space or decimal 0-9", _ => "' '/space" }} in file entry at file offset {entryOffset + i} while decoding field entry `{fieldName}`");
+ return false;
}
-
- return true;
}
+ return true;
+ }
- private bool TryDecodeDecimal(long entryOffset, Span buffer, int offset, int length, string fieldName, out ulong value)
+ private bool TryDecodeOctal(long entryOffset, Span buffer, int offset, int length, string fieldName, out uint value)
+ {
+ value = 0;
+ // == 0, expect number or space
+ // == 1, expect space
+ int state = 0;
+ for (int i = 0; i < length; i++)
{
- value = 0;
- // == 0, expect number or space
- // == 1, expect space
- int state = 0;
- for (int i = 0; i < length; i++)
+ var c = buffer[offset + i];
+ if (state == 0 && c >= '0' && c <= '7')
{
- var c = buffer[offset + i];
- if (state == 0 && c >= '0' && c <= '9')
- {
- value = value * 10 + (ulong) (c - '0');
- }
- else if (state >= 0 && c == ' ')
- {
- state = 1;
- }
- else
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry, $"Invalid ASCII character 0x{c:x} found instead of {state switch { 0 => "' '/space or decimal 0-9", _ => "' '/space" }} in file entry at file offset {entryOffset + i} while decoding field entry `{fieldName}`");
- return false;
- }
+ value = value * 8 + (uint)(c - '0');
}
- return true;
- }
-
- private bool TryDecodeOctal(long entryOffset, Span buffer, int offset, int length, string fieldName, out uint value)
- {
- value = 0;
- // == 0, expect number or space
- // == 1, expect space
- int state = 0;
- for (int i = 0; i < length; i++)
+ else if (state >= 0 && c == ' ')
{
- var c = buffer[offset + i];
- if (state == 0 && c >= '0' && c <= '7')
- {
- value = value * 8 + (uint)(c - '0');
- }
- else if (state >= 0 && c == ' ')
- {
- state = 1;
- }
- else
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry, $"Invalid ASCII character 0x{c:x} found instead of {state switch { 0 => "' '/space or octal 0-7", _ => "' '/space" }} in file entry at file offset {entryOffset + i} while decoding field entry `{fieldName}`");
- return false;
- }
+ state = 1;
+ }
+ else
+ {
+ Diagnostics.Error(DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry, $"Invalid ASCII character 0x{c:x} found instead of {state switch { 0 => "' '/space or octal 0-7", _ => "' '/space" }} in file entry at file offset {entryOffset + i} while decoding field entry `{fieldName}`");
+ return false;
}
- return true;
}
+ return true;
+ }
- private ArFile CreateFileEntryFromName(string name)
+ private ArFile CreateFileEntryFromName(string? name)
+ {
+ if (ArArchiveFile.Kind == ArArchiveKind.GNU)
{
- if (ArArchiveFile.Kind == ArArchiveKind.GNU)
+ switch (name)
{
- switch (name)
- {
- case ArSymbolTable.DefaultGNUSymbolTableName:
- return new ArSymbolTable();
- case ArLongNamesTable.DefaultName:
- return new ArLongNamesTable();
- }
+ case ArSymbolTable.DefaultGNUSymbolTableName:
+ return new ArSymbolTable();
+ case ArLongNamesTable.DefaultName:
+ return new ArLongNamesTable();
}
- else if (ArArchiveFile.Kind == ArArchiveKind.BSD)
+ }
+ else if (ArArchiveFile.Kind == ArArchiveKind.BSD)
+ {
+ if (name == ArSymbolTable.DefaultBSDSymbolTableName)
{
- if (name == ArSymbolTable.DefaultBSDSymbolTableName)
- {
- return new ArSymbolTable();
- }
+ return new ArSymbolTable();
}
+ }
- if (Options.ProcessObjectFiles)
+ if (Options.ProcessObjectFiles)
+ {
+ if (ElfObjectFile.IsElf(Stream))
{
- if (ElfObjectFile.IsElf(Stream))
- {
- return new ArElfFile();
- }
+ return new ArElfFile();
}
-
- return new ArBinaryFile();
}
+
+ return new ArBinaryFile();
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArArchiveFileReaderOptions.cs b/src/LibObjectFile/Ar/ArArchiveFileReaderOptions.cs
index 5c47683..f5b7fd9 100644
--- a/src/LibObjectFile/Ar/ArArchiveFileReaderOptions.cs
+++ b/src/LibObjectFile/Ar/ArArchiveFileReaderOptions.cs
@@ -2,40 +2,39 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// Reader options used by and other methods.
+///
+public class ArArchiveFileReaderOptions
{
///
- /// Reader options used by and other methods.
+ /// Initializes a new instance.
///
- public class ArArchiveFileReaderOptions
+ /// Type of the 'ar' file to load (GNU, BSD...)
+ public ArArchiveFileReaderOptions(ArArchiveKind archiveKind)
{
- ///
- /// Initializes a new instance.
- ///
- /// Type of the 'ar' file to load (GNU, BSD...)
- public ArArchiveFileReaderOptions(ArArchiveKind archiveKind)
- {
- ArchiveKind = archiveKind;
- ProcessObjectFiles = true;
- }
+ ArchiveKind = archiveKind;
+ ProcessObjectFiles = true;
+ }
- ///
- /// Gets or sets a boolean indicating if the file entries must keep a readonly view
- /// on the original stream for the content of the file entries, or it should copy
- /// them to modifiable .
- ///
- public bool IsReadOnly { get; set; }
+ ///
+ /// Gets or sets a boolean indicating if the file entries must keep a readonly view
+ /// on the original stream for the content of the file entries, or it should copy
+ /// them to modifiable .
+ ///
+ public bool IsReadOnly { get; set; }
- ///
- /// Gets or sets the type of file to load
- ///
- public ArArchiveKind ArchiveKind { get; set; }
+ ///
+ /// Gets or sets the type of file to load
+ ///
+ public ArArchiveKind ArchiveKind { get; set; }
- ///
- /// Gets or sets a boolean indicating if object files are being processed to return
- /// typed entries () instead of generic binary file entry ().
- /// Default is true
- ///
- public bool ProcessObjectFiles { get; set; }
- }
+ ///
+ /// Gets or sets a boolean indicating if object files are being processed to return
+ /// typed entries () instead of generic binary file entry ().
+ /// Default is true
+ ///
+ public bool ProcessObjectFiles { get; set; }
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArArchiveFileWriter.cs b/src/LibObjectFile/Ar/ArArchiveFileWriter.cs
index f0181cc..c775610 100644
--- a/src/LibObjectFile/Ar/ArArchiveFileWriter.cs
+++ b/src/LibObjectFile/Ar/ArArchiveFileWriter.cs
@@ -7,197 +7,196 @@
using System.Diagnostics;
using System.IO;
using System.Text;
+using LibObjectFile.Diagnostics;
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// Class for writing an to a .
+///
+public class ArArchiveFileWriter: ObjectFileReaderWriter
{
- ///
- /// Class for writing an to a .
- ///
- public class ArArchiveFileWriter: ObjectFileReaderWriter
- {
- private long _startStreamOffset;
+ private long _startStreamOffset;
- internal ArArchiveFileWriter(ArArchiveFile archiveFile, Stream stream) : base(stream)
- {
- ArArchiveFile = archiveFile;
- IsReadOnly = false;
- }
+ internal ArArchiveFileWriter(ArArchiveFile archiveFile, Stream stream) : base(archiveFile, stream)
+ {
+ KeepOriginalStreamForSubStreams = false;
+ }
- private ArArchiveFile ArArchiveFile { get; }
+ public ArArchiveFile ArArchiveFile => (ArArchiveFile)base.File;
- public override bool IsReadOnly { get; }
+ public override bool KeepOriginalStreamForSubStreams { get; }
- internal void Write()
+ internal void Write()
+ {
+ var localDiagnostics = new DiagnosticBag();
+ ArArchiveFile.UpdateLayout(localDiagnostics);
+ if (localDiagnostics.HasErrors)
{
- var localDiagnostics = new DiagnosticBag();
- ArArchiveFile.UpdateLayout(localDiagnostics);
- if (localDiagnostics.HasErrors)
- {
- throw new ObjectFileException("Invalid ar file", localDiagnostics);
- }
- // Copy for warnings
- localDiagnostics.CopyTo(Diagnostics);
+ throw new ObjectFileException("Invalid ar file", localDiagnostics);
+ }
+ // Copy for warnings
+ localDiagnostics.CopyTo(Diagnostics);
- _startStreamOffset = Stream.Position;
+ _startStreamOffset = Stream.Position;
- Stream.Write(ArArchiveFile.Magic);
- Span entryBuffer = stackalloc byte[ArFile.FileEntrySizeInBytes];
+ Stream.Write(ArArchiveFile.Magic);
+ Span entryBuffer = stackalloc byte[ArFile.FileEntrySizeInBytes];
- var headers = ArArchiveFile.LongNamesTable;
-
- // Serialize all file entries
- for (var i = 0; i < ArArchiveFile.Files.Count; i++)
- {
- var file = ArArchiveFile.Files[i];
+ var headers = ArArchiveFile.LongNamesTable;
- // Serialize the headers at the correct position only if they are required
- if (headers != null && headers.Index == i && headers.Size > 0)
- {
- WriteFileEntry(entryBuffer, headers);
- if (Diagnostics.HasErrors) break;
- }
+ // Serialize all file entries
+ for (var i = 0; i < ArArchiveFile.Files.Count; i++)
+ {
+ var file = ArArchiveFile.Files[i];
- WriteFileEntry(entryBuffer, file);
+ // Serialize the headers at the correct position only if they are required
+ if (headers != null && headers.Index == i && headers.Size > 0)
+ {
+ WriteFileEntry(entryBuffer, headers);
if (Diagnostics.HasErrors) break;
}
- if (Diagnostics.HasErrors)
- {
- throw new ObjectFileException("Unexpected error while writing ar file", Diagnostics);
- }
+ WriteFileEntry(entryBuffer, file);
+ if (Diagnostics.HasErrors) break;
}
- private void WriteFileEntry(Span buffer, ArFile file)
+ if (Diagnostics.HasErrors)
{
- Debug.Assert((ulong)(Stream.Position - _startStreamOffset) == file.Offset);
- buffer.Fill((byte)' ');
+ throw new ObjectFileException("Unexpected error while writing ar file", Diagnostics);
+ }
+ }
+
+ private void WriteFileEntry(Span buffer, ArFile file)
+ {
+ Debug.Assert((ulong)(Stream.Position - _startStreamOffset) == file.Position);
+ buffer.Fill((byte)' ');
- var name = file.InternalName;
+ var name = file.InternalName;
- bool postFixSlash = false;
+ bool postFixSlash = false;
- if (name == null)
+ if (name == null)
+ {
+ name = file.Name!;
+ if (ArArchiveFile.Kind != ArArchiveKind.Common && !name.EndsWith("/"))
{
- name = file.Name;
- if (ArArchiveFile.Kind != ArArchiveKind.Common && !name.EndsWith("/"))
- {
- postFixSlash = true;
- }
+ postFixSlash = true;
}
+ }
- uint? bsdNameLength = null;
+ uint? bsdNameLength = null;
- if (ArArchiveFile.Kind == ArArchiveKind.BSD)
+ if (ArArchiveFile.Kind == ArArchiveKind.BSD)
+ {
+ var nameLength = Encoding.UTF8.GetByteCount(name);
+ if (nameLength > ArFile.FieldNameLength)
{
- var nameLength = Encoding.UTF8.GetByteCount(name);
- if (nameLength > ArFile.FieldNameLength)
- {
- name = $"#1/{nameLength}";
- bsdNameLength = (uint)nameLength;
- postFixSlash = false;
- }
+ name = $"#1/{nameLength}";
+ bsdNameLength = (uint)nameLength;
+ postFixSlash = false;
}
+ }
- // Encode Length
- int length = Encoding.UTF8.GetBytes(name, buffer.Slice(0, ArFile.FieldNameLength));
- if (postFixSlash)
- {
- buffer[length] = (byte) '/';
- }
+ // Encode Length
+ int length = Encoding.UTF8.GetBytes(name, buffer.Slice(0, ArFile.FieldNameLength));
+ if (postFixSlash)
+ {
+ buffer[length] = (byte) '/';
+ }
- if (!(file is ArLongNamesTable))
- {
- // 16 12 File modification timestamp Decimal
- EncodeDecimal(buffer, ArFile.FieldTimestampOffset, ArFile.FieldTimestampLength, (ulong)file.Timestamp.ToUnixTimeSeconds());
- // 28 6 Owner ID Decimal
- EncodeDecimal(buffer, ArFile.FieldOwnerIdOffset, ArFile.FieldOwnerIdLength, file.OwnerId);
- // 34 6 Group ID Decimal
- EncodeDecimal(buffer, ArFile.FieldGroupIdOffset, ArFile.FieldGroupIdLength, file.GroupId);
- // 40 8 File mode Octal
- EncodeOctal(buffer, ArFile.FieldFileModeOffset, ArFile.FieldFileModeLength, file.FileMode);
- }
- // 48 10 File size in bytes Decimal
- EncodeDecimal(buffer, ArFile.FieldFileSizeOffset, ArFile.FieldFileSizeLength, file.Size);
+ if (!(file is ArLongNamesTable))
+ {
+ // 16 12 File modification timestamp Decimal
+ EncodeDecimal(buffer, ArFile.FieldTimestampOffset, ArFile.FieldTimestampLength, (ulong)file.Timestamp.ToUnixTimeSeconds());
+ // 28 6 Owner ID Decimal
+ EncodeDecimal(buffer, ArFile.FieldOwnerIdOffset, ArFile.FieldOwnerIdLength, file.OwnerId);
+ // 34 6 Group ID Decimal
+ EncodeDecimal(buffer, ArFile.FieldGroupIdOffset, ArFile.FieldGroupIdLength, file.GroupId);
+ // 40 8 File mode Octal
+ EncodeOctal(buffer, ArFile.FieldFileModeOffset, ArFile.FieldFileModeLength, file.FileMode);
+ }
+ // 48 10 File size in bytes Decimal
+ EncodeDecimal(buffer, ArFile.FieldFileSizeOffset, ArFile.FieldFileSizeLength, file.Size);
- buffer[ArFile.FieldEndCharactersOffset] = 0x60;
- buffer[ArFile.FieldEndCharactersOffset + 1] = (byte) '\n';
+ buffer[ArFile.FieldEndCharactersOffset] = 0x60;
+ buffer[ArFile.FieldEndCharactersOffset + 1] = (byte) '\n';
- // Write the entry
- Stream.Write(buffer);
+ // Write the entry
+ Stream.Write(buffer);
- // Handle BSD file name by serializing the name before the data if it is required
- if (bsdNameLength.HasValue)
+ // Handle BSD file name by serializing the name before the data if it is required
+ if (bsdNameLength.HasValue)
+ {
+ uint nameLength = bsdNameLength.Value;
+ var bufferName = ArrayPool.Shared.Rent((int) nameLength);
+ Encoding.UTF8.GetBytes(file.Name!, 0, file.Name!.Length, bufferName, 0);
+ try
{
- uint nameLength = bsdNameLength.Value;
- var bufferName = ArrayPool.Shared.Rent((int) nameLength);
- Encoding.UTF8.GetBytes(file.Name, 0, file.Name.Length, bufferName, 0);
- try
- {
- Stream.Write(bufferName, 0, (int)nameLength);
- }
- finally
- {
- ArrayPool.Shared.Return(bufferName);
- }
+ Stream.Write(bufferName, 0, (int)nameLength);
}
-
- // Write the content following the entry
- file.WriteInternal(this);
-
- // Align to even byte
- if ((Stream.Position & 1) != 0)
+ finally
{
- Stream.WriteByte((byte)'\n');
+ ArrayPool.Shared.Return(bufferName);
}
}
- private void EncodeDecimal(in Span buffer, int offset, int size, ulong value)
+ // Write the content following the entry
+ file.WriteInternal(this);
+
+ // Align to even byte
+ if ((Stream.Position & 1) != 0)
{
- int count = value == 0 ? 1 : 0;
- var check = value;
- while (check > 0)
- {
- check /= 10;
- count++;
- }
+ Stream.WriteByte((byte)'\n');
+ }
+ }
- if (count > size)
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_ExpectingNewLineCharacter, $"Cannot encode decimal `{value}` as the size is exceeding the available size {size}");
- return;
- }
+ private void EncodeDecimal(in Span buffer, int offset, int size, ulong value)
+ {
+ int count = value == 0 ? 1 : 0;
+ var check = value;
+ while (check > 0)
+ {
+ check /= 10;
+ count++;
+ }
- check = value;
- for (int i = 0; i < count; i++)
- {
- var dec = check % 10;
- buffer[offset + count - i - 1] = (byte)((byte) '0' + dec);
- check = check / 10;
- }
+ if (count > size)
+ {
+ Diagnostics.Error(DiagnosticId.AR_ERR_ExpectingNewLineCharacter, $"Cannot encode decimal `{value}` as the size is exceeding the available size {size}");
+ return;
}
- private void EncodeOctal(in Span buffer, int offset, int size, ulong value)
+ check = value;
+ for (int i = 0; i < count; i++)
{
- int count = value == 0 ? 1 : 0;
- var check = value;
- while (check > 0)
- {
- check /= 8;
- count++;
- }
+ var dec = check % 10;
+ buffer[offset + count - i - 1] = (byte)((byte) '0' + dec);
+ check = check / 10;
+ }
+ }
- if (count > size)
- {
- Diagnostics.Error(DiagnosticId.AR_ERR_ExpectingNewLineCharacter, $"Cannot encode octal `{value}` as the size is exceeding the available size {size}");
- }
+ private void EncodeOctal(in Span buffer, int offset, int size, ulong value)
+ {
+ int count = value == 0 ? 1 : 0;
+ var check = value;
+ while (check > 0)
+ {
+ check /= 8;
+ count++;
+ }
- check = value;
- for (int i = 0; i < count; i++)
- {
- var dec = check % 8;
- buffer[offset + count - i - 1] = (byte)((byte)'0' + dec);
- check = check / 8;
- }
+ if (count > size)
+ {
+ Diagnostics.Error(DiagnosticId.AR_ERR_ExpectingNewLineCharacter, $"Cannot encode octal `{value}` as the size is exceeding the available size {size}");
+ }
+
+ check = value;
+ for (int i = 0; i < count; i++)
+ {
+ var dec = check % 8;
+ buffer[offset + count - i - 1] = (byte)((byte)'0' + dec);
+ check = check / 8;
}
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArArchiveKind.cs b/src/LibObjectFile/Ar/ArArchiveKind.cs
index 6887e3f..ec8bc19 100644
--- a/src/LibObjectFile/Ar/ArArchiveKind.cs
+++ b/src/LibObjectFile/Ar/ArArchiveKind.cs
@@ -2,31 +2,30 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// The type of archive.
+///
+public enum ArArchiveKind
{
///
- /// The type of archive.
+ /// The common variant, used for example by 'deb' package files.
+ /// Supports only file names up to 16 characters.
///
- public enum ArArchiveKind
- {
- ///
- /// The common variant, used for example by 'deb' package files.
- /// Supports only file names up to 16 characters.
- ///
- Common,
+ Common,
- ///
- /// The GNU variant, used by the `ar` utility on GNU and other systems (including Windows)
- /// Based on file format, but using a different strategy
- /// for storing long file names, incompatible with format.
- ///
- GNU,
+ ///
+ /// The GNU variant, used by the `ar` utility on GNU and other systems (including Windows)
+ /// Based on file format, but using a different strategy
+ /// for storing long file names, incompatible with format.
+ ///
+ GNU,
- ///
- /// The BSD variant, used by the `ar` utility on BSD systems (including MacOS)
- /// Based on file format and backward compatible with it,
- /// but allows to store longer file names and file names containing space.
- ///
- BSD,
- }
+ ///
+ /// The BSD variant, used by the `ar` utility on BSD systems (including MacOS)
+ /// Based on file format and backward compatible with it,
+ /// but allows to store longer file names and file names containing space.
+ ///
+ BSD,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArBinaryFile.cs b/src/LibObjectFile/Ar/ArBinaryFile.cs
index c85c7d9..8f73bba 100644
--- a/src/LibObjectFile/Ar/ArBinaryFile.cs
+++ b/src/LibObjectFile/Ar/ArBinaryFile.cs
@@ -2,38 +2,35 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System;
using System.IO;
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// An binary stream .
+///
+public sealed class ArBinaryFile : ArFile
{
///
- /// An binary stream .
+ /// Gets or sets the stream associated to this entry.
///
- public sealed class ArBinaryFile : ArFile
- {
- ///
- /// Gets or sets the stream associated to this entry.
- ///
- public Stream Stream { get; set; }
+ public Stream? Stream { get; set; }
- protected override void Read(ArArchiveFileReader reader)
- {
- Stream = reader.ReadAsStream(Size);
- }
+ public override void Read(ArArchiveFileReader reader)
+ {
+ Stream = reader.ReadAsStream(Size);
+ }
- protected override void Write(ArArchiveFileWriter writer)
+ public override void Write(ArArchiveFileWriter writer)
+ {
+ if (Stream != null)
{
- if (Stream != null)
- {
- writer.Write(Stream);
- }
+ writer.Write(Stream);
}
+ }
- public override void UpdateLayout(DiagnosticBag diagnostics)
- {
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
- Size = Stream != null ? (ulong) Stream.Length : 0;
- }
+ protected override void UpdateLayoutCore(ArVisitorContext context)
+ {
+ Size = Stream != null ? (ulong) Stream.Length : 0;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArElfFile.cs b/src/LibObjectFile/Ar/ArElfFile.cs
index 4a496eb..b12873a 100644
--- a/src/LibObjectFile/Ar/ArElfFile.cs
+++ b/src/LibObjectFile/Ar/ArElfFile.cs
@@ -2,60 +2,57 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System;
using LibObjectFile.Elf;
-using LibObjectFile.Utils;
+using LibObjectFile.IO;
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// An ELF file entry.
+///
+public sealed class ArElfFile : ArFile
{
- ///
- /// An ELF file entry.
- ///
- public sealed class ArElfFile : ArFile
+ public ArElfFile()
{
- public ArElfFile()
- {
- }
+ }
- public ArElfFile(ElfObjectFile elfObjectFile)
- {
- ElfObjectFile = elfObjectFile;
- }
+ public ArElfFile(ElfObjectFile elfObjectFile)
+ {
+ ElfObjectFile = elfObjectFile;
+ }
- ///
- /// Gets or sets the ELF object file.
- ///
- public ElfObjectFile ElfObjectFile { get; set; }
+ ///
+ /// Gets or sets the ELF object file.
+ ///
+ public ElfObjectFile? ElfObjectFile { get; set; }
- protected override void Read(ArArchiveFileReader reader)
- {
- var startPosition = reader.Stream.Position;
- var endPosition = startPosition + (long) Size;
- ElfObjectFile = ElfObjectFile.Read(new SliceStream(reader.Stream, reader.Stream.Position, (long)Size));
- reader.Stream.Position = endPosition;
- }
+ public override void Read(ArArchiveFileReader reader)
+ {
+ var startPosition = reader.Stream.Position;
+ var endPosition = startPosition + (long) Size;
+ ElfObjectFile = ElfObjectFile.Read(new SubStream(reader.Stream, reader.Stream.Position, (long)Size));
+ reader.Stream.Position = endPosition;
+ }
- protected override void Write(ArArchiveFileWriter writer)
+ public override void Write(ArArchiveFileWriter writer)
+ {
+ if (ElfObjectFile != null)
{
- if (ElfObjectFile != null)
- {
- ElfObjectFile.TryWrite(writer.Stream, out var diagnostics);
- diagnostics.CopyTo(writer.Diagnostics);
- }
+ ElfObjectFile.TryWrite(writer.Stream, out var diagnostics);
+ diagnostics.CopyTo(writer.Diagnostics);
}
+ }
- public override void UpdateLayout(DiagnosticBag diagnostics)
- {
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
- Size = 0;
+ protected override void UpdateLayoutCore(ArVisitorContext context)
+ {
+ Size = 0;
- if (ElfObjectFile != null)
+ if (ElfObjectFile != null)
+ {
+ ElfObjectFile.UpdateLayout(context.Diagnostics);
+ if (!context.HasErrors)
{
- ElfObjectFile.UpdateLayout(diagnostics);
- if (!diagnostics.HasErrors)
- {
- Size = ElfObjectFile.Layout.TotalSize;
- }
+ Size = ElfObjectFile.Layout.TotalSize;
}
}
}
diff --git a/src/LibObjectFile/Ar/ArFile.cs b/src/LibObjectFile/Ar/ArFile.cs
index 3977b5c..5940ba6 100644
--- a/src/LibObjectFile/Ar/ArFile.cs
+++ b/src/LibObjectFile/Ar/ArFile.cs
@@ -3,146 +3,132 @@
// See the license.txt file in the project root for more information.
using System;
+using System.Text;
+using LibObjectFile.Diagnostics;
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// Base class for a file entry in
+///
+public abstract partial class ArFile : ArObject
{
+ private string? _name;
+ private DateTimeOffset _timestamp;
+
+ protected ArFile()
+ {
+ Timestamp = DateTimeOffset.UtcNow;
+ }
+
///
- /// Base class for a file entry in
+ /// Gets or sets the name of the file in the archive entry.
///
- public abstract partial class ArFile : ArObject
+ public virtual string? Name
{
- private string _name;
- private DateTimeOffset _timestamp;
-
- protected ArFile()
- {
- Timestamp = DateTimeOffset.UtcNow;
- }
-
- ///
- /// Gets or sets the name of the file in the archive entry.
- ///
- public virtual string Name
+ get => _name;
+ set
{
- get => _name;
- set
+ if (IsSystem)
{
- if (IsSystem)
- {
- throw CannotModifyProperty(nameof(Name));
- }
-
- if (value != null && value.Contains('/'))
- {
- throw new ArgumentException("The character `/` is not allowed in a file name entry");
- }
+ throw CannotModifyProperty(nameof(Name));
+ }
- _name = value;
+ if (value != null && value.Contains('/'))
+ {
+ throw new ArgumentException("The character `/` is not allowed in a file name entry");
}
+
+ _name = value;
}
+ }
- ///
- /// Gets or sets the real (internal) name used for storing this entry (used by )
- ///
- internal string InternalName { get; set; }
+ ///
+ /// Gets or sets the real (internal) name used for storing this entry (used by )
+ ///
+ internal string? InternalName { get; set; }
- ///
- /// Gets or sets the timestamp of this file (clamped to seconds since 1970/01/01)
- ///
- public DateTimeOffset Timestamp
- {
- get => _timestamp;
+ ///
+ /// Gets or sets the timestamp of this file (clamped to seconds since 1970/01/01)
+ ///
+ public DateTimeOffset Timestamp
+ {
+ get => _timestamp;
- // We clamp the timestamp to the precision supported by the system
- set => _timestamp = DateTimeOffset.FromUnixTimeSeconds(value.ToUnixTimeSeconds());
- }
+ // We clamp the timestamp to the precision supported by the system
+ set => _timestamp = DateTimeOffset.FromUnixTimeSeconds(value.ToUnixTimeSeconds());
+ }
- ///
- /// Gets or sets the owner id.
- ///
- public uint OwnerId { get; set; }
+ ///
+ /// Gets or sets the owner id.
+ ///
+ public uint OwnerId { get; set; }
- ///
- /// Gets or sets the group id.
- ///
- public uint GroupId { get; set; }
+ ///
+ /// Gets or sets the group id.
+ ///
+ public uint GroupId { get; set; }
- ///
- /// Gets or sets the file mode.
- ///
- public uint FileMode { get; set; }
+ ///
+ /// Gets or sets the file mode.
+ ///
+ public uint FileMode { get; set; }
- ///
- /// Gets a boolean indicating if this entry is a system entry (symbol table, header references)
- /// and so does not respect naming (that should exclude for example `/`)
- ///
- public virtual bool IsSystem => false;
+ ///
+ /// Gets a boolean indicating if this entry is a system entry (symbol table, header references)
+ /// and so does not respect naming (that should exclude for example `/`)
+ ///
+ public virtual bool IsSystem => false;
- internal void AfterReadInternal(DiagnosticBag diagnostics)
- {
- AfterRead(diagnostics);
- }
+ internal void AfterReadInternal(DiagnosticBag diagnostics)
+ {
+ AfterRead(diagnostics);
+ }
- internal void ReadInternal(ArArchiveFileReader reader)
+ internal void ReadInternal(ArArchiveFileReader reader)
+ {
+ var expectedSize = (long)Size;
+ var beforePosition = reader.Stream.Position;
+ Read(reader);
+ var afterPosition = reader.Stream.Position;
+ var size = afterPosition - beforePosition;
+ // Verifies that the Size property is actually valid with what is being read
+ if (size != expectedSize)
{
- var expectedSize = (long)Size;
- var beforePosition = reader.Stream.Position;
- Read(reader);
- var afterPosition = reader.Stream.Position;
- var size = afterPosition - beforePosition;
- // Verifies that the Size property is actually valid with what is being read
- if (size != expectedSize)
- {
- reader.Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected EOF / size (expected: {expectedSize} != read: {size}) while trying to read file entry {Name}");
- }
+ reader.Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected EOF / size (expected: {expectedSize} != read: {size}) while trying to read file entry {Name}");
}
+ }
- internal void WriteInternal(ArArchiveFileWriter writer)
+ internal void WriteInternal(ArArchiveFileWriter writer)
+ {
+ var expectedSize = (long)Size;
+ var beforePosition = writer.Stream.Position;
+ Write(writer);
+ var afterPosition = writer.Stream.Position;
+ var size = afterPosition - beforePosition;
+
+ // Verifies that the Size property is actually valid with what is being written
+ if (size != expectedSize)
{
- var expectedSize = (long)Size;
- var beforePosition = writer.Stream.Position;
- Write(writer);
- var afterPosition = writer.Stream.Position;
- var size = afterPosition - beforePosition;
-
- // Verifies that the Size property is actually valid with what is being written
- if (size != expectedSize)
- {
- // In that case, we don't log a diagnostics but throw an error, as it is an implementation problem.
- throw new InvalidOperationException($"Invalid implementation of {GetType()}.{nameof(Write)} method. The Size written to the disk doesn't match (expected: {expectedSize} != written: {size}) while trying to write file entry {Name}");
- }
+ // In that case, we don't log a diagnostics but throw an error, as it is an implementation problem.
+ throw new InvalidOperationException($"Invalid implementation of {GetType()}.{nameof(Write)} method. The Size written to the disk doesn't match (expected: {expectedSize} != written: {size}) while trying to write file entry {Name}");
}
+ }
- ///
- /// Reads this entry from a stream.
- ///
- /// The reader associated with the stream to read from.
- protected abstract void Read(ArArchiveFileReader reader);
-
- ///
- /// Performs after-read operation after all the other entries have been loaded.
- ///
- /// A diagnostic bag
- protected virtual void AfterRead(DiagnosticBag diagnostics) { }
-
- ///
- /// Writes this entry to a stream.
- ///
- /// The writer associated with the stream to write to.
- protected abstract void Write(ArArchiveFileWriter writer);
-
- protected InvalidOperationException CannotModifyProperty(string propertyName)
- {
- return new InvalidOperationException($"Cannot modify the property {propertyName} for this {GetType()} file entry instance");
- }
+ ///
+ /// Performs after-read operation after all the other entries have been loaded.
+ ///
+ /// A diagnostic bag
+ protected virtual void AfterRead(DiagnosticBag diagnostics) { }
- public override string ToString()
- {
- return $"{this.GetType().Name} [{Index}] `{Name}`";
- }
+ protected InvalidOperationException CannotModifyProperty(string propertyName)
+ {
+ return new InvalidOperationException($"Cannot modify the property {propertyName} for this {GetType()} file entry instance");
+ }
- public override void Verify(DiagnosticBag diagnostics)
- {
- }
+ protected override bool PrintMembers(StringBuilder builder)
+ {
+ builder.Append($"[{Index}] `{Name}");
+ return true;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArFileEntry.Constants.cs b/src/LibObjectFile/Ar/ArFileEntry.Constants.cs
index 4338152..0ed6437 100644
--- a/src/LibObjectFile/Ar/ArFileEntry.Constants.cs
+++ b/src/LibObjectFile/Ar/ArFileEntry.Constants.cs
@@ -2,83 +2,82 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+public abstract partial class ArFile
{
- public abstract partial class ArFile
- {
- ///
- /// Size in bytes of an AR file entry
- ///
- public const int FileEntrySizeInBytes = 60;
-
- ///
- /// Offset of the filename in the entry
- ///
- public const int FieldNameOffset = 0;
-
- ///
- /// Length in bytes of the filename in the entry
- ///
- public const int FieldNameLength = 16;
-
- ///
- /// Offset of the timestamp in the entry
- ///
- public const int FieldTimestampOffset = 16;
-
- ///
- /// Length in bytes of the timestamp in the entry
- ///
- public const int FieldTimestampLength = 12;
-
- ///
- /// Offset of the owner ID in the entry
- ///
- public const int FieldOwnerIdOffset = 28;
-
- ///
- /// Length in bytes of the timestamp in the entry
- ///
- public const int FieldOwnerIdLength = 6;
-
- ///
- /// Offset of the group ID in the entry
- ///
- public const int FieldGroupIdOffset = 34;
-
- ///
- /// Length in bytes of the timestamp in the entry
- ///
- public const int FieldGroupIdLength = 6;
-
- ///
- /// Offset of the file mode in the entry
- ///
- public const int FieldFileModeOffset = 40;
-
- ///
- /// Length in bytes of the timestamp in the entry
- ///
- public const int FieldFileModeLength = 8;
-
- ///
- /// Offset of the file size in the entry
- ///
- public const int FieldFileSizeOffset = 48;
-
- ///
- /// Length in bytes of the timestamp in the entry
- ///
- public const int FieldFileSizeLength = 10;
-
- ///
- /// Offset of the end characters in the entry
- ///
- public const int FieldEndCharactersOffset = 58;
-
- ///
- /// Length in bytes of the end characters in the entry
- ///
- public const int FieldEndCharactersLength = 2;
- }
+ ///
+ /// Size in bytes of an AR file entry
+ ///
+ public const int FileEntrySizeInBytes = 60;
+
+ ///
+ /// Offset of the filename in the entry
+ ///
+ public const int FieldNameOffset = 0;
+
+ ///
+ /// Length in bytes of the filename in the entry
+ ///
+ public const int FieldNameLength = 16;
+
+ ///
+ /// Offset of the timestamp in the entry
+ ///
+ public const int FieldTimestampOffset = 16;
+
+ ///
+ /// Length in bytes of the timestamp in the entry
+ ///
+ public const int FieldTimestampLength = 12;
+
+ ///
+ /// Offset of the owner ID in the entry
+ ///
+ public const int FieldOwnerIdOffset = 28;
+
+ ///
+ /// Length in bytes of the timestamp in the entry
+ ///
+ public const int FieldOwnerIdLength = 6;
+
+ ///
+ /// Offset of the group ID in the entry
+ ///
+ public const int FieldGroupIdOffset = 34;
+
+ ///
+ /// Length in bytes of the timestamp in the entry
+ ///
+ public const int FieldGroupIdLength = 6;
+
+ ///
+ /// Offset of the file mode in the entry
+ ///
+ public const int FieldFileModeOffset = 40;
+
+ ///
+ /// Length in bytes of the timestamp in the entry
+ ///
+ public const int FieldFileModeLength = 8;
+
+ ///
+ /// Offset of the file size in the entry
+ ///
+ public const int FieldFileSizeOffset = 48;
+
+ ///
+ /// Length in bytes of the timestamp in the entry
+ ///
+ public const int FieldFileSizeLength = 10;
+
+ ///
+ /// Offset of the end characters in the entry
+ ///
+ public const int FieldEndCharactersOffset = 58;
+
+ ///
+ /// Length in bytes of the end characters in the entry
+ ///
+ public const int FieldEndCharactersLength = 2;
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArLongNamesTable.cs b/src/LibObjectFile/Ar/ArLongNamesTable.cs
index c6ef197..c045884 100644
--- a/src/LibObjectFile/Ar/ArLongNamesTable.cs
+++ b/src/LibObjectFile/Ar/ArLongNamesTable.cs
@@ -2,147 +2,144 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System;
using System.Buffers;
using System.Collections.Generic;
using System.Text;
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// Internal class used for loading long file names for GNU `ar` and Windows `lib` archives.
+///
+internal sealed class ArLongNamesTable : ArFile
{
- ///
- /// Internal class used for loading long file names for GNU `ar` and Windows `lib` archives.
- ///
- internal class ArLongNamesTable : ArFile
- {
- public const string DefaultName = "//";
+ public const string DefaultName = "//";
- public ArLongNamesTable()
- {
- }
+ public ArLongNamesTable()
+ {
+ FileNames = new Dictionary();
+ }
- public override string Name
- {
- get => DefaultName;
- set => base.Name = value;
- }
+ public override string? Name
+ {
+ get => DefaultName;
+ set => base.Name = value;
+ }
- public Dictionary FileNames { get; private set; }
+ public Dictionary FileNames { get; private set; }
- public override bool IsSystem => true;
+ public override bool IsSystem => true;
- protected override void Read(ArArchiveFileReader reader)
+ public override void Read(ArArchiveFileReader reader)
+ {
+ FileNames.Clear();
+ var buffer = ArrayPool.Shared.Rent((int)Size);
+ int readCount = reader.Stream.Read(buffer, 0, (int)Size);
+ int startFileIndex = 0;
+ for (int i = 0; i < readCount; i++)
{
- FileNames = new Dictionary();
-
- var buffer = ArrayPool.Shared.Rent((int)Size);
- int readCount = reader.Stream.Read(buffer, 0, (int)Size);
- int startFileIndex = 0;
- for (int i = 0; i < readCount; i++)
+ if (buffer[i] == '\n')
{
- if (buffer[i] == '\n')
+ var fileNameLength = i - startFileIndex;
+ if (fileNameLength > 0)
{
- var fileNameLength = i - startFileIndex;
- if (fileNameLength > 0)
+ // Discard trailing `/`
+ if (buffer[startFileIndex + fileNameLength - 1] == '/')
{
- // Discard trailing `/`
- if (buffer[startFileIndex + fileNameLength - 1] == '/')
- {
- fileNameLength--;
- }
-
- // TODO: Is it UTF8 or ASCII?
- FileNames.Add(startFileIndex, Encoding.UTF8.GetString(buffer, startFileIndex, fileNameLength));
+ fileNameLength--;
}
- startFileIndex = i + 1;
+
+ // TODO: Is it UTF8 or ASCII?
+ FileNames.Add(startFileIndex, Encoding.UTF8.GetString(buffer, startFileIndex, fileNameLength));
}
+ startFileIndex = i + 1;
}
- ArrayPool.Shared.Return(buffer);
}
+ ArrayPool.Shared.Return(buffer);
+ }
- protected override void Write(ArArchiveFileWriter writer)
+ public override void Write(ArArchiveFileWriter writer)
+ {
+ var buffer = ArrayPool.Shared.Rent((int)Size);
+ uint offset = 0;
+ for (var i = (int)Index; i < Parent!.Files.Count; i++)
{
- var buffer = ArrayPool.Shared.Rent((int)Size);
- uint offset = 0;
- for (var i = (int)Index; i < Parent.Files.Count; i++)
- {
- var file = Parent.Files[i];
+ var file = Parent.Files[i];
- if (file is ArLongNamesTable) break;
+ if (file is ArLongNamesTable) break;
- var fileName = file.Name;
- if (fileName == null || fileName.StartsWith("/"))
- {
- continue;
- }
+ var fileName = file.Name;
+ if (fileName == null || fileName.StartsWith("/"))
+ {
+ continue;
+ }
- // byte count + `/`
- var fileNameLength = Encoding.UTF8.GetByteCount(fileName) + 1;
- if (fileNameLength <= FieldNameLength)
- {
- file.InternalName = null;
- continue;
- }
+ // byte count + `/`
+ var fileNameLength = Encoding.UTF8.GetByteCount(fileName) + 1;
+ if (fileNameLength <= FieldNameLength)
+ {
+ file.InternalName = null;
+ continue;
+ }
- // Add `\n`
- fileNameLength++;
+ // Add `\n`
+ fileNameLength++;
- if (fileNameLength > buffer.Length)
- {
- ArrayPool.Shared.Return(buffer);
- buffer = ArrayPool.Shared.Rent(fileNameLength);
- }
+ if (fileNameLength > buffer.Length)
+ {
+ ArrayPool.Shared.Return(buffer);
+ buffer = ArrayPool.Shared.Rent(fileNameLength);
+ }
- file.InternalName = $"/{offset}";
+ file.InternalName = $"/{offset}";
- Encoding.UTF8.GetBytes(fileName, 0, fileName.Length, buffer, 0);
- buffer[fileNameLength - 2] = (byte)'/';
- buffer[fileNameLength - 1] = (byte)'\n';
+ Encoding.UTF8.GetBytes(fileName, 0, fileName.Length, buffer, 0);
+ buffer[fileNameLength - 2] = (byte)'/';
+ buffer[fileNameLength - 1] = (byte)'\n';
- writer.Write(buffer, 0, fileNameLength);
- offset += (uint)fileNameLength;
- }
-
- if ((offset & 1) != 0)
- {
- writer.Stream.WriteByte((byte)'\n');
- }
- ArrayPool.Shared.Return(buffer);
+ writer.Write(buffer, 0, fileNameLength);
+ offset += (uint)fileNameLength;
}
- public override void UpdateLayout(DiagnosticBag diagnostics)
+ if ((offset & 1) != 0)
{
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
- Size = 0;
+ writer.Stream.WriteByte((byte)'\n');
+ }
+ ArrayPool.Shared.Return(buffer);
+ }
- if (Parent == null) return;
+ protected override void UpdateLayoutCore(ArVisitorContext context)
+ {
+ Size = 0;
- ulong size = 0;
- for (var i = (int)Index; i < Parent.Files.Count; i++)
- {
- var file = Parent.Files[i];
- if (file is ArLongNamesTable) break;
+ if (Parent == null) return;
- if (file.Name == null || file.Name.StartsWith("/"))
- {
- continue;
- }
+ ulong size = 0;
+ for (var i = (int)Index; i < Parent.Files.Count; i++)
+ {
+ var file = Parent.Files[i];
+ if (file is ArLongNamesTable) break;
- var byteCount = Encoding.UTF8.GetByteCount(file.Name);
- // byte count + `/`
- if (byteCount + 1 > FieldNameLength)
- {
- // byte count + `/` + `\n`
- size += (ulong)byteCount + 2;
- }
+ if (file.Name == null || file.Name.StartsWith("/"))
+ {
+ continue;
}
- if ((size & 1) != 0)
+ var byteCount = Encoding.UTF8.GetByteCount(file.Name);
+ // byte count + `/`
+ if (byteCount + 1 > FieldNameLength)
{
- size++;
+ // byte count + `/` + `\n`
+ size += (ulong)byteCount + 2;
}
+ }
- // Once it is calculated freeze it
- Size = size;
+ if ((size & 1) != 0)
+ {
+ size++;
}
+
+ // Once it is calculated freeze it
+ Size = size;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArObject.cs b/src/LibObjectFile/Ar/ArObject.cs
index 44e0fa0..791d384 100644
--- a/src/LibObjectFile/Ar/ArObject.cs
+++ b/src/LibObjectFile/Ar/ArObject.cs
@@ -8,25 +8,28 @@
namespace LibObjectFile.Ar;
-public abstract class ArObject : ObjectFileNode
+public abstract class ArObjectBase : ObjectFileElement
{
- protected override void ValidateParent(ObjectFileNodeBase parent)
- {
- if (!(parent is ArArchiveFile))
- {
- throw new ArgumentException($"Parent must inherit from type {nameof(ArArchiveFile)}");
- }
- }
-
+}
+public abstract class ArObject : ArObjectBase
+{
///
/// Gets the containing . Might be null if this section or segment
/// does not belong to an existing .
///
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public new ArArchiveFile Parent
+ public new ArArchiveFile? Parent
{
- get => (ArArchiveFile)base.Parent;
+ get => (ArArchiveFile?)base.Parent;
internal set => base.Parent = value;
}
+
+ protected override void ValidateParent(ObjectElement parent)
+ {
+ if (!(parent is ArArchiveFile))
+ {
+ throw new ArgumentException($"Parent must inherit from type {nameof(ArArchiveFile)}");
+ }
+ }
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArSymbol.cs b/src/LibObjectFile/Ar/ArSymbol.cs
index a5750d9..b6f064d 100644
--- a/src/LibObjectFile/Ar/ArSymbol.cs
+++ b/src/LibObjectFile/Ar/ArSymbol.cs
@@ -2,47 +2,46 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// A symbol stored in a
+///
+public struct ArSymbol
{
///
- /// A symbol stored in a
+ /// Initializes a new instance.
///
- public struct ArSymbol
+ /// The name of the symbol.
+ /// The associated file entry this symbol is coming from .
+ public ArSymbol(string name, ArFile file) : this()
{
- ///
- /// Initializes a new instance.
- ///
- /// The name of the symbol.
- /// The associated file entry this symbol is coming from .
- public ArSymbol(string name, ArFile file) : this()
- {
- Name = name;
- File = file;
- }
+ Name = name;
+ File = file;
+ }
- ///
- /// Gets or sets the name of this symbol.
- ///
- public string Name { get; set; }
+ ///
+ /// Gets or sets the name of this symbol.
+ ///
+ public string Name { get; set; }
- ///
- /// Internal offset for the name (used for reading)
- ///
- internal uint NameOffset { get; set; }
+ ///
+ /// Internal offset for the name (used for reading)
+ ///
+ internal uint NameOffset { get; set; }
- ///
- /// Gets or sets the associated file entry this symbol is coming from .
- ///
- public ArFile File { get; set; }
+ ///
+ /// Gets or sets the associated file entry this symbol is coming from .
+ ///
+ public ArFile File { get; set; }
- ///
- /// Internal offset of the file (used for reading)
- ///
- internal ulong FileOffset { get; set; }
+ ///
+ /// Internal offset of the file (used for reading)
+ ///
+ internal ulong FileOffset { get; set; }
- public override string ToString()
- {
- return $"Symbol: {Name} => {nameof(File)}: {File}";
- }
+ public override string ToString()
+ {
+ return $"Symbol: {Name} => {nameof(File)}: {File}";
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArSymbolTable.cs b/src/LibObjectFile/Ar/ArSymbolTable.cs
index 716da0a..6db07b2 100644
--- a/src/LibObjectFile/Ar/ArSymbolTable.cs
+++ b/src/LibObjectFile/Ar/ArSymbolTable.cs
@@ -2,241 +2,235 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
+using LibObjectFile.Diagnostics;
+using LibObjectFile.IO;
-namespace LibObjectFile.Ar
+namespace LibObjectFile.Ar;
+
+///
+/// The symbol table. When used it must be the first entry in .
+///
+public sealed class ArSymbolTable : ArFile
{
- ///
- /// The symbol table. When used it must be the first entry in .
- ///
- public sealed class ArSymbolTable : ArFile
- {
- public const string DefaultBSDSymbolTableName = "__.SYMDEF";
- public const string DefaultGNUSymbolTableName = "/";
+ public const string DefaultBSDSymbolTableName = "__.SYMDEF";
+ public const string DefaultGNUSymbolTableName = "/";
- public ArSymbolTable()
- {
- Symbols = new List();
- }
+ public ArSymbolTable()
+ {
+ Symbols = new List();
+ }
- public override string Name
+ public override string? Name
+ {
+ get
{
- get
- {
- if (Parent == null) return "";
+ if (Parent == null) return "";
- return Parent.Kind == ArArchiveKind.BSD ? DefaultBSDSymbolTableName : DefaultGNUSymbolTableName;
- }
- set => base.Name = value;
+ return Parent.Kind == ArArchiveKind.BSD ? DefaultBSDSymbolTableName : DefaultGNUSymbolTableName;
}
+ set => base.Name = value;
+ }
- public override bool IsSystem => true;
-
- ///
- /// Gets the symbols associated to this table.
- ///
- public List Symbols { get; }
-
- protected override void Read(ArArchiveFileReader reader)
- {
- long startOffset = reader.Stream.Position;
+ public override bool IsSystem => true;
- bool isBSD = reader.ArArchiveFile.Kind == ArArchiveKind.BSD;
+ ///
+ /// Gets the symbols associated to this table.
+ ///
+ public List Symbols { get; }
- // A 32-bit big endian integer, giving the number of entries in the table.
- uint entryCount = reader.Stream.ReadU32(false);
+ public override void Read(ArArchiveFileReader reader)
+ {
+ long startOffset = reader.Stream.Position;
- // A set of 32-bit big endian integers. One for each symbol, recording the position within the archive of the header for the file containing this symbol.
- for (uint i = 0; i < entryCount; i++)
- {
- uint stringOffset = 0;
+ bool isBSD = reader.ArArchiveFile.Kind == ArArchiveKind.BSD;
- if (isBSD)
- {
- stringOffset = reader.Stream.ReadU32(false);
- }
+ // A 32-bit big endian integer, giving the number of entries in the table.
+ uint entryCount = reader.Stream.ReadU32(false);
- uint offsetOfFile = reader.Stream.ReadU32(false);
+ // A set of 32-bit big endian integers. One for each symbol, recording the position within the archive of the header for the file containing this symbol.
+ for (uint i = 0; i < entryCount; i++)
+ {
+ uint stringOffset = 0;
- var symbol = new ArSymbol
- {
- NameOffset = stringOffset,
- FileOffset = offsetOfFile,
- };
- Symbols.Add(symbol);
+ if (isBSD)
+ {
+ stringOffset = reader.Stream.ReadU32(false);
}
- // A set of Zero-terminated strings. Each is a symbol name, and occurs in the same order as the list of positions in part 2.
- var startStringTableOffset = isBSD ? reader.Stream.Position : 0;
+ uint offsetOfFile = reader.Stream.ReadU32(false);
- for (uint i = 0; i < entryCount; i++)
+ var symbol = new ArSymbol
{
- bool hasError = false;
- var symbol = Symbols[(int)i];
+ NameOffset = stringOffset,
+ FileOffset = offsetOfFile,
+ };
+ Symbols.Add(symbol);
+ }
- var absoluteStringOffset = startStringTableOffset + symbol.NameOffset;
+ // A set of Zero-terminated strings. Each is a symbol name, and occurs in the same order as the list of positions in part 2.
+ var startStringTableOffset = isBSD ? reader.Stream.Position : 0;
- if (isBSD && absoluteStringOffset >= startOffset + (long)Size)
- {
- hasError = true;
- }
- else
- {
- // Only BSD requires to position correctly
- if (isBSD)
- {
- reader.Stream.Position = absoluteStringOffset;
- }
-
- var text = reader.ReadStringUTF8NullTerminated();
- symbol.Name = text;
- Symbols[(int)i] = symbol;
- }
+ for (uint i = 0; i < entryCount; i++)
+ {
+ bool hasError = false;
+ var symbol = Symbols[(int)i];
- if (hasError)
- {
- reader.Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected EOF while trying to read the string name [{i}] at file offset {absoluteStringOffset} in {this}");
- return;
- }
- }
+ var absoluteStringOffset = startStringTableOffset + symbol.NameOffset;
- var sizeRead = (ulong) (reader.Stream.Position - startOffset);
- if ((sizeRead & 1) != 0)
+ if (isBSD && absoluteStringOffset >= startOffset + (long)Size)
+ {
+ hasError = true;
+ }
+ else
{
- if (reader.Stream.ReadByte() >= 0)
+ // Only BSD requires to position correctly
+ if (isBSD)
{
- sizeRead++;
+ reader.Stream.Position = absoluteStringOffset;
}
+
+ var text = reader.ReadStringUTF8NullTerminated();
+ symbol.Name = text;
+ Symbols[(int)i] = symbol;
}
- Debug.Assert(Size == sizeRead);
- }
- protected override void AfterRead(DiagnosticBag diagnostics)
- {
- var offsets = new Dictionary();
- foreach (var fileEntry in Parent.Files)
+ if (hasError)
{
- offsets[fileEntry.Offset] = fileEntry;
+ reader.Diagnostics.Error(DiagnosticId.CMN_ERR_UnexpectedEndOfFile, $"Unexpected EOF while trying to read the string name [{i}] at file offset {absoluteStringOffset} in {this}");
+ return;
}
+ }
- for (var i = 0; i < Symbols.Count; i++)
+ var sizeRead = (ulong) (reader.Stream.Position - startOffset);
+ if ((sizeRead & 1) != 0)
+ {
+ if (reader.Stream.ReadByte() >= 0)
{
- var symbol = Symbols[i];
- if (offsets.TryGetValue(symbol.FileOffset, out var fileEntry))
- {
- symbol.File = fileEntry;
- Symbols[i] = symbol;
- }
- else
- {
- diagnostics.Error(DiagnosticId.AR_ERR_InvalidFileOffsetInSystemVSymbolLookupTable, $"Unable to find file at offset {symbol.FileOffset} for symbol entry [{i}] in {this}");
- }
+ sizeRead++;
}
}
+ Debug.Assert(Size == sizeRead);
+ }
- protected override void Write(ArArchiveFileWriter writer)
+ protected override void AfterRead(DiagnosticBag diagnostics)
+ {
+ var offsets = new Dictionary();
+ foreach (var fileEntry in Parent!.Files)
{
- long startOffset = writer.Stream.Position;
- writer.Stream.WriteU32(false, (uint)Symbols.Count);
+ offsets[fileEntry.Position] = fileEntry;
+ }
- uint stringOffset = 0;
- bool isBSD = Parent.Kind == ArArchiveKind.BSD;
- foreach (var symbol in Symbols)
+ for (var i = 0; i < Symbols.Count; i++)
+ {
+ var symbol = Symbols[i];
+ if (offsets.TryGetValue(symbol.FileOffset, out var fileEntry))
{
- if (isBSD)
- {
- writer.Stream.WriteU32(false, stringOffset);
- }
-
- writer.Stream.WriteU32(false, (uint)symbol.File.Offset);
-
- if (isBSD)
- {
- stringOffset += (uint) Encoding.UTF8.GetByteCount(symbol.Name) + 1;
- }
+ symbol.File = fileEntry;
+ Symbols[i] = symbol;
}
-
- foreach (var symbol in Symbols)
+ else
{
- writer.WriteStringUTF8NullTerminated(symbol.Name);
+ diagnostics.Error(DiagnosticId.AR_ERR_InvalidFileOffsetInSystemVSymbolLookupTable, $"Unable to find file at offset {symbol.FileOffset} for symbol entry [{i}] in {this}");
}
+ }
+ }
+
+ public override void Write(ArArchiveFileWriter writer)
+ {
+ long startOffset = writer.Stream.Position;
+ writer.Stream.WriteU32(false, (uint)Symbols.Count);
- var sizeWritten = writer.Stream.Position - startOffset;
- if ((sizeWritten & 1) != 0)
+ uint stringOffset = 0;
+ bool isBSD = Parent!.Kind == ArArchiveKind.BSD;
+ foreach (var symbol in Symbols)
+ {
+ if (isBSD)
{
- writer.Stream.WriteByte(0);
- sizeWritten++;
+ writer.Stream.WriteU32(false, stringOffset);
}
- // Double check that the size is actually matching what we have been serializing
- Debug.Assert(sizeWritten == (long)Size);
- }
+ writer.Stream.WriteU32(false, (uint)symbol.File.Position);
- public override void Verify(DiagnosticBag diagnostics)
- {
- base.Verify(diagnostics);
- for (var i = 0; i < Symbols.Count; i++)
+ if (isBSD)
{
- var symbol = Symbols[i];
- if (string.IsNullOrEmpty(symbol.Name))
- {
- diagnostics.Error(DiagnosticId.AR_ERR_InvalidNullOrEmptySymbolName, $"Invalid null or empty symbol name [{i}] in {this}");
- }
-
- if (symbol.File == null)
- {
- diagnostics.Error(DiagnosticId.AR_ERR_InvalidNullFileForSymbol, $"Invalid null file for symbol `{symbol.Name}` [{i}] in {this}");
- }
- else if (symbol.File.Parent == null)
- {
- diagnostics.Error(DiagnosticId.AR_ERR_InvalidNullParentFileForSymbol, $"Invalid null Parent for file `{symbol.File}` for symbol `{symbol.Name}` [{i}] in {this}");
- }
- else if (symbol.File.Parent != Parent)
- {
- diagnostics.Error(DiagnosticId.AR_ERR_InvalidParentFileForSymbol, $"Invalid parent for file `{symbol.File}` for symbol `{symbol.Name}` [{i}] in {this}. The parent {nameof(ArArchiveFile)} is not the same instance as this symbol table");
- }
+ stringOffset += (uint) Encoding.UTF8.GetByteCount(symbol.Name) + 1;
}
}
- public override string ToString()
+ foreach (var symbol in Symbols)
{
- return $"{base.ToString()}, {nameof(Symbols)} Count: {Symbols.Count}";
+ writer.WriteStringUTF8NullTerminated(symbol.Name);
}
- public override void UpdateLayout(DiagnosticBag diagnostics)
+ var sizeWritten = writer.Stream.Position - startOffset;
+ if ((sizeWritten & 1) != 0)
{
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
- if (Parent == null) return;
+ writer.Stream.WriteByte(0);
+ sizeWritten++;
+ }
- // number of entries (both for BSD and GNU)
- ulong sizeOfTable = sizeof(uint);
+ // Double check that the size is actually matching what we have been serializing
+ Debug.Assert(sizeWritten == (long)Size);
+ }
- foreach (var symbol in Symbols)
+ public override void Verify(ArVisitorContext context)
+ {
+ var diagnostics = context.Diagnostics;
+ for (var i = 0; i < Symbols.Count; i++)
+ {
+ var symbol = Symbols[i];
+ if (string.IsNullOrEmpty(symbol.Name))
{
- if (symbol.Name != null)
- {
- sizeOfTable += (ulong)Encoding.UTF8.GetByteCount(symbol.Name) + 1;
-
- // uint file_offset
- sizeOfTable += sizeof(uint);
+ diagnostics.Error(DiagnosticId.AR_ERR_InvalidNullOrEmptySymbolName, $"Invalid null or empty symbol name [{i}] in {this}");
+ }
- if (Parent.Kind == ArArchiveKind.BSD)
- {
- // uint string_offset
- sizeOfTable += sizeof(uint);
- }
- }
+ if (symbol.File.Parent == null)
+ {
+ diagnostics.Error(DiagnosticId.AR_ERR_InvalidNullParentFileForSymbol, $"Invalid null Parent for file `{symbol.File}` for symbol `{symbol.Name}` [{i}] in {this}");
+ }
+ else if (symbol.File.Parent != Parent)
+ {
+ diagnostics.Error(DiagnosticId.AR_ERR_InvalidParentFileForSymbol, $"Invalid parent for file `{symbol.File}` for symbol `{symbol.Name}` [{i}] in {this}. The parent {nameof(ArArchiveFile)} is not the same instance as this symbol table");
}
+ }
+ }
- if ((sizeOfTable & 1) != 0)
+ protected override bool PrintMembers(StringBuilder builder)
+ {
+ builder.Append($"{nameof(Symbols)} Count: {Symbols.Count}");
+ return true;
+ }
+
+
+ protected override void UpdateLayoutCore(ArVisitorContext context)
+ {
+ if (Parent == null) return;
+
+ // number of entries (both for BSD and GNU)
+ ulong sizeOfTable = sizeof(uint);
+
+ foreach (var symbol in Symbols)
+ {
+ sizeOfTable += (ulong)Encoding.UTF8.GetByteCount(symbol.Name) + 1;
+
+ // uint file_offset
+ sizeOfTable += sizeof(uint);
+
+ if (Parent.Kind == ArArchiveKind.BSD)
{
- sizeOfTable++;
+ // uint string_offset
+ sizeOfTable += sizeof(uint);
}
+ }
- Size = sizeOfTable;
+ if ((sizeOfTable & 1) != 0)
+ {
+ sizeOfTable++;
}
+
+ Size = sizeOfTable;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Ar/ArVisitorContext.cs b/src/LibObjectFile/Ar/ArVisitorContext.cs
new file mode 100644
index 0000000..ccd600b
--- /dev/null
+++ b/src/LibObjectFile/Ar/ArVisitorContext.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using LibObjectFile.Diagnostics;
+
+namespace LibObjectFile.Ar;
+
+public class ArVisitorContext : VisitorContextBase
+{
+ internal ArVisitorContext(ArArchiveFile file, DiagnosticBag diagnostics) : base(file, diagnostics)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Collections/ObjectList.cs b/src/LibObjectFile/Collections/ObjectList.cs
new file mode 100644
index 0000000..839445f
--- /dev/null
+++ b/src/LibObjectFile/Collections/ObjectList.cs
@@ -0,0 +1,241 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace LibObjectFile.Collections;
+
+///
+/// A list of objects that are attached to a parent object.
+///
+/// The type of the object file.
+[DebuggerDisplay("Count = {Count}")]
+[DebuggerTypeProxy(typeof(ObjectList<>.ObjectListDebuggerView))]
+public readonly struct ObjectList : IList
+ where TObject : ObjectElement
+{
+ // We are using an internal list to keep track of the parent object
+ private readonly InternalList _items;
+
+ [Obsolete("This constructor is not supported", true)]
+ public ObjectList() => throw new NotSupportedException("This constructor is not supported");
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The parent object file node.
+ public ObjectList(
+ ObjectElement parent,
+ Action? adding= null,
+ Action? added = null,
+ Action? removing = null,
+ Action? removed = null,
+ Action? updating = null,
+ Action? updated = null
+ )
+ {
+ ArgumentNullException.ThrowIfNull(parent);
+ _items = new InternalList(parent, adding, added, removing, removed, updating, updated);
+ }
+
+ public int Count => _items.Count;
+
+ public bool IsReadOnly => false;
+
+ public List UnsafeList => _items;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Add(TObject item)
+ {
+ CheckAdd(item);
+ var items = _items;
+ int index = items.Count;
+ items.Adding(index, item);
+ items.Add(AssignAdd(item));
+ item.Index = index;
+ items.Added(item);
+ }
+
+ public void Clear()
+ {
+ var items = _items;
+ for (var i = items.Count - 1; i >= 0; i--)
+ {
+ var item = items[i];
+ items.Removing(item);
+ items.RemoveAt(i);
+ item.Parent = null;
+ item.ResetIndex();
+ items.Removed(i, item);
+ }
+
+ items.Clear();
+ }
+
+ public bool Contains(TObject item) => _items.Contains(item);
+
+ public void CopyTo(TObject[] array, int arrayIndex) => _items.CopyTo(array, arrayIndex);
+
+ public bool Remove(TObject item)
+ {
+ var items = _items;
+ if (item.Parent != items.Parent)
+ {
+ return false;
+ }
+
+ item.Parent = null;
+ item.ResetIndex();
+
+ return items.Remove(item);
+ }
+
+ public int IndexOf(TObject item) => _items.IndexOf(item);
+
+ public void Insert(int index, TObject item)
+ {
+ if ((uint)index > (uint)_items.Count) throw new ArgumentOutOfRangeException(nameof(index));
+
+ CheckAdd(item);
+ var items = _items;
+ items.Adding(index, item);
+ items.Insert(index, AssignAdd(item));
+
+ for (int i = index; i < items.Count; i++)
+ {
+ items[i].Index = i;
+ }
+
+ items.Added(item);
+ }
+
+ public void RemoveAt(int index)
+ {
+ var items = _items;
+ var item = items[index];
+ items.Removing(item);
+ item.Parent = null;
+ item.ResetIndex();
+
+ items.RemoveAt(index);
+
+ for (int i = index; i < items.Count; i++)
+ {
+ items[i].Index = i;
+ }
+ }
+
+ public TObject this[int index]
+ {
+ get => _items[index];
+ set
+ {
+ CheckAdd(value);
+
+ // Unbind previous entry
+ var items = _items;
+ var previousItem = items[index];
+ items.Updating(index, previousItem, value);
+ items.Removing(previousItem);
+ previousItem.Parent = null;
+ previousItem.ResetIndex();
+
+ // Bind new entry
+ items[index] = AssignAdd(value);
+ value.Index = index;
+ items.Updated(index, previousItem, value);
+ }
+ }
+
+ public List.Enumerator GetEnumerator() => _items.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _items.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_items).GetEnumerator();
+ }
+
+ private void CheckAdd(TObject item)
+ {
+ ArgumentNullException.ThrowIfNull(item);
+ if (item.Parent != null)
+ {
+ throw new ArgumentException($"The object is already attached to another parent", nameof(item));
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private TObject AssignAdd(TObject item)
+ {
+ item.Parent = _items.Parent;
+ return item;
+ }
+
+ private sealed class InternalList(ObjectElement parent,
+ Action? adding,
+ Action? added,
+ Action? removing,
+ Action? removed,
+ Action? updating,
+ Action? updated
+ ) : List
+ {
+ private readonly Action? _adding = adding;
+ private readonly Action? _added = added;
+ private readonly Action? _removing = removing;
+ private readonly Action? _removed = removed;
+ private readonly Action? _updating = updating;
+ private readonly Action? _updated = updated;
+
+ public readonly ObjectElement Parent = parent;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Adding(int index, TObject item) => _adding?.Invoke(Parent, index, item);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Added(TObject item) => _added?.Invoke(Parent, item);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Removing(TObject item) => _removing?.Invoke(Parent, item);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Updating(int index, TObject previousItem, TObject newItem) => _updating?.Invoke(Parent, index, previousItem, newItem);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Updated(int index, TObject previousItem, TObject newItem) => _updated?.Invoke(Parent, index, previousItem, newItem);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Removed(int index, TObject removedItem) => _removed?.Invoke(Parent, index, removedItem);
+ }
+
+ internal sealed class ObjectListDebuggerView
+ {
+ private readonly List _collection;
+
+ public ObjectListDebuggerView(ObjectList collection)
+ {
+ ArgumentNullException.ThrowIfNull(collection, nameof(collection));
+ _collection = collection.UnsafeList;
+ }
+
+ [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+ public TObject[] Items
+ {
+ get
+ {
+ var array = new TObject[_collection.Count];
+ _collection.CopyTo(array, 0);
+ return array;
+ }
+ }
+ }
+}
diff --git a/src/LibObjectFile/Collections/ReadOnlyList.cs b/src/LibObjectFile/Collections/ReadOnlyList.cs
new file mode 100644
index 0000000..05b96db
--- /dev/null
+++ b/src/LibObjectFile/Collections/ReadOnlyList.cs
@@ -0,0 +1,73 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace LibObjectFile.Collections;
+
+///
+/// A lightweight read-only wrapper around a List<T> that avoids the cost of interface dispatch from IReadOnlyList<T>.
+///
+/// The type of the collection
+[DebuggerTypeProxy(typeof(ReadOnlyList<>.ReadOnlyListView))]
+[DebuggerDisplay("Count = {Count}")]
+public readonly struct ReadOnlyList : IReadOnlyList
+{
+ private readonly List _items;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The items to wrap.
+ public ReadOnlyList(List items) => _items = items;
+
+ ///
+ public int Count => _items.Count;
+
+ ///
+ public T this[int index] => _items[index];
+
+ public List.Enumerator GetEnumerator() => _items.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _items.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_items).GetEnumerator();
+ }
+
+ ///
+ /// Converts a List<T> to a ReadOnlyList<T>.
+ ///
+ /// The list to convert.
+ public static implicit operator ReadOnlyList(List items) => new(items);
+
+ internal sealed class ReadOnlyListView
+ {
+ private readonly List _collection;
+
+ public ReadOnlyListView(List collection)
+ {
+ ArgumentNullException.ThrowIfNull(collection, nameof(collection));
+ _collection = collection;
+ }
+
+ [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+ public T[] Items
+ {
+ get
+ {
+ T[] array = new T[_collection.Count];
+ _collection.CopyTo(array, 0);
+ return array;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Collections/SortedObjectList.cs b/src/LibObjectFile/Collections/SortedObjectList.cs
new file mode 100644
index 0000000..4dc08e1
--- /dev/null
+++ b/src/LibObjectFile/Collections/SortedObjectList.cs
@@ -0,0 +1,236 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace LibObjectFile.Collections;
+
+///
+/// A list of objects that are attached to a parent object.
+///
+/// The type of the object file.
+[DebuggerDisplay("Count = {Count}")]
+[DebuggerTypeProxy(typeof(SortedObjectList<>.ObjectListDebuggerView))]
+public readonly struct SortedObjectList : IList
+ where TObject : ObjectElement, IComparable
+{
+ // We are using an internal list to keep track of the parent object
+ private readonly InternalList _items;
+
+ [Obsolete("This constructor is not supported", true)]
+ public SortedObjectList() => throw new NotSupportedException("This constructor is not supported");
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The parent object file node.
+ public SortedObjectList(ObjectElement parent)
+ {
+ ArgumentNullException.ThrowIfNull(parent);
+ _items = new InternalList(parent);
+ }
+
+ public int Count => _items.Count;
+
+ public bool IsReadOnly => false;
+
+ public List UnsafeList => _items;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Add(TObject item)
+ {
+ CheckAdd(item);
+ var items = _items;
+ if (items.Count > 0 && item.CompareTo(items[^1]) > 0)
+ {
+ int index = items.Count;
+ items.Add(AssignAdd(item));
+ item.Index = index;
+ }
+ else
+ {
+ var index = items.BinarySearch(item);
+ if (index < 0)
+ {
+ index = ~index;
+ }
+ items.Insert(index, AssignAdd(item));
+ item.Index = index;
+ }
+ }
+
+ public void Clear()
+ {
+ var items = _items;
+ for (var i = items.Count - 1; i >= 0; i--)
+ {
+ var item = items[i];
+ items.RemoveAt(i);
+ item.Parent = null;
+ item.ResetIndex();
+ }
+
+ items.Clear();
+ }
+
+ public bool Contains(TObject item) => _items.Contains(item);
+
+ public void CopyTo(TObject[] array, int arrayIndex) => _items.CopyTo(array, arrayIndex);
+
+ public bool Remove(TObject item)
+ {
+ var items = _items;
+ if (item.Parent != items.Parent)
+ {
+ return false;
+ }
+
+ item.Parent = null;
+ item.ResetIndex();
+
+ return items.Remove(item);
+ }
+
+ public int IndexOf(TObject item) => _items.IndexOf(item);
+
+ public void Insert(int index, TObject item)
+ {
+ if ((uint)index > (uint)_items.Count) throw new ArgumentOutOfRangeException(nameof(index));
+
+ CheckAdd(item);
+ var items = _items;
+
+ var expectedIndex = items.BinarySearch(item);
+ if (expectedIndex < 0)
+ {
+ expectedIndex = ~expectedIndex;
+ }
+
+ if (expectedIndex != index)
+ {
+ throw new ArgumentException($"The index {index} is not valid for the item {item} to maintain the order of the list");
+ }
+
+ items.Insert(index, AssignAdd(item));
+
+ for (int i = index; i < items.Count; i++)
+ {
+ items[i].Index = i;
+ }
+ }
+
+ public void RemoveAt(int index)
+ {
+ var items = _items;
+ var item = items[index];
+ item.Parent = null;
+ item.ResetIndex();
+
+ items.RemoveAt(index);
+
+ for (int i = index; i < items.Count; i++)
+ {
+ items[i].Index = i;
+ }
+ }
+
+ public TObject this[int index]
+ {
+ get => _items[index];
+ set
+ {
+ if ((uint)index >= (uint)_items.Count) throw new ArgumentOutOfRangeException(nameof(index));
+ CheckAdd(value);
+
+ // Unbind previous entry
+ var items = _items;
+
+ var expectedIndex = items.BinarySearch(value);
+ if (expectedIndex < 0)
+ {
+ expectedIndex = ~expectedIndex;
+ }
+ if (expectedIndex != index)
+ {
+ throw new ArgumentException($"The index {index} is not valid for the item {value} to maintain the order of the list");
+ }
+
+ if (index < items.Count)
+ {
+ var previousItem = items[index];
+ previousItem.Parent = null;
+ previousItem.ResetIndex();
+
+ // Bind new entry
+ items[index] = AssignAdd(value);
+ value.Index = index;
+ }
+ else
+ {
+ items.Add(AssignAdd(value));
+ value.Index = items.Count - 1;
+ }
+ }
+ }
+
+ public List.Enumerator GetEnumerator() => _items.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _items.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_items).GetEnumerator();
+ }
+
+ private void CheckAdd(TObject item)
+ {
+ ArgumentNullException.ThrowIfNull(item);
+ if (item.Parent != null)
+ {
+ throw new ArgumentException($"The object is already attached to another parent", nameof(item));
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private TObject AssignAdd(TObject item)
+ {
+ item.Parent = _items.Parent;
+ return item;
+ }
+
+ private sealed class InternalList(ObjectElement parent) : List
+ {
+ public readonly ObjectElement Parent = parent;
+ }
+
+ internal sealed class ObjectListDebuggerView
+ {
+ private readonly List _collection;
+
+ public ObjectListDebuggerView(SortedObjectList collection)
+ {
+ ArgumentNullException.ThrowIfNull(collection, nameof(collection));
+ _collection = collection.UnsafeList;
+ }
+
+ [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+ public TObject[] Items
+ {
+ get
+ {
+ var array = new TObject[_collection.Count];
+ _collection.CopyTo(array, 0);
+ return array;
+ }
+ }
+ }
+}
diff --git a/src/LibObjectFile/Collections/TempSpan.cs b/src/LibObjectFile/Collections/TempSpan.cs
new file mode 100644
index 0000000..95c483e
--- /dev/null
+++ b/src/LibObjectFile/Collections/TempSpan.cs
@@ -0,0 +1,110 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Buffers;
+using System.Runtime.InteropServices;
+
+namespace LibObjectFile.Collections;
+
+///
+/// Represents a pooled span that can be created from a stack or heap memory.
+///
+/// The type of the elements in the span.
+public readonly ref struct TempSpan where T : unmanaged
+{
+ private readonly Span _span;
+ private readonly byte[]? _buffer;
+
+ ///
+ /// Initializes a new instance of the struct using a stack memory span.
+ ///
+ /// The stack memory span.
+ /// The size of the span in bytes.
+ private TempSpan(Span span, int size)
+ {
+ _span = MemoryMarshal.Cast(span.Slice(0, size));
+ _buffer = null;
+ }
+
+ ///
+ /// Initializes a new instance of the struct using a heap memory span.
+ ///
+ /// The heap memory buffer.
+ /// The size of the span in bytes.
+ private TempSpan(byte[] buffer, int size)
+ {
+ _span = MemoryMarshal.Cast(new(buffer, 0, size));
+ _buffer = buffer;
+ }
+
+ ///
+ /// Creates a new instance of the struct with the specified number of elements.
+ ///
+ /// The number of elements in the span.
+ /// A new instance of the struct.
+ public static unsafe TempSpan Create(int count, out Span span)
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(count, 0);
+ var size = count * sizeof(T);
+ var buffer = ArrayPool.Shared.Rent(size);
+ var tempSpan = new TempSpan(buffer, size);
+ span = tempSpan.Span;
+ return tempSpan;
+ }
+
+ ///
+ /// Creates a new instance of the struct with the specified number of elements, using a stack memory span if possible.
+ ///
+ /// The stack memory span.
+ /// The number of elements in the span.
+ /// A new instance of the struct.
+ public static unsafe TempSpan Create(Span stackSpan, int count, out Span span)
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(count, 0);
+ var size = count * sizeof(T);
+ if (size <= stackSpan.Length)
+ {
+ var tempSpan = new TempSpan(stackSpan, size);
+ span = tempSpan.Span;
+ return tempSpan;
+ }
+
+ return Create(count, out span);
+ }
+
+ ///
+ /// Gets the span of elements.
+ ///
+ public Span Span => _span;
+
+ ///
+ /// Gets the span of elements as bytes.
+ ///
+ public Span AsBytes => MemoryMarshal.AsBytes(_span);
+
+ ///
+ /// Releases the underlying memory buffer if it was allocated on the heap.
+ ///
+ public void Dispose()
+ {
+ var buffer = _buffer;
+ if (buffer != null)
+ {
+ ArrayPool.Shared.Return(buffer);
+ }
+ }
+
+ ///
+ /// Gets the span of elements.
+ ///
+ /// The pooled span to convert.
+ public static implicit operator Span(TempSpan tempSpan) => tempSpan.Span;
+
+ ///
+ /// Gets the span of elements as a span of bytes.
+ ///
+ /// The pooled span to convert.
+ public static implicit operator Span(TempSpan tempSpan) => tempSpan.AsBytes;
+}
diff --git a/src/LibObjectFile/DiagnosticBag.cs b/src/LibObjectFile/DiagnosticBag.cs
deleted file mode 100644
index 75e6ed0..0000000
--- a/src/LibObjectFile/DiagnosticBag.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
-// This file is licensed under the BSD-Clause 2 license.
-// See the license.txt file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-
-namespace LibObjectFile
-{
- ///
- /// A container for used for error reporting while reading/writing object files.
- ///
- [DebuggerDisplay("Count = {Messages.Count}, HasErrors = {" + nameof(HasErrors) + "}")]
- public class DiagnosticBag
- {
- private readonly List _messages;
-
- public DiagnosticBag()
- {
- _messages = new List();
- }
-
- ///
- /// List of messages.
- ///
- public IReadOnlyList Messages => _messages;
-
- ///
- /// If this instance contains error messages.
- ///
- public bool HasErrors { get; private set; }
-
- ///
- /// Clear all messages.
- ///
- public void Clear()
- {
- _messages.Clear();
- HasErrors = false;
- }
-
- ///
- /// Copy all the in this bag to another bag.
- ///
- /// The diagnostics receiving the copy of the
- public void CopyTo(DiagnosticBag diagnostics)
- {
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
- foreach (var diagnosticMessage in Messages)
- {
- diagnostics.Log(diagnosticMessage);
- }
- }
-
- ///
- /// Logs the specified .
- ///
- /// The diagnostic message
- public void Log(DiagnosticMessage message)
- {
- if (message.Message == null) throw new InvalidOperationException($"{nameof(DiagnosticMessage)}.{nameof(DiagnosticMessage.Message)} cannot be null");
- _messages.Add(message);
- if (message.Kind == DiagnosticKind.Error)
- {
- HasErrors = true;
- }
- }
-
- ///
- /// Log an error .
- ///
- /// The identifier of the diagnostic.
- /// The text of the message
- /// An optional context
- public void Error(DiagnosticId id, string message, object context = null)
- {
- if (message == null) throw new ArgumentNullException(nameof(message));
- Log(new DiagnosticMessage(DiagnosticKind.Error, id, message, context));
- }
-
- ///
- /// Log an error .
- ///
- /// The identifier of the diagnostic.
- /// The text of the message
- /// An optional context
- public void Warning(DiagnosticId id, string message, object context = null)
- {
- if (message == null) throw new ArgumentNullException(nameof(message));
- Log(new DiagnosticMessage(DiagnosticKind.Warning, id, message, context));
- }
-
- public override string ToString()
- {
- var builder = new StringBuilder();
- foreach (var diagnosticMessage in Messages)
- {
- builder.AppendLine(diagnosticMessage.ToString());
- }
-
- return builder.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/src/LibObjectFile/DiagnosticId.cs b/src/LibObjectFile/DiagnosticId.cs
deleted file mode 100644
index 170dd84..0000000
--- a/src/LibObjectFile/DiagnosticId.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
-// This file is licensed under the BSD-Clause 2 license.
-// See the license.txt file in the project root for more information.
-
-namespace LibObjectFile
-{
- ///
- /// Defines the various diagnostic message ids.
- ///
- public enum DiagnosticId
- {
- CMN_ERR_UnexpectedEndOfFile = 1,
-
- // Elf
- ELF_ERR_LinkOrInfoSectionNull = 102,
- ELF_ERR_LinkOrInfoInvalidSectionType = 103,
- ELF_ERR_LinkOrInfoInvalidSectionInstance = 104,
- ELF_ERR_InvalidHeaderFileClassNone = 105,
- ELF_ERR_InvalidHeaderIdentLength = 106,
- ELF_ERR_InvalidHeaderMagic = 107,
- //ELF_ERR_InvalidHeaderFileClass = 8,
- //ELF_ERR_InvalidHeaderEncoding = 9,
- ELF_ERR_MissingProgramHeaderTableSection = 110,
- ELF_ERR_InvalidSectionHeaderCount = 111,
- ELF_ERR_IncompleteHeader32Size = 112,
- ELF_ERR_IncompleteHeader64Size = 113,
- ELF_ERR_InvalidZeroProgramHeaderTableEntrySize = 114,
- ELF_ERR_InvalidProgramHeaderStreamOffset = 115,
- ELF_ERR_IncompleteProgramHeader32Size = 116,
- ELF_ERR_IncompleteProgramHeader64Size = 117,
- ELF_ERR_InvalidZeroSectionHeaderTableEntrySize = 118,
- ELF_ERR_InvalidSectionHeaderStreamOffset = 119,
- ELF_ERR_IncompleteSectionHeader32Size = 120,
- ELF_ERR_IncompleteSectionHeader64Size = 121,
- ELF_ERR_InvalidResolvedLink = 122,
- ELF_ERR_InvalidFirstSectionExpectingUndefined = 123,
- ELF_ERR_InvalidStringIndexMissingStringHeaderTable = 124,
- ELF_ERR_InvalidStringIndex = 125,
- ELF_ERR_InvalidOverlappingSections = 126,
- ELF_ERR_InvalidSegmentRange = 127,
- ELF_ERR_InvalidSectionSizeKind = 128,
- ELF_ERR_InvalidSectionLinkParent = 129,
- ELF_ERR_InvalidSectionInfoParent = 130,
- ELF_ERR_InvalidSegmentRangeBeginSectionParent = 131,
- ELF_ERR_InvalidSegmentRangeEndSectionParent = 132,
- ELF_ERR_InvalidSegmentRangeBeginOffset = 133,
- ELF_ERR_InvalidSegmentRangeEndOffset = 134,
- ELF_ERR_InvalidSegmentRangeIndices = 135,
- ELF_ERR_IncompleteRelocationAddendsEntry32Size = 136,
- ELF_ERR_IncompleteRelocationEntry32Size = 137,
- ELF_ERR_IncompleteRelocationAddendsEntry64Size = 138,
- ELF_ERR_IncompleteRelocationEntry64Size = 139,
- ELF_WRN_InvalidRelocationTablePrefixName = 140,
- ELF_WRN_InvalidRelocationTablePrefixTargetName = 141,
- ELF_ERR_InvalidRelocationInfoParent = 142,
- ELF_ERR_InvalidRelocationEntryAddend = 143,
- ELF_ERR_InvalidRelocationEntryArch = 144,
- ELF_ERR_InvalidRelocationSymbolIndex = 145,
- ELF_ERR_IncompleteSymbolEntry32Size = 146,
- ELF_ERR_IncompleteSymbolEntry64Size = 147,
- ELF_ERR_InvalidFirstSymbolEntryNonNull = 148,
- ELF_ERR_InvalidSymbolEntryNameIndex = 149,
- ELF_ERR_InvalidSymbolEntrySectionParent = 150,
- ELF_ERR_InvalidSymbolEntryLocalPosition = 151,
- ELF_ERR_IncompleteNoteEntrySize = 152,
- ELF_ERR_IncompleNoteGnuAbiTag = 153,
- ELF_ERR_InvalidSegmentVirtualAddressOrOffset = 154,
- ELF_ERR_InvalidSegmentAlignmentForLoad = 155,
- ELF_ERR_InvalidStreamForSectionNoBits = 156,
- ELF_ERR_InvalidNullSection = 157,
- ELF_ERR_InvalidAlignmentOutOfRange = 158,
- ELF_ERR_MissingSectionHeaderIndices = 159,
- ELF_ERR_MissingNullSection = 159,
-
- AR_ERR_InvalidMagicLength = 1000,
- AR_ERR_MagicNotFound = 1001,
- AR_ERR_ExpectingNewLineCharacter = 1002,
- //AR_ERR_UnexpectedEndOfFile = 1003,
- AR_ERR_InvalidFileEntryLength = 1004,
- AR_ERR_InvalidNonPrintableASCIIFoundInFileEntry = 1005,
- AR_ERR_InvalidCharacterFoundInFileEntry = 1006,
- AR_ERR_InvalidNullFileEntryName = 1007,
- AR_ERR_InvalidFileOffsetInSystemVSymbolLookupTable = 1008,
- AR_ERR_InvalidDuplicatedFutureHeadersTable = 1009,
- AR_ERR_InvalidReferenceToFutureHeadersTable = 1010,
- AR_ERR_InvalidFileEntryNameTooLong = 1011,
- AR_ERR_InvalidCharacterInFileEntryName = 1012,
- AR_ERR_InvalidNullOrEmptySymbolName = 1013,
- AR_ERR_InvalidNullFileForSymbol = 1014,
- AR_ERR_InvalidNullParentFileForSymbol = 1015,
- AR_ERR_InvalidParentFileForSymbol = 1016,
- AR_ERR_InvalidFileEntrySize = 1017,
-
-
- DWARF_ERR_AttributeLEB128OutOfRange = 2000,
- DWARF_ERR_VersionNotSupported = 2001,
- DWARF_ERR_InvalidData = 2002,
- DWARF_WRN_UnsupportedLineExtendedCode = 2003,
- DWARF_ERR_InvalidReference = 2004,
- DWARF_ERR_MissingStringTable = 2005,
- DWARF_ERR_InvalidNumberOfStandardOpCodeLengths = 2006,
- DWARF_ERR_InvalidStandardOpCodeLength = 2007,
- DWARF_WRN_CannotEncodeAddressIncrement = 2008,
- DWARF_ERR_InvalidNullFileNameEntry = 2009,
- DWARF_ERR_InvalidFileName = 2010,
- DWARF_ERR_InvalidMaximumOperationsPerInstruction = 2011,
- DWARF_ERR_InvalidNegativeAddressDelta = 2012,
- DWARF_ERR_InvalidOperationIndex = 2013,
- DWARF_ERR_InvalidAddressSize = 2014,
- DWARF_ERR_UnsupportedUnitType = 2015,
- DWARF_ERR_InvalidNullUnitForAddressRangeTable = 2016,
- DWARF_ERR_InvalidParentUnitForAddressRangeTable = 2017,
- DWARF_ERR_InvalidParentForDIE = 2018,
- DWARF_WRN_InvalidExtendedOpCodeLength = 2019,
- DWARF_ERR_InvalidParentForLocationList = 2020,
-
- }
-}
\ No newline at end of file
diff --git a/src/LibObjectFile/DiagnosticKind.cs b/src/LibObjectFile/DiagnosticKind.cs
deleted file mode 100644
index 2ec7425..0000000
--- a/src/LibObjectFile/DiagnosticKind.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
-// This file is licensed under the BSD-Clause 2 license.
-// See the license.txt file in the project root for more information.
-
-namespace LibObjectFile
-{
- ///
- /// Defines the kind of a
- ///
- public enum DiagnosticKind
- {
- ///
- /// A warning message.
- ///
- Warning,
-
- ///
- /// An error message.
- ///
- Error,
- }
-}
\ No newline at end of file
diff --git a/src/LibObjectFile/DiagnosticMessage.cs b/src/LibObjectFile/DiagnosticMessage.cs
deleted file mode 100644
index 52633fd..0000000
--- a/src/LibObjectFile/DiagnosticMessage.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
-// This file is licensed under the BSD-Clause 2 license.
-// See the license.txt file in the project root for more information.
-
-namespace LibObjectFile
-{
- ///
- /// A diagnostic message.
- ///
- public readonly struct DiagnosticMessage
- {
- public DiagnosticMessage(DiagnosticKind kind, DiagnosticId id, string message)
- {
- Kind = kind;
- Id = id;
- Context = null;
- Message = message;
- }
-
- public DiagnosticMessage(DiagnosticKind kind, DiagnosticId id, string message, object context)
- {
- Kind = kind;
- Id = id;
- Context = context;
- Message = message;
- }
-
- ///
- /// Gets the kind of this message.
- ///
- public DiagnosticKind Kind { get; }
-
- ///
- /// Gets the id of this message.
- ///
- public DiagnosticId Id { get; }
-
- ///
- /// Gets the context of this message.
- ///
- public object Context { get; }
-
- ///
- /// Gets the associated text of this message.
- ///
- public string Message { get; }
-
- public override string ToString()
- {
- return $"{Kind} LB{(uint)Id:0000}: {Message}";
- }
- }
-}
\ No newline at end of file
diff --git a/src/LibObjectFile/Diagnostics/DiagnosticBag.cs b/src/LibObjectFile/Diagnostics/DiagnosticBag.cs
new file mode 100644
index 0000000..f3f71d9
--- /dev/null
+++ b/src/LibObjectFile/Diagnostics/DiagnosticBag.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using LibObjectFile.Collections;
+
+namespace LibObjectFile.Diagnostics;
+
+///
+/// A container for used for error reporting while reading/writing object files.
+///
+[DebuggerDisplay("Count = {Messages.Count}, HasErrors = {" + nameof(HasErrors) + "}")]
+public class DiagnosticBag
+{
+ private readonly List _messages;
+
+ public DiagnosticBag()
+ {
+ _messages = new List();
+ }
+
+ ///
+ /// List of messages.
+ ///
+ public ReadOnlyList Messages => _messages;
+
+ ///
+ /// If this instance contains error messages.
+ ///
+ public bool HasErrors { get; private set; }
+
+ ///
+ /// Gets or sets a value indicating whether to enable stack trace for each message.
+ ///
+ public bool EnableStackTrace { get; set; }
+
+ ///
+ /// Clear all messages.
+ ///
+ public void Clear()
+ {
+ _messages.Clear();
+ HasErrors = false;
+ }
+
+ ///
+ /// Copy all the in this bag to another bag.
+ ///
+ /// The diagnostics receiving the copy of the
+ public void CopyTo(DiagnosticBag diagnostics)
+ {
+ if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
+ foreach (var diagnosticMessage in Messages)
+ {
+ diagnostics.Log(diagnosticMessage);
+ }
+ }
+
+ ///
+ /// Logs the specified .
+ ///
+ /// The diagnostic message
+ public void Log(DiagnosticMessage message)
+ {
+ if (message.Message == null) throw new InvalidOperationException($"{nameof(DiagnosticMessage)}.{nameof(DiagnosticMessage.Message)} cannot be null");
+ _messages.Add(message);
+ if (message.Kind == DiagnosticKind.Error)
+ {
+ HasErrors = true;
+ }
+ }
+
+ ///
+ /// Log an error .
+ ///
+ /// The identifier of the diagnostic.
+ /// The text of the message
+ /// An optional context
+ public void Error(DiagnosticId id, string message, object? context = null)
+ {
+ if (message == null) throw new ArgumentNullException(nameof(message));
+ Log(new DiagnosticMessage(DiagnosticKind.Error, id, message, context)
+ {
+ StackTrace = EnableStackTrace ? new StackTrace(1, true) : null
+ });
+ }
+
+ ///
+ /// Log an error .
+ ///
+ /// The identifier of the diagnostic.
+ /// The text of the message
+ /// An optional context
+ public void Warning(DiagnosticId id, string message, object? context = null)
+ {
+ if (message == null) throw new ArgumentNullException(nameof(message));
+ Log(new DiagnosticMessage(DiagnosticKind.Warning, id, message, context)
+ {
+ StackTrace = EnableStackTrace ? new StackTrace(1, true) : null
+ });
+ }
+
+ public override string ToString()
+ {
+ var builder = new StringBuilder();
+ foreach (var diagnosticMessage in Messages)
+ {
+ builder.AppendLine(diagnosticMessage.ToString());
+ }
+
+ return builder.ToString();
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Diagnostics/DiagnosticId.cs b/src/LibObjectFile/Diagnostics/DiagnosticId.cs
new file mode 100644
index 0000000..3690353
--- /dev/null
+++ b/src/LibObjectFile/Diagnostics/DiagnosticId.cs
@@ -0,0 +1,207 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+namespace LibObjectFile.Diagnostics;
+
+///
+/// Defines the various diagnostic message ids.
+///
+public enum DiagnosticId
+{
+ CMN_ERR_UnexpectedEndOfFile = 1,
+
+ // Elf
+ ELF_ERR_LinkOrInfoSectionNull = 102,
+ ELF_ERR_LinkOrInfoInvalidSectionType = 103,
+ ELF_ERR_LinkOrInfoInvalidSectionInstance = 104,
+ ELF_ERR_InvalidHeaderFileClassNone = 105,
+ ELF_ERR_InvalidHeaderIdentLength = 106,
+ ELF_ERR_InvalidHeaderMagic = 107,
+ //ELF_ERR_InvalidHeaderFileClass = 8,
+ //ELF_ERR_InvalidHeaderEncoding = 9,
+ ELF_ERR_MissingProgramHeaderTableSection = 110,
+ ELF_ERR_InvalidSectionHeaderCount = 111,
+ ELF_ERR_IncompleteHeader32Size = 112,
+ ELF_ERR_IncompleteHeader64Size = 113,
+ ELF_ERR_InvalidZeroProgramHeaderTableEntrySize = 114,
+ ELF_ERR_InvalidProgramHeaderStreamOffset = 115,
+ ELF_ERR_IncompleteProgramHeader32Size = 116,
+ ELF_ERR_IncompleteProgramHeader64Size = 117,
+ ELF_ERR_InvalidZeroSectionHeaderTableEntrySize = 118,
+ ELF_ERR_InvalidSectionHeaderStreamOffset = 119,
+ ELF_ERR_IncompleteSectionHeader32Size = 120,
+ ELF_ERR_IncompleteSectionHeader64Size = 121,
+ ELF_ERR_InvalidResolvedLink = 122,
+ ELF_ERR_InvalidFirstSectionExpectingUndefined = 123,
+ ELF_ERR_InvalidStringIndexMissingStringHeaderTable = 124,
+ ELF_ERR_InvalidStringIndex = 125,
+ ELF_ERR_InvalidOverlappingSections = 126,
+ ELF_ERR_InvalidSegmentRange = 127,
+ ELF_ERR_InvalidSectionSizeKind = 128,
+ ELF_ERR_InvalidSectionLinkParent = 129,
+ ELF_ERR_InvalidSectionInfoParent = 130,
+ ELF_ERR_InvalidSegmentRangeBeginSectionParent = 131,
+ ELF_ERR_InvalidSegmentRangeEndSectionParent = 132,
+ ELF_ERR_InvalidSegmentRangeBeginOffset = 133,
+ ELF_ERR_InvalidSegmentRangeEndOffset = 134,
+ ELF_ERR_InvalidSegmentRangeIndices = 135,
+ ELF_ERR_IncompleteRelocationAddendsEntry32Size = 136,
+ ELF_ERR_IncompleteRelocationEntry32Size = 137,
+ ELF_ERR_IncompleteRelocationAddendsEntry64Size = 138,
+ ELF_ERR_IncompleteRelocationEntry64Size = 139,
+ ELF_WRN_InvalidRelocationTablePrefixName = 140,
+ ELF_WRN_InvalidRelocationTablePrefixTargetName = 141,
+ ELF_ERR_InvalidRelocationInfoParent = 142,
+ ELF_ERR_InvalidRelocationEntryAddend = 143,
+ ELF_ERR_InvalidRelocationEntryArch = 144,
+ ELF_ERR_InvalidRelocationSymbolIndex = 145,
+ ELF_ERR_IncompleteSymbolEntry32Size = 146,
+ ELF_ERR_IncompleteSymbolEntry64Size = 147,
+ ELF_ERR_InvalidFirstSymbolEntryNonNull = 148,
+ ELF_ERR_InvalidSymbolEntryNameIndex = 149,
+ ELF_ERR_InvalidSymbolEntrySectionParent = 150,
+ ELF_ERR_InvalidSymbolEntryLocalPosition = 151,
+ ELF_ERR_IncompleteNoteEntrySize = 152,
+ ELF_ERR_IncompleNoteGnuAbiTag = 153,
+ ELF_ERR_InvalidSegmentVirtualAddressOrOffset = 154,
+ ELF_ERR_InvalidSegmentAlignmentForLoad = 155,
+ ELF_ERR_InvalidStreamForSectionNoBits = 156,
+ ELF_ERR_InvalidNullSection = 157,
+ ELF_ERR_InvalidAlignmentOutOfRange = 158,
+ ELF_ERR_MissingSectionHeaderIndices = 159,
+ ELF_ERR_MissingNullSection = 159,
+
+ AR_ERR_InvalidMagicLength = 1000,
+ AR_ERR_MagicNotFound = 1001,
+ AR_ERR_ExpectingNewLineCharacter = 1002,
+ //AR_ERR_UnexpectedEndOfFile = 1003,
+ AR_ERR_InvalidFileEntryLength = 1004,
+ AR_ERR_InvalidNonPrintableASCIIFoundInFileEntry = 1005,
+ AR_ERR_InvalidCharacterFoundInFileEntry = 1006,
+ AR_ERR_InvalidNullFileEntryName = 1007,
+ AR_ERR_InvalidFileOffsetInSystemVSymbolLookupTable = 1008,
+ AR_ERR_InvalidDuplicatedFutureHeadersTable = 1009,
+ AR_ERR_InvalidReferenceToFutureHeadersTable = 1010,
+ AR_ERR_InvalidFileEntryNameTooLong = 1011,
+ AR_ERR_InvalidCharacterInFileEntryName = 1012,
+ AR_ERR_InvalidNullOrEmptySymbolName = 1013,
+ AR_ERR_InvalidNullFileForSymbol = 1014,
+ AR_ERR_InvalidNullParentFileForSymbol = 1015,
+ AR_ERR_InvalidParentFileForSymbol = 1016,
+ AR_ERR_InvalidFileEntrySize = 1017,
+
+
+ DWARF_ERR_AttributeLEB128OutOfRange = 2000,
+ DWARF_ERR_VersionNotSupported = 2001,
+ DWARF_ERR_InvalidData = 2002,
+ DWARF_WRN_UnsupportedLineExtendedCode = 2003,
+ DWARF_ERR_InvalidReference = 2004,
+ DWARF_ERR_MissingStringTable = 2005,
+ DWARF_ERR_InvalidNumberOfStandardOpCodeLengths = 2006,
+ DWARF_ERR_InvalidStandardOpCodeLength = 2007,
+ DWARF_WRN_CannotEncodeAddressIncrement = 2008,
+ DWARF_ERR_InvalidNullFileNameEntry = 2009,
+ DWARF_ERR_InvalidFileName = 2010,
+ DWARF_ERR_InvalidMaximumOperationsPerInstruction = 2011,
+ DWARF_ERR_InvalidNegativeAddressDelta = 2012,
+ DWARF_ERR_InvalidOperationIndex = 2013,
+ DWARF_ERR_InvalidAddressSize = 2014,
+ DWARF_ERR_UnsupportedUnitType = 2015,
+ DWARF_ERR_InvalidNullUnitForAddressRangeTable = 2016,
+ DWARF_ERR_InvalidParentUnitForAddressRangeTable = 2017,
+ DWARF_ERR_InvalidParentForDIE = 2018,
+ DWARF_WRN_InvalidExtendedOpCodeLength = 2019,
+ DWARF_ERR_InvalidParentForLocationList = 2020,
+
+ // PE errors
+ PE_ERR_InvalidDosHeaderSize = 3000,
+ PE_ERR_InvalidDosHeaderMagic = 3001,
+ PE_ERR_InvalidDosStubSize = 3002,
+ PE_ERR_InvalidPESignature = 3003,
+ PE_ERR_InvalidCoffHeaderSize = 3004,
+ PE_ERR_InvalidOptionalHeaderSize = 3005,
+ PE_ERR_InvalidOptionalHeaderMagic = 3006,
+ PE_ERR_InvalidSectionHeadersSize = 3007,
+ PE_ERR_InvalidParent = 3008,
+ PE_ERR_InvalidExtraData = 3009,
+ PE_ERR_SectionSizeLargerThanVirtualSize = 3010,
+ PE_ERR_SectionRVALessThanPrevious = 3011,
+ PE_ERR_TooManySections = 3012,
+ PE_ERR_FileAlignmentNotPowerOfTwo = 3013,
+ PE_ERR_SectionAlignmentNotPowerOfTwo = 3014,
+ PE_ERR_SectionAlignmentLessThanFileAlignment = 3015,
+ PE_ERR_InvalidPEHeaderPosition = 3016,
+ PE_ERR_InvalidNumberOfDataDirectories = 3017,
+ PE_ERR_InvalidBaseOfCode = 3018,
+ PE_ERR_InvalidAddressOfEntryPoint = 3019,
+ PE_ERR_DirectoryWithSameKindAlreadyAdded = 3020,
+ PE_ERR_VerifyContextInvalidObject = 3021,
+ PE_ERR_ChecksumNotSupported = 3022,
+
+ // PE Exception directory
+ PE_ERR_InvalidExceptionDirectory_Entries = 3100,
+ PE_ERR_InvalidExceptionDirectory_Entry = 3101,
+ PE_ERR_InvalidExceptionDirectory_Size = 3102,
+
+ // PE Certificate directory
+ PE_ERR_InvalidCertificateEntry = 3200,
+
+ // PE BoundImport directory
+ PE_ERR_BoundImportDirectoryInvalidEndOfStream = 3400,
+ PE_ERR_BoundImportDirectoryInvalidModuleName = 3401,
+ PE_ERR_BoundImportDirectoryInvalidForwarderRefModuleName = 3402,
+
+ // PE DelayImport directory
+ PE_ERR_ImportDirectoryInvalidDelayLoadImportAddressTableRVA = 3500,
+ PE_ERR_ImportDirectoryInvalidDelayLoadImportNameTableRVA = 3501,
+ PE_ERR_ImportDirectoryInvalidBoundDelayLoadImportAddressTableRVA = 3502,
+ PE_ERR_ImportDirectoryInvalidUnloadDelayLoadImportAddressTableRVA = 3503,
+ PE_ERR_ImportDirectoryInvalidNameRVA = 3504,
+ PE_ERR_ImportDirectoryInvalidModuleHandleRVA = 3505,
+ PE_ERR_DelayImportDirectoryInvalidDllNameRVA = 3506,
+ PE_ERR_DelayImportDirectoryInvalidModuleHandleRVA = 3507,
+
+ // PE Debug directory
+ PE_ERR_DebugDirectorySize = 3600,
+ PE_ERR_DebugDirectorySectionNotFound = 3601,
+ PE_ERR_DebugDirectoryContainerNotFound = 3602,
+ PE_ERR_InvalidDebugDataRSDSSignature = 3603,
+ PE_ERR_InvalidDebugDataRSDSPdbPath = 3604,
+ PE_ERR_DebugDirectoryExtraData = 3605,
+
+ // PE BaseRelocation
+ PE_ERR_BaseRelocationDirectoryInvalidEndOfStream = 3700,
+ PE_ERR_BaseRelocationDirectoryInvalidSection = 3701,
+ PE_ERR_BaseRelocationDirectoryInvalidSectionData = 3702,
+ PE_ERR_InvalidDataDirectorySection = 3703,
+ PE_ERR_BaseRelocationDirectoryInvalidVirtualAddress = 3704,
+ PE_ERR_BaseRelocationDirectoryInvalidSizeOfBlock = 3705,
+ PE_ERR_InvalidBaseRelocationBlock = 3706,
+ PE_ERR_BaseRelocationDirectoryInvalidSectionLink = 3707,
+
+ // PE Import
+ PE_ERR_ImportDirectoryInvalidEndOfStream = 3800,
+ PE_ERR_ImportLookupTableInvalidEndOfStream = 3801,
+ PE_ERR_ImportLookupTableInvalidHintNameTableRVA = 3802,
+ PE_ERR_ImportLookupTableInvalidParent = 3803,
+ PE_ERR_ImportDirectoryInvalidImportAddressTableRVA = 3804,
+ PE_ERR_ImportDirectoryInvalidImportLookupTableRVA = 3805,
+ PE_ERR_ImportAddressTableNotFound = 3806,
+ PE_ERR_InvalidInternalState = 3807,
+ PE_WRN_ImportLookupTableInvalidRVAOutOfRange = 3808,
+
+ // PE Export
+ PE_ERR_ExportAddressTableInvalidRVA = 3900,
+ PE_ERR_ExportDirectoryInvalidAddressOfNames = 3901,
+ PE_ERR_ExportDirectoryInvalidAddressOfFunctions = 3902,
+ PE_ERR_ExportDirectoryInvalidAddressOfNameOrdinals = 3903,
+ PE_ERR_ExportDirectoryInvalidName = 3904,
+ PE_ERR_ExportNameTableInvalidRVA = 3905,
+
+ // PE Resource directory
+ PE_ERR_InvalidResourceDirectory = 4000,
+ PE_ERR_InvalidResourceDirectoryEntry = 4001,
+ PE_ERR_InvalidResourceDirectoryEntryRVAOffsetToData = 4002,
+ PE_ERR_InvalidResourceString = 4003,
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Diagnostics/DiagnosticKind.cs b/src/LibObjectFile/Diagnostics/DiagnosticKind.cs
new file mode 100644
index 0000000..d663cec
--- /dev/null
+++ b/src/LibObjectFile/Diagnostics/DiagnosticKind.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+namespace LibObjectFile.Diagnostics;
+
+///
+/// Defines the kind of a
+///
+public enum DiagnosticKind
+{
+ ///
+ /// A warning message.
+ ///
+ Warning,
+
+ ///
+ /// An error message.
+ ///
+ Error,
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Diagnostics/DiagnosticMessage.cs b/src/LibObjectFile/Diagnostics/DiagnosticMessage.cs
new file mode 100644
index 0000000..970f297
--- /dev/null
+++ b/src/LibObjectFile/Diagnostics/DiagnosticMessage.cs
@@ -0,0 +1,66 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace LibObjectFile.Diagnostics;
+
+///
+/// A diagnostic message.
+///
+public readonly struct DiagnosticMessage
+{
+ public DiagnosticMessage(DiagnosticKind kind, DiagnosticId id, string message)
+ {
+ Kind = kind;
+ Id = id;
+ Context = null;
+ Message = message;
+ }
+
+ public DiagnosticMessage(DiagnosticKind kind, DiagnosticId id, string message, object? context)
+ {
+ Kind = kind;
+ Id = id;
+ Context = context;
+ Message = message;
+ }
+
+ ///
+ /// Gets the kind of this message.
+ ///
+ public DiagnosticKind Kind { get; }
+
+ ///
+ /// Gets the id of this message.
+ ///
+ public DiagnosticId Id { get; }
+
+ ///
+ /// Gets the context of this message.
+ ///
+ public object? Context { get; }
+
+ ///
+ /// Gets the associated text of this message.
+ ///
+ public string Message { get; }
+
+ ///
+ /// Gets the associated stack trace of this message.
+ ///
+ public StackTrace? StackTrace { get; init; }
+
+ public override string ToString()
+ {
+ if (StackTrace is not null)
+ {
+ return $"{Kind} LB{(uint)Id:0000}: {Message}\n{StackTrace}";
+ }
+ else
+ {
+ return $"{Kind} LB{(uint)Id:0000}: {Message}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs b/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs
index 593b015..2996406 100644
--- a/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs
@@ -1,241 +1,241 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
+using System.Diagnostics.CodeAnalysis;
+using LibObjectFile.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
+public sealed class DwarfAbbreviation : DwarfObject
{
- [DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
- public sealed class DwarfAbbreviation : DwarfObject
+ private readonly List _items;
+ private readonly Dictionary _mapItems; // Only used if code are non contiguous
+ private readonly Dictionary _mapKeyToItem;
+ private ulong _nextCode;
+
+ public DwarfAbbreviation()
{
- private readonly List _items;
- private readonly Dictionary _mapItems; // Only used if code are non contiguous
- private readonly Dictionary _mapKeyToItem;
- private ulong _nextCode;
+ _items = new List();
+ _mapItems = new Dictionary();
+ _mapKeyToItem = new Dictionary();
+ _nextCode = 1;
+ }
- public DwarfAbbreviation()
+ public void Reset()
+ {
+ // Reset parent dependency
+ foreach (var dwarfAbbreviationItem in _items)
{
- _items = new List();
- _mapItems = new Dictionary();
- _mapKeyToItem = new Dictionary();
- _nextCode = 1;
+ dwarfAbbreviationItem.Parent = null;
}
- public void Reset()
+ if (_mapItems.Count > 0)
{
- // Reset parent dependency
- foreach (var dwarfAbbreviationItem in _items)
- {
- dwarfAbbreviationItem.Parent = null;
- }
-
- if (_mapItems.Count > 0)
+ foreach (var keyPair in _mapItems)
{
- foreach (var keyPair in _mapItems)
- {
- keyPair.Value.Parent = null;
- }
+ keyPair.Value.Parent = null;
}
-
- _items.Clear();
- _mapItems.Clear();
- _mapKeyToItem.Clear();
- _nextCode = 1;
}
- public IEnumerable Items => _mapItems.Count > 0 ? GetMapItems() : _items;
+ _items.Clear();
+ _mapItems.Clear();
+ _mapKeyToItem.Clear();
+ _nextCode = 1;
+ }
+
+ public IEnumerable Items => _mapItems.Count > 0 ? GetMapItems() : _items;
- private IEnumerable GetMapItems()
+ private IEnumerable GetMapItems()
+ {
+ foreach (var item in _mapItems.Values)
{
- foreach (var item in _mapItems.Values)
- {
- yield return item;
- }
+ yield return item;
}
+ }
- public DwarfAbbreviationItem GetOrCreate(DwarfAbbreviationItemKey itemKey)
+ public DwarfAbbreviationItem GetOrCreate(DwarfAbbreviationItemKey itemKey)
+ {
+ if (!_mapKeyToItem.TryGetValue(itemKey, out var item))
{
- if (!_mapKeyToItem.TryGetValue(itemKey, out var item))
+ item = new DwarfAbbreviationItem(_nextCode, itemKey.Tag, itemKey.HasChildren, itemKey.Descriptors)
{
- item = new DwarfAbbreviationItem(_nextCode, itemKey.Tag, itemKey.HasChildren, itemKey.Descriptors)
- {
- Parent = this
- };
+ Parent = this
+ };
- if (_mapItems.Count > 0)
- {
+ if (_mapItems.Count > 0)
+ {
- _mapItems[_nextCode] = item;
- }
- else
- {
- _items.Add(item);
- }
+ _mapItems[_nextCode] = item;
+ }
+ else
+ {
+ _items.Add(item);
+ }
- _mapKeyToItem[itemKey] = item;
+ _mapKeyToItem[itemKey] = item;
- _nextCode++;
- }
+ _nextCode++;
+ }
+
+ return item;
+ }
- return item;
+ public bool TryFindByCode(ulong code, [NotNullWhen(true)] out DwarfAbbreviationItem? item)
+ {
+ item = null;
+ if (code == 0)
+ {
+ return false;
}
- public bool TryFindByCode(ulong code, out DwarfAbbreviationItem item)
+ code--;
+
+ if (_mapItems.Count > 0)
{
- item = null;
- if (code == 0)
- {
- return false;
- }
+ return _mapItems.TryGetValue(code, out item);
+ }
- code--;
+ if (code < int.MaxValue && (int)code < _items.Count)
+ {
+ item = _items[(int) code];
+ return true;
+ }
- if (_mapItems.Count > 0)
- {
- return _mapItems.TryGetValue(code, out item);
- }
+ item = null;
+ return false;
+ }
- if (code < int.MaxValue && (int)code < _items.Count)
- {
- item = _items[(int) code];
- return true;
- }
+ private string DebuggerDisplay => $"Count = {(_mapItems.Count > 0 ? _mapItems.Count : _items.Count)}";
- item = null;
+ private bool TryReadNext(DwarfReader reader)
+ {
+ var startOffset = (ulong)reader.Position;
+ var code = reader.ReadULEB128();
+ if (code == 0)
+ {
return false;
}
- private string DebuggerDisplay => $"Count = {(_mapItems.Count > 0 ? _mapItems.Count : _items.Count)}";
-
- private bool TryReadNext(DwarfReader reader)
+ var item = new DwarfAbbreviationItem
{
- var startOffset = (ulong)reader.Offset;
- var code = reader.ReadULEB128();
- if (code == 0)
- {
- return false;
- }
+ Position = startOffset,
+ Code = code
+ };
- var item = new DwarfAbbreviationItem
- {
- Offset = startOffset,
- Code = code
- };
-
- var index = code - 1;
- bool canAddToList = _mapItems.Count == 0 && index < int.MaxValue && _items.Count == (int)index;
+ var index = code - 1;
+ bool canAddToList = _mapItems.Count == 0 && index < int.MaxValue && _items.Count == (int)index;
- item.ReadInternal(reader);
+ item.Read(reader);
- if (canAddToList)
- {
- _items.Add(item);
- _nextCode++;
- }
- else
+ if (canAddToList)
+ {
+ _items.Add(item);
+ _nextCode++;
+ }
+ else
+ {
+ if (_mapItems.Count == 0)
{
- if (_mapItems.Count == 0)
- {
- for (var i = 0; i < _items.Count; i++)
- {
- var previousItem = _items[i];
- _mapItems.Add((ulong)i + 1, previousItem);
- }
- _items.Clear();
- }
-
- // TODO: check collisions
- if (_mapItems.ContainsKey(code))
+ for (var i = 0; i < _items.Count; i++)
{
- reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
- return false;
+ var previousItem = _items[i];
+ _mapItems.Add((ulong)i + 1, previousItem);
}
- _mapItems.Add(code, item);
+ _items.Clear();
+ }
- _nextCode = Math.Max(code, _nextCode) + 1;
+ // TODO: check collisions
+ if (_mapItems.ContainsKey(code))
+ {
+ reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
+ return false;
}
+ _mapItems.Add(code, item);
- var key = new DwarfAbbreviationItemKey(item.Tag, item.HasChildren, item.Descriptors);
- _mapKeyToItem.Add(key, item);
+ _nextCode = Math.Max(code, _nextCode) + 1;
+ }
- return true;
+ var key = new DwarfAbbreviationItemKey(item.Tag, item.HasChildren, item.Descriptors);
+ _mapKeyToItem.Add(key, item);
+
+ return true;
+ }
+
+ public override void Read(DwarfReader reader)
+ {
+ Position = reader.Position;
+ while (TryReadNext(reader))
+ {
}
- protected override void Read(DwarfReader reader)
+ Size = (ulong)reader.Position - Position;
+ }
+
+ public override void Write(DwarfWriter writer)
+ {
+ var startOffset = writer.Position;
+ Debug.Assert(startOffset == Position);
+ if (_mapItems.Count > 0)
{
- Offset = reader.Offset;
- while (TryReadNext(reader))
+ foreach (var itemPair in _mapItems)
{
+ var item = itemPair.Value;
+ item.Write(writer);
}
- Size = (ulong)reader.Offset - Offset;
}
-
- protected override void Write(DwarfWriter writer)
+ else
{
- var startOffset = writer.Offset;
- Debug.Assert(startOffset == Offset);
- if (_mapItems.Count > 0)
- {
- foreach (var itemPair in _mapItems)
- {
- var item = itemPair.Value;
- item.WriteInternal(writer);
- }
-
- }
- else
+ if (_items.Count > 0)
{
- if (_items.Count > 0)
+ foreach (var item in _items)
{
- foreach (var item in _items)
- {
- item.WriteInternal(writer);
- }
+ item.Write(writer);
}
}
+ }
- // End of abbreviation item
- writer.WriteULEB128(0);
+ // End of abbreviation item
+ writer.WriteULEB128(0);
- Debug.Assert(writer.Offset - startOffset == Size);
- }
+ Debug.Assert(writer.Position - startOffset == Size);
+ }
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- var endOffset = Offset;
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ var endOffset = Position;
- if (_mapItems.Count > 0)
+ if (_mapItems.Count > 0)
+ {
+ foreach (var itemPair in _mapItems)
{
- foreach (var itemPair in _mapItems)
- {
- var item = itemPair.Value;
- item.Offset = endOffset;
- item.UpdateLayoutInternal(layoutContext);
- endOffset += item.Size;
- }
-
+ var item = itemPair.Value;
+ item.Position = endOffset;
+ item.UpdateLayout(context);
+ endOffset += item.Size;
}
- else
+
+ }
+ else
+ {
+ if (_items.Count > 0)
{
- if (_items.Count > 0)
+ foreach (var item in _items)
{
- foreach (var item in _items)
- {
- item.Offset = endOffset;
- item.UpdateLayoutInternal(layoutContext);
- endOffset += item.Size;
- }
+ item.Position = endOffset;
+ item.UpdateLayout(context);
+ endOffset += item.Size;
}
}
+ }
- endOffset += DwarfHelper.SizeOfULEB128(0);
+ endOffset += DwarfHelper.SizeOfULEB128(0);
- Size = endOffset - Offset;
- }
+ Size = endOffset - Position;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAbbreviationItem.cs b/src/LibObjectFile/Dwarf/DwarfAbbreviationItem.cs
index 32d1df7..0a2a9d3 100644
--- a/src/LibObjectFile/Dwarf/DwarfAbbreviationItem.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAbbreviationItem.cs
@@ -1,125 +1,125 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System.Collections.Generic;
using System.Diagnostics;
+using LibObjectFile.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public sealed class DwarfAbbreviationItem : DwarfObject
{
- public sealed class DwarfAbbreviationItem : DwarfObject
+ internal DwarfAbbreviationItem()
{
- internal DwarfAbbreviationItem()
- {
- }
+ }
- internal DwarfAbbreviationItem(ulong code, DwarfTagEx tag, bool hasChildren, DwarfAttributeDescriptors descriptors)
- {
- Code = code;
- Tag = tag;
- HasChildren = hasChildren;
- Descriptors = descriptors;
- }
+ internal DwarfAbbreviationItem(ulong code, DwarfTagEx tag, bool hasChildren, DwarfAttributeDescriptors descriptors)
+ {
+ Code = code;
+ Tag = tag;
+ HasChildren = hasChildren;
+ Descriptors = descriptors;
+ }
- public ulong Code { get; internal set; }
+ public ulong Code { get; internal set; }
- public DwarfTagEx Tag { get; private set; }
+ public DwarfTagEx Tag { get; private set; }
- public bool HasChildren { get; private set; }
+ public bool HasChildren { get; private set; }
- public DwarfAttributeDescriptors Descriptors { get; private set; }
+ public DwarfAttributeDescriptors Descriptors { get; private set; }
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- var endOffset = Offset;
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ var endOffset = Position;
- // Code
- endOffset += DwarfHelper.SizeOfULEB128(Code);
+ // Code
+ endOffset += DwarfHelper.SizeOfULEB128(Code);
- // Tag
- endOffset += DwarfHelper.SizeOfULEB128((uint)Tag.Value);
+ // Tag
+ endOffset += DwarfHelper.SizeOfULEB128((uint)Tag.Value);
- // HasChildren
- endOffset += 1;
+ // HasChildren
+ endOffset += 1;
- var descriptors = Descriptors;
- for (int i = 0; i < descriptors.Length; i++)
- {
- var descriptor = descriptors[i];
- endOffset += DwarfHelper.SizeOfULEB128((uint)descriptor.Kind.Value);
- endOffset += DwarfHelper.SizeOfULEB128((uint)descriptor.Form.Value);
- }
+ var descriptors = Descriptors;
+ for (int i = 0; i < descriptors.Length; i++)
+ {
+ var descriptor = descriptors[i];
+ endOffset += DwarfHelper.SizeOfULEB128((uint)descriptor.Kind.Value);
+ endOffset += DwarfHelper.SizeOfULEB128((uint)descriptor.Form.Value);
+ }
- // Null Kind and Form
- endOffset += DwarfHelper.SizeOfULEB128(0) * 2;
+ // Null Kind and Form
+ endOffset += DwarfHelper.SizeOfULEB128(0) * 2;
- Size = endOffset - Offset;
- }
+ Size = endOffset - Position;
+ }
- protected override void Read(DwarfReader reader)
+ public override void Read(DwarfReader reader)
+ {
+ var itemTag = new DwarfTagEx(reader.ReadULEB128AsU32());
+ Tag = itemTag;
+ var hasChildrenRaw = reader.ReadU8();
+ bool hasChildren = false;
+ if (hasChildrenRaw == DwarfNative.DW_CHILDREN_yes)
{
- var itemTag = new DwarfTagEx(reader.ReadULEB128AsU32());
- Tag = itemTag;
- var hasChildrenRaw = reader.ReadU8();
- bool hasChildren = false;
- if (hasChildrenRaw == DwarfNative.DW_CHILDREN_yes)
- {
- hasChildren = true;
- }
- else if (hasChildrenRaw != DwarfNative.DW_CHILDREN_no)
- {
- reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid children {hasChildrenRaw}. Must be either {DwarfNative.DW_CHILDREN_yes} or {DwarfNative.DW_CHILDREN_no}");
- return;
- }
-
- HasChildren = hasChildren;
+ hasChildren = true;
+ }
+ else if (hasChildrenRaw != DwarfNative.DW_CHILDREN_no)
+ {
+ reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid children {hasChildrenRaw}. Must be either {DwarfNative.DW_CHILDREN_yes} or {DwarfNative.DW_CHILDREN_no}");
+ return;
+ }
- List descriptors = null;
+ HasChildren = hasChildren;
- while (true)
- {
- var attributeName = new DwarfAttributeKindEx(reader.ReadULEB128AsU32());
- var attributeForm = new DwarfAttributeFormEx(reader.ReadULEB128AsU32());
+ List? descriptors = null;
- if (attributeForm.Value == 0 && attributeForm.Value == 0)
- {
- break;
- }
+ while (true)
+ {
+ var attributeName = new DwarfAttributeKindEx(reader.ReadULEB128AsU32());
+ var attributeForm = new DwarfAttributeFormEx(reader.ReadULEB128AsU32());
- if (descriptors == null) descriptors = new List(1);
- descriptors.Add(new DwarfAttributeDescriptor(attributeName, attributeForm));
+ if (attributeForm.Value == 0 && attributeForm.Value == 0)
+ {
+ break;
}
- Descriptors = descriptors != null ? new DwarfAttributeDescriptors(descriptors.ToArray()) : new DwarfAttributeDescriptors();
-
- Size = reader.Offset - Offset;
+ if (descriptors == null) descriptors = new List(1);
+ descriptors.Add(new DwarfAttributeDescriptor(attributeName, attributeForm));
}
- protected override void Write(DwarfWriter writer)
- {
- var startOffset = writer.Offset;
- Debug.Assert(startOffset == Offset);
+ Descriptors = descriptors != null ? new DwarfAttributeDescriptors(descriptors.ToArray()) : new DwarfAttributeDescriptors();
- // Code
- writer.WriteULEB128(Code);
+ Size = reader.Position - Position;
+ }
- // Tag
- writer.WriteULEB128((uint)Tag.Value);
+ public override void Write(DwarfWriter writer)
+ {
+ var startOffset = writer.Position;
+ Debug.Assert(startOffset == Position);
- // HasChildren
- writer.WriteU8(HasChildren ? DwarfNative.DW_CHILDREN_yes : DwarfNative.DW_CHILDREN_no);
+ // Code
+ writer.WriteULEB128(Code);
- var descriptors = Descriptors;
- for (int i = 0; i < descriptors.Length; i++)
- {
- var descriptor = descriptors[i];
- writer.WriteULEB128((uint)descriptor.Kind.Value);
- writer.WriteULEB128((uint)descriptor.Form.Value);
- }
- writer.WriteULEB128(0);
- writer.WriteULEB128(0);
+ // Tag
+ writer.WriteULEB128((uint)Tag.Value);
+
+ // HasChildren
+ writer.WriteU8(HasChildren ? DwarfNative.DW_CHILDREN_yes : DwarfNative.DW_CHILDREN_no);
- Debug.Assert(writer.Offset - startOffset == Size);
+ var descriptors = Descriptors;
+ for (int i = 0; i < descriptors.Length; i++)
+ {
+ var descriptor = descriptors[i];
+ writer.WriteULEB128((uint)descriptor.Kind.Value);
+ writer.WriteULEB128((uint)descriptor.Form.Value);
}
+ writer.WriteULEB128(0);
+ writer.WriteULEB128(0);
+
+ Debug.Assert(writer.Position - startOffset == Size);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAbbreviationItemKey.cs b/src/LibObjectFile/Dwarf/DwarfAbbreviationItemKey.cs
index a94024a..6d84f03 100644
--- a/src/LibObjectFile/Dwarf/DwarfAbbreviationItemKey.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAbbreviationItemKey.cs
@@ -4,58 +4,57 @@
using System;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public readonly struct DwarfAbbreviationItemKey : IEquatable
{
- public readonly struct DwarfAbbreviationItemKey : IEquatable
+ public DwarfAbbreviationItemKey(DwarfTagEx tag, bool hasChildren, DwarfAttributeDescriptors descriptors)
{
- public DwarfAbbreviationItemKey(DwarfTagEx tag, bool hasChildren, DwarfAttributeDescriptors descriptors)
- {
- Tag = tag;
- HasChildren = hasChildren;
- Descriptors = descriptors;
- }
+ Tag = tag;
+ HasChildren = hasChildren;
+ Descriptors = descriptors;
+ }
- public readonly DwarfTagEx Tag;
+ public readonly DwarfTagEx Tag;
- public readonly bool HasChildren;
+ public readonly bool HasChildren;
- public readonly DwarfAttributeDescriptors Descriptors;
+ public readonly DwarfAttributeDescriptors Descriptors;
- public bool Equals(DwarfAbbreviationItemKey other)
- {
- return Tag == other.Tag && HasChildren == other.HasChildren && Descriptors.Equals(other.Descriptors);
- }
+ public bool Equals(DwarfAbbreviationItemKey other)
+ {
+ return Tag == other.Tag && HasChildren == other.HasChildren && Descriptors.Equals(other.Descriptors);
+ }
- public override bool Equals(object obj)
- {
- return obj is DwarfAbbreviationItemKey other && Equals(other);
- }
+ public override bool Equals(object? obj)
+ {
+ return obj is DwarfAbbreviationItemKey other && Equals(other);
+ }
- public override int GetHashCode()
+ public override int GetHashCode()
+ {
+ unchecked
{
- unchecked
- {
- var hashCode = Tag.GetHashCode();
- hashCode = (hashCode * 397) ^ HasChildren.GetHashCode();
- hashCode = (hashCode * 397) ^ Descriptors.GetHashCode();
- return hashCode;
- }
+ var hashCode = Tag.GetHashCode();
+ hashCode = (hashCode * 397) ^ HasChildren.GetHashCode();
+ hashCode = (hashCode * 397) ^ Descriptors.GetHashCode();
+ return hashCode;
}
+ }
- public static bool operator ==(DwarfAbbreviationItemKey left, DwarfAbbreviationItemKey right)
- {
- return left.Equals(right);
- }
+ public static bool operator ==(DwarfAbbreviationItemKey left, DwarfAbbreviationItemKey right)
+ {
+ return left.Equals(right);
+ }
- public static bool operator !=(DwarfAbbreviationItemKey left, DwarfAbbreviationItemKey right)
- {
- return !left.Equals(right);
- }
+ public static bool operator !=(DwarfAbbreviationItemKey left, DwarfAbbreviationItemKey right)
+ {
+ return !left.Equals(right);
+ }
- public override string ToString()
- {
- return $"{nameof(Tag)}: {Tag}, {nameof(HasChildren)}: {HasChildren}, {nameof(Descriptors)}: {Descriptors}";
- }
+ public override string ToString()
+ {
+ return $"{nameof(Tag)}: {Tag}, {nameof(HasChildren)}: {HasChildren}, {nameof(Descriptors)}: {Descriptors}";
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAbbreviationTable.cs b/src/LibObjectFile/Dwarf/DwarfAbbreviationTable.cs
index dc607b2..8dcc94c 100644
--- a/src/LibObjectFile/Dwarf/DwarfAbbreviationTable.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAbbreviationTable.cs
@@ -1,86 +1,71 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System.Collections.Generic;
using System.Diagnostics;
+using LibObjectFile.Collections;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public class DwarfAbbreviationTable : DwarfSection
{
- public class DwarfAbbreviationTable : DwarfSection
- {
- private readonly List _abbreviations;
+ private readonly ObjectList _abbreviations;
- public DwarfAbbreviationTable()
- {
- _abbreviations = new List();
- }
+ public DwarfAbbreviationTable()
+ {
+ _abbreviations = new ObjectList(this);
+ }
- public IReadOnlyList Abbreviations => _abbreviations;
+ public ObjectList Abbreviations => _abbreviations;
- internal void AddAbbreviation(DwarfAbbreviation abbreviation)
+ internal void Reset()
+ {
+ foreach(var abbreviation in _abbreviations)
{
- _abbreviations.Add(this, abbreviation);
+ abbreviation.Reset();
}
+ _abbreviations.Clear();
+ }
- internal void RemoveAbbreviation(DwarfAbbreviation abbreviation)
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ ulong endOffset = Position;
+ foreach (var abbreviation in _abbreviations)
{
- _abbreviations.Remove(this, abbreviation);
+ abbreviation.Position = endOffset;
+ abbreviation.UpdateLayout(context);
+ endOffset += abbreviation.Size;
}
- internal DwarfAbbreviation RemoveAbbreviationAt(int index)
- {
- return _abbreviations.RemoveAt(this, index);
- }
+ Size = endOffset - Position;
+ }
- internal void Reset()
+ public override void Read(DwarfReader reader)
+ {
+ var endOffset = reader.Position;
+ while (reader.Position < reader.Length)
{
- foreach(var abbreviation in _abbreviations)
+ var abbreviation = new DwarfAbbreviation
{
- abbreviation.Reset();
- }
- _abbreviations.Clear();
+ Position = endOffset
+ };
+ abbreviation.Read(reader);
+ endOffset += abbreviation.Size;
+ _abbreviations.Add(abbreviation);
}
-
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- ulong endOffset = Offset;
- foreach (var abbreviation in _abbreviations)
- {
- abbreviation.Offset = endOffset;
- abbreviation.UpdateLayoutInternal(layoutContext);
- endOffset += abbreviation.Size;
- }
- Size = endOffset - Offset;
- }
+ Size = endOffset - Position;
+ }
- protected override void Read(DwarfReader reader)
+ public override void Write(DwarfWriter writer)
+ {
+ var startOffset = writer.Position;
+ foreach (var abbreviation in _abbreviations)
{
- var endOffset = reader.Offset;
- while (reader.Offset < reader.Length)
- {
- var abbreviation = new DwarfAbbreviation
- {
- Offset = endOffset
- };
- abbreviation.ReadInternal(reader);
- endOffset += abbreviation.Size;
- AddAbbreviation(abbreviation);
- }
-
- Size = endOffset - Offset;
+ abbreviation.Write(writer);
}
- protected override void Write(DwarfWriter writer)
- {
- var startOffset = writer.Offset;
- foreach (var abbreviation in _abbreviations)
- {
- abbreviation.WriteInternal(writer);
- }
-
- Debug.Assert(writer.Offset - startOffset == Size);
- }
+ Debug.Assert(writer.Position - startOffset == Size);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAccessibility.cs b/src/LibObjectFile/Dwarf/DwarfAccessibility.cs
index 67f3271..d0ce3e7 100644
--- a/src/LibObjectFile/Dwarf/DwarfAccessibility.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAccessibility.cs
@@ -2,14 +2,13 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public enum DwarfAccessibility : byte
{
- public enum DwarfAccessibility : byte
- {
- Public = DwarfNative.DW_ACCESS_public,
+ Public = DwarfNative.DW_ACCESS_public,
- Private = DwarfNative.DW_ACCESS_private,
+ Private = DwarfNative.DW_ACCESS_private,
- Protected = DwarfNative.DW_ACCESS_protected,
- }
+ Protected = DwarfNative.DW_ACCESS_protected,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAddressRange.cs b/src/LibObjectFile/Dwarf/DwarfAddressRange.cs
index 6a9e9d1..eccee75 100644
--- a/src/LibObjectFile/Dwarf/DwarfAddressRange.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAddressRange.cs
@@ -2,26 +2,25 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public struct DwarfAddressRange
{
- public struct DwarfAddressRange
+ public DwarfAddressRange(ulong segment, ulong address, ulong length)
{
- public DwarfAddressRange(ulong segment, ulong address, ulong length)
- {
- Segment = segment;
- Address = address;
- Length = length;
- }
+ Segment = segment;
+ Address = address;
+ Length = length;
+ }
- public ulong Segment { get; set; }
+ public ulong Segment { get; set; }
- public ulong Address { get; set; }
+ public ulong Address { get; set; }
- public ulong Length { get; set; }
+ public ulong Length { get; set; }
- public override string ToString()
- {
- return $"{nameof(Segment)}: 0x{Segment:x16}, {nameof(Address)}: 0x{Address:x16}, {nameof(Length)}: 0x{Length:x16}";
- }
+ public override string ToString()
+ {
+ return $"{nameof(Segment)}: 0x{Segment:x16}, {nameof(Address)}: 0x{Address:x16}, {nameof(Length)}: 0x{Length:x16}";
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAddressRangeTable.cs b/src/LibObjectFile/Dwarf/DwarfAddressRangeTable.cs
index 8bc3a3d..38f2510 100644
--- a/src/LibObjectFile/Dwarf/DwarfAddressRangeTable.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAddressRangeTable.cs
@@ -1,277 +1,274 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
+using LibObjectFile.Diagnostics;
using LibObjectFile.Utils;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+[DebuggerDisplay("Count = {Ranges.Count,nq}")]
+public class DwarfAddressRangeTable : DwarfRelocatableSection
{
- [DebuggerDisplay("Count = {Ranges.Count,nq}")]
- public class DwarfAddressRangeTable : DwarfRelocatableSection
+ public DwarfAddressRangeTable()
{
- public DwarfAddressRangeTable()
- {
- Ranges = new List();
- Version = 2;
- }
+ Ranges = new List();
+ Version = 2;
+ }
- public ushort Version { get; set; }
+ public ushort Version { get; set; }
- public bool Is64BitEncoding { get; set; }
+ public bool Is64BitEncoding { get; set; }
- public DwarfAddressSize AddressSize { get; set; }
+ public DwarfAddressSize AddressSize { get; set; }
- public DwarfAddressSize SegmentSelectorSize { get; set; }
+ public DwarfAddressSize SegmentSelectorSize { get; set; }
- public ulong DebugInfoOffset { get; private set; }
+ public ulong DebugInfoOffset { get; private set; }
- public DwarfUnit Unit { get; set; }
+ public DwarfUnit? Unit { get; set; }
- public List Ranges { get; }
+ public List Ranges { get; }
- public ulong HeaderLength => Size - DwarfHelper.SizeOfUnitLength(Is64BitEncoding);
+ public ulong HeaderLength => Size - DwarfHelper.SizeOfUnitLength(Is64BitEncoding);
- protected override void Read(DwarfReader reader)
- {
- Offset = reader.Offset;
- var unitLength = reader.ReadUnitLength();
- Is64BitEncoding = reader.Is64BitEncoding;
- Version = reader.ReadU16();
+ public override void Read(DwarfReader reader)
+ {
+ Position = reader.Position;
+ var unitLength = reader.ReadUnitLength();
+ Is64BitEncoding = reader.Is64BitEncoding;
+ Version = reader.ReadU16();
- if (Version != 2)
- {
- reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Version {Version} for .debug_aranges not supported");
- return;
- }
+ if (Version != 2)
+ {
+ reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Version {Version} for .debug_aranges not supported");
+ return;
+ }
- DebugInfoOffset = reader.ReadUIntFromEncoding();
+ DebugInfoOffset = reader.ReadUIntFromEncoding();
- AddressSize = reader.ReadAddressSize();
+ AddressSize = reader.ReadAddressSize();
- var segment_selector_size = (DwarfAddressSize)reader.ReadU8();
- SegmentSelectorSize = segment_selector_size;
+ var segment_selector_size = (DwarfAddressSize)reader.ReadU8();
+ SegmentSelectorSize = segment_selector_size;
- var align = (ulong)segment_selector_size + (ulong)AddressSize * 2;
+ var align = (ulong)segment_selector_size + (ulong)AddressSize * 2;
- // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
- reader.Offset = AlignHelper.AlignToUpper(reader.Offset, align);
+ // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
+ reader.Position = AlignHelper.AlignUp(reader.Position, align);
- while (true)
+ while (true)
+ {
+ ulong segment = 0;
+ switch (segment_selector_size)
{
- ulong segment = 0;
- switch (segment_selector_size)
- {
- case DwarfAddressSize.Bit8:
- segment = reader.ReadU8();
- break;
-
- case DwarfAddressSize.Bit16:
- segment = reader.ReadU16();
- break;
+ case DwarfAddressSize.Bit8:
+ segment = reader.ReadU8();
+ break;
- case DwarfAddressSize.Bit32:
- segment = reader.ReadU32();
- break;
+ case DwarfAddressSize.Bit16:
+ segment = reader.ReadU16();
+ break;
- case DwarfAddressSize.Bit64:
- segment = reader.ReadU64();
- break;
+ case DwarfAddressSize.Bit32:
+ segment = reader.ReadU32();
+ break;
- case DwarfAddressSize.None:
- break;
- }
+ case DwarfAddressSize.Bit64:
+ segment = reader.ReadU64();
+ break;
- ulong address = 0;
- ulong length = 0;
- switch (AddressSize)
- {
- case DwarfAddressSize.Bit8:
- address = reader.ReadU8();
- length = reader.ReadU8();
- break;
- case DwarfAddressSize.Bit16:
- address = reader.ReadU16();
- length = reader.ReadU16();
- break;
- case DwarfAddressSize.Bit32:
- address = reader.ReadU32();
- length = reader.ReadU32();
- break;
- case DwarfAddressSize.Bit64:
- address = reader.ReadU64();
- length = reader.ReadU64();
- break;
- }
+ case DwarfAddressSize.None:
+ break;
+ }
- if (segment == 0 && address == 0 && length == 0)
- {
+ ulong address = 0;
+ ulong length = 0;
+ switch (AddressSize)
+ {
+ case DwarfAddressSize.Bit8:
+ address = reader.ReadU8();
+ length = reader.ReadU8();
break;
- }
+ case DwarfAddressSize.Bit16:
+ address = reader.ReadU16();
+ length = reader.ReadU16();
+ break;
+ case DwarfAddressSize.Bit32:
+ address = reader.ReadU32();
+ length = reader.ReadU32();
+ break;
+ case DwarfAddressSize.Bit64:
+ address = reader.ReadU64();
+ length = reader.ReadU64();
+ break;
+ }
- Ranges.Add(new DwarfAddressRange(segment, address, length));
+ if (segment == 0 && address == 0 && length == 0)
+ {
+ break;
}
- Size = reader.Offset - Offset;
+ Ranges.Add(new DwarfAddressRange(segment, address, length));
}
- public override void Verify(DiagnosticBag diagnostics)
- {
- base.Verify(diagnostics);
+ Size = reader.Position - Position;
+ }
- if (Version != 2)
- {
- diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Non supported version {Version} for .debug_aranges");
- }
+ public override void Verify(DwarfVerifyContext context)
+ {
+ var diagnostics = context.Diagnostics;
+ if (Version != 2)
+ {
+ diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Non supported version {Version} for .debug_aranges");
+ }
- if (Unit == null)
+ if (Unit == null)
+ {
+ diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidNullUnitForAddressRangeTable, $"Invalid {nameof(Unit)} for .debug_aranges that cannot be null");
+ }
+ else
+ {
+ var parentFile = Unit.GetParentFile();
+ if (this.Parent != parentFile)
{
- diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidNullUnitForAddressRangeTable, $"Invalid {nameof(Unit)} for .debug_aranges that cannot be null");
- }
- else
- {
- var parentFile = Unit.GetParentFile();
- if (this.Parent != parentFile)
- {
- diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidParentUnitForAddressRangeTable, $"Invalid parent {nameof(DwarfFile)} of {nameof(Unit)} for .debug_aranges that doesn't match the parent of instance");
- }
+ diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidParentUnitForAddressRangeTable, $"Invalid parent {nameof(DwarfFile)} of {nameof(Unit)} for .debug_aranges that doesn't match the parent of instance");
}
}
+ }
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- ulong sizeOf = 0;
- // unit_length
- sizeOf += DwarfHelper.SizeOfUnitLength(Is64BitEncoding);
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ ulong sizeOf = 0;
+ // unit_length
+ sizeOf += DwarfHelper.SizeOfUnitLength(Is64BitEncoding);
- // version
- sizeOf += 2;
+ // version
+ sizeOf += 2;
- // debug_info_offset
- sizeOf += DwarfHelper.SizeOfUInt(Is64BitEncoding);
+ // debug_info_offset
+ sizeOf += DwarfHelper.SizeOfUInt(Is64BitEncoding);
- // Address size
- sizeOf += 1;
+ // Address size
+ sizeOf += 1;
- // segment selector size
- sizeOf += 1;
+ // segment selector size
+ sizeOf += 1;
- var align = (ulong)SegmentSelectorSize + (ulong)AddressSize * 2;
+ var align = (ulong)SegmentSelectorSize + (ulong)AddressSize * 2;
- // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
- sizeOf = AlignHelper.AlignToUpper(sizeOf, align);
+ // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
+ sizeOf = AlignHelper.AlignUp(sizeOf, align);
- // SizeOf ranges + 1 (for last 0 entry)
- sizeOf += ((ulong)Ranges.Count + 1UL) * align;
+ // SizeOf ranges + 1 (for last 0 entry)
+ sizeOf += ((ulong)Ranges.Count + 1UL) * align;
- Size = sizeOf;
+ Size = sizeOf;
- if (Unit != null)
- {
- DebugInfoOffset = Unit.Offset;
- }
+ if (Unit != null)
+ {
+ DebugInfoOffset = Unit.Position;
}
+ }
- protected override void Write(DwarfWriter writer)
- {
- var startOffset = writer.Offset;
+ public override void Write(DwarfWriter writer)
+ {
+ var startOffset = writer.Position;
- // unit_length
- writer.WriteUnitLength(Size - DwarfHelper.SizeOfUnitLength(Is64BitEncoding));
+ // unit_length
+ writer.WriteUnitLength(Size - DwarfHelper.SizeOfUnitLength(Is64BitEncoding));
- // version
- writer.WriteU16(Version);
+ // version
+ writer.WriteU16(Version);
- // debug_info_offset
- var debugInfoOffset = DebugInfoOffset;
- if (writer.EnableRelocation)
- {
- writer.RecordRelocation(DwarfRelocationTarget.DebugInfo, writer.SizeOfUIntEncoding(), debugInfoOffset);
- debugInfoOffset = 0;
- }
- writer.WriteUIntFromEncoding(debugInfoOffset);
+ // debug_info_offset
+ var debugInfoOffset = DebugInfoOffset;
+ if (writer.EnableRelocation)
+ {
+ writer.RecordRelocation(DwarfRelocationTarget.DebugInfo, writer.SizeOfUIntEncoding(), debugInfoOffset);
+ debugInfoOffset = 0;
+ }
+ writer.WriteUIntFromEncoding(debugInfoOffset);
- // address_size
- writer.AddressSize = AddressSize;
- writer.WriteU8((byte)AddressSize);
+ // address_size
+ writer.AddressSize = AddressSize;
+ writer.WriteU8((byte)AddressSize);
- writer.WriteU8((byte)SegmentSelectorSize);
+ writer.WriteU8((byte)SegmentSelectorSize);
- var align = (ulong)SegmentSelectorSize + (ulong)AddressSize * 2;
+ var align = (ulong)SegmentSelectorSize + (ulong)AddressSize * 2;
- // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
- var nextOffset = AlignHelper.AlignToUpper(writer.Offset, align);
- for (ulong offset = writer.Offset; offset < nextOffset; offset++)
- {
- writer.WriteU8(0);
- }
- Debug.Assert(writer.Offset == nextOffset);
-
- foreach (var range in Ranges)
- {
- if (SegmentSelectorSize != 0)
- {
- switch (SegmentSelectorSize)
- {
- case DwarfAddressSize.Bit8:
- writer.WriteU8((byte)range.Segment);
- break;
- case DwarfAddressSize.Bit16:
- writer.WriteU16((ushort)range.Segment);
- break;
- case DwarfAddressSize.Bit32:
- writer.WriteU32((uint)range.Segment);
- break;
- case DwarfAddressSize.Bit64:
- writer.WriteU64((ulong)range.Segment);
- break;
- }
- }
-
- writer.WriteAddress(DwarfRelocationTarget.Code, range.Address);
- writer.WriteUInt(range.Length);
- }
+ // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
+ var nextOffset = AlignHelper.AlignUp(writer.Position, align);
+ for (ulong offset = writer.Position; offset < nextOffset; offset++)
+ {
+ writer.WriteU8(0);
+ }
+ Debug.Assert(writer.Position == nextOffset);
+ foreach (var range in Ranges)
+ {
if (SegmentSelectorSize != 0)
{
switch (SegmentSelectorSize)
{
case DwarfAddressSize.Bit8:
- writer.WriteU8(0);
+ writer.WriteU8((byte)range.Segment);
break;
case DwarfAddressSize.Bit16:
- writer.WriteU16(0);
+ writer.WriteU16((ushort)range.Segment);
break;
case DwarfAddressSize.Bit32:
- writer.WriteU32(0);
+ writer.WriteU32((uint)range.Segment);
break;
case DwarfAddressSize.Bit64:
- writer.WriteU64(0);
+ writer.WriteU64((ulong)range.Segment);
break;
}
}
- switch (AddressSize)
+ writer.WriteAddress(DwarfRelocationTarget.Code, range.Address);
+ writer.WriteUInt(range.Length);
+ }
+
+ if (SegmentSelectorSize != 0)
+ {
+ switch (SegmentSelectorSize)
{
case DwarfAddressSize.Bit8:
- writer.WriteU16(0);
+ writer.WriteU8(0);
break;
case DwarfAddressSize.Bit16:
- writer.WriteU32(0);
+ writer.WriteU16(0);
break;
case DwarfAddressSize.Bit32:
- writer.WriteU64(0);
+ writer.WriteU32(0);
break;
case DwarfAddressSize.Bit64:
- writer.WriteU64(0);
writer.WriteU64(0);
break;
}
+ }
- Debug.Assert(writer.Offset - startOffset == Size);
+ switch (AddressSize)
+ {
+ case DwarfAddressSize.Bit8:
+ writer.WriteU16(0);
+ break;
+ case DwarfAddressSize.Bit16:
+ writer.WriteU32(0);
+ break;
+ case DwarfAddressSize.Bit32:
+ writer.WriteU64(0);
+ break;
+ case DwarfAddressSize.Bit64:
+ writer.WriteU64(0);
+ writer.WriteU64(0);
+ break;
}
+
+ Debug.Assert(writer.Position - startOffset == Size);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAddressSize.cs b/src/LibObjectFile/Dwarf/DwarfAddressSize.cs
index c2f072e..3bb0404 100644
--- a/src/LibObjectFile/Dwarf/DwarfAddressSize.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAddressSize.cs
@@ -2,18 +2,17 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public enum DwarfAddressSize : byte
{
- public enum DwarfAddressSize : byte
- {
- None = 0,
+ None = 0,
- Bit8 = 1,
+ Bit8 = 1,
- Bit16 = 2,
+ Bit16 = 2,
- Bit32 = 4,
+ Bit32 = 4,
- Bit64 = 8,
- }
+ Bit64 = 8,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfArrayOrderingKind.cs b/src/LibObjectFile/Dwarf/DwarfArrayOrderingKind.cs
index 8464d0c..b7e8f31 100644
--- a/src/LibObjectFile/Dwarf/DwarfArrayOrderingKind.cs
+++ b/src/LibObjectFile/Dwarf/DwarfArrayOrderingKind.cs
@@ -2,12 +2,11 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public enum DwarfArrayOrderingKind : byte
{
- public enum DwarfArrayOrderingKind : byte
- {
- RowMajor = DwarfNative.DW_ORD_row_major,
+ RowMajor = DwarfNative.DW_ORD_row_major,
- ColumnMajor = DwarfNative.DW_ORD_col_major,
- }
+ ColumnMajor = DwarfNative.DW_ORD_col_major,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttribute.cs b/src/LibObjectFile/Dwarf/DwarfAttribute.cs
index db0c381..cc5f5dc 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttribute.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttribute.cs
@@ -1,1001 +1,1006 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
using System.Diagnostics;
using System.IO;
+using System.Text;
+using LibObjectFile.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public sealed class DwarfAttribute : DwarfObject, IComparable
{
- public sealed class DwarfAttribute : DwarfObject, IComparable
- {
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private ulong _valueAsU64;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private ulong _valueAsU64;
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private object _valueAsObject;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private object? _valueAsObject;
- public DwarfAttributeKindEx Kind { get; set; }
+ public DwarfAttributeKindEx Kind { get; set; }
- public bool ValueAsBoolean
- {
- get => _valueAsU64 != 0;
- set => _valueAsU64 = value ? 1U : 0;
- }
+ public bool ValueAsBoolean
+ {
+ get => _valueAsU64 != 0;
+ set => _valueAsU64 = value ? 1U : 0;
+ }
- public int ValueAsI32
- {
- get => (int)_valueAsU64;
- set => _valueAsU64 = (ulong)(long)value;
- }
+ public int ValueAsI32
+ {
+ get => (int)_valueAsU64;
+ set => _valueAsU64 = (ulong)(long)value;
+ }
- public uint ValueAsU32
- {
- get => (uint)_valueAsU64;
- set => _valueAsU64 = value;
- }
+ public uint ValueAsU32
+ {
+ get => (uint)_valueAsU64;
+ set => _valueAsU64 = value;
+ }
- public long ValueAsI64
- {
- get => (long)_valueAsU64;
- set => _valueAsU64 = (ulong)value;
- }
+ public long ValueAsI64
+ {
+ get => (long)_valueAsU64;
+ set => _valueAsU64 = (ulong)value;
+ }
- public ulong ValueAsU64
- {
- get => _valueAsU64;
- set => _valueAsU64 = value;
- }
+ public ulong ValueAsU64
+ {
+ get => _valueAsU64;
+ set => _valueAsU64 = value;
+ }
- ///
- /// Gets or sets the encoding used for this attribute. Default is null meaning that the encoding
- /// is detected automatically. Some attributes may require to explicitly set this encoding to disambiguate
- /// between different encoding form (e.g boolean => instead of )
- ///
- public DwarfAttributeEncoding? Encoding { get; set; }
+ ///
+ /// Gets or sets the encoding used for this attribute. Default is null meaning that the encoding
+ /// is detected automatically. Some attributes may require to explicitly set this encoding to disambiguate
+ /// between different encoding form (e.g boolean => instead of )
+ ///
+ public DwarfAttributeEncoding? Encoding { get; set; }
- public DwarfAttributeFormEx Form { get; internal set; }
+ public DwarfAttributeFormEx Form { get; internal set; }
- public object ValueAsObject
+ public object? ValueAsObject
+ {
+ get => _valueAsObject;
+ set
{
- get => _valueAsObject;
- set
+ if (_valueAsObject is DwarfExpression oldExpression)
{
- if (_valueAsObject is DwarfExpression oldExpression)
- {
- oldExpression.Parent = null;
- }
- _valueAsObject = value;
+ oldExpression.Parent = null;
+ }
+ _valueAsObject = value;
- if (value is DwarfExpression newExpression)
- {
- if (newExpression.Parent != null) throw new InvalidOperationException($"Cannot set the {newExpression.GetType()} as it already belongs to another {newExpression.Parent.GetType()} instance");
- newExpression.Parent = this;
- }
+ if (value is DwarfExpression newExpression)
+ {
+ if (newExpression.Parent != null) throw new InvalidOperationException($"Cannot set the {newExpression.GetType()} as it already belongs to another {newExpression.Parent.GetType()} instance");
+ newExpression.Parent = this;
}
}
-
- public override void Verify(DiagnosticBag diagnostics)
- {
- base.Verify(diagnostics);
+ }
- // Check DwarfDIE reference
- if (ValueAsObject is DwarfDIE attrDIE)
- {
- var thisSection = this.GetParentSection();
- var attrSection = attrDIE.GetParentSection();
+ public override void Verify(DwarfVerifyContext context)
+ {
+ var diagnostics = context.Diagnostics;
- if (thisSection != attrSection)
- {
- diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidParentForDIE, $"Invalid parent for the DIE {attrDIE} referenced by the attribute {this}. It must be within the same parent {thisSection.GetType()}.");
- }
- }
- else if (ValueAsObject is DwarfExpression expr)
+ // Check DwarfDIE reference
+ if (ValueAsObject is DwarfDIE attrDIE)
+ {
+ var thisSection = this.GetParentSection()!;
+ var attrSection = attrDIE.GetParentSection();
+
+ if (thisSection != attrSection)
{
- expr.Verify(diagnostics);
+ diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidParentForDIE, $"Invalid parent for the DIE {attrDIE} referenced by the attribute {this}. It must be within the same parent {thisSection.GetType()}.");
}
- else if (ValueAsObject is DwarfLocationList locationList)
- {
- var thisSection = this.GetParentFile();
- var locationListSection = locationList.GetParentFile();
+ }
+ else if (ValueAsObject is DwarfExpression expr)
+ {
+ expr.Verify(context);
+ }
+ else if (ValueAsObject is DwarfLocationList locationList)
+ {
+ var thisSection = this.GetParentFile()!;
+ var locationListSection = locationList.GetParentFile();
- if (thisSection != locationListSection)
- {
- diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidParentForLocationList, $"Invalid parent for the LocationList {locationList} referenced by the attribute {this}. It must be within the same parent {thisSection.GetType()}.");
- }
+ if (thisSection != locationListSection)
+ {
+ diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidParentForLocationList, $"Invalid parent for the LocationList {locationList} referenced by the attribute {this}. It must be within the same parent {thisSection.GetType()}.");
}
}
+ }
- public int CompareTo(DwarfAttribute other)
+ public int CompareTo(DwarfAttribute? other)
+ {
+ if (other == null) return 1;
+ return ((uint)Kind).CompareTo((uint)other.Kind);
+ }
+
+ protected override bool PrintMembers(StringBuilder builder)
+ {
+ if (ValueAsObject != null)
{
- return ((uint)Kind).CompareTo((uint)other.Kind);
+ builder.Append(ValueAsU64 != 0 ? $"{nameof(Kind)}: {Kind}, Value: {ValueAsObject} Offset: {ValueAsU64}" : $"{nameof(Kind)}: {Kind}, Value: {ValueAsObject}, ");
}
+ else
+ {
+ builder.Append($"{nameof(Kind)}: {Kind}, Value: {ValueAsU64}, ");
+ }
+ base.PrintMembers(builder);
+
+ return true;
+ }
- public override string ToString()
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ var addressSize = context.CurrentUnit!.AddressSize;
+ var is64BitEncoding = context.CurrentUnit.Is64BitEncoding;
+
+ var endOffset = Position;
+ switch (Form.Value)
{
- if (ValueAsObject != null)
+ case DwarfAttributeForm.Addr:
+ endOffset += DwarfHelper.SizeOfUInt(addressSize); // WriteUInt(ValueAsU64);
+ break;
+ case DwarfAttributeForm.Data1:
+ endOffset += 1; // WriteU8((byte)ValueAsU64);
+ break;
+ case DwarfAttributeForm.Data2:
+ endOffset += 2; // WriteU16((ushort)ValueAsU64);
+ break;
+ case DwarfAttributeForm.Data4:
+ endOffset += 4; // WriteU32((uint)ValueAsU64);
+ break;
+ case DwarfAttributeForm.Data8:
+ endOffset += 8; // WriteU64(ValueAsU64);
+ break;
+ case DwarfAttributeForm.String:
+ endOffset += DwarfHelper.SizeOfStringUTF8NullTerminated((string?)ValueAsObject);
+ break;
+ case DwarfAttributeForm.Block:
{
- return ValueAsU64 != 0 ? $"{nameof(Kind)}: {Kind}, Value: {ValueAsObject} Offset: {ValueAsU64}" : $"{nameof(Kind)}: {Kind}, Value: {ValueAsObject}";
+ var stream = (Stream)ValueAsObject!;
+ endOffset += DwarfHelper.SizeOfULEB128((ulong)stream.Length);
+ endOffset += (ulong)stream.Length;
+ break;
}
- else
+ case DwarfAttributeForm.Block1:
{
- return $"{nameof(Kind)}: {Kind}, Value: {ValueAsU64}";
+ var stream = (Stream)ValueAsObject!;
+ endOffset += 1;
+ endOffset += (ulong)stream.Length;
+ break;
}
- }
-
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- var addressSize = layoutContext.CurrentUnit.AddressSize;
- var is64BitEncoding = layoutContext.CurrentUnit.Is64BitEncoding;
-
- var endOffset = Offset;
- switch (Form.Value)
+ case DwarfAttributeForm.Block2:
{
- case DwarfAttributeForm.Addr:
- endOffset += DwarfHelper.SizeOfUInt(addressSize); // WriteUInt(ValueAsU64);
- break;
- case DwarfAttributeForm.Data1:
- endOffset += 1; // WriteU8((byte)ValueAsU64);
- break;
- case DwarfAttributeForm.Data2:
- endOffset += 2; // WriteU16((ushort)ValueAsU64);
- break;
- case DwarfAttributeForm.Data4:
- endOffset += 4; // WriteU32((uint)ValueAsU64);
- break;
- case DwarfAttributeForm.Data8:
- endOffset += 8; // WriteU64(ValueAsU64);
- break;
- case DwarfAttributeForm.String:
- endOffset += DwarfHelper.SizeOfStringUTF8NullTerminated((string)ValueAsObject);
- break;
- case DwarfAttributeForm.Block:
- {
- var stream = (Stream)ValueAsObject;
- endOffset += DwarfHelper.SizeOfULEB128((ulong)stream.Length);
- endOffset += (ulong)stream.Length;
- break;
- }
- case DwarfAttributeForm.Block1:
- {
- var stream = (Stream)ValueAsObject;
- endOffset += 1;
- endOffset += (ulong)stream.Length;
- break;
- }
- case DwarfAttributeForm.Block2:
- {
- var stream = (Stream)ValueAsObject;
- endOffset += 2;
- endOffset += (ulong)stream.Length;
- break;
- }
- case DwarfAttributeForm.Block4:
- {
- var stream = (Stream)ValueAsObject;
- endOffset += 4;
- endOffset += (ulong)stream.Length;
- break;
- }
- case DwarfAttributeForm.Flag:
- endOffset += 1; // WriteU8((byte)(ValueAsU64 != 0 ? 1 : 0));
- break;
- case DwarfAttributeForm.Sdata:
- endOffset += DwarfHelper.SizeOfILEB128(ValueAsI64); // WriteILEB128(ValueAsI64);
- break;
- case DwarfAttributeForm.Strp:
- endOffset += DwarfHelper.SizeOfUInt(is64BitEncoding); // WriteUIntFromEncoding(offset);
- break;
- case DwarfAttributeForm.Udata:
- endOffset += DwarfHelper.SizeOfULEB128(ValueAsU64); // ReadULEB128();
- break;
- case DwarfAttributeForm.RefAddr:
- endOffset += DwarfHelper.SizeOfUInt(is64BitEncoding); // WriteUIntFromEncoding(dieRef.Offset);
- break;
- case DwarfAttributeForm.Ref1:
- endOffset += 1; // WriteU8((byte)(dieRef.Offset - _currentUnit.Offset));
- break;
- case DwarfAttributeForm.Ref2:
- endOffset += 2; // WriteU16((ushort)(dieRef.Offset - _currentUnit.Offset));
- break;
- case DwarfAttributeForm.Ref4:
- endOffset += 4; // WriteU32((uint)(dieRef.Offset - _currentUnit.Offset));
- break;
- case DwarfAttributeForm.Ref8:
- endOffset += 8; // WriteU64((dieRef.Offset - _currentUnit.Offset));
- break;
- case DwarfAttributeForm.RefUdata:
- {
- var dieRef = (DwarfDIE)ValueAsObject;
- endOffset += DwarfHelper.SizeOfULEB128(dieRef.Offset - layoutContext.CurrentUnit.Offset); // WriteULEB128((dieRef.Offset - _currentUnit.Offset));
- break;
- }
-
- //case DwarfAttributeForm.indirect:
- //{
- // attributeForm = ReadLEB128As();
- // goto indirect;
- //}
-
- // addptr
- // lineptr
- // loclist
- // loclistptr
- // macptr
- // rnglist
- // rngrlistptr
- // stroffsetsptr
- case DwarfAttributeForm.SecOffset:
- endOffset += DwarfHelper.SizeOfUInt(is64BitEncoding);
- break;
-
- case DwarfAttributeForm.Exprloc:
- var expr = (DwarfExpression)ValueAsObject;
- expr.Offset = endOffset;
- expr.UpdateLayoutInternal(layoutContext);
- endOffset += expr.Size;
- break;
-
- case DwarfAttributeForm.FlagPresent:
- break;
-
- case DwarfAttributeForm.RefSig8:
- endOffset += 8; // WriteU64(ValueAsU64);
- break;
-
- case DwarfAttributeForm.Strx: throw new NotSupportedException("DW_FORM_strx - DWARF5");
- case DwarfAttributeForm.Addrx: throw new NotSupportedException("DW_FORM_addrx - DWARF5");
- case DwarfAttributeForm.RefSup4: throw new NotSupportedException("DW_FORM_ref_sup4 - DWARF5");
- case DwarfAttributeForm.StrpSup: throw new NotSupportedException("DW_FORM_strp_sup - DWARF5");
- case DwarfAttributeForm.Data16: throw new NotSupportedException("DW_FORM_data16 - DWARF5");
- case DwarfAttributeForm.LineStrp: throw new NotSupportedException("DW_FORM_line_strp - DWARF5");
- case DwarfAttributeForm.ImplicitConst: throw new NotSupportedException("DW_FORM_implicit_const - DWARF5");
- case DwarfAttributeForm.Loclistx: throw new NotSupportedException("DW_FORM_loclistx - DWARF5");
- case DwarfAttributeForm.Rnglistx: throw new NotSupportedException("DW_FORM_rnglistx - DWARF5");
- case DwarfAttributeForm.RefSup8: throw new NotSupportedException("DW_FORM_ref_sup8 - DWARF5");
- case DwarfAttributeForm.Strx1: throw new NotSupportedException("DW_FORM_strx1 - DWARF5");
- case DwarfAttributeForm.Strx2: throw new NotSupportedException("DW_FORM_strx2 - DWARF5");
- case DwarfAttributeForm.Strx3: throw new NotSupportedException("DW_FORM_strx3 - DWARF5");
- case DwarfAttributeForm.Strx4: throw new NotSupportedException("DW_FORM_strx4 - DWARF5");
- case DwarfAttributeForm.Addrx1: throw new NotSupportedException("DW_FORM_addrx1 - DWARF5");
- case DwarfAttributeForm.Addrx2: throw new NotSupportedException("DW_FORM_addrx2 - DWARF5");
- case DwarfAttributeForm.Addrx3: throw new NotSupportedException("DW_FORM_addrx3 - DWARF5");
- case DwarfAttributeForm.Addrx4: throw new NotSupportedException("DW_FORM_addrx4 - DWARF5");
- case DwarfAttributeForm.GNUAddrIndex: throw new NotSupportedException("DW_FORM_GNU_addr_index - GNU extension in debug_info.dwo.");
- case DwarfAttributeForm.GNUStrIndex: throw new NotSupportedException("DW_FORM_GNU_str_index - GNU extension, somewhat like DW_FORM_strp");
- case DwarfAttributeForm.GNURefAlt: throw new NotSupportedException("DW_FORM_GNU_ref_alt - GNU extension. Offset in .debug_info.");
- case DwarfAttributeForm.GNUStrpAlt: throw new NotSupportedException("DW_FORM_GNU_strp_alt - GNU extension. Offset in .debug_str of another object file.");
- default:
- throw new NotSupportedException($"Unknown {nameof(DwarfAttributeForm)}: {Form}");
+ var stream = (Stream)ValueAsObject!;
+ endOffset += 2;
+ endOffset += (ulong)stream.Length;
+ break;
+ }
+ case DwarfAttributeForm.Block4:
+ {
+ var stream = (Stream)ValueAsObject!;
+ endOffset += 4;
+ endOffset += (ulong)stream.Length;
+ break;
+ }
+ case DwarfAttributeForm.Flag:
+ endOffset += 1; // WriteU8((byte)(ValueAsU64 != 0 ? 1 : 0));
+ break;
+ case DwarfAttributeForm.Sdata:
+ endOffset += DwarfHelper.SizeOfILEB128(ValueAsI64); // WriteILEB128(ValueAsI64);
+ break;
+ case DwarfAttributeForm.Strp:
+ endOffset += DwarfHelper.SizeOfUInt(is64BitEncoding); // WriteUIntFromEncoding(offset);
+ break;
+ case DwarfAttributeForm.Udata:
+ endOffset += DwarfHelper.SizeOfULEB128(ValueAsU64); // ReadULEB128();
+ break;
+ case DwarfAttributeForm.RefAddr:
+ endOffset += DwarfHelper.SizeOfUInt(is64BitEncoding); // WriteUIntFromEncoding(dieRef.Offset);
+ break;
+ case DwarfAttributeForm.Ref1:
+ endOffset += 1; // WriteU8((byte)(dieRef.Offset - _currentUnit.Offset));
+ break;
+ case DwarfAttributeForm.Ref2:
+ endOffset += 2; // WriteU16((ushort)(dieRef.Offset - _currentUnit.Offset));
+ break;
+ case DwarfAttributeForm.Ref4:
+ endOffset += 4; // WriteU32((uint)(dieRef.Offset - _currentUnit.Offset));
+ break;
+ case DwarfAttributeForm.Ref8:
+ endOffset += 8; // WriteU64((dieRef.Offset - _currentUnit.Offset));
+ break;
+ case DwarfAttributeForm.RefUdata:
+ {
+ var dieRef = (DwarfDIE)ValueAsObject!;
+ endOffset += DwarfHelper.SizeOfULEB128(dieRef.Position - context.CurrentUnit.Position); // WriteULEB128((dieRef.Offset - _currentUnit.Offset));
+ break;
}
- Size = endOffset - Offset;
+ //case DwarfAttributeForm.indirect:
+ //{
+ // attributeForm = ReadLEB128As();
+ // goto indirect;
+ //}
+
+ // addptr
+ // lineptr
+ // loclist
+ // loclistptr
+ // macptr
+ // rnglist
+ // rngrlistptr
+ // stroffsetsptr
+ case DwarfAttributeForm.SecOffset:
+ endOffset += DwarfHelper.SizeOfUInt(is64BitEncoding);
+ break;
+
+ case DwarfAttributeForm.Exprloc:
+ var expr = (DwarfExpression)ValueAsObject!;
+ expr.Position = endOffset;
+ expr.UpdateLayout(context);
+ endOffset += expr.Size;
+ break;
+
+ case DwarfAttributeForm.FlagPresent:
+ break;
+
+ case DwarfAttributeForm.RefSig8:
+ endOffset += 8; // WriteU64(ValueAsU64);
+ break;
+
+ case DwarfAttributeForm.Strx: throw new NotSupportedException("DW_FORM_strx - DWARF5");
+ case DwarfAttributeForm.Addrx: throw new NotSupportedException("DW_FORM_addrx - DWARF5");
+ case DwarfAttributeForm.RefSup4: throw new NotSupportedException("DW_FORM_ref_sup4 - DWARF5");
+ case DwarfAttributeForm.StrpSup: throw new NotSupportedException("DW_FORM_strp_sup - DWARF5");
+ case DwarfAttributeForm.Data16: throw new NotSupportedException("DW_FORM_data16 - DWARF5");
+ case DwarfAttributeForm.LineStrp: throw new NotSupportedException("DW_FORM_line_strp - DWARF5");
+ case DwarfAttributeForm.ImplicitConst: throw new NotSupportedException("DW_FORM_implicit_const - DWARF5");
+ case DwarfAttributeForm.Loclistx: throw new NotSupportedException("DW_FORM_loclistx - DWARF5");
+ case DwarfAttributeForm.Rnglistx: throw new NotSupportedException("DW_FORM_rnglistx - DWARF5");
+ case DwarfAttributeForm.RefSup8: throw new NotSupportedException("DW_FORM_ref_sup8 - DWARF5");
+ case DwarfAttributeForm.Strx1: throw new NotSupportedException("DW_FORM_strx1 - DWARF5");
+ case DwarfAttributeForm.Strx2: throw new NotSupportedException("DW_FORM_strx2 - DWARF5");
+ case DwarfAttributeForm.Strx3: throw new NotSupportedException("DW_FORM_strx3 - DWARF5");
+ case DwarfAttributeForm.Strx4: throw new NotSupportedException("DW_FORM_strx4 - DWARF5");
+ case DwarfAttributeForm.Addrx1: throw new NotSupportedException("DW_FORM_addrx1 - DWARF5");
+ case DwarfAttributeForm.Addrx2: throw new NotSupportedException("DW_FORM_addrx2 - DWARF5");
+ case DwarfAttributeForm.Addrx3: throw new NotSupportedException("DW_FORM_addrx3 - DWARF5");
+ case DwarfAttributeForm.Addrx4: throw new NotSupportedException("DW_FORM_addrx4 - DWARF5");
+ case DwarfAttributeForm.GNUAddrIndex: throw new NotSupportedException("DW_FORM_GNU_addr_index - GNU extension in debug_info.dwo.");
+ case DwarfAttributeForm.GNUStrIndex: throw new NotSupportedException("DW_FORM_GNU_str_index - GNU extension, somewhat like DW_FORM_strp");
+ case DwarfAttributeForm.GNURefAlt: throw new NotSupportedException("DW_FORM_GNU_ref_alt - GNU extension. Offset in .debug_info.");
+ case DwarfAttributeForm.GNUStrpAlt: throw new NotSupportedException("DW_FORM_GNU_strp_alt - GNU extension. Offset in .debug_str of another object file.");
+ default:
+ throw new NotSupportedException($"Unknown {nameof(DwarfAttributeForm)}: {Form}");
}
- protected override void Read(DwarfReader reader)
- {
- var descriptor = reader.CurrentAttributeDescriptor;
+ Size = endOffset - Position;
+ }
+
+ public override void Read(DwarfReader reader)
+ {
+ var descriptor = reader.CurrentAttributeDescriptor;
- Kind = descriptor.Kind;
- Form = descriptor.Form;
+ Kind = descriptor.Kind;
+ Form = descriptor.Form;
- ReadAttributeFormRawValue(reader);
+ ReadAttributeFormRawValue(reader);
- Size = reader.Offset - Offset;
+ Size = reader.Position - Position;
- ResolveAttributeValue(reader);
- }
+ ResolveAttributeValue(reader);
+ }
- private void ResolveAttributeValue(DwarfReader reader)
+ private void ResolveAttributeValue(DwarfReader reader)
+ {
+ switch (Kind.Value)
{
- switch (Kind.Value)
+ case DwarfAttributeKind.DeclFile:
{
- case DwarfAttributeKind.DeclFile:
+ var currentLineProgramTable = reader.CurrentLineProgramTable;
+ if (currentLineProgramTable == null)
{
- var currentLineProgramTable = reader.CurrentLineProgramTable;
- if (currentLineProgramTable == null)
- {
- // Log and error
- }
- else
- {
- var file = currentLineProgramTable.FileNames[ValueAsI32 - 1];
- ValueAsU64 = 0;
- ValueAsObject = file;
- }
- break;
+ // Log and error
}
-
- case DwarfAttributeKind.StmtList:
+ else
{
- if (ValueAsU64 == 0) return;
+ var file = currentLineProgramTable.FileNames[ValueAsI32 - 1];
+ ValueAsU64 = 0;
+ ValueAsObject = file;
+ }
+ break;
+ }
- if (reader.File.LineSection != null)
+ case DwarfAttributeKind.StmtList:
+ {
+ if (ValueAsU64 == 0) return;
+
+ if (reader.File.LineSection != null)
+ {
+ if (reader.OffsetToLineProgramTable.TryGetValue(ValueAsU64, out var lineProgramTable))
{
- if (reader.OffsetToLineProgramTable.TryGetValue(ValueAsU64, out var lineProgramTable))
- {
- ValueAsU64 = 0;
- ValueAsObject = lineProgramTable;
- reader.PushLineProgramTable(lineProgramTable);
- }
- else
- {
- // Log and error
- }
+ ValueAsU64 = 0;
+ ValueAsObject = lineProgramTable;
+ reader.PushLineProgramTable(lineProgramTable);
}
else
{
-
- // Log an error
+ // Log and error
}
+ }
+ else
+ {
- break;
-
+ // Log an error
}
- case DwarfAttributeKind.Location:
+ break;
+
+ }
+
+ case DwarfAttributeKind.Location:
+ {
+ if (Form == DwarfAttributeFormEx.SecOffset)
{
- if (Form == DwarfAttributeFormEx.SecOffset)
+ if (reader.OffsetToLocationList.TryGetValue(ValueAsU64, out var locationList))
+ {
+ ValueAsU64 = 0;
+ ValueAsObject = locationList;
+ }
+ else
{
- if (reader.OffsetToLocationList.TryGetValue(ValueAsU64, out var locationList))
- {
- ValueAsU64 = 0;
- ValueAsObject = locationList;
- }
- else
- {
- // Log and error
- }
+ // Log and error
}
- break;
}
+ break;
}
}
+ }
- private void ReadAttributeFormRawValue(DwarfReader reader)
+ private void ReadAttributeFormRawValue(DwarfReader reader)
+ {
+ var attributeForm = Form;
+
+ indirect:
+ switch (attributeForm.Value)
{
- var attributeForm = Form;
+ case DwarfAttributeForm.Addr:
+ {
+ ValueAsU64 = reader.ReadUInt();
+ break;
+ }
- indirect:
- switch (attributeForm.Value)
+ case DwarfAttributeForm.Data1:
{
- case DwarfAttributeForm.Addr:
- {
- ValueAsU64 = reader.ReadUInt();
- break;
- }
+ ValueAsU64 = reader.ReadU8();
+ break;
+ }
+ case DwarfAttributeForm.Data2:
+ {
+ ValueAsU64 = reader.ReadU16();
+ break;
+ }
+ case DwarfAttributeForm.Data4:
+ {
+ ValueAsU64 = reader.ReadU32();
+ break;
+ }
+ case DwarfAttributeForm.Data8:
+ {
+ ValueAsU64 = reader.ReadU64();
+ break;
+ }
- case DwarfAttributeForm.Data1:
- {
- ValueAsU64 = reader.ReadU8();
- break;
- }
- case DwarfAttributeForm.Data2:
- {
- ValueAsU64 = reader.ReadU16();
- break;
- }
- case DwarfAttributeForm.Data4:
- {
- ValueAsU64 = reader.ReadU32();
- break;
- }
- case DwarfAttributeForm.Data8:
- {
- ValueAsU64 = reader.ReadU64();
- break;
- }
+ case DwarfAttributeForm.String:
+ {
+ ValueAsObject = reader.ReadStringUTF8NullTerminated();
+ break;
+ }
- case DwarfAttributeForm.String:
- {
- ValueAsObject = reader.ReadStringUTF8NullTerminated();
- break;
- }
+ case DwarfAttributeForm.Block:
+ {
+ var length = reader.ReadULEB128();
+ ValueAsObject = reader.ReadAsStream(length);
+ break;
+ }
+ case DwarfAttributeForm.Block1:
+ {
+ var length = reader.ReadU8();
+ ValueAsObject = reader.ReadAsStream(length);
+ break;
+ }
+ case DwarfAttributeForm.Block2:
+ {
+ var length = reader.ReadU16();
+ ValueAsObject = reader.ReadAsStream(length);
+ break;
+ }
+ case DwarfAttributeForm.Block4:
+ {
+ var length = reader.ReadU32();
+ ValueAsObject = reader.ReadAsStream(length);
+ break;
+ }
- case DwarfAttributeForm.Block:
- {
- var length = reader.ReadULEB128();
- ValueAsObject = reader.ReadAsStream(length);
- break;
- }
- case DwarfAttributeForm.Block1:
- {
- var length = reader.ReadU8();
- ValueAsObject = reader.ReadAsStream(length);
- break;
- }
- case DwarfAttributeForm.Block2:
- {
- var length = reader.ReadU16();
- ValueAsObject = reader.ReadAsStream(length);
- break;
- }
- case DwarfAttributeForm.Block4:
- {
- var length = reader.ReadU32();
- ValueAsObject = reader.ReadAsStream(length);
- break;
- }
+ case DwarfAttributeForm.Flag:
+ {
+ ValueAsBoolean = reader.ReadU8() != 0;
+ break;
+ }
+ case DwarfAttributeForm.Sdata:
+ {
+ ValueAsI64 = reader.ReadILEB128();
+ break;
+ }
+ case DwarfAttributeForm.Strp:
+ {
+ var offset = reader.ReadUIntFromEncoding();
+ ValueAsObject = reader.File.StringTable.GetStringFromOffset(offset);
+ break;
+ }
+ case DwarfAttributeForm.Udata:
+ {
+ ValueAsU64 = reader.ReadULEB128();
+ break;
+ }
+ case DwarfAttributeForm.RefAddr:
+ {
+ ValueAsU64 = reader.ReadUIntFromEncoding();
+ reader.ResolveAttributeReferenceWithinSection(AttributeToDIERef(this), false);
+ break;
+ }
+ case DwarfAttributeForm.Ref1:
+ {
+ ValueAsU64 = reader.ReadU8();
+ reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
+ break;
+ }
+ case DwarfAttributeForm.Ref2:
+ {
+ ValueAsU64 = reader.ReadU16();
+ reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
+ break;
+ }
+ case DwarfAttributeForm.Ref4:
+ {
+ ValueAsU64 = reader.ReadU32();
+ reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
+ break;
+ }
+ case DwarfAttributeForm.Ref8:
+ {
+ ValueAsU64 = reader.ReadU64();
+ reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
+ break;
+ }
+ case DwarfAttributeForm.RefUdata:
+ {
+ ValueAsU64 = reader.ReadULEB128();
+ reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
+ break;
+ }
+ case DwarfAttributeForm.Indirect:
+ {
+ attributeForm = new DwarfAttributeFormEx(reader.ReadULEB128AsU32());
+ goto indirect;
+ }
- case DwarfAttributeForm.Flag:
- {
- ValueAsBoolean = reader.ReadU8() != 0;
- break;
- }
- case DwarfAttributeForm.Sdata:
- {
- ValueAsI64 = reader.ReadILEB128();
- break;
- }
- case DwarfAttributeForm.Strp:
- {
- var offset = reader.ReadUIntFromEncoding();
- ValueAsObject = reader.File.StringTable.GetStringFromOffset(offset);
- break;
- }
- case DwarfAttributeForm.Udata:
- {
- ValueAsU64 = reader.ReadULEB128();
- break;
- }
- case DwarfAttributeForm.RefAddr:
- {
- ValueAsU64 = reader.ReadUIntFromEncoding();
- reader.ResolveAttributeReferenceWithinSection(AttributeToDIERef(this), false);
- break;
- }
- case DwarfAttributeForm.Ref1:
- {
- ValueAsU64 = reader.ReadU8();
- reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
- break;
- }
- case DwarfAttributeForm.Ref2:
- {
- ValueAsU64 = reader.ReadU16();
- reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
- break;
- }
- case DwarfAttributeForm.Ref4:
- {
- ValueAsU64 = reader.ReadU32();
- reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
- break;
- }
- case DwarfAttributeForm.Ref8:
- {
- ValueAsU64 = reader.ReadU64();
- reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
- break;
- }
- case DwarfAttributeForm.RefUdata:
- {
- ValueAsU64 = reader.ReadULEB128();
- reader.ResolveAttributeReferenceWithinCompilationUnit(AttributeToDIERef(this), false);
- break;
- }
- case DwarfAttributeForm.Indirect:
- {
- attributeForm = new DwarfAttributeFormEx(reader.ReadULEB128AsU32());
- goto indirect;
- }
+ // addptr
+ // lineptr
+ // loclist
+ // loclistptr
+ // macptr
+ // rnglist
+ // rngrlistptr
+ // stroffsetsptr
+ case DwarfAttributeForm.SecOffset:
+ {
+ ValueAsU64 = reader.ReadUIntFromEncoding();
+ //Console.WriteLine($"attribute {Key} offset: {ValueAsU64}");
+ break;
+ }
- // addptr
- // lineptr
- // loclist
- // loclistptr
- // macptr
- // rnglist
- // rngrlistptr
- // stroffsetsptr
- case DwarfAttributeForm.SecOffset:
- {
- ValueAsU64 = reader.ReadUIntFromEncoding();
- //Console.WriteLine($"attribute {Key} offset: {ValueAsU64}");
- break;
- }
+ case DwarfAttributeForm.Exprloc:
+ {
+ var expression = new DwarfExpression();
+ expression.ReadInternal(reader);
+ ValueAsObject = expression;
+ break;
+ }
- case DwarfAttributeForm.Exprloc:
- {
- var expression = new DwarfExpression();
- expression.ReadInternal(reader);
- ValueAsObject = expression;
- break;
- }
+ case DwarfAttributeForm.FlagPresent:
+ {
+ ValueAsBoolean = true;
+ break;
+ }
- case DwarfAttributeForm.FlagPresent:
- {
- ValueAsBoolean = true;
- break;
- }
+ case DwarfAttributeForm.RefSig8:
+ {
+ var offset = reader.ReadU64();
+ ValueAsU64 = offset;
+ break;
+ }
- case DwarfAttributeForm.RefSig8:
- {
- var offset = reader.ReadU64();
- ValueAsU64 = offset;
+ case DwarfAttributeForm.Strx: throw new NotSupportedException("DW_FORM_strx - DWARF5");
+ case DwarfAttributeForm.Addrx: throw new NotSupportedException("DW_FORM_addrx - DWARF5");
+ case DwarfAttributeForm.RefSup4: throw new NotSupportedException("DW_FORM_ref_sup4 - DWARF5");
+ case DwarfAttributeForm.StrpSup: throw new NotSupportedException("DW_FORM_strp_sup - DWARF5");
+ case DwarfAttributeForm.Data16: throw new NotSupportedException("DW_FORM_data16 - DWARF5");
+ case DwarfAttributeForm.LineStrp: throw new NotSupportedException("DW_FORM_line_strp - DWARF5");
+ case DwarfAttributeForm.ImplicitConst: throw new NotSupportedException("DW_FORM_implicit_const - DWARF5");
+ case DwarfAttributeForm.Loclistx: throw new NotSupportedException("DW_FORM_loclistx - DWARF5");
+ case DwarfAttributeForm.Rnglistx: throw new NotSupportedException("DW_FORM_rnglistx - DWARF5");
+ case DwarfAttributeForm.RefSup8: throw new NotSupportedException("DW_FORM_ref_sup8 - DWARF5");
+ case DwarfAttributeForm.Strx1: throw new NotSupportedException("DW_FORM_strx1 - DWARF5");
+ case DwarfAttributeForm.Strx2: throw new NotSupportedException("DW_FORM_strx2 - DWARF5");
+ case DwarfAttributeForm.Strx3: throw new NotSupportedException("DW_FORM_strx3 - DWARF5");
+ case DwarfAttributeForm.Strx4: throw new NotSupportedException("DW_FORM_strx4 - DWARF5");
+ case DwarfAttributeForm.Addrx1: throw new NotSupportedException("DW_FORM_addrx1 - DWARF5");
+ case DwarfAttributeForm.Addrx2: throw new NotSupportedException("DW_FORM_addrx2 - DWARF5");
+ case DwarfAttributeForm.Addrx3: throw new NotSupportedException("DW_FORM_addrx3 - DWARF5");
+ case DwarfAttributeForm.Addrx4: throw new NotSupportedException("DW_FORM_addrx4 - DWARF5");
+ case DwarfAttributeForm.GNUAddrIndex: throw new NotSupportedException("DW_FORM_GNU_addr_index - GNU extension in debug_info.dwo.");
+ case DwarfAttributeForm.GNUStrIndex: throw new NotSupportedException("DW_FORM_GNU_str_index - GNU extension, somewhat like DW_FORM_strp");
+ case DwarfAttributeForm.GNURefAlt: throw new NotSupportedException("DW_FORM_GNU_ref_alt - GNU extension. Offset in .debug_info.");
+ case DwarfAttributeForm.GNUStrpAlt: throw new NotSupportedException("DW_FORM_GNU_strp_alt - GNU extension. Offset in .debug_str of another object file.");
+ default:
+ throw new NotSupportedException($"Unknown {nameof(DwarfAttributeForm)}: {attributeForm.Value}");
+ }
+ }
+
+ internal void UpdateAttributeForm(DwarfLayoutContext context)
+ {
+ Form = ComputeAttributeForm(context);
+ }
+
+ private DwarfAttributeForm ComputeAttributeForm(DwarfLayoutContext context)
+ {
+ var key = Kind;
+ var encoding = DwarfHelper.GetAttributeEncoding(key);
+
+ if (encoding == DwarfAttributeEncoding.None)
+ {
+ switch (Kind.Value)
+ {
+ case DwarfAttributeKind.GNUAllCallSites:
+ case DwarfAttributeKind.GNUAllTailCallSites:
+ encoding = DwarfAttributeEncoding.Flag;
+ break;
+ case DwarfAttributeKind.GNUCallSiteTarget:
+ case DwarfAttributeKind.GNUCallSiteValue:
+ encoding = DwarfAttributeEncoding.ExpressionLocation | DwarfAttributeEncoding.LocationList;
break;
- }
- case DwarfAttributeForm.Strx: throw new NotSupportedException("DW_FORM_strx - DWARF5");
- case DwarfAttributeForm.Addrx: throw new NotSupportedException("DW_FORM_addrx - DWARF5");
- case DwarfAttributeForm.RefSup4: throw new NotSupportedException("DW_FORM_ref_sup4 - DWARF5");
- case DwarfAttributeForm.StrpSup: throw new NotSupportedException("DW_FORM_strp_sup - DWARF5");
- case DwarfAttributeForm.Data16: throw new NotSupportedException("DW_FORM_data16 - DWARF5");
- case DwarfAttributeForm.LineStrp: throw new NotSupportedException("DW_FORM_line_strp - DWARF5");
- case DwarfAttributeForm.ImplicitConst: throw new NotSupportedException("DW_FORM_implicit_const - DWARF5");
- case DwarfAttributeForm.Loclistx: throw new NotSupportedException("DW_FORM_loclistx - DWARF5");
- case DwarfAttributeForm.Rnglistx: throw new NotSupportedException("DW_FORM_rnglistx - DWARF5");
- case DwarfAttributeForm.RefSup8: throw new NotSupportedException("DW_FORM_ref_sup8 - DWARF5");
- case DwarfAttributeForm.Strx1: throw new NotSupportedException("DW_FORM_strx1 - DWARF5");
- case DwarfAttributeForm.Strx2: throw new NotSupportedException("DW_FORM_strx2 - DWARF5");
- case DwarfAttributeForm.Strx3: throw new NotSupportedException("DW_FORM_strx3 - DWARF5");
- case DwarfAttributeForm.Strx4: throw new NotSupportedException("DW_FORM_strx4 - DWARF5");
- case DwarfAttributeForm.Addrx1: throw new NotSupportedException("DW_FORM_addrx1 - DWARF5");
- case DwarfAttributeForm.Addrx2: throw new NotSupportedException("DW_FORM_addrx2 - DWARF5");
- case DwarfAttributeForm.Addrx3: throw new NotSupportedException("DW_FORM_addrx3 - DWARF5");
- case DwarfAttributeForm.Addrx4: throw new NotSupportedException("DW_FORM_addrx4 - DWARF5");
- case DwarfAttributeForm.GNUAddrIndex: throw new NotSupportedException("DW_FORM_GNU_addr_index - GNU extension in debug_info.dwo.");
- case DwarfAttributeForm.GNUStrIndex: throw new NotSupportedException("DW_FORM_GNU_str_index - GNU extension, somewhat like DW_FORM_strp");
- case DwarfAttributeForm.GNURefAlt: throw new NotSupportedException("DW_FORM_GNU_ref_alt - GNU extension. Offset in .debug_info.");
- case DwarfAttributeForm.GNUStrpAlt: throw new NotSupportedException("DW_FORM_GNU_strp_alt - GNU extension. Offset in .debug_str of another object file.");
default:
- throw new NotSupportedException($"Unknown {nameof(DwarfAttributeForm)}: {attributeForm.Value}");
+ // TODO: Add pluggable support for requesting attribute encoding here
+ throw new InvalidOperationException($"Unsupported attribute {this} with unknown encoding");
}
}
- internal void UpdateAttributeForm(DwarfLayoutContext context)
+ // If the attribute has a requested encoding
+ if (Encoding.HasValue)
{
- Form = ComputeAttributeForm(context);
+ var requestedEncoding = Encoding.Value;
+ if ((encoding & requestedEncoding) == 0)
+ {
+ throw new InvalidOperationException($"Requested encoding {requestedEncoding} for {this} doesn't match supported encoding {encoding} for this attribute");
+ }
+
+ // Replace encoding with requested encoding
+ encoding = requestedEncoding;
}
-
- private DwarfAttributeForm ComputeAttributeForm(DwarfLayoutContext context)
- {
- var key = Kind;
- var encoding = DwarfHelper.GetAttributeEncoding(key);
- if (encoding == DwarfAttributeEncoding.None)
+ // Do we still have a complex encoding?
+ if ((((uint)encoding) & ((uint)encoding - 1)) != 0U)
+ {
+ // if we have, try to detect which one we should select
+ if (ValueAsObject is DwarfDIE)
{
- switch (Kind.Value)
+ if ((encoding & DwarfAttributeEncoding.Reference) == 0)
{
- case DwarfAttributeKind.GNUAllCallSites:
- case DwarfAttributeKind.GNUAllTailCallSites:
- encoding = DwarfAttributeEncoding.Flag;
- break;
- case DwarfAttributeKind.GNUCallSiteTarget:
- case DwarfAttributeKind.GNUCallSiteValue:
- encoding = DwarfAttributeEncoding.ExpressionLocation | DwarfAttributeEncoding.LocationList;
- break;
-
- default:
- // TODO: Add pluggable support for requesting attribute encoding here
- throw new InvalidOperationException($"Unsupported attribute {this} with unknown encoding");
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The DIE value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Reference.");
}
- }
- // If the attribute has a requested encoding
- if (Encoding.HasValue)
+ encoding = DwarfAttributeEncoding.Reference;
+ }
+ else if (this.ValueAsObject is Stream)
{
- var requestedEncoding = Encoding.Value;
- if ((encoding & requestedEncoding) == 0)
+ if ((encoding & DwarfAttributeEncoding.Block) == 0)
{
- throw new InvalidOperationException($"Requested encoding {requestedEncoding} for {this} doesn't match supported encoding {encoding} for this attribute");
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The Stream value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Block.");
}
- // Replace encoding with requested encoding
- encoding = requestedEncoding;
+ encoding = DwarfAttributeEncoding.Block;
}
-
- // Do we still have a complex encoding?
- if ((((uint)encoding) & ((uint)encoding - 1)) != 0U)
+ else if (this.ValueAsObject is string)
{
- // if we have, try to detect which one we should select
- if (ValueAsObject is DwarfDIE)
+ if ((encoding & DwarfAttributeEncoding.String) == 0)
{
- if ((encoding & DwarfAttributeEncoding.Reference) == 0)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The DIE value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Reference.");
- }
-
- encoding = DwarfAttributeEncoding.Reference;
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The string value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting String.");
}
- else if (this.ValueAsObject is Stream)
- {
- if ((encoding & DwarfAttributeEncoding.Block) == 0)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The Stream value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Block.");
- }
- encoding = DwarfAttributeEncoding.Block;
- }
- else if (this.ValueAsObject is string)
+ encoding = DwarfAttributeEncoding.String;
+ }
+ else if (this.ValueAsObject is DwarfExpression)
+ {
+ if ((encoding & DwarfAttributeEncoding.ExpressionLocation) == 0)
{
- if ((encoding & DwarfAttributeEncoding.String) == 0)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The string value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting String.");
- }
-
- encoding = DwarfAttributeEncoding.String;
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The expression value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting ExpressionLocation.");
}
- else if (this.ValueAsObject is DwarfExpression)
- {
- if ((encoding & DwarfAttributeEncoding.ExpressionLocation) == 0)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The expression value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting ExpressionLocation.");
- }
- encoding = DwarfAttributeEncoding.ExpressionLocation;
+ encoding = DwarfAttributeEncoding.ExpressionLocation;
+ }
+ else if (this.ValueAsObject is DwarfLocationList)
+ {
+ if ((encoding & DwarfAttributeEncoding.LocationList) == 0)
+ {
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The expression value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting LocationList.");
}
- else if (this.ValueAsObject is DwarfLocationList)
+
+ encoding = DwarfAttributeEncoding.LocationList;
+ }
+ else if ((encoding & DwarfAttributeEncoding.Address) != 0)
+ {
+ if (this.ValueAsObject != null)
{
- if ((encoding & DwarfAttributeEncoding.LocationList) == 0)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The expression value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting LocationList.");
- }
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The {this.ValueAsObject.GetType()} value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Address.");
+ }
- encoding = DwarfAttributeEncoding.LocationList;
+ // If not specified explicitly, We consider HighPC as a constant (delta from LowPC)
+ if (this.Kind == DwarfAttributeKindEx.HighPC)
+ {
+ encoding = DwarfAttributeEncoding.Constant;
}
- else if ((encoding & DwarfAttributeEncoding.Address) != 0)
+ else
{
- if (this.ValueAsObject != null)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The {this.ValueAsObject.GetType()} value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Address.");
- }
-
- // If not specified explicitly, We consider HighPC as a constant (delta from LowPC)
- if (this.Kind == DwarfAttributeKindEx.HighPC)
- {
- encoding = DwarfAttributeEncoding.Constant;
- }
- else
- {
- encoding = DwarfAttributeEncoding.Address;
- }
+ encoding = DwarfAttributeEncoding.Address;
}
- else if ((encoding & DwarfAttributeEncoding.Constant) != 0)
+ }
+ else if ((encoding & DwarfAttributeEncoding.Constant) != 0)
+ {
+ if (this.ValueAsObject != null)
{
- if (this.ValueAsObject != null)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The {this.ValueAsObject.GetType()} value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Constant.");
- }
-
- encoding = DwarfAttributeEncoding.Constant;
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The {this.ValueAsObject.GetType()} value of attribute {this} from DIE {this.Parent} is not valid for supported attribute encoding {encoding}. Expecting Constant.");
}
+
+ encoding = DwarfAttributeEncoding.Constant;
}
+ }
- switch (encoding)
- {
- case DwarfAttributeEncoding.Address:
- return DwarfAttributeForm.Addr;
+ switch (encoding)
+ {
+ case DwarfAttributeEncoding.Address:
+ return DwarfAttributeForm.Addr;
- case DwarfAttributeEncoding.Block:
- VerifyAttributeValueNotNull(context);
+ case DwarfAttributeEncoding.Block:
+ VerifyAttributeValueNotNull(context);
- if (!(this.ValueAsObject is Stream))
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a System.IO.Stream");
- }
+ if (!(this.ValueAsObject is Stream))
+ {
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a System.IO.Stream");
+ }
- return DwarfAttributeForm.Block;
+ return DwarfAttributeForm.Block;
- case DwarfAttributeEncoding.Constant:
+ case DwarfAttributeEncoding.Constant:
- if (this.ValueAsU64 <= byte.MaxValue)
- {
- return DwarfAttributeForm.Data1;
- }
+ if (this.ValueAsU64 <= byte.MaxValue)
+ {
+ return DwarfAttributeForm.Data1;
+ }
- if (this.ValueAsU64 <= ushort.MaxValue)
- {
- return DwarfAttributeForm.Data2;
- }
+ if (this.ValueAsU64 <= ushort.MaxValue)
+ {
+ return DwarfAttributeForm.Data2;
+ }
- if (this.ValueAsU64 <= uint.MaxValue)
- {
- return DwarfAttributeForm.Data4;
- }
+ if (this.ValueAsU64 <= uint.MaxValue)
+ {
+ return DwarfAttributeForm.Data4;
+ }
- return DwarfAttributeForm.Data8;
+ return DwarfAttributeForm.Data8;
- case DwarfAttributeEncoding.ExpressionLocation:
- VerifyAttributeValueNotNull(context);
+ case DwarfAttributeEncoding.ExpressionLocation:
+ VerifyAttributeValueNotNull(context);
- if (!(this.ValueAsObject is DwarfExpression))
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a {nameof(DwarfExpression)}");
- }
+ if (!(this.ValueAsObject is DwarfExpression))
+ {
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a {nameof(DwarfExpression)}");
+ }
- return DwarfAttributeForm.Exprloc;
+ return DwarfAttributeForm.Exprloc;
- case DwarfAttributeEncoding.Flag:
- return this.ValueAsBoolean ? DwarfAttributeForm.FlagPresent : DwarfAttributeForm.Flag;
+ case DwarfAttributeEncoding.Flag:
+ return this.ValueAsBoolean ? DwarfAttributeForm.FlagPresent : DwarfAttributeForm.Flag;
- case DwarfAttributeEncoding.LinePointer:
- bool canHaveNull = this.Kind.Value == DwarfAttributeKind.StmtList;
- if (!canHaveNull)
- {
- VerifyAttributeValueNotNull(context);
+ case DwarfAttributeEncoding.LinePointer:
+ bool canHaveNull = this.Kind.Value == DwarfAttributeKind.StmtList;
+ if (!canHaveNull)
+ {
+ VerifyAttributeValueNotNull(context);
- if (!(this.ValueAsObject is DwarfLine))
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a {nameof(DwarfLine)}");
- }
+ if (!(this.ValueAsObject is DwarfLine))
+ {
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a {nameof(DwarfLine)}");
}
+ }
- return DwarfAttributeForm.SecOffset;
+ return DwarfAttributeForm.SecOffset;
- case DwarfAttributeEncoding.Reference:
- VerifyAttributeValueNotNull(context);
+ case DwarfAttributeEncoding.Reference:
+ VerifyAttributeValueNotNull(context);
- if (this.ValueAsObject is DwarfDIE die)
- {
- var dieParentUnit = die.GetParentUnit();
- // If we are not from the same unit
- if (dieParentUnit != context.CurrentUnit)
- {
- return DwarfAttributeForm.RefAddr;
- }
- }
- else
+ if (this.ValueAsObject is DwarfDIE die)
+ {
+ var dieParentUnit = die.GetParentUnit();
+ // If we are not from the same unit
+ if (dieParentUnit != context.CurrentUnit)
{
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a {nameof(DwarfDIE)}");
+ return DwarfAttributeForm.RefAddr;
}
+ }
+ else
+ {
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a {nameof(DwarfDIE)}");
+ }
- return context.Config.DefaultAttributeFormForReference;
+ return context.Config.DefaultAttributeFormForReference;
- case DwarfAttributeEncoding.String:
- VerifyAttributeValueNotNull(context);
+ case DwarfAttributeEncoding.String:
+ VerifyAttributeValueNotNull(context);
- if (this.ValueAsObject is string str)
- {
- // Create string offset
- if (context.File.StringTable.Contains(str))
- {
- return DwarfAttributeForm.Strp;
- }
- }
- else
+ if (this.ValueAsObject is string str)
+ {
+ // Create string offset
+ if (context.File.StringTable.Contains(str))
{
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a string.");
+ return DwarfAttributeForm.Strp;
}
+ }
+ else
+ {
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The value of attribute {this} from DIE {this.Parent} must be a string.");
+ }
- return DwarfAttributeForm.String;
+ return DwarfAttributeForm.String;
- case DwarfAttributeEncoding.RangeList:
- case DwarfAttributeEncoding.LocationList:
- case DwarfAttributeEncoding.Indirect:
- case DwarfAttributeEncoding.AddressPointer:
- case DwarfAttributeEncoding.LocationListsPointer:
- case DwarfAttributeEncoding.RangeListsPointer:
- case DwarfAttributeEncoding.StringOffsetPointer:
- case DwarfAttributeEncoding.LocationListPointer:
- case DwarfAttributeEncoding.MacroPointer:
- case DwarfAttributeEncoding.RangeListPointer:
- return DwarfAttributeForm.SecOffset;
- }
-
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The encoding {encoding} of attribute {this} from DIE {this.Parent} is not supported.");
- return DwarfAttributeForm.Data8;
+ case DwarfAttributeEncoding.RangeList:
+ case DwarfAttributeEncoding.LocationList:
+ case DwarfAttributeEncoding.Indirect:
+ case DwarfAttributeEncoding.AddressPointer:
+ case DwarfAttributeEncoding.LocationListsPointer:
+ case DwarfAttributeEncoding.RangeListsPointer:
+ case DwarfAttributeEncoding.StringOffsetPointer:
+ case DwarfAttributeEncoding.LocationListPointer:
+ case DwarfAttributeEncoding.MacroPointer:
+ case DwarfAttributeEncoding.RangeListPointer:
+ return DwarfAttributeForm.SecOffset;
}
- private void VerifyAttributeValueNotNull(DwarfLayoutContext context)
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The encoding {encoding} of attribute {this} from DIE {this.Parent} is not supported.");
+ return DwarfAttributeForm.Data8;
+ }
+
+ private void VerifyAttributeValueNotNull(DwarfLayoutContext context)
+ {
+ if (ValueAsObject == null)
{
- if (ValueAsObject == null)
- {
- context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The object value of attribute {this} from DIE {this.Parent} cannot be null");
- }
+ context.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"The object value of attribute {this} from DIE {this.Parent} cannot be null");
}
+ }
- protected override void Write(DwarfWriter writer)
- {
- var startAttributeOffset = Offset;
- Debug.Assert(Offset == startAttributeOffset);
+ public override void Write(DwarfWriter writer)
+ {
+ var startAttributeOffset = Position;
+ Debug.Assert(Position == startAttributeOffset);
- switch (Form.Value)
+ switch (Form.Value)
+ {
+ case DwarfAttributeForm.Addr:
{
- case DwarfAttributeForm.Addr:
- {
- writer.WriteAddress(DwarfRelocationTarget.Code, ValueAsU64);
- break;
- }
- case DwarfAttributeForm.Data1:
- {
- writer.WriteU8((byte) ValueAsU64);
- break;
- }
- case DwarfAttributeForm.Data2:
- {
- writer.WriteU16((ushort) ValueAsU64);
- break;
- }
- case DwarfAttributeForm.Data4:
- {
- writer.WriteU32((uint) ValueAsU64);
- break;
- }
- case DwarfAttributeForm.Data8:
- {
- writer.WriteU64(ValueAsU64);
- break;
- }
- case DwarfAttributeForm.String:
- {
- writer.WriteStringUTF8NullTerminated((string) ValueAsObject);
- break;
- }
- case DwarfAttributeForm.Block:
- {
- var stream = (Stream) ValueAsObject;
- writer.WriteULEB128((ulong) stream.Length);
- writer.Write(stream);
- break;
- }
- case DwarfAttributeForm.Block1:
- {
- var stream = (Stream) ValueAsObject;
- writer.WriteU8((byte) stream.Length);
- writer.Write(stream);
- break;
- }
- case DwarfAttributeForm.Block2:
- {
- var stream = (Stream) ValueAsObject;
- writer.WriteU16((ushort) stream.Length);
- writer.Write(stream);
- break;
- }
- case DwarfAttributeForm.Block4:
- {
- var stream = (Stream) ValueAsObject;
- writer.WriteU32((uint) stream.Length);
- writer.Write(stream);
- break;
- }
- case DwarfAttributeForm.Flag:
- {
- writer.WriteU8((byte) (ValueAsU64 != 0 ? 1 : 0));
- break;
- }
- case DwarfAttributeForm.Sdata:
- {
- writer.WriteILEB128(ValueAsI64);
- break;
- }
- case DwarfAttributeForm.Strp:
- {
- var offset = writer.File.StringTable.GetOrCreateString((string) ValueAsObject);
- if (writer.EnableRelocation)
- {
- writer.RecordRelocation(DwarfRelocationTarget.DebugString, writer.SizeOfUIntEncoding(), offset);
- offset = 0;
- }
- writer.WriteUIntFromEncoding(offset);
- break;
- }
- case DwarfAttributeForm.Udata:
- {
- writer.WriteULEB128(ValueAsU64);
- break;
- }
- case DwarfAttributeForm.RefAddr:
- {
- var dieRef = (DwarfDIE) ValueAsObject;
- writer.WriteUIntFromEncoding(dieRef.Offset);
- break;
- }
- case DwarfAttributeForm.Ref1:
- {
- var dieRef = (DwarfDIE) ValueAsObject;
- writer.WriteU8((byte) (dieRef.Offset - writer.CurrentUnit.Offset));
- break;
- }
- case DwarfAttributeForm.Ref2:
- {
- var dieRef = (DwarfDIE) ValueAsObject;
- writer.WriteU16((ushort) (dieRef.Offset - writer.CurrentUnit.Offset));
- break;
- }
- case DwarfAttributeForm.Ref4:
- {
- var dieRef = (DwarfDIE) ValueAsObject;
- writer.WriteU32((uint) (dieRef.Offset - writer.CurrentUnit.Offset));
- break;
- }
- case DwarfAttributeForm.Ref8:
+ writer.WriteAddress(DwarfRelocationTarget.Code, ValueAsU64);
+ break;
+ }
+ case DwarfAttributeForm.Data1:
+ {
+ writer.WriteU8((byte) ValueAsU64);
+ break;
+ }
+ case DwarfAttributeForm.Data2:
+ {
+ writer.WriteU16((ushort) ValueAsU64);
+ break;
+ }
+ case DwarfAttributeForm.Data4:
+ {
+ writer.WriteU32((uint) ValueAsU64);
+ break;
+ }
+ case DwarfAttributeForm.Data8:
+ {
+ writer.WriteU64(ValueAsU64);
+ break;
+ }
+ case DwarfAttributeForm.String:
+ {
+ writer.WriteStringUTF8NullTerminated((string)ValueAsObject!);
+ break;
+ }
+ case DwarfAttributeForm.Block:
+ {
+ var stream = (Stream) ValueAsObject!;
+ writer.WriteULEB128((ulong) stream.Length);
+ writer.Write(stream);
+ break;
+ }
+ case DwarfAttributeForm.Block1:
+ {
+ var stream = (Stream) ValueAsObject!;
+ writer.WriteU8((byte) stream.Length);
+ writer.Write(stream);
+ break;
+ }
+ case DwarfAttributeForm.Block2:
+ {
+ var stream = (Stream) ValueAsObject!;
+ writer.WriteU16((ushort) stream.Length);
+ writer.Write(stream);
+ break;
+ }
+ case DwarfAttributeForm.Block4:
+ {
+ var stream = (Stream) ValueAsObject!;
+ writer.WriteU32((uint) stream.Length);
+ writer.Write(stream);
+ break;
+ }
+ case DwarfAttributeForm.Flag:
+ {
+ writer.WriteU8((byte) (ValueAsU64 != 0 ? 1 : 0));
+ break;
+ }
+ case DwarfAttributeForm.Sdata:
+ {
+ writer.WriteILEB128(ValueAsI64);
+ break;
+ }
+ case DwarfAttributeForm.Strp:
+ {
+ var offset = writer.File.StringTable.GetOrCreateString((string?) ValueAsObject);
+ if (writer.EnableRelocation)
{
- var dieRef = (DwarfDIE) ValueAsObject;
- writer.WriteU64((dieRef.Offset - writer.CurrentUnit.Offset));
- break;
+ writer.RecordRelocation(DwarfRelocationTarget.DebugString, writer.SizeOfUIntEncoding(), offset);
+ offset = 0;
}
- case DwarfAttributeForm.RefUdata:
+ writer.WriteUIntFromEncoding(offset);
+ break;
+ }
+ case DwarfAttributeForm.Udata:
+ {
+ writer.WriteULEB128(ValueAsU64);
+ break;
+ }
+ case DwarfAttributeForm.RefAddr:
+ {
+ var dieRef = (DwarfDIE) ValueAsObject!;
+ writer.WriteUIntFromEncoding(dieRef.Position);
+ break;
+ }
+ case DwarfAttributeForm.Ref1:
+ {
+ var dieRef = (DwarfDIE) ValueAsObject!;
+ writer.WriteU8((byte) (dieRef.Position - writer.CurrentUnit!.Position));
+ break;
+ }
+ case DwarfAttributeForm.Ref2:
+ {
+ var dieRef = (DwarfDIE) ValueAsObject!;
+ writer.WriteU16((ushort) (dieRef.Position - writer.CurrentUnit!.Position));
+ break;
+ }
+ case DwarfAttributeForm.Ref4:
+ {
+ var dieRef = (DwarfDIE) ValueAsObject!;
+ writer.WriteU32((uint) (dieRef.Position - writer.CurrentUnit!.Position));
+ break;
+ }
+ case DwarfAttributeForm.Ref8:
+ {
+ var dieRef = (DwarfDIE) ValueAsObject!;
+ writer.WriteU64((dieRef.Position - writer.CurrentUnit!.Position));
+ break;
+ }
+ case DwarfAttributeForm.RefUdata:
+ {
+ var dieRef = (DwarfDIE) ValueAsObject!;
+ writer.WriteULEB128((dieRef.Position - writer.CurrentUnit!.Position));
+ break;
+ }
+
+ //case DwarfAttributeForm.indirect:
+ //{
+ // attributeForm = reader.ReadLEB128As();
+ // goto indirect;
+ //}
+
+ // addptr
+ // lineptr
+ // loclist
+ // loclistptr
+ // macptr
+ // rnglist
+ // rngrlistptr
+ // stroffsetsptr
+ case DwarfAttributeForm.SecOffset:
+ {
+ if (ValueAsObject != null)
{
- var dieRef = (DwarfDIE) ValueAsObject;
- writer.WriteULEB128((dieRef.Offset - writer.CurrentUnit.Offset));
- break;
+ writer.WriteUIntFromEncoding(((DwarfObject) ValueAsObject).Position);
}
-
- //case DwarfAttributeForm.indirect:
- //{
- // attributeForm = reader.ReadLEB128As();
- // goto indirect;
- //}
-
- // addptr
- // lineptr
- // loclist
- // loclistptr
- // macptr
- // rnglist
- // rngrlistptr
- // stroffsetsptr
- case DwarfAttributeForm.SecOffset:
+ else
{
- if (ValueAsObject != null)
- {
- writer.WriteUIntFromEncoding(((DwarfObject) ValueAsObject).Offset);
- }
- else
- {
- writer.WriteUIntFromEncoding(ValueAsU64);
- }
- break;
+ writer.WriteUIntFromEncoding(ValueAsU64);
}
-
- case DwarfAttributeForm.Exprloc:
- ((DwarfExpression) ValueAsObject).WriteInternal(writer);
- break;
-
- case DwarfAttributeForm.FlagPresent:
- Debug.Assert(ValueAsBoolean);
- break;
-
- case DwarfAttributeForm.RefSig8:
- writer.WriteU64(ValueAsU64);
- break;
-
- case DwarfAttributeForm.Strx: throw new NotSupportedException("DW_FORM_strx - DWARF5");
- case DwarfAttributeForm.Addrx: throw new NotSupportedException("DW_FORM_addrx - DWARF5");
- case DwarfAttributeForm.RefSup4: throw new NotSupportedException("DW_FORM_ref_sup4 - DWARF5");
- case DwarfAttributeForm.StrpSup: throw new NotSupportedException("DW_FORM_strp_sup - DWARF5");
- case DwarfAttributeForm.Data16: throw new NotSupportedException("DW_FORM_data16 - DWARF5");
- case DwarfAttributeForm.LineStrp: throw new NotSupportedException("DW_FORM_line_strp - DWARF5");
- case DwarfAttributeForm.ImplicitConst: throw new NotSupportedException("DW_FORM_implicit_const - DWARF5");
- case DwarfAttributeForm.Loclistx: throw new NotSupportedException("DW_FORM_loclistx - DWARF5");
- case DwarfAttributeForm.Rnglistx: throw new NotSupportedException("DW_FORM_rnglistx - DWARF5");
- case DwarfAttributeForm.RefSup8: throw new NotSupportedException("DW_FORM_ref_sup8 - DWARF5");
- case DwarfAttributeForm.Strx1: throw new NotSupportedException("DW_FORM_strx1 - DWARF5");
- case DwarfAttributeForm.Strx2: throw new NotSupportedException("DW_FORM_strx2 - DWARF5");
- case DwarfAttributeForm.Strx3: throw new NotSupportedException("DW_FORM_strx3 - DWARF5");
- case DwarfAttributeForm.Strx4: throw new NotSupportedException("DW_FORM_strx4 - DWARF5");
- case DwarfAttributeForm.Addrx1: throw new NotSupportedException("DW_FORM_addrx1 - DWARF5");
- case DwarfAttributeForm.Addrx2: throw new NotSupportedException("DW_FORM_addrx2 - DWARF5");
- case DwarfAttributeForm.Addrx3: throw new NotSupportedException("DW_FORM_addrx3 - DWARF5");
- case DwarfAttributeForm.Addrx4: throw new NotSupportedException("DW_FORM_addrx4 - DWARF5");
- case DwarfAttributeForm.GNUAddrIndex: throw new NotSupportedException("DW_FORM_GNU_addr_index - GNU extension in debug_info.dwo.");
- case DwarfAttributeForm.GNUStrIndex: throw new NotSupportedException("DW_FORM_GNU_str_index - GNU extension, somewhat like DW_FORM_strp");
- case DwarfAttributeForm.GNURefAlt: throw new NotSupportedException("DW_FORM_GNU_ref_alt - GNU extension. Offset in .debug_info.");
- case DwarfAttributeForm.GNUStrpAlt: throw new NotSupportedException("DW_FORM_GNU_strp_alt - GNU extension. Offset in .debug_str of another object file.");
- default:
- throw new NotSupportedException($"Unknown {nameof(DwarfAttributeForm)}: {Form}");
+ break;
}
- Debug.Assert(writer.Offset - startAttributeOffset == Size);
+ case DwarfAttributeForm.Exprloc:
+ ((DwarfExpression) ValueAsObject!).WriteInternal(writer);
+ break;
+
+ case DwarfAttributeForm.FlagPresent:
+ Debug.Assert(ValueAsBoolean);
+ break;
+
+ case DwarfAttributeForm.RefSig8:
+ writer.WriteU64(ValueAsU64);
+ break;
+
+ case DwarfAttributeForm.Strx: throw new NotSupportedException("DW_FORM_strx - DWARF5");
+ case DwarfAttributeForm.Addrx: throw new NotSupportedException("DW_FORM_addrx - DWARF5");
+ case DwarfAttributeForm.RefSup4: throw new NotSupportedException("DW_FORM_ref_sup4 - DWARF5");
+ case DwarfAttributeForm.StrpSup: throw new NotSupportedException("DW_FORM_strp_sup - DWARF5");
+ case DwarfAttributeForm.Data16: throw new NotSupportedException("DW_FORM_data16 - DWARF5");
+ case DwarfAttributeForm.LineStrp: throw new NotSupportedException("DW_FORM_line_strp - DWARF5");
+ case DwarfAttributeForm.ImplicitConst: throw new NotSupportedException("DW_FORM_implicit_const - DWARF5");
+ case DwarfAttributeForm.Loclistx: throw new NotSupportedException("DW_FORM_loclistx - DWARF5");
+ case DwarfAttributeForm.Rnglistx: throw new NotSupportedException("DW_FORM_rnglistx - DWARF5");
+ case DwarfAttributeForm.RefSup8: throw new NotSupportedException("DW_FORM_ref_sup8 - DWARF5");
+ case DwarfAttributeForm.Strx1: throw new NotSupportedException("DW_FORM_strx1 - DWARF5");
+ case DwarfAttributeForm.Strx2: throw new NotSupportedException("DW_FORM_strx2 - DWARF5");
+ case DwarfAttributeForm.Strx3: throw new NotSupportedException("DW_FORM_strx3 - DWARF5");
+ case DwarfAttributeForm.Strx4: throw new NotSupportedException("DW_FORM_strx4 - DWARF5");
+ case DwarfAttributeForm.Addrx1: throw new NotSupportedException("DW_FORM_addrx1 - DWARF5");
+ case DwarfAttributeForm.Addrx2: throw new NotSupportedException("DW_FORM_addrx2 - DWARF5");
+ case DwarfAttributeForm.Addrx3: throw new NotSupportedException("DW_FORM_addrx3 - DWARF5");
+ case DwarfAttributeForm.Addrx4: throw new NotSupportedException("DW_FORM_addrx4 - DWARF5");
+ case DwarfAttributeForm.GNUAddrIndex: throw new NotSupportedException("DW_FORM_GNU_addr_index - GNU extension in debug_info.dwo.");
+ case DwarfAttributeForm.GNUStrIndex: throw new NotSupportedException("DW_FORM_GNU_str_index - GNU extension, somewhat like DW_FORM_strp");
+ case DwarfAttributeForm.GNURefAlt: throw new NotSupportedException("DW_FORM_GNU_ref_alt - GNU extension. Offset in .debug_info.");
+ case DwarfAttributeForm.GNUStrpAlt: throw new NotSupportedException("DW_FORM_GNU_strp_alt - GNU extension. Offset in .debug_str of another object file.");
+ default:
+ throw new NotSupportedException($"Unknown {nameof(DwarfAttributeForm)}: {Form}");
}
- private static readonly DwarfReader.DwarfDIEReferenceResolver DwarfAttributeDIEReferenceResolverInstance = DwarfAttributeDIEReferenceResolver;
+ Debug.Assert(writer.Position - startAttributeOffset == Size);
+ }
- private static DwarfReader.DwarfDIEReference AttributeToDIERef(DwarfAttribute attr)
- {
- return new DwarfReader.DwarfDIEReference(attr.ValueAsU64, attr, DwarfAttributeDIEReferenceResolverInstance);
- }
+ private static readonly DwarfReader.DwarfDIEReferenceResolver DwarfAttributeDIEReferenceResolverInstance = DwarfAttributeDIEReferenceResolver;
- private static void DwarfAttributeDIEReferenceResolver(ref DwarfReader.DwarfDIEReference dieRef)
- {
- var attr = (DwarfAttribute)dieRef.DwarfObject;
- attr.ValueAsU64 = 0;
- attr.ValueAsObject = dieRef.Resolved;
- }
+ private static DwarfReader.DwarfDIEReference AttributeToDIERef(DwarfAttribute attr)
+ {
+ return new DwarfReader.DwarfDIEReference(attr.ValueAsU64, attr, DwarfAttributeDIEReferenceResolverInstance);
+ }
+
+ private static void DwarfAttributeDIEReferenceResolver(ref DwarfReader.DwarfDIEReference dieRef)
+ {
+ var attr = (DwarfAttribute)dieRef.DwarfObject;
+ attr.ValueAsU64 = 0;
+ attr.ValueAsObject = dieRef.Resolved;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttributeDescriptor.cs b/src/LibObjectFile/Dwarf/DwarfAttributeDescriptor.cs
index 8add13e..948fb8a 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttributeDescriptor.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttributeDescriptor.cs
@@ -5,51 +5,50 @@
using System;
using System.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+[DebuggerDisplay("{Kind} {Form}")]
+public readonly struct DwarfAttributeDescriptor : IEquatable
{
- [DebuggerDisplay("{Kind} {Form}")]
- public readonly struct DwarfAttributeDescriptor : IEquatable
- {
- public static readonly DwarfAttributeDescriptor Empty = new DwarfAttributeDescriptor();
+ public static readonly DwarfAttributeDescriptor Empty = new DwarfAttributeDescriptor();
- public DwarfAttributeDescriptor(DwarfAttributeKindEx kind, DwarfAttributeFormEx form)
- {
- Kind = kind;
- Form = form;
- }
+ public DwarfAttributeDescriptor(DwarfAttributeKindEx kind, DwarfAttributeFormEx form)
+ {
+ Kind = kind;
+ Form = form;
+ }
- public readonly DwarfAttributeKindEx Kind;
+ public readonly DwarfAttributeKindEx Kind;
- public readonly DwarfAttributeFormEx Form;
+ public readonly DwarfAttributeFormEx Form;
- public bool IsNull => Kind.Value == 0 && Form.Value == 0;
+ public bool IsNull => Kind.Value == 0 && Form.Value == 0;
- public bool Equals(DwarfAttributeDescriptor other)
- {
- return Kind.Equals(other.Kind) && Form.Equals(other.Form);
- }
+ public bool Equals(DwarfAttributeDescriptor other)
+ {
+ return Kind.Equals(other.Kind) && Form.Equals(other.Form);
+ }
- public override bool Equals(object obj)
- {
- return obj is DwarfAttributeDescriptor other && Equals(other);
- }
+ public override bool Equals(object? obj)
+ {
+ return obj is DwarfAttributeDescriptor other && Equals(other);
+ }
- public override int GetHashCode()
+ public override int GetHashCode()
+ {
+ unchecked
{
- unchecked
- {
- return (Kind.GetHashCode() * 397) ^ Form.GetHashCode();
- }
+ return (Kind.GetHashCode() * 397) ^ Form.GetHashCode();
}
+ }
- public static bool operator ==(DwarfAttributeDescriptor left, DwarfAttributeDescriptor right)
- {
- return left.Equals(right);
- }
+ public static bool operator ==(DwarfAttributeDescriptor left, DwarfAttributeDescriptor right)
+ {
+ return left.Equals(right);
+ }
- public static bool operator !=(DwarfAttributeDescriptor left, DwarfAttributeDescriptor right)
- {
- return !left.Equals(right);
- }
+ public static bool operator !=(DwarfAttributeDescriptor left, DwarfAttributeDescriptor right)
+ {
+ return !left.Equals(right);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttributeDescriptors.cs b/src/LibObjectFile/Dwarf/DwarfAttributeDescriptors.cs
index 50ffe43..f6c28d2 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttributeDescriptors.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttributeDescriptors.cs
@@ -3,80 +3,78 @@
// See the license.txt file in the project root for more information.
using System;
-using System.Collections;
using System.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
+public readonly struct DwarfAttributeDescriptors : IEquatable
{
- [DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
- public readonly struct DwarfAttributeDescriptors : IEquatable
- {
- private readonly DwarfAttributeDescriptor[] _descriptors;
+ private readonly DwarfAttributeDescriptor[] _descriptors;
- public DwarfAttributeDescriptors(DwarfAttributeDescriptor[] descriptors)
- {
- _descriptors = descriptors ?? throw new ArgumentNullException(nameof(descriptors));
- }
+ public DwarfAttributeDescriptors(DwarfAttributeDescriptor[] descriptors)
+ {
+ _descriptors = descriptors ?? throw new ArgumentNullException(nameof(descriptors));
+ }
- public int Length => _descriptors?.Length ?? 0;
+ public int Length => _descriptors?.Length ?? 0;
- public DwarfAttributeDescriptor this[int index]
+ public DwarfAttributeDescriptor this[int index]
+ {
+ get
{
- get
- {
- if (_descriptors == null) throw new ArgumentException("This descriptors instance is not initialized");
- return _descriptors[index];
- }
+ if (_descriptors == null) throw new ArgumentException("This descriptors instance is not initialized");
+ return _descriptors[index];
}
+ }
- public bool Equals(DwarfAttributeDescriptors other)
- {
- if (ReferenceEquals(_descriptors, other._descriptors)) return true;
- if (_descriptors == null || other._descriptors == null) return false;
- if (_descriptors.Length != other._descriptors.Length) return false;
+ public bool Equals(DwarfAttributeDescriptors other)
+ {
+ if (ReferenceEquals(_descriptors, other._descriptors)) return true;
+ if (_descriptors == null || other._descriptors == null) return false;
+ if (_descriptors.Length != other._descriptors.Length) return false;
- for (int i = 0; i < _descriptors.Length; i++)
+ for (int i = 0; i < _descriptors.Length; i++)
+ {
+ if (_descriptors[i] != other._descriptors[i])
{
- if (_descriptors[i] != other._descriptors[i])
- {
- return false;
- }
+ return false;
}
- return true;
}
+ return true;
+ }
- public override bool Equals(object obj)
- {
- return obj is DwarfAttributeDescriptors other && Equals(other);
- }
+ public override bool Equals(object? obj)
+ {
+ return obj is DwarfAttributeDescriptors other && Equals(other);
+ }
- public override int GetHashCode()
+ public override int GetHashCode()
+ {
+ int hashCode = _descriptors == null ? 0 : _descriptors.Length;
+ if (hashCode == 0) return hashCode;
+ foreach (var descriptor in _descriptors!)
{
- int hashCode = _descriptors == null ? 0 : _descriptors.Length;
- if (hashCode == 0) return hashCode;
- foreach (var descriptor in _descriptors)
- {
- hashCode = (hashCode * 397) ^ descriptor.GetHashCode();
- }
- return hashCode;
+ hashCode = (hashCode * 397) ^ descriptor.GetHashCode();
}
+ return hashCode;
+ }
- private string DebuggerDisplay => ToString();
+ private string DebuggerDisplay => ToString();
- public static bool operator ==(DwarfAttributeDescriptors left, DwarfAttributeDescriptors right)
- {
- return left.Equals(right);
- }
+ public static bool operator ==(DwarfAttributeDescriptors left, DwarfAttributeDescriptors right)
+ {
+ return left.Equals(right);
+ }
- public static bool operator !=(DwarfAttributeDescriptors left, DwarfAttributeDescriptors right)
- {
- return !left.Equals(right);
- }
+ public static bool operator !=(DwarfAttributeDescriptors left, DwarfAttributeDescriptors right)
+ {
+ return !left.Equals(right);
+ }
- public override string ToString()
- {
- return $"Count = {_descriptors.Length}";
- }
+ public override string ToString()
+ {
+ return $"Count = {_descriptors.Length}";
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttributeEncoding.cs b/src/LibObjectFile/Dwarf/DwarfAttributeEncoding.cs
index f722ab3..e1d8f4a 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttributeEncoding.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttributeEncoding.cs
@@ -4,47 +4,46 @@
using System;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+[Flags]
+public enum DwarfAttributeEncoding
{
- [Flags]
- public enum DwarfAttributeEncoding
- {
- None,
+ None,
- Address = 1,
+ Address = 1,
- Block = 1 << 1,
+ Block = 1 << 1,
- Constant = 1 << 2,
+ Constant = 1 << 2,
- ExpressionLocation = 1 << 3,
+ ExpressionLocation = 1 << 3,
- Flag = 1 << 4,
+ Flag = 1 << 4,
- LinePointer = 1 << 5,
+ LinePointer = 1 << 5,
- LocationListPointer = 1 << 6,
+ LocationListPointer = 1 << 6,
- MacroPointer = 1 << 7,
+ MacroPointer = 1 << 7,
- RangeListPointer = 1 << 8,
+ RangeListPointer = 1 << 8,
- Reference = 1 << 9,
+ Reference = 1 << 9,
- String = 1 << 10,
+ String = 1 << 10,
- RangeList = 1 << 11,
+ RangeList = 1 << 11,
- Indirect = 1 << 12,
+ Indirect = 1 << 12,
- LocationList = 1 << 13,
+ LocationList = 1 << 13,
- AddressPointer = 1 << 14,
+ AddressPointer = 1 << 14,
- LocationListsPointer = 1 << 15,
+ LocationListsPointer = 1 << 15,
- RangeListsPointer = 1 << 16,
+ RangeListsPointer = 1 << 16,
- StringOffsetPointer = 1 << 17,
- }
+ StringOffsetPointer = 1 << 17,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttributeFormEx.cs b/src/LibObjectFile/Dwarf/DwarfAttributeFormEx.cs
index fa00158..2465509 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttributeFormEx.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttributeFormEx.cs
@@ -5,60 +5,59 @@
using System;
using System.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+///
+/// Defines the kind of an .
+/// This is the value seen in
+///
+[DebuggerDisplay("{ToString(),nq}")]
+public readonly partial struct DwarfAttributeFormEx : IEquatable
{
- ///
- /// Defines the kind of an .
- /// This is the value seen in
- ///
- [DebuggerDisplay("{ToString(),nq}")]
- public readonly partial struct DwarfAttributeFormEx : IEquatable
+ public DwarfAttributeFormEx(uint value)
{
- public DwarfAttributeFormEx(uint value)
- {
- Value = (DwarfAttributeForm)value;
- }
- public DwarfAttributeFormEx(DwarfAttributeForm value)
- {
- Value = value;
- }
+ Value = (DwarfAttributeForm)value;
+ }
+ public DwarfAttributeFormEx(DwarfAttributeForm value)
+ {
+ Value = value;
+ }
- public readonly DwarfAttributeForm Value;
+ public readonly DwarfAttributeForm Value;
- public bool Equals(DwarfAttributeFormEx other)
- {
- return Value == other.Value;
- }
+ public bool Equals(DwarfAttributeFormEx other)
+ {
+ return Value == other.Value;
+ }
- public override bool Equals(object obj)
- {
- return obj is DwarfAttributeFormEx other && Equals(other);
- }
+ public override bool Equals(object? obj)
+ {
+ return obj is DwarfAttributeFormEx other && Equals(other);
+ }
- public override int GetHashCode()
- {
- return (int) Value;
- }
+ public override int GetHashCode()
+ {
+ return (int) Value;
+ }
- public static bool operator ==(DwarfAttributeFormEx left, DwarfAttributeFormEx right)
- {
- return left.Equals(right);
- }
+ public static bool operator ==(DwarfAttributeFormEx left, DwarfAttributeFormEx right)
+ {
+ return left.Equals(right);
+ }
- public static bool operator !=(DwarfAttributeFormEx left, DwarfAttributeFormEx right)
- {
- return !left.Equals(right);
- }
+ public static bool operator !=(DwarfAttributeFormEx left, DwarfAttributeFormEx right)
+ {
+ return !left.Equals(right);
+ }
- public override string ToString()
- {
- return ToStringInternal() ?? $"Unknown {nameof(DwarfAttributeFormEx)} (0x{Value:X4})";
- }
+ public override string ToString()
+ {
+ return ToStringInternal() ?? $"Unknown {nameof(DwarfAttributeFormEx)} (0x{Value:X4})";
+ }
- public static explicit operator uint(DwarfAttributeFormEx form) => (uint)form.Value;
+ public static explicit operator uint(DwarfAttributeFormEx form) => (uint)form.Value;
- public static implicit operator DwarfAttributeFormEx(DwarfAttributeForm kind) => new DwarfAttributeFormEx(kind);
+ public static implicit operator DwarfAttributeFormEx(DwarfAttributeForm kind) => new DwarfAttributeFormEx(kind);
- public static implicit operator DwarfAttributeForm(DwarfAttributeFormEx kind) => kind.Value;
- }
+ public static implicit operator DwarfAttributeForm(DwarfAttributeFormEx kind) => kind.Value;
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttributeKindEx.cs b/src/LibObjectFile/Dwarf/DwarfAttributeKindEx.cs
index eb12ac9..376c88f 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttributeKindEx.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttributeKindEx.cs
@@ -5,62 +5,61 @@
using System;
using System.Diagnostics;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+///
+/// Defines the kind of an .
+/// This is the value seen in
+///
+[DebuggerDisplay("{ToString(),nq}")]
+public readonly partial struct DwarfAttributeKindEx : IEquatable
{
- ///
- /// Defines the kind of an .
- /// This is the value seen in
- ///
- [DebuggerDisplay("{ToString(),nq}")]
- public readonly partial struct DwarfAttributeKindEx : IEquatable
+ public DwarfAttributeKindEx(uint value)
{
- public DwarfAttributeKindEx(uint value)
- {
- Value = (DwarfAttributeKind)value;
- }
+ Value = (DwarfAttributeKind)value;
+ }
- public DwarfAttributeKindEx(DwarfAttributeKind value)
- {
- Value = value;
- }
+ public DwarfAttributeKindEx(DwarfAttributeKind value)
+ {
+ Value = value;
+ }
- public readonly DwarfAttributeKind Value;
+ public readonly DwarfAttributeKind Value;
- public bool Equals(DwarfAttributeKindEx other)
- {
- return Value == other.Value;
- }
+ public bool Equals(DwarfAttributeKindEx other)
+ {
+ return Value == other.Value;
+ }
- public override bool Equals(object obj)
- {
- return obj is DwarfAttributeKindEx other && Equals(other);
- }
+ public override bool Equals(object? obj)
+ {
+ return obj is DwarfAttributeKindEx other && Equals(other);
+ }
- public override int GetHashCode()
- {
- return (int) Value;
- }
+ public override int GetHashCode()
+ {
+ return (int) Value;
+ }
- public static bool operator ==(DwarfAttributeKindEx left, DwarfAttributeKindEx right)
- {
- return left.Equals(right);
- }
+ public static bool operator ==(DwarfAttributeKindEx left, DwarfAttributeKindEx right)
+ {
+ return left.Equals(right);
+ }
- public static bool operator !=(DwarfAttributeKindEx left, DwarfAttributeKindEx right)
- {
- return !left.Equals(right);
- }
+ public static bool operator !=(DwarfAttributeKindEx left, DwarfAttributeKindEx right)
+ {
+ return !left.Equals(right);
+ }
- public override string ToString()
- {
- return ToStringInternal() ?? $"Unknown {nameof(DwarfAttributeKindEx)} (0x{Value:X4})";
- }
+ public override string ToString()
+ {
+ return ToStringInternal() ?? $"Unknown {nameof(DwarfAttributeKindEx)} (0x{Value:X4})";
+ }
- public static explicit operator uint(DwarfAttributeKindEx kind) => (uint)kind.Value;
+ public static explicit operator uint(DwarfAttributeKindEx kind) => (uint)kind.Value;
- public static implicit operator DwarfAttributeKindEx(DwarfAttributeKind kind) => new DwarfAttributeKindEx(kind);
+ public static implicit operator DwarfAttributeKindEx(DwarfAttributeKind kind) => new DwarfAttributeKindEx(kind);
- public static implicit operator DwarfAttributeKind(DwarfAttributeKindEx kind) => kind.Value;
- }
+ public static implicit operator DwarfAttributeKind(DwarfAttributeKindEx kind) => kind.Value;
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfAttributeValue.cs b/src/LibObjectFile/Dwarf/DwarfAttributeValue.cs
index b68406f..215f79c 100644
--- a/src/LibObjectFile/Dwarf/DwarfAttributeValue.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAttributeValue.cs
@@ -2,20 +2,19 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public class DwarfAttributeValue
{
- public class DwarfAttributeValue
+ public DwarfAttributeValue(object value)
{
- public DwarfAttributeValue(object value)
- {
- Value = value;
- }
+ Value = value;
+ }
- public object Value { get; set; }
+ public object Value { get; set; }
- public override string ToString()
- {
- return $"{nameof(Value)}: {Value}";
- }
+ public override string ToString()
+ {
+ return $"{nameof(Value)}: {Value}";
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfCallingConventionEx.cs b/src/LibObjectFile/Dwarf/DwarfCallingConventionEx.cs
index ce84db3..7cbe258 100644
--- a/src/LibObjectFile/Dwarf/DwarfCallingConventionEx.cs
+++ b/src/LibObjectFile/Dwarf/DwarfCallingConventionEx.cs
@@ -4,56 +4,55 @@
using System;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public readonly partial struct DwarfCallingConventionEx : IEquatable
{
- public readonly partial struct DwarfCallingConventionEx : IEquatable
- {
- public DwarfCallingConventionEx(byte value)
- {
- Value = (DwarfCallingConvention)value;
- }
-
- public DwarfCallingConventionEx(DwarfCallingConvention value)
- {
- Value = value;
- }
-
- public readonly DwarfCallingConvention Value;
-
- public override string ToString()
- {
- return ToStringInternal() ?? $"Unknown {nameof(DwarfCallingConvention)} (0x{Value:x2})";
- }
-
- public bool Equals(DwarfCallingConventionEx other)
- {
- return Value == other.Value;
- }
-
- public override bool Equals(object obj)
- {
- return obj is DwarfCallingConventionEx other && Equals(other);
- }
-
- public override int GetHashCode()
- {
- return Value.GetHashCode();
- }
-
- public static bool operator ==(DwarfCallingConventionEx left, DwarfCallingConventionEx right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(DwarfCallingConventionEx left, DwarfCallingConventionEx right)
- {
- return !left.Equals(right);
- }
-
- public static explicit operator uint(DwarfCallingConventionEx callConv) => (uint)callConv.Value;
+ public DwarfCallingConventionEx(byte value)
+ {
+ Value = (DwarfCallingConvention)value;
+ }
+
+ public DwarfCallingConventionEx(DwarfCallingConvention value)
+ {
+ Value = value;
+ }
+
+ public readonly DwarfCallingConvention Value;
+
+ public override string ToString()
+ {
+ return ToStringInternal() ?? $"Unknown {nameof(DwarfCallingConvention)} (0x{Value:x2})";
+ }
+
+ public bool Equals(DwarfCallingConventionEx other)
+ {
+ return Value == other.Value;
+ }
- public static implicit operator DwarfCallingConventionEx(DwarfCallingConvention callConv) => new DwarfCallingConventionEx(callConv);
+ public override bool Equals(object? obj)
+ {
+ return obj is DwarfCallingConventionEx other && Equals(other);
+ }
- public static implicit operator DwarfCallingConvention(DwarfCallingConventionEx callConv) => callConv.Value;
+ public override int GetHashCode()
+ {
+ return Value.GetHashCode();
+ }
+
+ public static bool operator ==(DwarfCallingConventionEx left, DwarfCallingConventionEx right)
+ {
+ return left.Equals(right);
}
+
+ public static bool operator !=(DwarfCallingConventionEx left, DwarfCallingConventionEx right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static explicit operator uint(DwarfCallingConventionEx callConv) => (uint)callConv.Value;
+
+ public static implicit operator DwarfCallingConventionEx(DwarfCallingConvention callConv) => new DwarfCallingConventionEx(callConv);
+
+ public static implicit operator DwarfCallingConvention(DwarfCallingConventionEx callConv) => callConv.Value;
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfCompilationUnit.cs b/src/LibObjectFile/Dwarf/DwarfCompilationUnit.cs
index 86603c4..a4b70ff 100644
--- a/src/LibObjectFile/Dwarf/DwarfCompilationUnit.cs
+++ b/src/LibObjectFile/Dwarf/DwarfCompilationUnit.cs
@@ -2,80 +2,79 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public class DwarfCompilationUnit : DwarfUnit
{
- public class DwarfCompilationUnit : DwarfUnit
+ public DwarfCompilationUnit()
{
- public DwarfCompilationUnit()
- {
- Kind = DwarfUnitKind.Compile;
- // Default to version 4
- Version = 4;
- }
+ Kind = DwarfUnitKind.Compile;
+ // Default to version 4
+ Version = 4;
+ }
- protected override void ReadHeader(DwarfReader reader)
+ protected override void ReadHeader(DwarfReader reader)
+ {
+ if (Version < 5)
{
- if (Version < 5)
- {
- // 3. debug_abbrev_offset (section offset)
- DebugAbbreviationOffset = reader.ReadUIntFromEncoding();
+ // 3. debug_abbrev_offset (section offset)
+ DebugAbbreviationOffset = reader.ReadUIntFromEncoding();
- // 4. address_size (ubyte)
- AddressSize = reader.ReadAddressSize();
- reader.AddressSize = AddressSize;
- }
- else
- {
- // NOTE: order of address_size/debug_abbrev_offset are different from Dwarf 4
+ // 4. address_size (ubyte)
+ AddressSize = reader.ReadAddressSize();
+ reader.AddressSize = AddressSize;
+ }
+ else
+ {
+ // NOTE: order of address_size/debug_abbrev_offset are different from Dwarf 4
- // 4. address_size (ubyte)
- AddressSize = reader.ReadAddressSize();
- reader.AddressSize = AddressSize;
+ // 4. address_size (ubyte)
+ AddressSize = reader.ReadAddressSize();
+ reader.AddressSize = AddressSize;
- // 5. debug_abbrev_offset (section offset)
- DebugAbbreviationOffset = reader.ReadUIntFromEncoding();
- }
+ // 5. debug_abbrev_offset (section offset)
+ DebugAbbreviationOffset = reader.ReadUIntFromEncoding();
}
+ }
- protected override void WriteHeader(DwarfWriter writer)
+ protected override void WriteHeader(DwarfWriter writer)
+ {
+ if (Version < 5)
{
- if (Version < 5)
+ // 3. debug_abbrev_offset (section offset)
+ var abbrevOffset = Abbreviation!.Position;
+ if (writer.EnableRelocation)
{
- // 3. debug_abbrev_offset (section offset)
- var abbrevOffset = Abbreviation.Offset;
- if (writer.EnableRelocation)
- {
- writer.RecordRelocation(DwarfRelocationTarget.DebugAbbrev, writer.SizeOfUIntEncoding(), abbrevOffset);
- abbrevOffset = 0;
- }
- writer.WriteUIntFromEncoding(abbrevOffset);
-
- // 4. address_size (ubyte)
- writer.WriteAddressSize(AddressSize);
+ writer.RecordRelocation(DwarfRelocationTarget.DebugAbbrev, writer.SizeOfUIntEncoding(), abbrevOffset);
+ abbrevOffset = 0;
}
- else
- {
- // NOTE: order of address_size/debug_abbrev_offset are different from Dwarf 4
-
- // 4. address_size (ubyte)
- writer.WriteAddressSize(AddressSize);
+ writer.WriteUIntFromEncoding(abbrevOffset);
- // 5. debug_abbrev_offset (section offset)
- var abbrevOffset = Abbreviation.Offset;
- if (writer.EnableRelocation)
- {
- writer.RecordRelocation(DwarfRelocationTarget.DebugAbbrev, writer.SizeOfUIntEncoding(), abbrevOffset);
- abbrevOffset = 0;
- }
- writer.WriteUIntFromEncoding(abbrevOffset);
- }
+ // 4. address_size (ubyte)
+ writer.WriteAddressSize(AddressSize);
}
-
- protected override ulong GetLayoutHeaderSize()
+ else
{
- // 3. debug_abbrev_offset (section offset)
+ // NOTE: order of address_size/debug_abbrev_offset are different from Dwarf 4
+
// 4. address_size (ubyte)
- return DwarfHelper.SizeOfUInt(Is64BitEncoding) + 1;
+ writer.WriteAddressSize(AddressSize);
+
+ // 5. debug_abbrev_offset (section offset)
+ var abbrevOffset = Abbreviation!.Position;
+ if (writer.EnableRelocation)
+ {
+ writer.RecordRelocation(DwarfRelocationTarget.DebugAbbrev, writer.SizeOfUIntEncoding(), abbrevOffset);
+ abbrevOffset = 0;
+ }
+ writer.WriteUIntFromEncoding(abbrevOffset);
}
}
+
+ protected override ulong GetLayoutHeaderSize()
+ {
+ // 3. debug_abbrev_offset (section offset)
+ // 4. address_size (ubyte)
+ return DwarfHelper.SizeOfUInt(Is64BitEncoding) + 1;
+ }
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfConstant.cs b/src/LibObjectFile/Dwarf/DwarfConstant.cs
index 8c83fa0..eaed5f9 100644
--- a/src/LibObjectFile/Dwarf/DwarfConstant.cs
+++ b/src/LibObjectFile/Dwarf/DwarfConstant.cs
@@ -4,68 +4,67 @@
using System.IO;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public struct DwarfConstant
{
- public struct DwarfConstant
+ public DwarfConstant(int value)
{
- public DwarfConstant(int value)
- {
- AsValue = new DwarfInteger() {I64 = value};
- AsObject = null;
- }
+ AsValue = new DwarfInteger() {I64 = value};
+ AsObject = null;
+ }
- public DwarfConstant(DwarfExpression expression)
- {
- AsValue = default;
- AsObject = expression;
- }
+ public DwarfConstant(DwarfExpression expression)
+ {
+ AsValue = default;
+ AsObject = expression;
+ }
- public DwarfConstant(DwarfDIE dieRef)
- {
- AsValue = default;
- AsObject = dieRef;
- }
+ public DwarfConstant(DwarfDIE dieRef)
+ {
+ AsValue = default;
+ AsObject = dieRef;
+ }
- public DwarfConstant(Stream stream)
- {
- AsValue = default;
- AsObject = stream;
- }
+ public DwarfConstant(Stream stream)
+ {
+ AsValue = default;
+ AsObject = stream;
+ }
- public DwarfInteger AsValue;
+ public DwarfInteger AsValue;
- public object AsObject;
+ public object? AsObject;
- public DwarfExpression AsExpression => AsObject as DwarfExpression;
+ public DwarfExpression? AsExpression => AsObject as DwarfExpression;
- public DwarfDIE AsReference => AsObject as DwarfDIE;
+ public DwarfDIE? AsReference => AsObject as DwarfDIE;
- public Stream AsStream => AsObject as Stream;
+ public Stream? AsStream => AsObject as Stream;
- public string AsString => AsObject as string;
+ public string? AsString => AsObject as string;
- public override string ToString()
- {
- if (AsExpression != null) return $"Constant Expression: {AsExpression}";
- if (AsReference != null) return $"Constant Reference: {AsReference}";
- if (AsStream != null) return $"Constant Block: Length = {AsStream.Length}";
- if (AsString != null) return $"Constant String: {AsString}";
- return $"Constant Value: {AsValue}";
- }
+ public override string ToString()
+ {
+ if (AsExpression != null) return $"Constant Expression: {AsExpression}";
+ if (AsReference != null) return $"Constant Reference: {AsReference}";
+ if (AsStream != null) return $"Constant Block: Length = {AsStream.Length}";
+ if (AsString != null) return $"Constant String: {AsString}";
+ return $"Constant Value: {AsValue}";
+ }
- public static implicit operator DwarfConstant(int value)
- {
- return new DwarfConstant(value);
- }
+ public static implicit operator DwarfConstant(int value)
+ {
+ return new DwarfConstant(value);
+ }
- public static implicit operator DwarfConstant(DwarfExpression value)
- {
- return new DwarfConstant(value);
- }
+ public static implicit operator DwarfConstant(DwarfExpression value)
+ {
+ return new DwarfConstant(value);
+ }
- public static implicit operator DwarfConstant(DwarfDIE value)
- {
- return new DwarfConstant(value);
- }
+ public static implicit operator DwarfConstant(DwarfDIE value)
+ {
+ return new DwarfConstant(value);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfContainer.cs b/src/LibObjectFile/Dwarf/DwarfContainer.cs
index 83940ff..55cd4bb 100644
--- a/src/LibObjectFile/Dwarf/DwarfContainer.cs
+++ b/src/LibObjectFile/Dwarf/DwarfContainer.cs
@@ -2,15 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System;
+namespace LibObjectFile.Dwarf;
-namespace LibObjectFile.Dwarf
+public abstract class DwarfContainer : DwarfObject
{
- public abstract class DwarfContainer : DwarfObject
- {
- public override void Verify(DiagnosticBag diagnostics)
- {
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
- }
- }
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfDIE.cs b/src/LibObjectFile/Dwarf/DwarfDIE.cs
index 2c73998..cd103f4 100644
--- a/src/LibObjectFile/Dwarf/DwarfDIE.cs
+++ b/src/LibObjectFile/Dwarf/DwarfDIE.cs
@@ -1,516 +1,462 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
-// This attribute is licensed under the BSD-Clause 2 license.
-// See the license.txt attribute in the project root for more information.
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Text;
+using LibObjectFile.Collections;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public class DwarfDIE : DwarfContainer
{
- public class DwarfDIE : DwarfContainer
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private readonly SortedObjectList _attributes;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private readonly ObjectList _children;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private DwarfTagEx _tag;
+
+ ///
+ /// The current line program table when reading.
+ ///
+ internal DwarfLineProgramTable? CurrentLineProgramTable;
+
+ public DwarfDIE()
{
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly List _attributes;
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly List _children;
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private DwarfTagEx _tag;
-
- ///
- /// The current line program table when reading.
- ///
- internal DwarfLineProgramTable CurrentLineProgramTable;
-
- public DwarfDIE()
- {
- _attributes = new List();
- _children = new List();
- }
-
- protected DwarfDIE(DwarfTagEx tag)
- {
- _tag = tag;
- }
+ _attributes = new SortedObjectList(this);
+ _children = new ObjectList(this);
+ }
- public virtual DwarfTagEx Tag
- {
- get => _tag;
- set => _tag = value;
- }
+ public virtual DwarfTagEx Tag
+ {
+ get => _tag;
+ set => _tag = value;
+ }
- public IReadOnlyList Attributes => _attributes;
+ public SortedObjectList Attributes => _attributes;
- public IReadOnlyList Children => _children;
+ public ObjectList Children => _children;
- public DwarfAbbreviationItem Abbrev { get; internal set; }
+ public DwarfAbbreviationItem? Abbrev { get; internal set; }
- ///
- /// Adds a child to .
- ///
- /// A child
- public void AddChild(DwarfDIE child)
- {
- _children.Add(this, child);
- }
- ///
- /// Inserts a child into at the specified index.
- ///
- /// Index into to insert the specified child
- /// The child to insert
- public void InsertChildAt(int index, DwarfDIE child)
+ public override void Verify(DwarfVerifyContext context)
+ {
+ foreach (var attr in _attributes)
{
- _children.InsertAt(this, index, child);
+ attr.Verify(context);
}
- ///
- /// Removes a child from
- ///
- /// The child to remove
- public void RemoveChild(DwarfDIE child)
+ foreach (var child in _children)
{
- _children.Remove(this, child);
+ child.Verify(context);
}
+ }
- ///
- /// Removes a child from at the specified index.
- ///
- /// Index into to remove the specified child
- public DwarfDIE RemoveChildAt(int index)
- {
- return _children.RemoveAt(this, index);
- }
+ protected override bool PrintMembers(StringBuilder builder)
+ {
+ builder.Append($"{nameof(Tag)}: {Tag}, {nameof(Attributes)}: {Attributes.Count}, {nameof(Children)}: {Children.Count}, ");
+ base.PrintMembers(builder);
+ return true;
+ }
- ///
- /// Adds an attribute to .
- ///
- /// A attribute
- public void AddAttribute(DwarfAttribute attribute)
+ protected TValue? GetAttributeValue(DwarfAttributeKind kind)
+ {
+ foreach (var attr in _attributes)
{
- _attributes.AddSorted(this, attribute, true);
+ if (attr.Kind == kind)
+ {
+ return (TValue?)attr.ValueAsObject;
+ }
}
- ///
- /// Removes an attribute from
- ///
- /// The attribute to remove
- public void RemoveAttribute(DwarfAttribute attribute)
- {
- _attributes.Remove(this, attribute);
- }
+ return default;
+ }
- ///
- /// Removes an attribute from at the specified index.
- ///
- /// Index into to remove the specified attribute
- public DwarfAttribute RemoveAttributeAt(int index)
+ protected unsafe TValue? GetAttributeValueOpt(DwarfAttributeKind kind) where TValue : unmanaged
+ {
+ Debug.Assert(sizeof(TValue) <= sizeof(ulong));
+
+ foreach (var attr in _attributes)
{
- return _attributes.RemoveAt(this, index);
+ if (attr.Kind == kind)
+ {
+ ulong localU64 = attr.ValueAsU64;
+ return *(TValue*) &localU64;
+ }
}
+ return default;
+ }
- public override void Verify(DiagnosticBag diagnostics)
+ protected DwarfConstant? GetAttributeConstantOpt(DwarfAttributeKind kind)
+ {
+ foreach (var attr in _attributes)
{
- base.Verify(diagnostics);
-
- foreach (var attr in _attributes)
- {
- attr.Verify(diagnostics);
- }
-
- foreach (var child in _children)
+ if (attr.Kind == kind)
{
- child.Verify(diagnostics);
+ return new DwarfConstant
+ {
+ AsValue =
+ {
+ U64 = attr.ValueAsU64
+ },
+ AsObject = attr.ValueAsObject
+ };
}
}
- public override string ToString()
- {
- return $"{nameof(Tag)}: {Tag}, {nameof(Attributes)}: {Attributes.Count}, {nameof(Children)}: {Children.Count}";
- }
+ return null;
+ }
- protected TValue GetAttributeValue(DwarfAttributeKind kind)
+ protected void SetAttributeConstantOpt(DwarfAttributeKind kind, DwarfConstant? cst)
+ {
+ for (int i = 0; i < _attributes.Count; i++)
{
- foreach (var attr in _attributes)
+ var attr = _attributes[i];
+ if (attr.Kind == kind)
{
- if (attr.Kind == kind)
+ if (!cst.HasValue)
+ {
+ Attributes.RemoveAt(i);
+ }
+ else
{
- return (TValue)attr.ValueAsObject;
+ var value = cst.Value;
+ attr.ValueAsU64 = value.AsValue.U64;
+ attr.ValueAsObject = value.AsExpression;
}
+ return;
}
-
- return default;
}
- protected unsafe TValue? GetAttributeValueOpt(DwarfAttributeKind kind) where TValue : unmanaged
+ if (cst.HasValue)
{
- Debug.Assert(sizeof(TValue) <= sizeof(ulong));
-
- foreach (var attr in _attributes)
+ var value = cst.Value;
+ Attributes.Add(new DwarfAttribute()
{
- if (attr.Kind == kind)
- {
- ulong localU64 = attr.ValueAsU64;
- return *(TValue*) &localU64;
- }
- }
-
- return default;
+ Kind = kind,
+ ValueAsU64 = value.AsValue.U64,
+ ValueAsObject = value.AsExpression
+ });
}
+ }
- protected DwarfConstant? GetAttributeConstantOpt(DwarfAttributeKind kind)
+ protected DwarfLocation? GetAttributeLocationOpt(DwarfAttributeKind kind)
+ {
+ foreach (var attr in _attributes)
{
- foreach (var attr in _attributes)
+ if (attr.Kind == kind)
{
- if (attr.Kind == kind)
+ return new DwarfLocation
{
- return new DwarfConstant
+ AsValue =
{
- AsValue =
- {
- U64 = attr.ValueAsU64
- },
- AsObject = attr.ValueAsObject
- };
- }
+ U64 = attr.ValueAsU64
+ },
+ AsObject = attr.ValueAsObject
+ };
}
-
- return null;
}
- protected void SetAttributeConstantOpt(DwarfAttributeKind kind, DwarfConstant? cst)
+ return null;
+ }
+
+ protected void SetAttributeLocationOpt(DwarfAttributeKind kind, DwarfLocation? cst)
+ {
+ for (int i = 0; i < _attributes.Count; i++)
{
- for (int i = 0; i < _attributes.Count; i++)
+ var attr = _attributes[i];
+ if (attr.Kind == kind)
{
- var attr = _attributes[i];
- if (attr.Kind == kind)
+ if (!cst.HasValue)
{
- if (!cst.HasValue)
- {
- RemoveAttributeAt(i);
- }
- else
- {
- var value = cst.Value;
- attr.ValueAsU64 = value.AsValue.U64;
- attr.ValueAsObject = value.AsExpression;
- }
- return;
+ Attributes.RemoveAt(i);
}
- }
-
- if (cst.HasValue)
- {
- var value = cst.Value;
- AddAttribute(new DwarfAttribute()
+ else
{
- Kind = kind,
- ValueAsU64 = value.AsValue.U64,
- ValueAsObject = value.AsExpression
- });
+ var value = cst.Value;
+ attr.ValueAsU64 = value.AsValue.U64;
+ attr.ValueAsObject = value.AsObject;
+ }
+ return;
}
}
- protected DwarfLocation? GetAttributeLocationOpt(DwarfAttributeKind kind)
+ if (cst.HasValue)
{
- foreach (var attr in _attributes)
+ var value = cst.Value;
+ Attributes.Add(new DwarfAttribute()
{
- if (attr.Kind == kind)
- {
- return new DwarfLocation
- {
- AsValue =
- {
- U64 = attr.ValueAsU64
- },
- AsObject = attr.ValueAsObject
- };
- }
- }
-
- return null;
+ Kind = kind,
+ ValueAsU64 = value.AsValue.U64,
+ ValueAsObject = value.AsObject
+ });
}
+ }
- protected void SetAttributeLocationOpt(DwarfAttributeKind kind, DwarfLocation? cst)
+ public DwarfAttribute? FindAttributeByKey(DwarfAttributeKind kind)
+ {
+ foreach (var attr in _attributes)
{
- for (int i = 0; i < _attributes.Count; i++)
+ if (attr.Kind == kind)
{
- var attr = _attributes[i];
- if (attr.Kind == kind)
- {
- if (!cst.HasValue)
- {
- RemoveAttributeAt(i);
- }
- else
- {
- var value = cst.Value;
- attr.ValueAsU64 = value.AsValue.U64;
- attr.ValueAsObject = value.AsObject;
- }
- return;
- }
- }
-
- if (cst.HasValue)
- {
- var value = cst.Value;
- AddAttribute(new DwarfAttribute()
- {
- Kind = kind,
- ValueAsU64 = value.AsValue.U64,
- ValueAsObject = value.AsObject
- });
+ return attr;
}
}
- public DwarfAttribute FindAttributeByKey(DwarfAttributeKind kind)
+ return null;
+ }
+
+ protected unsafe void SetAttributeValue(DwarfAttributeKind kind, TValue? value)
+ {
+ for (int i = 0; i < _attributes.Count; i++)
{
- foreach (var attr in _attributes)
+ var attr = _attributes[i];
+ if (attr.Kind == kind)
{
- if (attr.Kind == kind)
+ if (value == null)
{
- return attr;
+ Attributes.RemoveAt(i);
}
- }
-
- return null;
- }
-
- protected unsafe void SetAttributeValue(DwarfAttributeKind kind, TValue value)
- {
- for (int i = 0; i < _attributes.Count; i++)
- {
- var attr = _attributes[i];
- if (attr.Kind == kind)
+ else
{
- if (value == null)
- {
- RemoveAttributeAt(i);
- }
- else
- {
- attr.ValueAsObject = value;
- }
- return;
+ attr.ValueAsObject = value;
}
+ return;
}
-
- if (value == null) return;
- AddAttribute(new DwarfAttribute() { Kind = kind, ValueAsObject = value});
}
- protected void SetAttributeLinkValue(DwarfAttributeKind kind, TLink link) where TLink : IObjectFileNodeLink
+ if (value == null) return;
+ Attributes.Add(new DwarfAttribute() { Kind = kind, ValueAsObject = value});
+ }
+
+ //protected void SetAttributeLinkValue(DwarfAttributeKind kind, TLink link) where TLink : IObjectFileNodeLink
+ //{
+ // for (int i = 0; i < _attributes.Count; i++)
+ // {
+ // var attr = _attributes[i];
+ // if (attr.Kind == kind)
+ // {
+ // if (link == null)
+ // {
+ // RemoveAttributeAt(i);
+ // }
+ // else
+ // {
+ // attr.ValueAsU64 = link.GetRelativeOffset();
+ // attr.ValueAsObject = link.GetObjectFileNode();
+ // }
+ // return;
+ // }
+ // }
+
+ // AddAttribute(new DwarfAttribute()
+ // {
+ // Kind = kind,
+ // ValueAsU64 = link.GetRelativeOffset(),
+ // ValueAsObject = link.GetObjectFileNode()
+ // });
+ //}
+
+ protected unsafe void SetAttributeValueOpt(DwarfAttributeKind kind, TValue? value) where TValue : unmanaged
+ {
+ Debug.Assert(sizeof(TValue) <= sizeof(ulong));
+
+ for (int i = 0; i < _attributes.Count; i++)
{
- for (int i = 0; i < _attributes.Count; i++)
+ var attr = _attributes[i];
+ if (attr.Kind == kind)
{
- var attr = _attributes[i];
- if (attr.Kind == kind)
+ if (!value.HasValue)
{
- if (link == null)
- {
- RemoveAttributeAt(i);
- }
- else
- {
- attr.ValueAsU64 = link.GetRelativeOffset();
- attr.ValueAsObject = link.GetObjectFileNode();
- }
- return;
+ Attributes.RemoveAt(i);
}
+ else
+ {
+ ulong valueU64 = 0;
+ *((TValue*) &valueU64) = value.Value;
+ attr.ValueAsU64 = valueU64;
+ attr.ValueAsObject = null;
+ }
+ return;
}
-
- AddAttribute(new DwarfAttribute()
- {
- Kind = kind,
- ValueAsU64 = link.GetRelativeOffset(),
- ValueAsObject = link.GetObjectFileNode()
- });
}
- protected unsafe void SetAttributeValueOpt(DwarfAttributeKind kind, TValue? value) where TValue : unmanaged
+ if (value.HasValue)
{
- Debug.Assert(sizeof(TValue) <= sizeof(ulong));
+ var attr = new DwarfAttribute() {Kind = kind};
+ ulong valueU64 = 0;
+ *((TValue*)&valueU64) = value.Value;
+ attr.ValueAsU64 = valueU64;
+ Attributes.Add(attr);
+ }
+ }
- for (int i = 0; i < _attributes.Count; i++)
- {
- var attr = _attributes[i];
- if (attr.Kind == kind)
- {
- if (!value.HasValue)
- {
- RemoveAttributeAt(i);
- }
- else
- {
- ulong valueU64 = 0;
- *((TValue*) &valueU64) = value.Value;
- attr.ValueAsU64 = valueU64;
- attr.ValueAsObject = null;
- }
- return;
- }
- }
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ var abbrev = Abbrev;
- if (value.HasValue)
- {
- var attr = new DwarfAttribute() {Kind = kind};
- ulong valueU64 = 0;
- *((TValue*)&valueU64) = value.Value;
- attr.ValueAsU64 = valueU64;
- AddAttribute(attr);
- }
+ var endOffset = Position;
+ if (abbrev is null)
+ {
+ throw new InvalidOperationException("Abbreviation is not set");
}
+ endOffset += DwarfHelper.SizeOfULEB128(abbrev.Code); // WriteULEB128(abbreviationItem.Code);
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
+ foreach (var attr in _attributes)
{
- var abbrev = Abbrev;
-
- var endOffset = Offset;
- endOffset += DwarfHelper.SizeOfULEB128(abbrev.Code); // WriteULEB128(abbreviationItem.Code);
+ attr.Position = endOffset;
+ attr.UpdateLayout(context);
+ endOffset += attr.Size;
+ }
- foreach (var attr in _attributes)
+ if (abbrev.HasChildren)
+ {
+ foreach (var child in _children)
{
- attr.Offset = endOffset;
- attr.UpdateLayoutInternal(layoutContext);
- endOffset += attr.Size;
+ child.Position = endOffset;
+ child.UpdateLayout(context);
+ endOffset += child.Size;
}
- if (abbrev.HasChildren)
- {
- foreach (var child in _children)
- {
- child.Offset = endOffset;
- child.UpdateLayout(layoutContext);
- endOffset += child.Size;
- }
+ // Encode abbreviation 0 code
+ endOffset += DwarfHelper.SizeOfULEB128(0);
+ }
- // Encode abbreviation 0 code
- endOffset += DwarfHelper.SizeOfULEB128(0);
- }
+ Size = endOffset - Position;
+ }
- Size = endOffset - Offset;
- }
+ public override void Read(DwarfReader reader)
+ {
+ // Store map offset to DIE to resolve references
+ reader.PushDIE(this);
- protected override void Read(DwarfReader reader)
- {
- // Store map offset to DIE to resolve references
- reader.PushDIE(this);
+ // Console.WriteLine($" <{level}><{die.Offset:x}> Abbrev Number: {abbreviationCode} ({die.Tag})");
- // Console.WriteLine($" <{level}><{die.Offset:x}> Abbrev Number: {abbreviationCode} ({die.Tag})");
+ if (Abbrev is null)
+ {
+ throw new InvalidOperationException("Abbreviation is not set");
+ }
- var descriptors = Abbrev.Descriptors;
- if (descriptors.Length > 0)
+ var descriptors = Abbrev.Descriptors;
+ if (descriptors.Length > 0)
+ {
+ for (int i = 0; i < descriptors.Length; i++)
{
- for (int i = 0; i < descriptors.Length; i++)
- {
- reader.CurrentAttributeDescriptor = descriptors[i];
+ reader.CurrentAttributeDescriptor = descriptors[i];
- var attribute = new DwarfAttribute()
- {
- Offset = reader.Offset,
- };
+ var attribute = new DwarfAttribute()
+ {
+ Position = reader.Position,
+ };
- attribute.ReadInternal(reader);
+ attribute.Read(reader);
- AddAttribute(attribute);
- }
+ Attributes.Add(attribute);
}
+ }
- if (Abbrev.HasChildren)
+ if (Abbrev.HasChildren)
+ {
+ while (true)
{
- while (true)
- {
- reader.DIELevel++;
- var child = ReadInstance(reader);
- reader.DIELevel--;
- if (child == null) break;
+ reader.DIELevel++;
+ var child = ReadInstance(reader);
+ reader.DIELevel--;
+ if (child == null) break;
- AddChild(child);
- }
+ Children.Add(child);
}
+ }
- reader.PopDIE();
+ reader.PopDIE();
- Size = reader.Offset - Offset;
- }
+ Size = reader.Position - Position;
+ }
+
+ internal static DwarfDIE? ReadInstance(DwarfReader reader)
+ {
+ var startDIEOffset = reader.Position;
+ var abbreviationCode = reader.ReadULEB128();
+ DwarfDIE? die = null;
- internal static DwarfDIE ReadInstance(DwarfReader reader)
+ if (abbreviationCode != 0)
{
- var startDIEOffset = reader.Offset;
- var abbreviationCode = reader.ReadULEB128();
- DwarfDIE die = null;
- if (abbreviationCode != 0)
+ if (!reader.CurrentUnit!.Abbreviation!.TryFindByCode(abbreviationCode, out var abbreviationItem))
{
-
- if (!reader.CurrentUnit.Abbreviation.TryFindByCode(abbreviationCode, out var abbreviationItem))
- {
- throw new InvalidOperationException($"Invalid abbreviation code {abbreviationCode}");
- }
-
- die = DIEHelper.ConvertTagToDwarfDIE((ushort) abbreviationItem.Tag);
- die.Offset = startDIEOffset;
- die.Abbrev = abbreviationItem;
- die.Tag = abbreviationItem.Tag;
- die.ReadInternal(reader);
+ throw new InvalidOperationException($"Invalid abbreviation code {abbreviationCode}");
}
- return die;
+ die = DIEHelper.ConvertTagToDwarfDIE((ushort) abbreviationItem.Tag);
+ die.Position = startDIEOffset;
+ die.Abbrev = abbreviationItem;
+ die.Tag = abbreviationItem.Tag;
+ die.Read(reader);
}
- internal void UpdateAbbreviationItem(DwarfLayoutContext context)
- {
- // Initialize the offset of DIE to ulong.MaxValue to make sure that when we have a reference
- // to it, we can detect if it is a forward or backward reference.
- // If it is a backward reference, we will be able to encode the offset
- // otherwise we will have to pad the encoding with NOP (for DwarfOperation in expressions)
- Offset = ulong.MaxValue;
+ return die;
+ }
- // TODO: pool if not used by GetOrCreate below
- var descriptorArray = new DwarfAttributeDescriptor[Attributes.Count];
+ internal void UpdateAbbreviationItem(DwarfLayoutContext context)
+ {
+ // Initialize the offset of DIE to ulong.MaxValue to make sure that when we have a reference
+ // to it, we can detect if it is a forward or backward reference.
+ // If it is a backward reference, we will be able to encode the offset
+ // otherwise we will have to pad the encoding with NOP (for DwarfOperation in expressions)
+ Position = ulong.MaxValue;
- for (var i = 0; i < Attributes.Count; i++)
- {
- var attr = Attributes[i];
- attr.UpdateAttributeForm(context);
- descriptorArray[i] = new DwarfAttributeDescriptor(attr.Kind, attr.Form);
- }
+ // TODO: pool if not used by GetOrCreate below
+ var descriptorArray = new DwarfAttributeDescriptor[Attributes.Count];
+
+ for (var i = 0; i < Attributes.Count; i++)
+ {
+ var attr = Attributes[i];
+ attr.UpdateAttributeForm(context);
+ descriptorArray[i] = new DwarfAttributeDescriptor(attr.Kind, attr.Form);
+ }
- var key = new DwarfAbbreviationItemKey(Tag, Children.Count > 0, new DwarfAttributeDescriptors(descriptorArray));
- var item = context.CurrentUnit.Abbreviation.GetOrCreate(key);
+ var key = new DwarfAbbreviationItemKey(Tag, Children.Count > 0, new DwarfAttributeDescriptors(descriptorArray));
+ var item = context.CurrentUnit!.Abbreviation!.GetOrCreate(key);
- Abbrev = item;
+ Abbrev = item;
- foreach (var children in Children)
- {
- children.UpdateAbbreviationItem(context);
- }
+ foreach (var children in Children)
+ {
+ children.UpdateAbbreviationItem(context);
}
+ }
- protected override void Write(DwarfWriter writer)
+ public override void Write(DwarfWriter writer)
+ {
+ var startDIEOffset = Position;
+ Debug.Assert(Position == startDIEOffset);
+ var abbrev = Abbrev;
+ if (abbrev is null)
{
- var startDIEOffset = Offset;
- Debug.Assert(Offset == startDIEOffset);
- var abbrev = Abbrev;
- writer.WriteULEB128(abbrev.Code);
+ throw new InvalidOperationException("Abbreviation is not set");
+ }
- foreach (var attr in _attributes)
- {
- attr.WriteInternal(writer);
- }
+ writer.WriteULEB128(abbrev.Code);
- if (abbrev.HasChildren)
+ foreach (var attr in _attributes)
+ {
+ attr.Write(writer);
+ }
+
+ if (abbrev.HasChildren)
+ {
+ foreach (var child in _children)
{
- foreach (var child in _children)
- {
- child.Write(writer);
- }
- writer.WriteULEB128(0);
+ child.Write(writer);
}
-
- Debug.Assert(Size == writer.Offset - startDIEOffset);
+ writer.WriteULEB128(0);
}
+
+ Debug.Assert(Size == writer.Position - startDIEOffset);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfDIEDeclaration.cs b/src/LibObjectFile/Dwarf/DwarfDIEDeclaration.cs
index 179a1c0..8b682be 100644
--- a/src/LibObjectFile/Dwarf/DwarfDIEDeclaration.cs
+++ b/src/LibObjectFile/Dwarf/DwarfDIEDeclaration.cs
@@ -2,27 +2,26 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public abstract class DwarfDIEDeclaration : DwarfDIE
{
- public abstract class DwarfDIEDeclaration : DwarfDIE
+ // DW_AT_decl_column, DW_AT_decl_file, and DW_AT_decl_line
+ public ulong? DeclColumn
{
- // DW_AT_decl_column, DW_AT_decl_file, and DW_AT_decl_line
- public ulong? DeclColumn
- {
- get => GetAttributeValueOpt(DwarfAttributeKind.DeclColumn);
- set => SetAttributeValueOpt(DwarfAttributeKind.DeclColumn, value);
- }
+ get => GetAttributeValueOpt(DwarfAttributeKind.DeclColumn);
+ set => SetAttributeValueOpt(DwarfAttributeKind.DeclColumn, value);
+ }
- public DwarfFileName DeclFile
- {
- get => GetAttributeValue(DwarfAttributeKind.DeclFile);
- set => SetAttributeValue(DwarfAttributeKind.DeclFile, value);
- }
+ public DwarfFileName? DeclFile
+ {
+ get => GetAttributeValue(DwarfAttributeKind.DeclFile);
+ set => SetAttributeValue(DwarfAttributeKind.DeclFile, value);
+ }
- public ulong? DeclLine
- {
- get => GetAttributeValueOpt(DwarfAttributeKind.DeclLine);
- set => SetAttributeValueOpt(DwarfAttributeKind.DeclLine, value);
- }
+ public ulong? DeclLine
+ {
+ get => GetAttributeValueOpt(DwarfAttributeKind.DeclLine);
+ set => SetAttributeValueOpt(DwarfAttributeKind.DeclLine, value);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfDiscriminantListKind.cs b/src/LibObjectFile/Dwarf/DwarfDiscriminantListKind.cs
index b059ae4..5aa5841 100644
--- a/src/LibObjectFile/Dwarf/DwarfDiscriminantListKind.cs
+++ b/src/LibObjectFile/Dwarf/DwarfDiscriminantListKind.cs
@@ -2,12 +2,11 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public enum DwarfDiscriminantListKind : byte
{
- public enum DwarfDiscriminantListKind : byte
- {
- Label = DwarfNative.DW_DSC_label,
+ Label = DwarfNative.DW_DSC_label,
- Range = DwarfNative.DW_DSC_range,
- }
+ Range = DwarfNative.DW_DSC_range,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfElfContext.cs b/src/LibObjectFile/Dwarf/DwarfElfContext.cs
index a8bf895..1547da7 100644
--- a/src/LibObjectFile/Dwarf/DwarfElfContext.cs
+++ b/src/LibObjectFile/Dwarf/DwarfElfContext.cs
@@ -6,336 +6,336 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using LibObjectFile.Diagnostics;
using LibObjectFile.Elf;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public class DwarfElfContext : VisitorContextBase
{
- public class DwarfElfContext
+ private readonly int _codeSectionSymbolIndex;
+ private int _infoSectionSymbolIndex;
+ private int _abbreviationTableSymbolIndex;
+ private int _lineTableSymbolIndex;
+ private int _stringTableSymbolIndex;
+ private int _locationSectionSymbolIndex;
+ private readonly ElfSymbolTable? _symbolTable;
+
+ public DwarfElfContext(ElfObjectFile elf) : base(elf, new DiagnosticBag())
{
- private readonly int _codeSectionSymbolIndex;
- private int _infoSectionSymbolIndex;
- private int _abbreviationTableSymbolIndex;
- private int _lineTableSymbolIndex;
- private int _stringTableSymbolIndex;
- private int _locationSectionSymbolIndex;
- private readonly ElfSymbolTable _symbolTable;
-
- public DwarfElfContext(ElfObjectFile elf)
- {
- Elf = elf ?? throw new ArgumentNullException(nameof(elf));
+ Elf = elf ?? throw new ArgumentNullException(nameof(elf));
- var relocContext = new ElfRelocationContext();
+ var relocContext = new ElfRelocationContext();
- var codeSection = elf.Sections.OfType().FirstOrDefault(s => s.Name == ".text");
+ var codeSection = elf.Sections.OfType().FirstOrDefault(s => s.Name == ".text");
- _symbolTable = elf.Sections.OfType().FirstOrDefault();
- var mapSectionToSymbolIndex = new Dictionary();
- if (_symbolTable != null)
+ _symbolTable = elf.Sections.OfType().FirstOrDefault();
+ var mapSectionToSymbolIndex = new Dictionary();
+ if (_symbolTable != null)
+ {
+ for (var i = 0; i < _symbolTable.Entries.Count; i++)
{
- for (var i = 0; i < _symbolTable.Entries.Count; i++)
- {
- var entry = _symbolTable.Entries[i];
+ var entry = _symbolTable.Entries[i];
- if (entry.Type == ElfSymbolType.Section && entry.Section.Section != null)
- {
- mapSectionToSymbolIndex[entry.Section.Section] = i;
- }
+ if (entry.Type == ElfSymbolType.Section && entry.Section.Section != null)
+ {
+ mapSectionToSymbolIndex[entry.Section.Section] = i;
}
+ }
- if (codeSection != null)
+ if (codeSection != null)
+ {
+ if (!mapSectionToSymbolIndex.TryGetValue(codeSection, out _codeSectionSymbolIndex))
{
- if (!mapSectionToSymbolIndex.TryGetValue(codeSection, out _codeSectionSymbolIndex))
+ _codeSectionSymbolIndex = _symbolTable.Entries.Count;
+ _symbolTable.Entries.Add(new ElfSymbol()
{
- _codeSectionSymbolIndex = _symbolTable.Entries.Count;
- _symbolTable.Entries.Add(new ElfSymbol()
- {
- Type = ElfSymbolType.Section,
- Section = codeSection,
- });
- }
+ Type = ElfSymbolType.Section,
+ Section = codeSection,
+ });
}
}
+ }
- foreach (var section in elf.Sections)
+ foreach (var section in elf.Sections)
+ {
+ switch (section.Name.Value)
{
- switch (section.Name.Value)
- {
- case ".debug_info":
- InfoSection = ((ElfBinarySection)section);
- mapSectionToSymbolIndex.TryGetValue(InfoSection, out _infoSectionSymbolIndex);
- break;
- case ".debug_abbrev":
- AbbreviationTable = ((ElfBinarySection)section);
- mapSectionToSymbolIndex.TryGetValue(AbbreviationTable, out _abbreviationTableSymbolIndex);
- break;
- case ".debug_aranges":
- AddressRangeTable = ((ElfBinarySection)section);
- break;
- case ".debug_str":
- StringTable = ((ElfBinarySection)section);
- mapSectionToSymbolIndex.TryGetValue(StringTable, out _stringTableSymbolIndex);
- break;
- case ".debug_line":
- LineTable = ((ElfBinarySection)section);
- mapSectionToSymbolIndex.TryGetValue(LineTable, out _lineTableSymbolIndex);
- break;
- case ".debug_loc":
- LocationSection = ((ElfBinarySection)section);
- mapSectionToSymbolIndex.TryGetValue(LocationSection, out _locationSectionSymbolIndex);
- break;
-
- case ".rela.debug_aranges":
- case ".rel.debug_aranges":
- RelocAddressRangeTable = (ElfRelocationTable)section;
- RelocAddressRangeTable.Relocate(relocContext);
- break;
-
- case ".rela.debug_line":
- case ".rel.debug_line":
- RelocLineTable = (ElfRelocationTable)section;
- RelocLineTable.Relocate(relocContext);
- break;
-
- case ".rela.debug_info":
- case ".rel.debug_info":
- RelocInfoSection = (ElfRelocationTable)section;
- RelocInfoSection.Relocate(relocContext);
- break;
-
- case ".rela.debug_loc":
- case ".rel.debug_loc":
- RelocLocationSection = (ElfRelocationTable)section;
- RelocLocationSection.Relocate(relocContext);
- break;
- }
+ case ".debug_info":
+ InfoSection = ((ElfBinarySection)section);
+ mapSectionToSymbolIndex.TryGetValue(InfoSection, out _infoSectionSymbolIndex);
+ break;
+ case ".debug_abbrev":
+ AbbreviationTable = ((ElfBinarySection)section);
+ mapSectionToSymbolIndex.TryGetValue(AbbreviationTable, out _abbreviationTableSymbolIndex);
+ break;
+ case ".debug_aranges":
+ AddressRangeTable = ((ElfBinarySection)section);
+ break;
+ case ".debug_str":
+ StringTable = ((ElfBinarySection)section);
+ mapSectionToSymbolIndex.TryGetValue(StringTable, out _stringTableSymbolIndex);
+ break;
+ case ".debug_line":
+ LineTable = ((ElfBinarySection)section);
+ mapSectionToSymbolIndex.TryGetValue(LineTable, out _lineTableSymbolIndex);
+ break;
+ case ".debug_loc":
+ LocationSection = ((ElfBinarySection)section);
+ mapSectionToSymbolIndex.TryGetValue(LocationSection, out _locationSectionSymbolIndex);
+ break;
+
+ case ".rela.debug_aranges":
+ case ".rel.debug_aranges":
+ RelocAddressRangeTable = (ElfRelocationTable)section;
+ RelocAddressRangeTable.Relocate(relocContext);
+ break;
+
+ case ".rela.debug_line":
+ case ".rel.debug_line":
+ RelocLineTable = (ElfRelocationTable)section;
+ RelocLineTable.Relocate(relocContext);
+ break;
+
+ case ".rela.debug_info":
+ case ".rel.debug_info":
+ RelocInfoSection = (ElfRelocationTable)section;
+ RelocInfoSection.Relocate(relocContext);
+ break;
+
+ case ".rela.debug_loc":
+ case ".rel.debug_loc":
+ RelocLocationSection = (ElfRelocationTable)section;
+ RelocLocationSection.Relocate(relocContext);
+ break;
}
}
+ }
- public ElfObjectFile Elf { get; }
+ public ElfObjectFile Elf { get; }
- public bool IsLittleEndian => Elf.Encoding == ElfEncoding.Lsb;
+ public bool IsLittleEndian => Elf.Encoding == ElfEncoding.Lsb;
- public DwarfAddressSize AddressSize => Elf.FileClass == ElfFileClass.Is64 ? DwarfAddressSize.Bit64 : DwarfAddressSize.Bit32;
+ public DwarfAddressSize AddressSize => Elf.FileClass == ElfFileClass.Is64 ? DwarfAddressSize.Bit64 : DwarfAddressSize.Bit32;
- public ElfBinarySection InfoSection { get; private set; }
+ public ElfBinarySection? InfoSection { get; private set; }
- public ElfRelocationTable RelocInfoSection { get; set; }
+ public ElfRelocationTable? RelocInfoSection { get; set; }
- public ElfBinarySection AbbreviationTable { get; set; }
+ public ElfBinarySection? AbbreviationTable { get; set; }
- public ElfBinarySection AddressRangeTable { get; private set; }
+ public ElfBinarySection? AddressRangeTable { get; private set; }
- public ElfRelocationTable RelocAddressRangeTable { get; set; }
+ public ElfRelocationTable? RelocAddressRangeTable { get; set; }
- public ElfBinarySection StringTable { get; set; }
+ public ElfBinarySection? StringTable { get; set; }
- public ElfBinarySection LineTable { get; set; }
+ public ElfBinarySection? LineTable { get; set; }
- public ElfRelocationTable RelocLineTable { get; set; }
+ public ElfRelocationTable? RelocLineTable { get; set; }
- public ElfBinarySection LocationSection { get; private set; }
+ public ElfBinarySection? LocationSection { get; private set; }
- public ElfRelocationTable RelocLocationSection { get; set; }
+ public ElfRelocationTable? RelocLocationSection { get; set; }
- public int CodeSectionSymbolIndex => _codeSectionSymbolIndex;
+ public int CodeSectionSymbolIndex => _codeSectionSymbolIndex;
- public int InfoSectionSymbolIndex => _infoSectionSymbolIndex;
+ public int InfoSectionSymbolIndex => _infoSectionSymbolIndex;
- public int StringTableSymbolIndex => _stringTableSymbolIndex;
+ public int StringTableSymbolIndex => _stringTableSymbolIndex;
- public int AbbreviationTableSymbolIndex => _abbreviationTableSymbolIndex;
+ public int AbbreviationTableSymbolIndex => _abbreviationTableSymbolIndex;
- public int LineTableSymbolIndex => _lineTableSymbolIndex;
+ public int LineTableSymbolIndex => _lineTableSymbolIndex;
- public int LocationSectionSymbolIndex => _locationSectionSymbolIndex;
+ public int LocationSectionSymbolIndex => _locationSectionSymbolIndex;
- public ElfBinarySection GetOrCreateInfoSection()
- {
- return InfoSection ??= GetOrCreateDebugSection(".debug_info", true, out _infoSectionSymbolIndex);
- }
+ public ElfBinarySection GetOrCreateInfoSection()
+ {
+ return InfoSection ??= GetOrCreateDebugSection(".debug_info", true, out _infoSectionSymbolIndex);
+ }
- public ElfRelocationTable GetOrCreateRelocInfoSection()
- {
- return RelocInfoSection ??= GetOrCreateRelocationTable(InfoSection);
- }
+ public ElfRelocationTable GetOrCreateRelocInfoSection()
+ {
+ return RelocInfoSection ??= GetOrCreateRelocationTable(InfoSection!);
+ }
- public ElfBinarySection GetOrCreateAbbreviationTable()
- {
- return AbbreviationTable ??= GetOrCreateDebugSection(".debug_abbrev", true, out _abbreviationTableSymbolIndex);
- }
+ public ElfBinarySection GetOrCreateAbbreviationTable()
+ {
+ return AbbreviationTable ??= GetOrCreateDebugSection(".debug_abbrev", true, out _abbreviationTableSymbolIndex);
+ }
- public ElfBinarySection GetOrCreateAddressRangeTable()
- {
- return AddressRangeTable ??= GetOrCreateDebugSection(".debug_aranges", false, out _);
- }
+ public ElfBinarySection GetOrCreateAddressRangeTable()
+ {
+ return AddressRangeTable ??= GetOrCreateDebugSection(".debug_aranges", false, out _);
+ }
- public ElfRelocationTable GetOrCreateRelocAddressRangeTable()
- {
- return RelocAddressRangeTable ??= GetOrCreateRelocationTable(AddressRangeTable);
- }
+ public ElfRelocationTable GetOrCreateRelocAddressRangeTable()
+ {
+ return RelocAddressRangeTable ??= GetOrCreateRelocationTable(AddressRangeTable!);
+ }
- public ElfBinarySection GetOrCreateLineSection()
- {
- return LineTable ??= GetOrCreateDebugSection(".debug_line", true, out _lineTableSymbolIndex);
- }
+ public ElfBinarySection GetOrCreateLineSection()
+ {
+ return LineTable ??= GetOrCreateDebugSection(".debug_line", true, out _lineTableSymbolIndex);
+ }
- public ElfRelocationTable GetOrCreateRelocLineSection()
- {
- return RelocLineTable ??= GetOrCreateRelocationTable(LineTable);
- }
+ public ElfRelocationTable GetOrCreateRelocLineSection()
+ {
+ return RelocLineTable ??= GetOrCreateRelocationTable(LineTable!);
+ }
- public ElfBinarySection GetOrCreateStringTable()
- {
- return StringTable ??= GetOrCreateDebugSection(".debug_str", true, out _stringTableSymbolIndex);
- }
+ public ElfBinarySection GetOrCreateStringTable()
+ {
+ return StringTable ??= GetOrCreateDebugSection(".debug_str", true, out _stringTableSymbolIndex);
+ }
- public ElfBinarySection GetOrCreateLocationSection()
- {
- return LocationSection ??= GetOrCreateDebugSection(".debug_loc", true, out _locationSectionSymbolIndex);
- }
+ public ElfBinarySection GetOrCreateLocationSection()
+ {
+ return LocationSection ??= GetOrCreateDebugSection(".debug_loc", true, out _locationSectionSymbolIndex);
+ }
- public ElfRelocationTable GetOrCreateRelocLocationSection()
- {
- return RelocLocationSection ??= GetOrCreateRelocationTable(LocationSection);
- }
+ public ElfRelocationTable GetOrCreateRelocLocationSection()
+ {
+ return RelocLocationSection ??= GetOrCreateRelocationTable(LocationSection!);
+ }
- public void RemoveStringTable()
+ public void RemoveStringTable()
+ {
+ if (StringTable != null)
{
- if (StringTable != null)
- {
- Elf.RemoveSection(StringTable);
- StringTable = null;
- }
+ Elf.RemoveSection(StringTable);
+ StringTable = null;
}
+ }
- public void RemoveAbbreviationTable()
+ public void RemoveAbbreviationTable()
+ {
+ if (AbbreviationTable != null)
{
- if (AbbreviationTable != null)
- {
- Elf.RemoveSection(AbbreviationTable);
- AbbreviationTable = null;
- }
+ Elf.RemoveSection(AbbreviationTable);
+ AbbreviationTable = null;
}
+ }
- public void RemoveLineTable()
+ public void RemoveLineTable()
+ {
+ if (LineTable != null)
{
- if (LineTable != null)
- {
- Elf.RemoveSection(LineTable);
- LineTable = null;
- }
-
- RemoveRelocLineTable();
+ Elf.RemoveSection(LineTable);
+ LineTable = null;
}
- public void RemoveRelocLineTable()
+ RemoveRelocLineTable();
+ }
+
+ public void RemoveRelocLineTable()
+ {
+ if (RelocLineTable != null)
{
- if (RelocLineTable != null)
- {
- Elf.RemoveSection(RelocLineTable);
- RelocLineTable = null;
- }
+ Elf.RemoveSection(RelocLineTable);
+ RelocLineTable = null;
}
+ }
- public void RemoveAddressRangeTable()
+ public void RemoveAddressRangeTable()
+ {
+ if (AddressRangeTable != null)
{
- if (AddressRangeTable != null)
- {
- Elf.RemoveSection(AddressRangeTable);
- AddressRangeTable = null;
- }
-
- RemoveRelocAddressRangeTable();
+ Elf.RemoveSection(AddressRangeTable);
+ AddressRangeTable = null;
}
- public void RemoveRelocAddressRangeTable()
+ RemoveRelocAddressRangeTable();
+ }
+
+ public void RemoveRelocAddressRangeTable()
+ {
+ if (RelocAddressRangeTable != null)
{
- if (RelocAddressRangeTable != null)
- {
- Elf.RemoveSection(RelocAddressRangeTable);
- RelocAddressRangeTable = null;
- }
+ Elf.RemoveSection(RelocAddressRangeTable);
+ RelocAddressRangeTable = null;
}
+ }
- public void RemoveInfoSection()
+ public void RemoveInfoSection()
+ {
+ if (InfoSection != null)
{
- if (InfoSection != null)
- {
- Elf.RemoveSection(InfoSection);
- InfoSection = null;
- }
-
- RemoveRelocInfoSection();
+ Elf.RemoveSection(InfoSection);
+ InfoSection = null;
}
- public void RemoveRelocInfoSection()
+ RemoveRelocInfoSection();
+ }
+
+ public void RemoveRelocInfoSection()
+ {
+ if (RelocInfoSection != null)
{
- if (RelocInfoSection != null)
- {
- Elf.RemoveSection(RelocInfoSection);
- RelocInfoSection = null;
- }
+ Elf.RemoveSection(RelocInfoSection);
+ RelocInfoSection = null;
}
+ }
- public void RemoveLocationSection()
+ public void RemoveLocationSection()
+ {
+ if (LocationSection != null)
{
- if (LocationSection != null)
- {
- Elf.RemoveSection(LocationSection);
- LocationSection = null;
- }
-
- RemoveRelocLocationSection();
+ Elf.RemoveSection(LocationSection);
+ LocationSection = null;
}
- public void RemoveRelocLocationSection()
+ RemoveRelocLocationSection();
+ }
+
+ public void RemoveRelocLocationSection()
+ {
+ if (RelocLocationSection != null)
{
- if (RelocLocationSection != null)
- {
- Elf.RemoveSection(RelocLocationSection);
- RelocLocationSection = null;
- }
+ Elf.RemoveSection(RelocLocationSection);
+ RelocLocationSection = null;
}
+ }
- private ElfBinarySection GetOrCreateDebugSection(string name, bool createSymbol, out int symbolIndex)
+ private ElfBinarySection GetOrCreateDebugSection(string name, bool createSymbol, out int symbolIndex)
+ {
+ var newSection = new ElfBinarySection()
{
- var newSection = new ElfBinarySection()
- {
- Name = name,
- Alignment = 1,
- Type = ElfSectionType.ProgBits,
- Stream = new MemoryStream(),
- };
+ Name = name,
+ Alignment = 1,
+ Type = ElfSectionType.ProgBits,
+ Stream = new MemoryStream(),
+ };
- Elf.AddSection(newSection);
- symbolIndex = 0;
+ Elf.AddSection(newSection);
+ symbolIndex = 0;
- if (createSymbol && _symbolTable != null)
+ if (createSymbol && _symbolTable != null)
+ {
+ symbolIndex = _symbolTable.Entries.Count;
+ _symbolTable.Entries.Add(new ElfSymbol()
{
- symbolIndex = _symbolTable.Entries.Count;
- _symbolTable.Entries.Add(new ElfSymbol()
- {
- Type = ElfSymbolType.Section,
- Section = newSection,
- });
- }
-
- return newSection;
+ Type = ElfSymbolType.Section,
+ Section = newSection,
+ });
}
- private ElfRelocationTable GetOrCreateRelocationTable(ElfBinarySection section)
+ return newSection;
+ }
+
+ private ElfRelocationTable GetOrCreateRelocationTable(ElfBinarySection section)
+ {
+ var newSection = new ElfRelocationTable()
{
- var newSection = new ElfRelocationTable()
- {
- Name = $".rela{section.Name}",
- Alignment = (ulong)AddressSize,
- Flags = ElfSectionFlags.InfoLink,
- Type = ElfSectionType.RelocationAddends,
- Info = section,
- Link = _symbolTable,
- };
- Elf.AddSection(newSection);
- return newSection;
- }
+ Name = $".rela{section.Name}",
+ Alignment = (ulong)AddressSize,
+ Flags = ElfSectionFlags.InfoLink,
+ Type = ElfSectionType.RelocationAddends,
+ Info = section,
+ Link = _symbolTable,
+ };
+ Elf.AddSection(newSection);
+ return newSection;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfExpression.cs b/src/LibObjectFile/Dwarf/DwarfExpression.cs
index 9dbe2aa..fdcef71 100644
--- a/src/LibObjectFile/Dwarf/DwarfExpression.cs
+++ b/src/LibObjectFile/Dwarf/DwarfExpression.cs
@@ -1,132 +1,111 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using LibObjectFile.Collections;
-namespace LibObjectFile.Dwarf
-{
- [DebuggerDisplay("Count = {Operations.Count,nq}")]
- public class DwarfExpression : DwarfObject
- {
- private readonly List _operations;
+namespace LibObjectFile.Dwarf;
- public DwarfExpression()
- {
- _operations = new List();
- }
+[DebuggerDisplay("Count = {Operations.Count,nq}")]
+public class DwarfExpression : DwarfObject
+{
+ private readonly ObjectList _operations;
- public IReadOnlyList Operations => _operations;
+ public DwarfExpression()
+ {
+ _operations = new ObjectList(this);
+ }
- internal List InternalOperations => _operations;
+ public ObjectList Operations => _operations;
- public ulong OperationLengthInBytes { get; internal set; }
+ public ulong OperationLengthInBytes { get; internal set; }
- public void AddOperation(DwarfOperation operation)
+ public override void Verify(DwarfVerifyContext context)
+ {
+ foreach (var op in _operations)
{
- if (operation == null) throw new ArgumentNullException(nameof(operation));
- _operations.Add(this, operation);
+ op.Verify(context);
}
+ }
- public void RemoveOperation(DwarfOperation operation)
- {
- if (operation == null) throw new ArgumentNullException(nameof(operation));
- _operations.Remove(this, operation);
- }
+ internal void ReadInternal(DwarfReader reader, bool inLocationSection = false)
+ {
+ Position = reader.Position;
+ var size = inLocationSection ? reader.ReadU16() : reader.ReadULEB128();
+ OperationLengthInBytes = size;
+ var endPosition = reader.Position + size;
- public DwarfOperation RemoveOperationAt(int index)
+ while (reader.Position < endPosition)
{
- return _operations.RemoveAt(this, index);
+ var op = new DwarfOperation() {Position = reader.Position};
+ op.Read(reader);
+ Operations.Add(op);
}
- public override void Verify(DiagnosticBag diagnostics)
- {
- base.Verify(diagnostics);
+ Size = reader.Position - Position;
+ }
- foreach (var op in _operations)
- {
- op.Verify(diagnostics);
- }
- }
+ internal void WriteInternal(DwarfWriter writer, bool inLocationSection = false)
+ {
+ Debug.Assert(Position == writer.Position);
+ Debug.Assert(!inLocationSection || OperationLengthInBytes <= ushort.MaxValue);
- internal void ReadInternal(DwarfReader reader, bool inLocationSection = false)
+ var startExpressionOffset = writer.Position;
+ if (inLocationSection)
{
- Offset = reader.Offset;
- var size = inLocationSection ? reader.ReadU16() : reader.ReadULEB128();
- OperationLengthInBytes = size;
- var endPosition = reader.Offset + size;
-
- while (reader.Offset < endPosition)
- {
- var op = new DwarfOperation() {Offset = reader.Offset};
- op.ReadInternal(reader);
- AddOperation(op);
- }
-
- Size = reader.Offset - Offset;
+ writer.WriteU16((ushort)OperationLengthInBytes);
}
-
- internal void WriteInternal(DwarfWriter writer, bool inLocationSection = false)
+ else
{
- Debug.Assert(Offset == writer.Offset);
- Debug.Assert(!inLocationSection || OperationLengthInBytes <= ushort.MaxValue);
-
- var startExpressionOffset = writer.Offset;
- if (inLocationSection)
- {
- writer.WriteU16((ushort)OperationLengthInBytes);
- }
- else
- {
- writer.WriteULEB128(OperationLengthInBytes);
- }
-
- foreach (var op in Operations)
- {
- op.WriteInternal(writer);
- }
-
- Debug.Assert(writer.Offset - startExpressionOffset == Size);
+ writer.WriteULEB128(OperationLengthInBytes);
}
- internal void UpdateLayoutInternal(DwarfLayoutContext layoutContext, bool inLocationSection = false)
+ foreach (var op in Operations)
{
- var endOffset = Offset;
- foreach (var op in _operations)
- {
- op.Offset = endOffset;
- op.UpdateLayoutInternal(layoutContext);
- endOffset += op.Size;
- }
-
- OperationLengthInBytes = endOffset - Offset;
-
- // We need to shift the expression which is prefixed by its size encoded in LEB128,
- // or fixed-size U2 in .debug_loc section
- var deltaLength = inLocationSection ? sizeof(ushort) : DwarfHelper.SizeOfULEB128(Size);
- foreach (var op in InternalOperations)
- {
- op.Offset += deltaLength;
- }
-
- Size = OperationLengthInBytes + deltaLength;
+ op.Write(writer);
}
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- UpdateLayoutInternal(layoutContext, inLocationSection: false);
- }
+ Debug.Assert(writer.Position - startExpressionOffset == Size);
+ }
- protected override void Read(DwarfReader reader)
+ internal void UpdateLayout(DwarfLayoutContext layoutContext, bool inLocationSection)
+ {
+ var endOffset = Position;
+ foreach (var op in _operations)
{
- ReadInternal(reader, inLocationSection: false);
+ op.Position = endOffset;
+ op.UpdateLayout(layoutContext);
+ endOffset += op.Size;
}
- protected override void Write(DwarfWriter writer)
+ OperationLengthInBytes = endOffset - Position;
+
+ // We need to shift the expression which is prefixed by its size encoded in LEB128,
+ // or fixed-size U2 in .debug_loc section
+ var deltaLength = inLocationSection ? sizeof(ushort) : DwarfHelper.SizeOfULEB128(Size);
+ foreach (var op in _operations.UnsafeList)
{
- WriteInternal(writer, inLocationSection: false);
+ op.Position += deltaLength;
}
+
+ Size = OperationLengthInBytes + deltaLength;
+ }
+
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ UpdateLayout(context, inLocationSection: false);
+ }
+
+ public override void Read(DwarfReader reader)
+ {
+ ReadInternal(reader, inLocationSection: false);
+ }
+
+ public override void Write(DwarfWriter writer)
+ {
+ WriteInternal(writer, inLocationSection: false);
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfFile.cs b/src/LibObjectFile/Dwarf/DwarfFile.cs
index 0d37d0d..bf0d71f 100644
--- a/src/LibObjectFile/Dwarf/DwarfFile.cs
+++ b/src/LibObjectFile/Dwarf/DwarfFile.cs
@@ -1,456 +1,458 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
+using LibObjectFile.Diagnostics;
using LibObjectFile.Elf;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public class DwarfFile : DwarfContainer
{
- public class DwarfFile : DwarfContainer
+ private ObjectFileElementHolder _abbreviationTable;
+ private ObjectFileElementHolder _stringTable;
+ private ObjectFileElementHolder _lineSection;
+ private ObjectFileElementHolder _infoSection;
+ private ObjectFileElementHolder _addressRangeTable;
+ private ObjectFileElementHolder _locationSection;
+
+ public DwarfFile()
{
- private DwarfAbbreviationTable _abbreviationTable;
- private DwarfStringTable _stringTable;
- private DwarfLineSection _lineSection;
- private DwarfInfoSection _infoSection;
- private DwarfAddressRangeTable _addressRangeTable;
- private DwarfLocationSection _locationSection;
-
- public DwarfFile()
- {
- AbbreviationTable = new DwarfAbbreviationTable();
- StringTable = new DwarfStringTable();
- LineSection = new DwarfLineSection();
- InfoSection = new DwarfInfoSection();
- LocationSection = new DwarfLocationSection();
- AddressRangeTable = new DwarfAddressRangeTable();
- }
+ _abbreviationTable = new(this, new DwarfAbbreviationTable());
+ _stringTable = new(this, new DwarfStringTable());
+ _lineSection = new(this, new DwarfLineSection());
+ _infoSection = new(this, new DwarfInfoSection());
+ _addressRangeTable = new(this, new DwarfAddressRangeTable());
+ _locationSection = new(this, new DwarfLocationSection());
+ }
- public DwarfAbbreviationTable AbbreviationTable
- {
- get => _abbreviationTable;
- set => AttachChild(this, value, ref _abbreviationTable, false);
- }
+ public DwarfAbbreviationTable AbbreviationTable
+ {
+ get => _abbreviationTable;
+ set => _abbreviationTable.Set(this, value);
+ }
- public DwarfStringTable StringTable
- {
- get => _stringTable;
- set => AttachChild(this, value, ref _stringTable, false);
- }
+ public DwarfStringTable StringTable
+ {
+ get => _stringTable;
+ set => _stringTable.Set(this, value);
+ }
- public DwarfLineSection LineSection
- {
- get => _lineSection;
- set => AttachChild(this, value, ref _lineSection, false);
- }
+ public DwarfLineSection LineSection
+ {
+ get => _lineSection;
+ set => _lineSection.Set(this, value);
+ }
- public DwarfAddressRangeTable AddressRangeTable
- {
- get => _addressRangeTable;
- set => AttachChild(this, value, ref _addressRangeTable, false);
- }
+ public DwarfAddressRangeTable AddressRangeTable
+ {
+ get => _addressRangeTable;
+ set => _addressRangeTable.Set(this, value);
+ }
- public DwarfInfoSection InfoSection
+ public DwarfInfoSection InfoSection
+ {
+ get => _infoSection;
+ set => _infoSection.Set(this, value);
+ }
+
+ public DwarfLocationSection LocationSection
+ {
+ get => _locationSection;
+ set => _locationSection.Set(this, value);
+ }
+
+ public override void Read(DwarfReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Verify(DwarfVerifyContext context)
+ {
+ LineSection.Verify(context);
+ AbbreviationTable.Verify(context);
+ AddressRangeTable.Verify(context);
+ StringTable.Verify(context);
+ InfoSection.Verify(context);
+ }
+
+ public void UpdateLayout(DwarfLayoutConfig config, DiagnosticBag diagnostics)
+ {
+ if (config == null) throw new ArgumentNullException(nameof(config));
+ if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
+
+ var layoutContext = new DwarfLayoutContext(this, config, diagnostics);
+
+ LineSection.Position = 0;
+ LineSection.UpdateLayout(layoutContext);
+ if (layoutContext.HasErrors)
{
- get => _infoSection;
- set => AttachChild(this, value, ref _infoSection, false);
+ return;
}
- public DwarfLocationSection LocationSection
+ // Reset the abbreviation table
+ // TODO: Make this configurable via the DwarfWriterContext
+ AbbreviationTable.Position = 0;
+ AbbreviationTable.Reset();
+
+ InfoSection.Position = 0;
+ InfoSection.UpdateLayout(layoutContext);
+ if (layoutContext.HasErrors)
{
- get => _locationSection;
- set => AttachChild(this, value, ref _locationSection, false);
+ return;
}
- protected override void Read(DwarfReader reader)
+ // Update AddressRangeTable layout after Info
+ AddressRangeTable.Position = 0;
+ AddressRangeTable.UpdateLayout(layoutContext);
+ if (layoutContext.HasErrors)
{
- throw new NotImplementedException();
+ return;
}
- public override void Verify(DiagnosticBag diagnostics)
+ // Update string table right after updating the layout of Info
+ StringTable.Position = 0;
+ StringTable.UpdateLayout(layoutContext);
+ if (layoutContext.HasErrors)
{
- base.Verify(diagnostics);
-
- LineSection.Verify(diagnostics);
- AbbreviationTable.Verify(diagnostics);
- AddressRangeTable.Verify(diagnostics);
- StringTable.Verify(diagnostics);
- InfoSection.Verify(diagnostics);
+ return;
}
-
- public void UpdateLayout(DwarfLayoutConfig config, DiagnosticBag diagnostics)
- {
- if (config == null) throw new ArgumentNullException(nameof(config));
- if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
-
- var layoutContext = new DwarfLayoutContext(this, config, diagnostics);
-
- LineSection.Offset = 0;
- LineSection.UpdateLayoutInternal(layoutContext);
- if (layoutContext.HasErrors)
- {
- return;
- }
- // Reset the abbreviation table
- // TODO: Make this configurable via the DwarfWriterContext
- AbbreviationTable.Offset = 0;
- AbbreviationTable.Reset();
+ // Update the abbrev table right after we have computed the entire layout of Info
+ AbbreviationTable.Position = 0;
+ AbbreviationTable.UpdateLayout(layoutContext);
- InfoSection.Offset = 0;
- InfoSection.UpdateLayoutInternal(layoutContext);
- if (layoutContext.HasErrors)
- {
- return;
- }
-
- // Update AddressRangeTable layout after Info
- AddressRangeTable.Offset = 0;
- AddressRangeTable.UpdateLayoutInternal(layoutContext);
- if (layoutContext.HasErrors)
- {
- return;
- }
-
- // Update string table right after updating the layout of Info
- StringTable.Offset = 0;
- StringTable.UpdateLayoutInternal(layoutContext);
- if (layoutContext.HasErrors)
- {
- return;
- }
-
- // Update the abbrev table right after we have computed the entire layout of Info
- AbbreviationTable.Offset = 0;
- AbbreviationTable.UpdateLayoutInternal(layoutContext);
+ LocationSection.Position = 0;
+ LocationSection.UpdateLayout(layoutContext);
+ }
- LocationSection.Offset = 0;
- LocationSection.UpdateLayoutInternal(layoutContext);
- }
+ public void Write(DwarfWriterContext writerContext)
+ {
+ if (writerContext == null) throw new ArgumentNullException(nameof(writerContext));
- public void Write(DwarfWriterContext writerContext)
- {
- if (writerContext == null) throw new ArgumentNullException(nameof(writerContext));
+ var diagnostics = new DiagnosticBag();
- var diagnostics = new DiagnosticBag();
+ var verifyContext = new DwarfVerifyContext(this, diagnostics);
- // Verify correctness
- Verify(diagnostics);
- CheckErrors(diagnostics);
+ // Verify correctness
+ Verify(verifyContext);
+ CheckErrors(diagnostics);
- // Update the layout of all section and tables
- UpdateLayout(writerContext.LayoutConfig, diagnostics);
- CheckErrors(diagnostics);
+ // Update the layout of all section and tables
+ UpdateLayout(writerContext.LayoutConfig, diagnostics);
+ CheckErrors(diagnostics);
- // Write all section and stables
- var writer = new DwarfWriter(this, writerContext.IsLittleEndian, diagnostics);
- writer.AddressSize = writerContext.AddressSize;
- writer.EnableRelocation = writerContext.EnableRelocation;
+ // Write all section and stables
+ var writer = new DwarfWriter(this, writerContext.IsLittleEndian, diagnostics);
+ writer.AddressSize = writerContext.AddressSize;
+ writer.EnableRelocation = writerContext.EnableRelocation;
- writer.Log = writerContext.DebugLinePrinter;
+ writer.DebugLog = writerContext.DebugLinePrinter;
+ if (writerContext.DebugLineStream != null)
+ {
writer.Stream = writerContext.DebugLineStream;
- if (writer.Stream != null)
- {
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = LineSection;
- LineSection.Relocations.Clear();
- LineSection.WriteInternal(writer);
- }
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = LineSection;
+ LineSection.Relocations.Clear();
+ LineSection.Write(writer);
+ }
- writer.Log = null;
+ writer.DebugLog = null;
+ if (writerContext.DebugAbbrevStream != null)
+ {
writer.Stream = writerContext.DebugAbbrevStream;
- if (writer.Stream != null)
- {
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = AbbreviationTable;
- AbbreviationTable.WriteInternal(writer);
- }
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = AbbreviationTable;
+ AbbreviationTable.Write(writer);
+ }
+ if (writerContext.DebugAddressRangeStream != null)
+ {
writer.Stream = writerContext.DebugAddressRangeStream;
- if (writer.Stream != null)
- {
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = AddressRangeTable;
- AddressRangeTable.Relocations.Clear();
- AddressRangeTable.WriteInternal(writer);
- }
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = AddressRangeTable;
+ AddressRangeTable.Relocations.Clear();
+ AddressRangeTable.Write(writer);
+ }
+ if (writerContext.DebugStringStream != null)
+ {
writer.Stream = writerContext.DebugStringStream;
- if (writer.Stream != null)
- {
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = StringTable;
- StringTable.WriteInternal(writer);
- }
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = StringTable;
+ StringTable.Write(writer);
+ }
+ if (writerContext.DebugInfoStream != null)
+ {
writer.Stream = writerContext.DebugInfoStream;
- if (writer.Stream != null)
- {
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = InfoSection;
- InfoSection.Relocations.Clear();
- InfoSection.WriteInternal(writer);
- }
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = InfoSection;
+ InfoSection.Relocations.Clear();
+ InfoSection.Write(writer);
+ }
+ if (writerContext.DebugLocationStream != null)
+ {
writer.Stream = writerContext.DebugLocationStream;
- if (writer.Stream != null)
- {
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = LocationSection;
- LocationSection.Relocations.Clear();
- LocationSection.WriteInternal(writer);
- }
-
- CheckErrors(diagnostics);
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = LocationSection;
+ LocationSection.Relocations.Clear();
+ LocationSection.Write(writer);
}
+
+ CheckErrors(diagnostics);
+ }
- public void WriteToElf(DwarfElfContext elfContext, DwarfLayoutConfig layoutConfig = null)
- {
- if (elfContext == null) throw new ArgumentNullException(nameof(elfContext));
+ public void WriteToElf(DwarfElfContext elfContext, DwarfLayoutConfig? layoutConfig = null)
+ {
+ if (elfContext == null) throw new ArgumentNullException(nameof(elfContext));
- var diagnostics = new DiagnosticBag();
+ var diagnostics = new DiagnosticBag();
- layoutConfig ??= new DwarfLayoutConfig();
+ layoutConfig ??= new DwarfLayoutConfig();
- // Verify correctness
- Verify(diagnostics);
- CheckErrors(diagnostics);
+ var verifyContext = new DwarfVerifyContext(this, diagnostics);
- // Update the layout of all section and tables
- UpdateLayout(layoutConfig, diagnostics);
- CheckErrors(diagnostics);
+ // Verify correctness
+ Verify(verifyContext);
+ CheckErrors(diagnostics);
- // Setup the output based on actual content of Dwarf infos
- var writer = new DwarfWriter(this, elfContext.IsLittleEndian, diagnostics)
- {
- AddressSize = elfContext.AddressSize,
- EnableRelocation = elfContext.Elf.FileType == ElfFileType.Relocatable
- };
-
- // Pre-create table/sections to create symbols as well
- if (StringTable.Size > 0) elfContext.GetOrCreateStringTable();
- if (AbbreviationTable.Size > 0) elfContext.GetOrCreateAbbreviationTable();
- if (LineSection.Size > 0) elfContext.GetOrCreateLineSection();
- if (AddressRangeTable.Size > 0) elfContext.GetOrCreateAddressRangeTable();
- if (InfoSection.Size > 0) elfContext.GetOrCreateInfoSection();
-
- // String table
- if (StringTable.Size > 0)
- {
- writer.Stream = elfContext.GetOrCreateStringTable().Stream;
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = StringTable;
- StringTable.WriteInternal(writer);
- }
- else
- {
- elfContext.RemoveStringTable();
- }
+ // Update the layout of all section and tables
+ UpdateLayout(layoutConfig, diagnostics);
+ CheckErrors(diagnostics);
- // Abbreviation table
- if (AbbreviationTable.Size > 0)
- {
- writer.Stream = elfContext.GetOrCreateAbbreviationTable().Stream;
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = AbbreviationTable;
- AbbreviationTable.WriteInternal(writer);
- }
- else
- {
- elfContext.RemoveAbbreviationTable();
- }
+ // Setup the output based on actual content of Dwarf infos
+ var writer = new DwarfWriter(this, elfContext.IsLittleEndian, diagnostics)
+ {
+ AddressSize = elfContext.AddressSize,
+ EnableRelocation = elfContext.Elf.FileType == ElfFileType.Relocatable
+ };
+
+ // Pre-create table/sections to create symbols as well
+ if (StringTable.Size > 0) elfContext.GetOrCreateStringTable();
+ if (AbbreviationTable.Size > 0) elfContext.GetOrCreateAbbreviationTable();
+ if (LineSection.Size > 0) elfContext.GetOrCreateLineSection();
+ if (AddressRangeTable.Size > 0) elfContext.GetOrCreateAddressRangeTable();
+ if (InfoSection.Size > 0) elfContext.GetOrCreateInfoSection();
+
+ // String table
+ if (StringTable.Size > 0)
+ {
+ writer.Stream = elfContext.GetOrCreateStringTable().Stream!;
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = StringTable;
+ StringTable.Write(writer);
+ }
+ else
+ {
+ elfContext.RemoveStringTable();
+ }
- // Line table
- if (LineSection.Size > 0)
+ // Abbreviation table
+ if (AbbreviationTable.Size > 0)
+ {
+ writer.Stream = elfContext.GetOrCreateAbbreviationTable().Stream!;
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = AbbreviationTable;
+ AbbreviationTable.Write(writer);
+ }
+ else
+ {
+ elfContext.RemoveAbbreviationTable();
+ }
+
+ // Line table
+ if (LineSection.Size > 0)
+ {
+ writer.Stream = elfContext.GetOrCreateLineSection().Stream!;
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = LineSection;
+ LineSection.Relocations.Clear();
+ LineSection.Write(writer);
+ if (writer.EnableRelocation && LineSection.Relocations.Count > 0)
{
- writer.Stream = elfContext.GetOrCreateLineSection().Stream;
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = LineSection;
- LineSection.Relocations.Clear();
- LineSection.WriteInternal(writer);
- if (writer.EnableRelocation && LineSection.Relocations.Count > 0)
- {
- LineSection.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocLineSection());
- }
- else
- {
- elfContext.RemoveRelocLineTable();
- }
+ LineSection.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocLineSection());
}
else
{
- elfContext.RemoveLineTable();
+ elfContext.RemoveRelocLineTable();
}
+ }
+ else
+ {
+ elfContext.RemoveLineTable();
+ }
- // AddressRange table
- if (AddressRangeTable.Size > 0)
+ // AddressRange table
+ if (AddressRangeTable.Size > 0)
+ {
+ writer.Stream = elfContext.GetOrCreateAddressRangeTable().Stream!;
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = AddressRangeTable;
+ AddressRangeTable.Relocations.Clear();
+ AddressRangeTable.Write(writer);
+
+ if (writer.EnableRelocation && AddressRangeTable.Relocations.Count > 0)
{
- writer.Stream = elfContext.GetOrCreateAddressRangeTable().Stream;
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = AddressRangeTable;
- AddressRangeTable.Relocations.Clear();
- AddressRangeTable.WriteInternal(writer);
-
- if (writer.EnableRelocation && AddressRangeTable.Relocations.Count > 0)
- {
- AddressRangeTable.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocAddressRangeTable());
- }
- else
- {
- elfContext.RemoveAddressRangeTable();
- }
+ AddressRangeTable.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocAddressRangeTable());
}
else
{
elfContext.RemoveAddressRangeTable();
}
+ }
+ else
+ {
+ elfContext.RemoveAddressRangeTable();
+ }
- // InfoSection
- if (InfoSection.Size > 0)
+ // InfoSection
+ if (InfoSection.Size > 0)
+ {
+ writer.Stream = elfContext.GetOrCreateInfoSection().Stream!;
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = InfoSection;
+ InfoSection.Relocations.Clear();
+ InfoSection.Write(writer);
+
+ if (writer.EnableRelocation && InfoSection.Relocations.Count > 0)
{
- writer.Stream = elfContext.GetOrCreateInfoSection().Stream;
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = InfoSection;
- InfoSection.Relocations.Clear();
- InfoSection.WriteInternal(writer);
-
- if (writer.EnableRelocation && InfoSection.Relocations.Count > 0)
- {
- InfoSection.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocInfoSection());
- }
- else
- {
- elfContext.RemoveRelocInfoSection();
- }
+ InfoSection.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocInfoSection());
}
else
{
- elfContext.RemoveInfoSection();
+ elfContext.RemoveRelocInfoSection();
}
+ }
+ else
+ {
+ elfContext.RemoveInfoSection();
+ }
- // LocationSection
- if (LocationSection.Size > 0)
+ // LocationSection
+ if (LocationSection.Size > 0)
+ {
+ writer.Stream = elfContext.GetOrCreateLocationSection().Stream!;
+ writer.Stream.Position = 0;
+ writer.Stream.SetLength(0);
+ writer.CurrentSection = LocationSection;
+ LocationSection.Relocations.Clear();
+ LocationSection.Write(writer);
+
+ if (writer.EnableRelocation && LocationSection.Relocations.Count > 0)
{
- writer.Stream = elfContext.GetOrCreateLocationSection().Stream;
- writer.Stream.Position = 0;
- writer.Stream.SetLength(0);
- writer.CurrentSection = LocationSection;
- LocationSection.Relocations.Clear();
- LocationSection.WriteInternal(writer);
-
- if (writer.EnableRelocation && LocationSection.Relocations.Count > 0)
- {
- LocationSection.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocLocationSection());
- }
- else
- {
- elfContext.RemoveRelocLocationSection();
- }
+ LocationSection.CopyRelocationsTo(elfContext, elfContext.GetOrCreateRelocLocationSection());
}
else
{
- elfContext.RemoveLocationSection();
+ elfContext.RemoveRelocLocationSection();
}
-
- CheckErrors(diagnostics);
}
-
- public static DwarfFile Read(DwarfReaderContext readerContext)
+ else
{
- if (readerContext == null) throw new ArgumentNullException(nameof(readerContext));
+ elfContext.RemoveLocationSection();
+ }
+
+ CheckErrors(diagnostics);
+ }
- var dwarf = new DwarfFile();
- var reader = new DwarfReader(readerContext, dwarf, new DiagnosticBag());
+ public static DwarfFile Read(DwarfReaderContext readerContext)
+ {
+ if (readerContext == null) throw new ArgumentNullException(nameof(readerContext));
+
+ var dwarf = new DwarfFile();
+ var reader = new DwarfReader(readerContext, dwarf, new DiagnosticBag());
- reader.Log = null;
+ reader.DebugLog = null;
+ if (readerContext.DebugAbbrevStream != null)
+ {
reader.Stream = readerContext.DebugAbbrevStream;
- if (reader.Stream != null)
- {
- reader.CurrentSection = dwarf.AbbreviationTable;
- dwarf.AbbreviationTable.ReadInternal(reader);
- }
+ reader.CurrentSection = dwarf.AbbreviationTable;
+ dwarf.AbbreviationTable.Read(reader);
+ }
+ if (readerContext.DebugStringStream != null)
+ {
reader.Stream = readerContext.DebugStringStream;
- if (reader.Stream != null)
- {
- reader.CurrentSection = dwarf.StringTable;
- dwarf.StringTable.ReadInternal(reader);
- }
+ reader.CurrentSection = dwarf.StringTable;
+ dwarf.StringTable.Read(reader);
+ }
- reader.Log = readerContext.DebugLinePrinter;
+ reader.DebugLog = readerContext.DebugLinePrinter;
+ if (readerContext.DebugLineStream != null)
+ {
reader.Stream = readerContext.DebugLineStream;
- if (reader.Stream != null)
- {
- reader.CurrentSection = dwarf.LineSection;
- dwarf.LineSection.ReadInternal(reader);
- }
+ reader.CurrentSection = dwarf.LineSection;
+ dwarf.LineSection.Read(reader);
+ }
+ reader.DebugLog = null;
- reader.Log = null;
+ if (readerContext.DebugAddressRangeStream != null)
+ {
reader.Stream = readerContext.DebugAddressRangeStream;
- if (reader.Stream != null)
- {
- reader.CurrentSection = dwarf.AddressRangeTable;
- dwarf.AddressRangeTable.ReadInternal(reader);
- }
+ reader.CurrentSection = dwarf.AddressRangeTable;
+ dwarf.AddressRangeTable.Read(reader);
+ }
- reader.Log = null;
+ reader.DebugLog = null;
+ if (readerContext.DebugLocationStream != null)
+ {
reader.Stream = readerContext.DebugLocationStream;
- if (reader.Stream != null)
- {
- reader.CurrentSection = dwarf.LocationSection;
- dwarf.LocationSection.ReadInternal(reader);
- }
+ reader.CurrentSection = dwarf.LocationSection;
+ dwarf.LocationSection.Read(reader);
+ }
- reader.Log = null;
+ reader.DebugLog = null;
+ if (readerContext.DebugInfoStream != null)
+ {
reader.Stream = readerContext.DebugInfoStream;
- if (reader.Stream != null)
- {
- reader.DefaultUnitKind = DwarfUnitKind.Compile;
- reader.CurrentSection = dwarf.InfoSection;
- dwarf.InfoSection.ReadInternal(reader);
- }
+ reader.DefaultUnitKind = DwarfUnitKind.Compile;
+ reader.CurrentSection = dwarf.InfoSection;
+ dwarf.InfoSection.Read(reader);
+ }
- CheckErrors(reader.Diagnostics);
+ CheckErrors(reader.Diagnostics);
- return dwarf;
- }
+ return dwarf;
+ }
- public static DwarfFile ReadFromElf(DwarfElfContext elfContext)
- {
- if (elfContext == null) throw new ArgumentNullException(nameof(elfContext));
- return Read(new DwarfReaderContext(elfContext));
- }
+ public static DwarfFile ReadFromElf(DwarfElfContext elfContext)
+ {
+ if (elfContext == null) throw new ArgumentNullException(nameof(elfContext));
+ return Read(new DwarfReaderContext(elfContext));
+ }
- public static DwarfFile ReadFromElf(ElfObjectFile elf)
- {
- return ReadFromElf(new DwarfElfContext(elf));
- }
+ public static DwarfFile ReadFromElf(ElfObjectFile elf)
+ {
+ return ReadFromElf(new DwarfElfContext(elf));
+ }
- private static void CheckErrors(DiagnosticBag diagnostics)
+ private static void CheckErrors(DiagnosticBag diagnostics)
+ {
+ if (diagnostics.HasErrors)
{
- if (diagnostics.HasErrors)
- {
- throw new ObjectFileException("Unexpected errors while verifying and updating the layout", diagnostics);
- }
+ throw new ObjectFileException("Unexpected errors while verifying and updating the layout", diagnostics);
}
+ }
- protected override void UpdateLayout(DwarfLayoutContext layoutContext)
- {
- }
+ protected override void UpdateLayoutCore(DwarfLayoutContext context)
+ {
+ }
- protected override void Write(DwarfWriter writer)
- {
- }
+ public override void Write(DwarfWriter writer)
+ {
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfFileName.cs b/src/LibObjectFile/Dwarf/DwarfFileName.cs
index ece43bc..e7558da 100644
--- a/src/LibObjectFile/Dwarf/DwarfFileName.cs
+++ b/src/LibObjectFile/Dwarf/DwarfFileName.cs
@@ -4,27 +4,30 @@
using System.IO;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public sealed class DwarfFileName
{
- public sealed class DwarfFileName
+ public DwarfFileName(string name)
{
- public string Name { get; set; }
+ Name = name;
+ }
+
+ public string Name { get; }
- public string Directory { get; set; }
+ public string? Directory { get; set; }
- public ulong Time { get; set; }
+ public ulong Time { get; set; }
- public ulong Size { get; set; }
+ public ulong Size { get; set; }
- public override string ToString()
+ public override string ToString()
+ {
+ if (Directory != null)
{
- if (string.IsNullOrEmpty(Name)) return "";
- if (Directory != null)
- {
- return Directory.Contains(Path.AltDirectorySeparatorChar) ? $"{Directory}{Path.AltDirectorySeparatorChar}{Name}" : $"{Directory}{Path.DirectorySeparatorChar}{Name}";
- }
-
- return Name;
+ return Directory.Contains(Path.AltDirectorySeparatorChar) ? $"{Directory}{Path.AltDirectorySeparatorChar}{Name}" : $"{Directory}{Path.DirectorySeparatorChar}{Name}";
}
+
+ return Name;
}
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfHelper.cs b/src/LibObjectFile/Dwarf/DwarfHelper.cs
index daad1a9..0aef1b4 100644
--- a/src/LibObjectFile/Dwarf/DwarfHelper.cs
+++ b/src/LibObjectFile/Dwarf/DwarfHelper.cs
@@ -2,113 +2,112 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-using System.Text;
using System.Numerics;
+using System.Text;
+
+namespace LibObjectFile.Dwarf;
-namespace LibObjectFile.Dwarf
+public static partial class DwarfHelper
{
- public static partial class DwarfHelper
+ public static ulong SizeOfStringUTF8NullTerminated(string? text)
{
- public static ulong SizeOfStringUTF8NullTerminated(string text)
- {
- if (text == null) return 0;
- return (ulong)Encoding.UTF8.GetByteCount(text) + 1;
- }
+ if (text == null) return 0;
+ return (ulong)Encoding.UTF8.GetByteCount(text) + 1;
+ }
- public static uint SizeOfUnitLength(bool is64Bit)
- {
- return is64Bit ? 12U : 4U;
- }
-
- public static uint SizeOfUInt(bool is64Bit)
- {
- return is64Bit ? 8U : 4U;
- }
+ public static uint SizeOfUnitLength(bool is64Bit)
+ {
+ return is64Bit ? 12U : 4U;
+ }
- public static uint SizeOfUInt(DwarfAddressSize addressSize)
- {
- return (uint)(addressSize);
- }
+ public static uint SizeOfUInt(bool is64Bit)
+ {
+ return is64Bit ? 8U : 4U;
+ }
- public static uint SizeOfULEB128(ulong value)
- {
- // bits_to_encode = (data != 0) ? 64 - CLZ(x) : 1 = 64 - CLZ(data | 1)
- // bytes = ceil(bits_to_encode / 7.0); = (6 + bits_to_encode) / 7
- uint x = 6 + 64 - (uint)BitOperations.LeadingZeroCount(value | 1UL);
+ public static uint SizeOfUInt(DwarfAddressSize addressSize)
+ {
+ return (uint)(addressSize);
+ }
- // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
- // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
- return (x * 37) >> 8;
- }
+ public static uint SizeOfULEB128(ulong value)
+ {
+ // bits_to_encode = (data != 0) ? 64 - CLZ(x) : 1 = 64 - CLZ(data | 1)
+ // bytes = ceil(bits_to_encode / 7.0); = (6 + bits_to_encode) / 7
+ uint x = 6 + 64 - (uint)BitOperations.LeadingZeroCount(value | 1UL);
- public static uint SizeOfILEB128(long value)
- {
- // The same as SizeOfULEB128 calculation but we have to account for the sign bit.
- value ^= value >> 63;
- uint x = 1 + 6 + 64 - (uint)BitOperations.LeadingZeroCount((ulong)value | 1UL);
- return (x * 37) >> 8;
- }
+ // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
+ // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
+ return (x * 37) >> 8;
+ }
- public static DwarfAttributeEncoding GetAttributeEncoding(DwarfAttributeKindEx kind)
- {
- if ((uint)kind.Value >= AttributeToEncoding.Length) return DwarfAttributeEncoding.None;
- return AttributeToEncoding[(int) kind.Value];
- }
+ public static uint SizeOfILEB128(long value)
+ {
+ // The same as SizeOfULEB128 calculation but we have to account for the sign bit.
+ value ^= value >> 63;
+ uint x = 1 + 6 + 64 - (uint)BitOperations.LeadingZeroCount((ulong)value | 1UL);
+ return (x * 37) >> 8;
+ }
- private static readonly DwarfAttributeEncoding[] Encodings = new DwarfAttributeEncoding[]
- {
- DwarfAttributeEncoding.None , // 0
- DwarfAttributeEncoding.Address , // DW_FORM_addr 0x01
- DwarfAttributeEncoding.None , // Reserved 0x02
- DwarfAttributeEncoding.Block , // DW_FORM_block2 0x03
- DwarfAttributeEncoding.Block , // DW_FORM_block4 0x04
- DwarfAttributeEncoding.Constant , // DW_FORM_data2 0x05
- DwarfAttributeEncoding.Constant , // DW_FORM_data4 0x06
- DwarfAttributeEncoding.Constant , // DW_FORM_data8 0x07
- DwarfAttributeEncoding.String , // DW_FORM_string 0x08
- DwarfAttributeEncoding.Block , // DW_FORM_block 0x09
- DwarfAttributeEncoding.Block , // DW_FORM_block1 0x0a
- DwarfAttributeEncoding.Constant , // DW_FORM_data1 0x0b
- DwarfAttributeEncoding.Flag , // DW_FORM_flag 0x0c
- DwarfAttributeEncoding.Constant , // DW_FORM_sdata 0x0d
- DwarfAttributeEncoding.String , // DW_FORM_strp 0x0e
- DwarfAttributeEncoding.Constant , // DW_FORM_udata 0x0f
- DwarfAttributeEncoding.Reference , // DW_FORM_ref_addr 0x10
- DwarfAttributeEncoding.Reference , // DW_FORM_ref1 0x11
- DwarfAttributeEncoding.Reference , // DW_FORM_ref2 0x12
- DwarfAttributeEncoding.Reference , // DW_FORM_ref4 0x13
- DwarfAttributeEncoding.Reference , // DW_FORM_ref8 0x14
- DwarfAttributeEncoding.Reference , // DW_FORM_ref_udata 0x15
- DwarfAttributeEncoding.Indirect , // DW_FORM_indirect 0x16
- DwarfAttributeEncoding.AddressPointer |
- DwarfAttributeEncoding.LinePointer |
- DwarfAttributeEncoding.LocationList |
- DwarfAttributeEncoding.LocationListsPointer |
- DwarfAttributeEncoding.MacroPointer |
- DwarfAttributeEncoding.RangeList |
- DwarfAttributeEncoding.RangeListsPointer |
- DwarfAttributeEncoding.StringOffsetPointer, // DW_FORM_sec_offset 0x17
- DwarfAttributeEncoding.ExpressionLocation , // DW_FORM_exprloc 0x18
- DwarfAttributeEncoding.Flag , // DW_FORM_flag_present 0x19
- DwarfAttributeEncoding.String , // DW_FORM_strx 0x1a
- DwarfAttributeEncoding.Address , // DW_FORM_addrx 0x1b
- DwarfAttributeEncoding.Reference , // DW_FORM_ref_sup4 0x1c
- DwarfAttributeEncoding.String , // DW_FORM_strp_sup 0x1d
- DwarfAttributeEncoding.Constant , // DW_FORM_data16 0x1e
- DwarfAttributeEncoding.String , // DW_FORM_line_strp 0x1f
- DwarfAttributeEncoding.Reference , // DW_FORM_ref_sig8 0x20
- DwarfAttributeEncoding.Constant , // DW_FORM_implicit_const 0x21
- DwarfAttributeEncoding.LocationList , // DW_FORM_loclistx 0x22
- DwarfAttributeEncoding.RangeList , // DW_FORM_rnglistx 0x23
- DwarfAttributeEncoding.Reference , // DW_FORM_ref_sup8 0x24
- DwarfAttributeEncoding.String , // DW_FORM_strx1 0x25
- DwarfAttributeEncoding.String , // DW_FORM_strx2 0x26
- DwarfAttributeEncoding.String , // DW_FORM_strx3 0x27
- DwarfAttributeEncoding.String , // DW_FORM_strx4 0x28
- DwarfAttributeEncoding.Address , // DW_FORM_addrx1 0x29
- DwarfAttributeEncoding.Address , // DW_FORM_addrx2 0x2a
- DwarfAttributeEncoding.Address , // DW_FORM_addrx3 0x2b
- DwarfAttributeEncoding.Address , // DW_FORM_addrx4 0x2c
- };
+ public static DwarfAttributeEncoding GetAttributeEncoding(DwarfAttributeKindEx kind)
+ {
+ if ((uint)kind.Value >= AttributeToEncoding.Length) return DwarfAttributeEncoding.None;
+ return AttributeToEncoding[(int) kind.Value];
}
+
+ private static readonly DwarfAttributeEncoding[] Encodings = new DwarfAttributeEncoding[]
+ {
+ DwarfAttributeEncoding.None , // 0
+ DwarfAttributeEncoding.Address , // DW_FORM_addr 0x01
+ DwarfAttributeEncoding.None , // Reserved 0x02
+ DwarfAttributeEncoding.Block , // DW_FORM_block2 0x03
+ DwarfAttributeEncoding.Block , // DW_FORM_block4 0x04
+ DwarfAttributeEncoding.Constant , // DW_FORM_data2 0x05
+ DwarfAttributeEncoding.Constant , // DW_FORM_data4 0x06
+ DwarfAttributeEncoding.Constant , // DW_FORM_data8 0x07
+ DwarfAttributeEncoding.String , // DW_FORM_string 0x08
+ DwarfAttributeEncoding.Block , // DW_FORM_block 0x09
+ DwarfAttributeEncoding.Block , // DW_FORM_block1 0x0a
+ DwarfAttributeEncoding.Constant , // DW_FORM_data1 0x0b
+ DwarfAttributeEncoding.Flag , // DW_FORM_flag 0x0c
+ DwarfAttributeEncoding.Constant , // DW_FORM_sdata 0x0d
+ DwarfAttributeEncoding.String , // DW_FORM_strp 0x0e
+ DwarfAttributeEncoding.Constant , // DW_FORM_udata 0x0f
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref_addr 0x10
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref1 0x11
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref2 0x12
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref4 0x13
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref8 0x14
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref_udata 0x15
+ DwarfAttributeEncoding.Indirect , // DW_FORM_indirect 0x16
+ DwarfAttributeEncoding.AddressPointer |
+ DwarfAttributeEncoding.LinePointer |
+ DwarfAttributeEncoding.LocationList |
+ DwarfAttributeEncoding.LocationListsPointer |
+ DwarfAttributeEncoding.MacroPointer |
+ DwarfAttributeEncoding.RangeList |
+ DwarfAttributeEncoding.RangeListsPointer |
+ DwarfAttributeEncoding.StringOffsetPointer, // DW_FORM_sec_offset 0x17
+ DwarfAttributeEncoding.ExpressionLocation , // DW_FORM_exprloc 0x18
+ DwarfAttributeEncoding.Flag , // DW_FORM_flag_present 0x19
+ DwarfAttributeEncoding.String , // DW_FORM_strx 0x1a
+ DwarfAttributeEncoding.Address , // DW_FORM_addrx 0x1b
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref_sup4 0x1c
+ DwarfAttributeEncoding.String , // DW_FORM_strp_sup 0x1d
+ DwarfAttributeEncoding.Constant , // DW_FORM_data16 0x1e
+ DwarfAttributeEncoding.String , // DW_FORM_line_strp 0x1f
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref_sig8 0x20
+ DwarfAttributeEncoding.Constant , // DW_FORM_implicit_const 0x21
+ DwarfAttributeEncoding.LocationList , // DW_FORM_loclistx 0x22
+ DwarfAttributeEncoding.RangeList , // DW_FORM_rnglistx 0x23
+ DwarfAttributeEncoding.Reference , // DW_FORM_ref_sup8 0x24
+ DwarfAttributeEncoding.String , // DW_FORM_strx1 0x25
+ DwarfAttributeEncoding.String , // DW_FORM_strx2 0x26
+ DwarfAttributeEncoding.String , // DW_FORM_strx3 0x27
+ DwarfAttributeEncoding.String , // DW_FORM_strx4 0x28
+ DwarfAttributeEncoding.Address , // DW_FORM_addrx1 0x29
+ DwarfAttributeEncoding.Address , // DW_FORM_addrx2 0x2a
+ DwarfAttributeEncoding.Address , // DW_FORM_addrx3 0x2b
+ DwarfAttributeEncoding.Address , // DW_FORM_addrx4 0x2c
+ };
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfIdentifierCaseKind.cs b/src/LibObjectFile/Dwarf/DwarfIdentifierCaseKind.cs
index 5358d88..1c61d00 100644
--- a/src/LibObjectFile/Dwarf/DwarfIdentifierCaseKind.cs
+++ b/src/LibObjectFile/Dwarf/DwarfIdentifierCaseKind.cs
@@ -2,16 +2,15 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public enum DwarfIdentifierCaseKind : byte
{
- public enum DwarfIdentifierCaseKind : byte
- {
- Sensitive = DwarfNative.DW_ID_case_sensitive,
+ Sensitive = DwarfNative.DW_ID_case_sensitive,
- UpCase = DwarfNative.DW_ID_up_case,
+ UpCase = DwarfNative.DW_ID_up_case,
- DownCase = DwarfNative.DW_ID_down_case,
+ DownCase = DwarfNative.DW_ID_down_case,
- Insensitive = DwarfNative.DW_ID_case_insensitive,
- }
+ Insensitive = DwarfNative.DW_ID_case_insensitive,
}
\ No newline at end of file
diff --git a/src/LibObjectFile/Dwarf/DwarfInfoSection.cs b/src/LibObjectFile/Dwarf/DwarfInfoSection.cs
index 5f727a1..2cc0b75 100644
--- a/src/LibObjectFile/Dwarf/DwarfInfoSection.cs
+++ b/src/LibObjectFile/Dwarf/DwarfInfoSection.cs
@@ -1,105 +1,88 @@
-// Copyright (c) Alexandre Mutel. All rights reserved.
+// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System.Collections.Generic;
using System.Diagnostics;
+using LibObjectFile.Collections;
-namespace LibObjectFile.Dwarf
+namespace LibObjectFile.Dwarf;
+
+public sealed class DwarfInfoSection : DwarfRelocatableSection
{
- public sealed class DwarfInfoSection : DwarfRelocatableSection
- {
- private readonly List _units;
+ private readonly ObjectList