This is an archive of the discontinued LLVM Phabricator instance.

[Object][XCOFF] Add support for 64-bit file header and section header dumping.
ClosedPublic

Authored by sfertile on Jun 26 2019, 2:04 PM.

Details

Summary

Adds a readobj dumper for 32-bit and 64-bit section header tables, and extend support for the file-header dumping to include 64-bit object files.

Diff Detail

Event Timeline

sfertile created this revision.Jun 26 2019, 2:04 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 26 2019, 2:04 PM
DiggerLin added inline comments.Jun 27 2019, 2:15 PM
llvm/include/llvm/Object/XCOFFObjectFile.h
240–244

I prefer to keep as uint16_t getFlags() const { return FileHdrPtr->Flags; };

llvm/lib/Object/XCOFFObjectFile.cpp
126

there are assert(!is64Bit() && "Symbol table support not implemented for 64-bit."); in the toSymbolEntry() , I do not think we need assert(!is64Bit() && "Symbol table support not implemented for 64-bit."); here.

132

ditto

182

ditto

482

it looks the flag as

support::big32_t Flags

in the XCOFFObjectFile.h

uint32_t XCOFFObjectFile::getSectionFlags(DataRefImpl Sec) const
should be int32_t XCOFFObjectFile::getSectionFlags(DataRefImpl Sec) const

496

if is64Bit(). it should return here.

llvm/tools/llvm-readobj/XCOFFDumper.cpp
145

do you want to try to use W.printEnum to output Sec.Flags, it will be more readable

148

do we need to print relocation here ?

151

ditto

154

ditto

MaskRay added inline comments.Jun 27 2019, 9:38 PM
llvm/lib/Object/XCOFFObjectFile.cpp
49

getWithOffset does not seem useful: it just does a plus operation.

67

You may use Offset >= getSectionHeaderSize() * getNumberOfSections() instead.

84

I think inline reinterpret_cast may be clearer, then the viewAs helper can be deleted.

129

return; is redundant.

359–378

Consider making XCOFFObjectFile a class template.

See ELFObjectFile<ELFT> as an example, then you may avoid various is64Bit() dispatching in this file.

473

warning: using the result of an assignment as a condition without parentheses [-Wparentheses]

I remember I said in the initial check-in of this file: lib/Object code is moving away from std::error_code, ErrorOr and errorCodeToError. Error Expected etc should be used instead.

sfertile marked 9 inline comments as done.Jun 28 2019, 5:49 AM
sfertile added inline comments.
llvm/include/llvm/Object/XCOFFObjectFile.h
240–244

We can't because of the underlying type depends on if its a 64-bit object or a 32-bit object, do you mean you would prefer if

return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;

was inline here?

llvm/lib/Object/XCOFFObjectFile.cpp
126

In the spirit of trying to keep this patch to a minimum I only implemented section headers and file-header support. I put defensive assert to indicate that I hadn't evaluated any of the symbol related interfaces for 64-bit. While this would technically work for 64-bit, that is only because the 64-bit symbol table entrey happens to also be 18 bytes of data. Casting a 64-bit symbol table entry to an XCOFFSymbolEntry is still wrong as they have different layouts.

132

Again, the 64-bit and 32-bit symbol table entries have different layouts, this function AFAICT would not work for a 64-bit Symbol table entry. (Its String table offset member is at offset 8 instead of offset 4).

482

Good catch, updated.

496

is64Bit() has already returned on line 495.

llvm/tools/llvm-readobj/XCOFFDumper.cpp
145

Updated, thats a good suggestion.

148

When that is supported, yes.

151

Yep, once dumping symbols from objdump is supported.

154

same.

sfertile updated this revision to Diff 207046.Jun 28 2019, 5:55 AM

Addressed first round of review comments.

  • Fix getSectionFlags return value to be signed.
  • Print the section flags as its symbolic value.
llvm/lib/Object/XCOFFObjectFile.cpp
49

The function helps the code be more self-documenting about the intended semantics and is much more greppable than raw arithmetic. This allows pointer arithmetic to be properly performed in pointer space. Although not all such arithmetic is done in pointer space currently, that does not mean that we shouldn't keep the instances where they are.

84

The viewAs helper is not new to this patch. Additionally, it saves on verbosity and noise that is distracting. Familiarity with viewAs is not difficult to attain.

DiggerLin marked an inline comment as done.Jun 28 2019, 7:07 AM
DiggerLin added inline comments.
llvm/lib/Object/XCOFFObjectFile.cpp
496

thanks.

sfertile updated this revision to Diff 207069.Jun 28 2019, 8:15 AM

Address further comments:

  • Simplified the address checking in 'checkSectionAddress'
  • Removed unneeded asserts. As Digger pointed out, an symbol related function that casts a DataRefImpl.p to a symbol table entry already asserts in toSymbolEntry.

Still outstanding: cleaning up of the error handling in the constructor.

sfertile marked 8 inline comments as done and an inline comment as not done.Jun 28 2019, 8:20 AM
sfertile added inline comments.
llvm/lib/Object/XCOFFObjectFile.cpp
126

Sorry Digger you are correct, I don't need to add an assert in any of the interfaces that cast a DataRefImpl to a SymbolEntry as the helper fucntion asserts. Updated.

473

Attempting to clean this up next.

sfertile updated this revision to Diff 207142.Jun 28 2019, 2:08 PM

Converted the way parsing the binary is done to not need an error_code out argument in the constructor. Creates a bare bones object file, then attempts to parse the expected structures out of the memory buffer. Trying to match the style ELF used.

llvm/include/llvm/Object/XCOFFObjectFile.h
162

Typo: "Constuctor [sic]".

Suggestion:
Constructor and "create" factory function. The constructor is only a thin wrapper around the base constructor. The "create" function fills out the XCOFF-specific information and performs the error checking along the way.

168

I would suggest adding an empty line before this comment block. Also, break the sentence just before "returns" (where the comma is).

173

s/freind/friend/;

211

If the extra empty line is meant to signify that the interface functions below are not inherited from a base class, then perhaps a comment would work better.

213

This is a public function, so there should be an assertion regarding use when is64Bit() is true.

234

Add an empty line before this. Also, missing "as" before "an index".

llvm/lib/Object/XCOFFObjectFile.cpp
200–201

Remove the space before the return type.

399

What does SI mean?

507

Use either "string table's size" or "string-table size".
Typo: s/as string/a string/;

This patch seems to have suffered from scope creep. The replacement of error_code has led to a considerable shifting around of the code that makes it more difficult to review the other part of the patch. Since it has already happened, I guess we will push through; however, I believe this sort of situation should be avoided.

llvm/lib/Object/XCOFFObjectFile.cpp
508

Just practising my theoretical-overflow avoidance:

assert(Obj->Data.getBufferSize() >= Offset);
if (Obj->Data.getBufferSize() - Offset < 4)

Or use a helper function:

if (auto EC = Binary::checkOffset(Obj->Data, Offset, 4))
513

Use getObject.

518

s/StingTablePtr/StringTablePtr/g;

llvm/lib/Object/XCOFFObjectFile.cpp
532

const auto *Base.

533

MemoryBufferRef Data.

547

s/Pase/Parse/;

Suggestion:
Parse the section header table if it is present.

547

The XCOFFObjectFile constructor will assert as appropriate without this assert here.

llvm/tools/llvm-readobj/XCOFFDumper.cpp
154

STYP_OVRFLO/_OVERFLOW_MARKER handling TODO here.

160

Please test STYP_DWARF. It looks like the handling of DWARF section subtypes is missing. At the least, Sec.Flags & 0xffU might help.

164

These should be report_fatal_error.

llvm/tools/obj2yaml/xcoff2yaml.cpp
44

s/suported/supported/;

sfertile updated this revision to Diff 208078.Jul 4 2019, 1:47 PM
  • Lots of tweaks to comments and whitespace.
    • Added assertion to 'getPointerToSymbolTable`
    • Changed name of local variable in getSymbolSectionName to be more descriptive.
    • Use checkOffset and getObject'in parseStringTable.
    • Changed unreachables to report_fatal_error in 'printSectionHeaders`.
    • Added TODO where overflow checking eventually needs to be done.
    • Added comment about DWARF subsection types, & limited section flag printing to the section type flags.
sfertile marked 22 inline comments as done.Jul 4 2019, 1:53 PM
sfertile added inline comments.
llvm/include/llvm/Object/XCOFFObjectFile.h
162

Updated with suggested comment.

llvm/lib/Object/XCOFFObjectFile.cpp
399

No idea :S. Updated to a more appropriate name.

llvm/lib/Object/XCOFFObjectFile.cpp
509

I would much prefer to perform the addition before the cast.

llvm/tools/llvm-readobj/XCOFFDumper.cpp
155

s/STYP_OVRFLO/_OVERFLOW_MARKER/;

There's no _OVERFLOW_MARKER in the code currently, so we might want to add an appropriate named constant.

sfertile updated this revision to Diff 208179.Jul 5 2019, 7:29 AM
sfertile marked 2 inline comments as done.
  • Perform address arithmetic on const char* before casting to a uintptr_t.
    • Fixup comment. NumberOfX == STYP_OVRFLO doesn't make sense as STYP_OVRFLO is a section type. _OVERFLOW_MARKER is the name of the constant representing the overflow marker value.
sfertile marked 4 inline comments as done.Jul 5 2019, 7:33 AM
sfertile added inline comments.
llvm/lib/Object/XCOFFObjectFile.cpp
509

Good catch, updated.

llvm/tools/llvm-readobj/XCOFFDumper.cpp
155

Updated the comment.

I didn't add the named constant yet because its not used in the code anywhere and I though expressing how there are 32-bit and 64-bit values for _OVERFLOW_MARKER with the 64-bit value (IIUC) not actually representing overflow difficult to do without the overflow handling code.

This revision is now accepted and ready to land.Jul 5 2019, 7:54 AM
This revision was automatically updated to reflect the committed changes.
sfertile marked 2 inline comments as done.