This is an archive of the discontinued LLVM Phabricator instance.

[yaml2obj] - Allow setting the symbol st_other field to any integer.
ClosedPublic

Authored by grimar on Aug 22 2019, 5:05 AM.

Details

Summary

st_other field of a symbol usually contains its visibility.
Other bits are usually 0, though some targets, like
MIPS can set them using the named bit field values.

Problem is that there is no way to set an arbitrary value now,
though that might be useful for our test cases.

In this patch I introduced a way to set st_other to any numeric
value using the new StOther field.
I added a test and simplified the existent one to show the effect/benefit.

Diff Detail

Event Timeline

grimar created this revision.Aug 22 2019, 5:05 AM
jhenderson added inline comments.Aug 22 2019, 5:37 AM
lib/ObjectYAML/ELFYAML.cpp
893

helds -> holds

YAML -> YAML document

894

into the two fields -> into two fields

The last -> The former

895

"and so almost never printed. Though some targets..." -> "and so is almost never printed, although some targets..."

897

producing the broken -> producing broken

898

values -> value

899

YAML -> YAML document

I'd rephrase the rest of the sentence as follows: "we set st_other to that integer, ignoring the other fields."

I do wonder whether it should be an error if StOther is specified at the same time as either Visibility or Other.

test/tools/yaml2obj/elf-symbol-stother.yaml
2

"sets the value of a symbol's..."

4

report -> reports
when -> when using an

5

is used in -> to what is specified by the

9

Nit: the lining up here looks a bit messy. I think you can just delete a single space before "Other:"

21

I'd change this first line to "Test that STO_* can be used with their correct machine type."

42

we can use "StOther" -> we can use the "StOther"

to set any arbitrary value to -> to set st_other to any arbitrary value

52

Testing the exact printing here seems somewhat irrelevant to yaml2obj, I think? I think all that's important is that the Other value is correct (and that we don't error for MIPS values/unknown values etc as you already do).

In other words, I think you only need to test "Other [ (0x4)" and "Other [ (0xFF)" with their symbol names.

By the way, do you think there's a risk that the wrong symbol's Other value will be checked here? The check will match the first "Other [ (0x4)" line, not necessarily the Other line that goes with "foo".

grimar updated this revision to Diff 216619.Aug 22 2019, 7:45 AM
grimar marked 16 inline comments as done.
  • Addressed review comments.
lib/ObjectYAML/ELFYAML.cpp
894

The last -> The former

I think you meant "-> The latter", as I really meant that "Other" usually holds no value.

899

I do wonder whether it should be an error if StOther is specified at the same time as either Visibility or Other.

It is reasonable, but not that easy it seems.

Currently, if for example, you have both StOther and Other:

- Name:    bar
    StOther: 0xff
    Other: [ STO_MIPS_OPTIONAL ]

then yaml2obj reports an "unknown key" error:

YAML:72:14: error: unknown key 'Other'
    Other: [ STO_MIPS_OPTIONAL ]

(because mapOptional is never called for Other/Visibility in this case).

It is sure not ideal. At first look the right way seems to be to check it in MappingTraits<ELFYAML::Symbol>::validate below
somehow. Perhaps we might need to store both Other and StOther as Optional<> for that.
Or, as an alternative perhaps we could change MappingNormalization/NormalizedOther and report a correct
error right here. Seems it is not the best place for error reporting though.

Since we do not allow specifying these options at the same time currently,
what about if I'll investigate more how to improve the error we report and suggest a follow up patch?

test/tools/yaml2obj/elf-symbol-stother.yaml
52

By the way, do you think there's a risk that the wrong symbol's Other value will be checked here? The check will match the first "Other [ (0x4)" line, not necessarily the Other line that goes with "foo".

Yeah, I thougt about that a bit when wrote, but supposed there is no risk, since we have only two symbols here.
Though I see no problems with making the test a bit stricter. I've done it.

jhenderson accepted this revision.Aug 23 2019, 1:10 AM

LGTM, with one remaining comment nit.

lib/ObjectYAML/ELFYAML.cpp
894

Yes, sorry.

899

Doing it in the validate function seems right to me (we already do that for other fields). Happy for it to be a follow-up though, if it's easier.

test/tools/yaml2obj/elf-symbol-stother.yaml
4

You missed the "when using an" bit...

This revision is now accepted and ready to land.Aug 23 2019, 1:10 AM
MaskRay accepted this revision.Aug 23 2019, 2:08 AM

All of MIPS/PPC64/AArch64 can make use of these st_other bits now.

grimar added a comment.EditedAug 23 2019, 2:13 AM

All of MIPS/PPC64/AArch64 can make use of these st_other bits now.

But do they need it? I see that yaml2obj supports only MIPS flags atm:

void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
                                                  ELFYAML::ELF_STO &Value) {
  const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
  assert(Object && "The IO context is not initialized");
#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
  switch (Object->Header.Machine) {
  case ELF::EM_MIPS:
    BCase(STO_MIPS_OPTIONAL);
    BCase(STO_MIPS_PLT);
    BCase(STO_MIPS_PIC);
    BCase(STO_MIPS_MICROMIPS);
    break;
  default:
    break; // Nothing to do
  }
#undef BCase
#undef BCaseMask
}

A normal way for PPC64/AArch64/(?) would be to teach yaml2obj about their flags and use an existent "Other" field
(instead of "StOther" added by this patch).

This is still useful for testing new STO_* flags and broken values on these targets though.

This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2019, 2:35 AM
Herald added a subscriber: hiraditya. · View Herald Transcript

All of MIPS/PPC64/AArch64 can make use of these st_other bits now.

But do they need it? I see that yaml2obj supports only MIPS flags atm:

void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
                                                  ELFYAML::ELF_STO &Value) {
  const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
  assert(Object && "The IO context is not initialized");
#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
  switch (Object->Header.Machine) {
  case ELF::EM_MIPS:
    BCase(STO_MIPS_OPTIONAL);
    BCase(STO_MIPS_PLT);
    BCase(STO_MIPS_PIC);
    BCase(STO_MIPS_MICROMIPS);
    break;
  default:
    break; // Nothing to do
  }
#undef BCase
#undef BCaseMask
}

A normal way for PPC64/AArch64/(?) would be to teach yaml2obj about their flags and use an existent "Other" field
(instead of "StOther" added by this patch).

This is still useful for testing new STO_* flags and broken values on these targets though.

In PPC64, these bits are not used separately for difference purposes. Instead, it is shifted to represent a number, which encodes the localentry value. StOther might be the best to represent that piece of information.