[PATCH] D103490: [SystemZ][z/OS] Add support for TXT records in the GOFF reader
James Henderson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 9 01:13:59 PDT 2021
jhenderson added a comment.
In D103490#2806504 <https://reviews.llvm.org/D103490#2806504>, @yusra.syeda wrote:
> ping :)
Sorry, I've been away, and this is pretty low on my review priority list, so I haven't had a chance to look at this until now.
================
Comment at: llvm/include/llvm/Object/GOFF.h:95
+public:
+ /// \brief Maximum length of data; any more must go in continuation.
+ static const uint8_t TXTMaxDataLength = 56;
----------------
================
Comment at: llvm/include/llvm/Object/GOFF.h:103
+
+ static void getElementEsdId(const uint8_t *Record, uint32_t &EsdId) {
+ get<uint32_t>(Record, 4, EsdId);
----------------
What's the motivation for returning by updating an input parameter, rather than returning via the return type?
================
Comment at: llvm/include/llvm/Object/GOFFObjectFile.h:33
class GOFFObjectFile : public ObjectFile {
+ friend class GOFFSymbolRef;
+
----------------
There may be a perfectly valid reason for this, but why make this a friend class rather than just making the relevant functions public?
================
Comment at: llvm/include/llvm/Object/GOFFObjectFile.h:36
IndexedMap<const uint8_t *> EsdPtrs; // Indexed by EsdId.
+ SmallVector<const uint8_t *, 256> TextPtrs;
----------------
Any particular reason you've chosen the size 256 here and in various other places? It may deserve a comment or some sort of named constant.
================
Comment at: llvm/include/llvm/Object/GOFFObjectFile.h:70-71
+ bool isSectionNoLoad(DataRefImpl Sec) const;
+ bool isSectionReadOnlyData(DataRefImpl Sec) const;
+ bool isSectionZeroInit(DataRefImpl Sec) const;
----------------
What's the motivation for adding these two functions at this point? It seems like a bad idea to expand the interface without a use-case (and if there is a use-case, what is it)?
================
Comment at: llvm/include/llvm/Object/GOFFObjectFile.h:72
+ bool isSectionReadOnlyData(DataRefImpl Sec) const;
+ bool isSectionZeroInit(DataRefImpl Sec) const;
+
----------------
By name, this function sounds awfully like `isSectionBSS` (which for ELF at least means a section that is allocated space and zero-initialised at load time).
================
Comment at: llvm/include/llvm/Object/GOFFObjectFile.h:130
+public:
+ GOFFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
+ assert(isa<GOFFObjectFile>(SymbolRef::getObject()));
----------------
`*Ref` types are designed to be copied. Don't pass them as `const &`.
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:432
+ LLVM_DEBUG(dbgs() << "Got section: " << Res << '\n');
+ // TODO: Make clang look for C____clangast instead of this
+ if (Res.equals("C___clangast"))
----------------
This TODO sounds a bit odd. What does the clang compiler have to do with this code?
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:478
+ ESDRecord::getFillBytePresent(EdEsdRecord, FillBytePresent);
+ uint8_t FillByte = '\0';
+ if (FillBytePresent)
----------------
Any particular reason you've used `'\0'` rather than simply `0`? After all, you're storing it in a `uint8_t` (a number) rather than a `char`/`unsigned char`.
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:519-520
+
+ StringRef Res = StringRef(Data);
+ return arrayRefFromStringRef(Res);
+}
----------------
Why not simply `return arrayRefFromStringRef(StringRef(Data));`? In fact, could you get away with returning simply `Data.data()` or similar?
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:527
+ ESDRecord::getAlignment(EsdRecord, Pow2Alignment);
+ uint64_t ByteAlignment = 1 << (uint64_t)Pow2Alignment;
+ return ByteAlignment;
----------------
I'm pretty sure the right hand side of this function will return an `int` because that's the type of the literal `1` in this context. I think you want to do `UINT64_C(1)` to force the type of the literal (and therefore the result of the left-shift operation) to 64-bit.
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:539-540
+ ESDRecord::getExecutable(EsdRecord, Executable);
+ bool IsSectionText = (Executable == GOFF::ESD_EXE_CODE);
+ return IsSectionText;
+}
----------------
Don't add unnecessary local variable. Same below for the other functions.
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:564-573
+ bool Result;
+ if (isSectionData(Sec)) {
+ const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
+ GOFF::ESDLoadingBehavior LoadingBehavior;
+ ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
+ Result = LoadingBehavior == GOFF::ESD_LB_Initial;
+ } else {
----------------
================
Comment at: llvm/lib/Object/GOFFObjectFile.cpp:576-580
+bool GOFFObjectFile::isSectionZeroInit(DataRefImpl Sec) const {
+ // GOFF uses fill characters and fill characters are applied
+ // on getSectionContents() - so we say false to zero init.
+ return false;
+}
----------------
Why are you adding this function?
================
Comment at: llvm/unittests/Object/GOFFObjectFileTest.cpp:507
+TEST(GOFFObjectFileTest, TXTConstruct) {
+ char GOFFData[GOFF::RecordLength * 6] = {0x00};
+
----------------
You can omit the explicit 0 from here. This will zero-initialise the whole array.
================
Comment at: llvm/unittests/Object/GOFFObjectFileTest.cpp:587
+
+
+ for (SymbolRef Symbol : GOFFObj->symbols()) {
----------------
Get rid of double blank line.
================
Comment at: llvm/unittests/Object/GOFFObjectFileTest.cpp:595
+
+ for (const SectionRef &Section : GOFFObj->sections()) {
+ Expected<StringRef> SectionContent = Section.getContents();
----------------
================
Comment at: llvm/unittests/Object/GOFFObjectFileTest.cpp:600-603
+ const char *Str = "\x12\x34\x56\x78\x9a\xbc\xde\xf0";
+ StringRef Expected(Str);
+
+ ASSERT_EQ(Expected, Contents);
----------------
You should be able to just do `EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0");`
Use `EXPECT_EQ` because one section's content not being right shouldn't impact other sections, same as with the SymbolName check above.
Additionally, you need checks that `symbols()` and `sections()` return the right number of symbols and sections somewhere. Your test would pass as things stand, if `symbols()` or `sections()` returned an empty list (and therefore no looping occurred).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103490/new/
https://reviews.llvm.org/D103490
More information about the llvm-commits
mailing list