[llvm] 945df8b - [obj2yaml][XCOFF] Dump sections
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 14 22:17:08 PDT 2021
Author: Esme-Yi
Date: 2021-09-15T05:16:33Z
New Revision: 945df8bc4cf3c72a9721431ec490e2f196be170e
URL: https://github.com/llvm/llvm-project/commit/945df8bc4cf3c72a9721431ec490e2f196be170e
DIFF: https://github.com/llvm/llvm-project/commit/945df8bc4cf3c72a9721431ec490e2f196be170e.diff
LOG: [obj2yaml][XCOFF] Dump sections
Summary: This patch implements parsing sections for obj2yaml on AIX.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D98003
Added:
llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml
llvm/test/tools/obj2yaml/XCOFF/invalid-symbol.yaml
Modified:
llvm/test/tools/obj2yaml/XCOFF/aix.yaml
llvm/tools/obj2yaml/xcoff2yaml.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
index a67a52b5ac007..f49d981aaf010 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
@@ -1,80 +1,147 @@
-# RUN: obj2yaml %S/Inputs/aix_xcoff.o | FileCheck %s
-# Test that we can parse the XCOFF object file correctly.
-# CHECK: --- !XCOFF
-# CHECK-NEXT: FileHeader:
-# CHECK-NEXT: MagicNumber: 0x1DF
-# CHECK-NEXT: NumberOfSections: 2
-# CHECK-NEXT: CreationTime: 1552337792
-# CHECK-NEXT: OffsetToSymbolTable: 0x13A
-# CHECK-NEXT: EntriesInSymbolTable: 22
-# CHECK-NEXT: AuxiliaryHeaderSize: 0
-# CHECK-NEXT: Flags: 0x0
+## This is a basic test to check if we can parse the XCOFF object file correctly.
+# RUN: yaml2obj %s -DMAGIC=0x01DF -o %t-32
+# RUN: obj2yaml %t-32 | FileCheck %s --check-prefix=CHECK32
+# RUN: yaml2obj %s -DMAGIC=0x01F7 -o %t-64
+# RUN: obj2yaml %t-64 | FileCheck %s --check-prefix=CHECK64
-# CHECK: Symbols:
-# CHECK-NEXT: - Name: .file
-# CHECK-NEXT: Value: 0x0
-# CHECK-NEXT: Section: N_DEBUG
-# CHECK-NEXT: Type: 0x3
-# CHECK-NEXT: StorageClass: C_FILE
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: i
-# CHECK-NEXT: Value: 0x0
-# CHECK-NEXT: Section: N_UNDEF
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_EXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: TestforXcoff
-# CHECK-NEXT: Value: 0x0
-# CHECK-NEXT: Section: N_UNDEF
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_EXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: .text
-# CHECK-NEXT: Value: 0x0
-# CHECK-NEXT: Section: .text
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_HIDEXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: .main
-# CHECK-NEXT: Value: 0x0
-# CHECK-NEXT: Section: .text
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_EXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: main
-# CHECK-NEXT: Value: 0x60
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_HIDEXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: main
-# CHECK-NEXT: Value: 0x60
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_EXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: .data
-# CHECK-NEXT: Value: 0x70
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_HIDEXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: TOC
-# CHECK-NEXT: Value: 0x74
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_HIDEXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: i
-# CHECK-NEXT: Value: 0x74
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_HIDEXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-# CHECK-NEXT: - Name: TestforXcoff
-# CHECK-NEXT: Value: 0x78
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: Type: 0x0
-# CHECK-NEXT: StorageClass: C_HIDEXT
-# CHECK-NEXT: NumberOfAuxEntries: 1
-## TODO: Dump the string table.
+# CHECK32: --- !XCOFF
+# CHECK32-NEXT: FileHeader:
+# CHECK32-NEXT: MagicNumber: 0x1DF
+# CHECK32-NEXT: NumberOfSections: 2
+# CHECK32-NEXT: CreationTime: 0
+# CHECK32-NEXT: OffsetToSymbolTable: 0x80
+# CHECK32-NEXT: EntriesInSymbolTable: 4
+# CHECK32-NEXT: AuxiliaryHeaderSize: 0
+# CHECK32-NEXT: Flags: 0x0
+# CHECK32-NEXT: Sections:
+# CHECK32-NEXT: - Name: .text
+# CHECK32-NEXT: Address: 0x0
+# CHECK32-NEXT: Size: 0x4
+# CHECK32-NEXT: FileOffsetToData: 0x64
+# CHECK32-NEXT: FileOffsetToRelocations: 0x6C
+# CHECK32-NEXT: FileOffsetToLineNumbers: 0x0
+# CHECK32-NEXT: NumberOfRelocations: 0x1
+# CHECK32-NEXT: NumberOfLineNumbers: 0x0
+# CHECK32-NEXT: Flags: [ STYP_TEXT ]
+# CHECK32-NEXT: SectionData: '00007400'
+# CHECK32-NEXT: Relocations:
+# CHECK32-NEXT: - Address: 0xE
+# CHECK32-NEXT: Symbol: 0x12
+# CHECK32-NEXT: Info: 0xF
+# CHECK32-NEXT: Type: 0x3
+# CHECK32-NEXT: - Name: .data
+# CHECK32-NEXT: Address: 0x4
+# CHECK32-NEXT: Size: 0x4
+# CHECK32-NEXT: FileOffsetToData: 0x68
+# CHECK32-NEXT: FileOffsetToRelocations: 0x76
+# CHECK32-NEXT: FileOffsetToLineNumbers: 0x0
+# CHECK32-NEXT: NumberOfRelocations: 0x1
+# CHECK32-NEXT: NumberOfLineNumbers: 0x0
+# CHECK32-NEXT: Flags: [ STYP_DATA ]
+# CHECK32-NEXT: SectionData: '00007700'
+# CHECK32-NEXT: Relocations:
+# CHECK32-NEXT: - Address: 0x60
+# CHECK32-NEXT: Symbol: 0x8
+# CHECK32-NEXT: Info: 0x1F
+# CHECK32-NEXT: Type: 0x0
+# CHECK32-NEXT: Symbols:
+# CHECK32-NEXT: - Name: TestforXcoff
+# CHECK32-NEXT: Value: 0x0
+# CHECK32-NEXT: Section: N_UNDEF
+# CHECK32-NEXT: Type: 0x0
+# CHECK32-NEXT: StorageClass: C_EXT
+# CHECK32-NEXT: NumberOfAuxEntries: 1
+# CHECK32-NEXT: - Name: .data
+# CHECK32-NEXT: Value: 0x70
+# CHECK32-NEXT: Section: .data
+# CHECK32-NEXT: Type: 0x0
+# CHECK32-NEXT: StorageClass: C_HIDEXT
+# CHECK32-NEXT: NumberOfAuxEntries: 1
+
+# CHECK64: --- !XCOFF
+# CHECK64-NEXT: FileHeader:
+# CHECK64-NEXT: MagicNumber: 0x1F7
+# CHECK64-NEXT: NumberOfSections: 2
+# CHECK64-NEXT: CreationTime: 0
+# CHECK64-NEXT: OffsetToSymbolTable: 0xCC
+# CHECK64-NEXT: EntriesInSymbolTable: 4
+# CHECK64-NEXT: AuxiliaryHeaderSize: 0
+# CHECK64-NEXT: Flags: 0x0
+# CHECK64-NEXT: Sections:
+# CHECK64-NEXT: - Name: .text
+# CHECK64-NEXT: Address: 0x0
+# CHECK64-NEXT: Size: 0x4
+# CHECK64-NEXT: FileOffsetToData: 0xA8
+# CHECK64-NEXT: FileOffsetToRelocations: 0xB0
+# CHECK64-NEXT: FileOffsetToLineNumbers: 0x0
+# CHECK64-NEXT: NumberOfRelocations: 0x1
+# CHECK64-NEXT: NumberOfLineNumbers: 0x0
+# CHECK64-NEXT: Flags: [ STYP_TEXT ]
+# CHECK64-NEXT: SectionData: '00007400'
+# CHECK64-NEXT: Relocations:
+# CHECK64-NEXT: - Address: 0xE
+# CHECK64-NEXT: Symbol: 0x12
+# CHECK64-NEXT: Info: 0xF
+# CHECK64-NEXT: Type: 0x3
+# CHECK64-NEXT: - Name: .data
+# CHECK64-NEXT: Address: 0x4
+# CHECK64-NEXT: Size: 0x4
+# CHECK64-NEXT: FileOffsetToData: 0xAC
+# CHECK64-NEXT: FileOffsetToRelocations: 0xBE
+# CHECK64-NEXT: FileOffsetToLineNumbers: 0x0
+# CHECK64-NEXT: NumberOfRelocations: 0x1
+# CHECK64-NEXT: NumberOfLineNumbers: 0x0
+# CHECK64-NEXT: Flags: [ STYP_DATA ]
+# CHECK64-NEXT: SectionData: '00007700'
+# CHECK64-NEXT: Relocations:
+# CHECK64-NEXT: - Address: 0x60
+# CHECK64-NEXT: Symbol: 0x8
+# CHECK64-NEXT: Info: 0x1F
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: Symbols:
+# CHECK64-NEXT: - Name: TestforXcoff
+# CHECK64-NEXT: Value: 0x0
+# CHECK64-NEXT: Section: N_UNDEF
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: StorageClass: C_EXT
+# CHECK64-NEXT: NumberOfAuxEntries: 1
+# CHECK64-NEXT: - Name: .data
+# CHECK64-NEXT: Value: 0x70
+# CHECK64-NEXT: Section: .data
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: StorageClass: C_HIDEXT
+# CHECK64-NEXT: NumberOfAuxEntries: 1
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: [[MAGIC]]
+Sections:
+ - Name: .text
+ Flags: [ STYP_TEXT ]
+ SectionData: '00007400'
+ Relocations:
+ - Address: 0xE
+ Symbol: 0x12
+ Info: 0xF
+ Type: 0x3
+ - Name: .data
+ Flags: [ STYP_DATA ]
+ SectionData: '00007700'
+ Relocations:
+ - Address: 0x60
+ Symbol: 0x8
+ Info: 0x1F
+ Type: 0x0
+Symbols:
+ - Name: TestforXcoff
+ Value: 0x0
+ Section: N_UNDEF
+ Type: 0x0
+ StorageClass: C_EXT
+ NumberOfAuxEntries: 1
+ - Name: .data
+ Value: 0x70
+ Section: .data
+ Type: 0x0
+ StorageClass: C_HIDEXT
+ NumberOfAuxEntries: 1
diff --git a/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml b/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml
new file mode 100644
index 0000000000000..81c02b2208959
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml
@@ -0,0 +1,32 @@
+## Check that obj2yaml reports a suitable error when it encounters
+## invalid content in Section.
+
+## Error1: failed to get section data.
+# RUN: yaml2obj %s --docnum=1 -o %t1
+# RUN: not obj2yaml %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=ERROR1
+
+# ERROR1: The end of the file was unexpectedly encountered
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01DF
+Sections:
+ - SectionData: '00007400'
+ FileOffsetToData: 0x70
+
+## Error2: failed to get relocations.
+# RUN: yaml2obj %s --docnum=2 -o %t2
+# RUN: not obj2yaml %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=ERROR2
+
+# ERROR2: The end of the file was unexpectedly encountered
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01DF
+Sections:
+ - NumberOfRelocations: 0x3
+ Relocations:
+ - Address: 0xE
+ Symbol: 0x12
+ Info: 0xF
+ Type: 0x3
diff --git a/llvm/test/tools/obj2yaml/XCOFF/invalid-symbol.yaml b/llvm/test/tools/obj2yaml/XCOFF/invalid-symbol.yaml
new file mode 100644
index 0000000000000..6a243797770cb
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/XCOFF/invalid-symbol.yaml
@@ -0,0 +1,30 @@
+## Check that obj2yaml reports a suitable error when it encounters
+## invalid content in Symbol.
+
+## Error1: failed to get the section name for a symbol.
+# RUN: yaml2obj %s --docnum=1 -o %t1
+# RUN: not obj2yaml %t1 2>&1 | FileCheck %s --check-prefix=ERROR1
+
+# ERROR1: Invalid section index
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01DF
+Sections:
+ - Name: .text
+Symbols:
+ - SectionIndex: 2
+
+## Error2: failed to get the symbol name.
+# RUN: yaml2obj %s --docnum=2 -o %t2
+# RUN: not obj2yaml %t2 2>&1 | FileCheck %s --check-prefix=ERROR2
+
+# ERROR2: Invalid data was encountered while parsing the file
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01DF
+Symbols:
+ - Name: nameInStrTbl
+StringTable:
+ Length: 0
diff --git a/llvm/tools/obj2yaml/xcoff2yaml.cpp b/llvm/tools/obj2yaml/xcoff2yaml.cpp
index 0309856556baf..5f3b580c645a5 100644
--- a/llvm/tools/obj2yaml/xcoff2yaml.cpp
+++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp
@@ -9,6 +9,7 @@
#include "obj2yaml.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/ObjectYAML/XCOFFYAML.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
@@ -19,38 +20,93 @@ class XCOFFDumper {
const object::XCOFFObjectFile &Obj;
XCOFFYAML::Object YAMLObj;
void dumpHeader();
- std::error_code dumpSymbols();
+ Error dumpSections();
+ Error dumpSymbols();
+ template <typename Shdr, typename Reloc>
+ Error dumpSections(ArrayRef<Shdr> Sections);
public:
XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
- std::error_code dump();
+ Error dump();
XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
};
} // namespace
-std::error_code XCOFFDumper::dump() {
+Error XCOFFDumper::dump() {
dumpHeader();
+ if (Error E = dumpSections())
+ return E;
return dumpSymbols();
}
void XCOFFDumper::dumpHeader() {
-
YAMLObj.Header.Magic = Obj.getMagic();
YAMLObj.Header.NumberOfSections = Obj.getNumberOfSections();
YAMLObj.Header.TimeStamp = Obj.getTimeStamp();
-
- // TODO FIXME only dump 32 bit header for now.
- if (Obj.is64Bit())
- report_fatal_error("64-bit XCOFF files not supported yet.");
- YAMLObj.Header.SymbolTableOffset = Obj.getSymbolTableOffset32();
-
+ YAMLObj.Header.SymbolTableOffset = Obj.is64Bit()
+ ? Obj.getSymbolTableOffset64()
+ : Obj.getSymbolTableOffset32();
YAMLObj.Header.NumberOfSymTableEntries =
- Obj.getRawNumberOfSymbolTableEntries32();
+ Obj.is64Bit() ? Obj.getNumberOfSymbolTableEntries64()
+ : Obj.getRawNumberOfSymbolTableEntries32();
YAMLObj.Header.AuxHeaderSize = Obj.getOptionalHeaderSize();
YAMLObj.Header.Flags = Obj.getFlags();
}
-std::error_code XCOFFDumper::dumpSymbols() {
+Error XCOFFDumper::dumpSections() {
+ if (Obj.is64Bit())
+ return dumpSections<XCOFFSectionHeader64, XCOFFRelocation64>(
+ Obj.sections64());
+ return dumpSections<XCOFFSectionHeader32, XCOFFRelocation32>(
+ Obj.sections32());
+}
+
+template <typename Shdr, typename Reloc>
+Error XCOFFDumper::dumpSections(ArrayRef<Shdr> Sections) {
+ std::vector<XCOFFYAML::Section> &YamlSections = YAMLObj.Sections;
+ for (const Shdr &S : Sections) {
+ XCOFFYAML::Section YamlSec;
+ YamlSec.SectionName = S.getName();
+ YamlSec.Address = S.PhysicalAddress;
+ YamlSec.Size = S.SectionSize;
+ YamlSec.NumberOfRelocations = S.NumberOfRelocations;
+ YamlSec.NumberOfLineNumbers = S.NumberOfLineNumbers;
+ YamlSec.FileOffsetToData = S.FileOffsetToRawData;
+ YamlSec.FileOffsetToRelocations = S.FileOffsetToRelocationInfo;
+ YamlSec.FileOffsetToLineNumbers = S.FileOffsetToLineNumberInfo;
+ YamlSec.Flags = S.Flags;
+
+ // Dump section data.
+ if (S.FileOffsetToRawData) {
+ DataRefImpl SectionDRI;
+ SectionDRI.p = reinterpret_cast<uintptr_t>(&S);
+ Expected<ArrayRef<uint8_t>> SecDataRefOrErr =
+ Obj.getSectionContents(SectionDRI);
+ if (!SecDataRefOrErr)
+ return SecDataRefOrErr.takeError();
+ YamlSec.SectionData = SecDataRefOrErr.get();
+ }
+
+ // Dump relocations.
+ if (S.NumberOfRelocations) {
+ auto RelRefOrErr = Obj.relocations<Shdr, Reloc>(S);
+ if (!RelRefOrErr)
+ return RelRefOrErr.takeError();
+ for (const Reloc &R : RelRefOrErr.get()) {
+ XCOFFYAML::Relocation YamlRel;
+ YamlRel.Type = R.Type;
+ YamlRel.Info = R.Info;
+ YamlRel.SymbolIndex = R.SymbolIndex;
+ YamlRel.VirtualAddress = R.VirtualAddress;
+ YamlSec.Relocations.push_back(YamlRel);
+ }
+ }
+ YamlSections.push_back(YamlSec);
+ }
+ return Error::success();
+}
+
+Error XCOFFDumper::dumpSymbols() {
std::vector<XCOFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
for (const SymbolRef &S : Obj.symbols()) {
@@ -60,7 +116,7 @@ std::error_code XCOFFDumper::dumpSymbols() {
Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
if (!SymNameRefOrErr) {
- return errorToErrorCode(SymNameRefOrErr.takeError());
+ return SymNameRefOrErr.takeError();
}
Sym.SymbolName = SymNameRefOrErr.get();
@@ -69,7 +125,7 @@ std::error_code XCOFFDumper::dumpSymbols() {
Expected<StringRef> SectionNameRefOrErr =
Obj.getSymbolSectionName(SymbolEntRef);
if (!SectionNameRefOrErr)
- return errorToErrorCode(SectionNameRefOrErr.takeError());
+ return SectionNameRefOrErr.takeError();
Sym.SectionName = SectionNameRefOrErr.get();
@@ -79,15 +135,15 @@ std::error_code XCOFFDumper::dumpSymbols() {
Symbols.push_back(Sym);
}
- return std::error_code();
+ return Error::success();
}
std::error_code xcoff2yaml(raw_ostream &Out,
const object::XCOFFObjectFile &Obj) {
XCOFFDumper Dumper(Obj);
- if (std::error_code EC = Dumper.dump())
- return EC;
+ if (Error E = Dumper.dump())
+ return errorToErrorCode(std::move(E));
yaml::Output Yout(Out);
Yout << Dumper.getYAMLObj();
More information about the llvm-commits
mailing list