Right now Symbols must be either undefined or defined in a specific section. Some symbols have section indexes like SHN_ABS however. This change adds support for outputting symbols that have such section indexes.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/ObjectYAML/ELFYAML.cpp | ||
---|---|---|
491 | SHN_XINDEX is a special animal unlike other special cases. It means the real shndx value is elsewhere. See SHN_XINDEX handling elsewhere in the code base (or the ELF spec). SHN_UNDEF, SHN_ABS, and SHN_COMMON are standard special cases. Those just go through as they are. SHN_{LO,HI}* are not actual values, but markers for the ranges used for machine-specific and OS-specific values. I think you need to handle each such value specially, because the correct way to treat it will depend on the specific machine/OS-specific definition. |
lib/ObjectYAML/ELFYAML.cpp | ||
---|---|---|
491 | This is just code that translates strings of t he form " SHN_* " to the appropriate value for use anywhere in yaml2elf. It doesn't handle what happens in these cases any further than that. I think there's an argument that SHN_{LO,HI}* shouldn't be here since you would never want to use those names when building an ELF object. The rest of the file however includes such values however (see SHT_LOOS and SHT_LOPROC in the equivliant code for section types) so I followed suit. In general ELF_SHN should be the type of values with names SHN_* in this code base; even the ones which are not logically values you would want to use in a yaml file to produce an ELF. |
lib/ObjectYAML/ELFYAML.cpp | ||
---|---|---|
491 | Understood. I think you still need to handle SHN_XINDEX specially though, because it has a structural meaning. You should certainly handle all the reserved-range SHN_* names in include/llvm/BinaryFormat/ELF.h (there are more that binutils groks). |
lib/ObjectYAML/ELFYAML.cpp | ||
---|---|---|
491 | I think sean would likely say that yaml2obj should handle large indexes automagically, following the logic that it should be hard to produce invalid files. That being the case I don't think I want to support large indexes in this patch. Perhaps I should throw an error if the user creates a large SHN_XINDEX? As is you can't produce a valid file that uses large section indexes because there's no support for SHT_SYMTAB_SHNDX (I would have to add that). |
lib/ObjectYAML/ELFYAML.cpp | ||
---|---|---|
491 | It sounds fine to have this change only add support for the known SHN_* names. Perhaps it should recognize SHN_XINDEX as a name, but specifically refuse to write it out, since you should never use it explicitly if yaml2obj should not easily produce invalid ELF files. You should also make sure that it refuses numeric section numbers >= SHN_LORESERVE. A separate change to produce SHT_SYMTAB_SHNDX automagically for large number section numbers makes sense. |
- Added support for the rest of the SHN_* values in ELF.h
- An error should now be thrown if the user tries to use SHN_XINDEX
- Added check to make sure the users uses "Section: <section name>" to specify section indexes and not "Index: <value>"
Not being expert in the yaml2obj code base, this looks good to me with the caveats below.
include/llvm/ObjectYAML/ELFYAML.h | ||
---|---|---|
53 | This is actually a 16-bit field in ElfNN_Sym. | |
lib/ObjectYAML/ELFYAML.cpp | ||
743 | It looks like llvm::Optional has both operator* and operator==/operator< et al that essentially forward the operator to the value that operator* would yield (in the has-value case, anyway--the overall semantics of the comparison operators on Optional are a bit weird, and I think there's some implicit copy construction in there too), so either Symbol.Index or *Symbol.Index works here, but you should be consistent, and *Symbol.Index looks more natural next to the Symbol.Index->bool test (and I suspect is the only pattern with sensible semantics when dealing with Optional<T> where T is not a trivial POD type like this one). |
I agree that it should be *Symbol.Index. This was a mistake on my part.
- Fixed not dereferencing the optional value
- Changes indexes to be 16-bit instead of 32-bit
Ideally I'd like to have Sean or Simon look at this first before landing.
Sorry for the delay.
One suggestion for paring down the recognized SHN_* list and how I'm personally conceptualizing my thought process for what to include there.
This LGTM.
lib/ObjectYAML/ELFYAML.cpp | ||
---|---|---|
491 | I agree with jake that the SHN_XINDEX is purely an artifact of the file encoding, so we probably don't want to allow the user to explicitly provide it (seems too error-prone) It might be interesting to add an error check/diagnostic in the case of too many sections in the input yaml file, but for now just omitting SHN_XINDEX from the list of possibilities seems fine. There probably isn't much harm in keeping in the SHN_{LO,HI}* values around, though I assume the common usage of them would be something like SHN_LORESERVE + <N> or similar so a hex value would likely still be needed (or adding support for a semantic constant like has been done for the hexagon ones). So I'd probably lean towards removing the SHN_{LO,HI}* values since it would make the test case difficult to read (for example, of somebody used SHN_LORESERVE instead of SHN_HEXAGON_SCOMMON which has the same numerical value). On the other hand, that breaks the simplicity of "what should we list in ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration", which is currently just every SHN_* it seems. So if we omit some we should definitely have a comment explaining the rationale for what values we allow/omit. For now, let's just follow a YAGNI principle and just support SHN_ABS since it seems that that's all you really need (and a comment to that effect in ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration). SHN_COMMON is a likely eventual need too. But SHN_UNDEF probably isn't since we handle undef symbols already by omitting the section (so in a sense it is a default value, though conceivably we could allow it to be explicitly specified). |
This is actually a 16-bit field in ElfNN_Sym.