[PATCH] D81585: [AIX][XCOFF][Patch1] Provide decoding trace back table information API for xcoff object file for llvm-objdump -d
Digger via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 21 08:03:12 PDT 2020
DiggerLin marked 14 inline comments as done.
DiggerLin added inline comments.
================
Comment at: llvm/include/llvm/BinaryFormat/XCOFF.h:320
+ static constexpr uint32_t IsInterruptHandlerMask = 0x0000'0080;
+ static constexpr uint32_t HasFunctionNamePresentMask = 0x0000'0040;
+ static constexpr uint32_t IsAllocaUsedMask = 0x0000'0020;
----------------
jhenderson wrote:
> Does this name reflect a name from a specification? I'd expect it to be `IsFunctionNamePresentMask` or possibly `HasFunctionNameMask` otherwise ("is" expects an adjective, i.e. "present", whereas has would expect a noun, i.e. "name").
thanks. it maybe better to change to IsFunctionNamePresentMask
================
Comment at: llvm/include/llvm/BinaryFormat/XCOFF.h:350
+ static constexpr uint32_t ParmTypeIsFloatingBit = 0x8000'0000;
+ static constexpr uint32_t ParmTypeFloatingIsDoubleBit = 0x4000'0000;
+};
----------------
jhenderson wrote:
> I don't have any XCOFF knowledge, but should this be `ParmTypeIsFloatingDoubleBit`?
I think the name "ParmTypeFloatingIsDoubleBit" express the spec better.
I copied some content from the file of /usr/include/sys/debug.h of aix OS.
* a structure or an union. Whether or not portions exist is determinable
* from bit-fields within the base procedure-end table.
*
* parminfo exists if fixedparms or floatparms != 0.
* tb_offset exists if has_tboff bit is set.
* hand_mask exists if int_hndl bit is set.
* ctl_info exists if has_ctl bit is set.
* ctl_info_disp exists if ctl_info exists.
* name_len exists if name_present bit is set.
* name exists if name_len exists.
* alloca_reg exists if uses_alloca bit is set.
* vec_ext exists if has_vec bit is set.
*/
struct tbtable_ext {
unsigned int parminfo; /* Order and type encoding of parameters:
* Left-justified bit-encoding as follows:
* '0' ==> fixed parameter
* '10' ==> single-precision float parameter
* '11' ==> double-precision float parameter
*
* if has_vec is set, encoded as follows:
* '00' ==> fixed parameter
* '01' ==> vector parameter
* '10' ==> single-precision float parameter
* '11' ==> double-precision float parameter
*/
unsigned int tb_offset; /* Offset from start of code to tb table */
int hand_mask; /* What interrupts are handled by */
int ctl_info; /* Number of CTL anchors, followed by */
int ctl_info_disp[1]; /* Actually ctl_info_disp[ctl_info] */
/* Displacements into stack of each anchor */
short name_len; /* Length of procedure name */
char name[1]; /* Actually char[name_len] (no NULL) */
char alloca_reg; /* Register for alloca automatic storage */
struct vec_ext vec_ext; /* Vector extension (if has_vec is set) */
unsigned char xtbtable; /* More tbtable fields, if longtbtable is set*/
};
================
Comment at: llvm/lib/Object/XCOFFObjectFile.cpp:890
+
+ DE.getU64(&OffsetPtr, &Err);
+
----------------
jhenderson wrote:
> DiggerLin wrote:
> > jhenderson wrote:
> > > Not sure if you've come across it yet, but you could simplify all these calls using `DataExtractor::Cursor` instead. This stores the error internally, whilst also allowing you to continue parsing to the end, with no harmful effects (because nothing is read if `Cursor` is in an error state), similar to `Err` being passed in everywhere. It also tracks the offset. Usage is:
> > >
> > > ```
> > > DataExtractor::Cursor C(/*Offset=*/0);
> > > DE.getU64(C); // By the way, what is this value for?
> > > ...
> > > // No need for ifs here.
> > > CodeLen = DE.getU32(C);
> > > HandlerMask = DE.getU32(C);
> > > ...
> > >
> > > Err = C.takeError();
> > > ```
> > I considered to use Cursor before, but most of our data member are Optianl I think it maybe better to keep current implement, using Cursor, it still get a value(for example zero), and the CodeLen, ParaType, FunctionName etc are Optional type. it will do Optional &operator=(T &&y) for all the fields(CodeLen HandlerMask etc,) even if there is error before and if will always call parseParaType(). I do not think it is efficient.
> I don't think the `return 0` behaviour of `Cursor` in the event of an error stops you using it. You can still do `if (C)` to check whether you should do a thing, just like you do with `if (!Err)`. For example:
>
> ```
> DataExtractor::Cursor C(Offset);
> DE.getU64(C);
> if (C)
> ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
> if (C && ParmNum > 0 && !hasVectorInfo())
> ParmsType = parseParmsType(DE.getU32(C), ParmNum);
> if (C && hasTraceBackTableOffset())
> TraceBackTableOffset = DE.getU32(C);
>
> ...
> Offset = C.tell();
> Err = C.takeError();
> ```
>
> It doesn't save much, but I find the get* functions easier to read that way.
thanks
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D81585/new/
https://reviews.llvm.org/D81585
More information about the llvm-commits
mailing list